Skip to content

Releases: CounterpartyXCP/counterparty-core

v11.2.0

Choose a tag to compare

@ouziel-slama ouziel-slama released this 08 Jul 11:50
ca2496d

Release Notes - Counterparty Core v11.2.0 (2026-07-08)

Counterparty Core v11.2.0 focuses on smaller databases, faster API paths, clearer API validation and a set of gated protocol fixes. The upgrade path is the same as usual; the main operational difference is a one-time Ledger DB compaction on first start, so operators should schedule the restart for a window where a longer startup is acceptable.

Upgrading

Upgrade Instructions:

To upgrade, download the latest version of counterparty-core and restart counterparty-server.

With Docker Compose:

cd counterparty-core
git pull
docker compose stop counterparty-core
docker compose --profile mainnet up -d

or use ctrl-c to interrupt the server:

cd counterparty-core
git pull
cd counterparty-rs
pip install -e .
cd ../counterparty-core
pip install -e .
counterparty-server start

The Ledger DB is automatically compacted on first start of v11.2.0 (migration 0010.compact_hash_storage). No manual reparse is required. On large databases this can take a while and temporarily needs extra free disk space while SQLite rewrites and vacuums the DB; keeping a normal pre-upgrade backup or snapshot is recommended.

ChangeLog

API Breaking Changes

  • Unknown query parameters are now rejected with a 400 error instead of being silently ignored; each route only accepts its own documented parameters.
  • Stricter parameter validation: booleans, enums, dust sizes, fees, confirmation_target (1–1008), utxo_value, more_outputs/inputs_set values, duplicate or out-of-range UTXOs, dispense quantity and memo types are now validated. Previously-tolerated invalid values now return a clean 400 instead of being coerced or causing a 500.
  • compose/dispense response change: in the returned params, source is renamed to address and destination to dispenser, and quantity_normalized is added.
  • The non-functional sort parameter was removed from the multi-address balances route (/v2/addresses/<addresses>/balances).

Protocol Changes

The activation block heights are 961100 (mainnet), 5064400 (testnet3), 147200 (testnet4) and 316200 (signet) — targeting roughly 2026-08-03; the one exception is fairmint_pool, which is also active on signet from genesis (signet_block_index: 0) for testing:

  • sweep_skip_zero_balances: sweeps no longer include zero-quantity balances, the anti-spam fee is computed only over the balances/ownerships selected by the sweep flags, and an empty sweep is no longer charged the legacy flat fee.
  • issuance_callable_lock_fix: removes the obsolete "cannot change callability / advance call date / reduce call price" reissuance restrictions (the issuance_callability_parameters_removal guard is preserved).
  • multisig_utxo_addresses: bare multisig (P2MS) UTXOs now resolve to an address instead of failing with "vout does not have an address".
  • fix_fairminter_commission_minimum: rejects a minted_asset_commission between 0 and 0.0000001 (which would round to zero).
  • Add fairmint pool seeding behind a new fairmint_pool gate: compose_fairminter accepts two new optional fields — pool_quantity (tokens to reserve for the AMM pool) and lp_asset (numeric asset to use as LP token, auto-generated if omitted) — which, when the fairminter closes at soft cap, automatically creates a constant-product AMM pool seeded with pool_quantity of the minted asset and the corresponding XCP proceeds; hard_cap must equal existing_supply + premint_quantity + pool_quantity + soft_cap (all mintable supply is reserved for buyers or the pool), burn_payment is disallowed, and the issuer must hold sufficient XCP to cover the pool-deposit gas fee at compose time; pool creation is deferred to the after_block hook so it is gated on the same block as fairminter close; the LP token is earmarked against the active fairminter to prevent griefing.
  • fix_pool_deposit_product_overflow: removes a redundant quantity_a * quantity_b > MAX_INT overflow check in pooldeposit.validate() that rejected otherwise-valid large AMM deposits — it capped each side of a balanced divisible pair at floor(sqrt(MAX_INT)) raw units (~30.37 divisible units) even when both quantities, the minted LP amount, balances, and stored reserves were each individually valid (#3324).
  • fix_pool_best_price_routing: fixes AMM best-price routing under integer pool math. compute_pool_input_for_target_price() solved a continuous-price quadratic while execution floors the pool output to an integer (compute_pool_output), so a pool fill that was actually cheaper than the next book order could floor to zero output and send the taker to the worse book order (and misroute in the other direction); routing is now consistent with the integer execution (#3325).
  • enforce_utxo_vout_max: a tx_hash:vout UTXO reference whose vout exceeds 0xFFFFFFFF (4294967295) is no longer recognized as a valid UTXO format. UTXO-format detection routes a transaction's attach/detach and debit/credit classification, so this is a consensus change; before activation the legacy behavior is kept (any non-negative integer vout that round-trips through str(int(...)) is accepted).

Performance

  • Compact hash storage in the Ledger DB: transaction hashes, block hashes and other fixed-size hex strings are now stored as raw 32-byte BLOBs instead of 64-char hex strings, cutting hash-column storage roughly in half. A new migration (0010.compact_hash_storage) rewrites all affected tables and runs VACUUM afterwards; a new hashcodec module handles encoding/decoding transparently so the rest of the codebase is unaffected. The migration runs automatically during upgrade and may need additional temporary disk space while it completes.
  • Composite match-ID normalization (folded into 0010.compact_hash_storage): the 129-char tx0hash_tx1hash TEXT match id is replaced by an integer (tx0_index, tx1_index) foreign-key pair on order_matches, bet_matches, rps_matches, the three *_match_expirations tables, bet_match_resolutions, btcpays and rpsresolves. The textual id / *_match_id is reconstructed on read at the API and consensus boundaries, so the public API surface and the consensus hashes are unchanged.
  • Asset normalization (folded into 0010.compact_hash_storage): the assets table gains a compact, sequentially-assigned asset_index INTEGER PRIMARY KEY surrogate, and every asset-name TEXT column (asset, give_asset, get_asset, forward_asset, backward_asset, dividend_asset, asset_parent, asset_a, asset_b on balances, credits, debits, sends, orders, order_matches, issuances, dividends, dispensers, dispenses, dispenser_refills, fairminters, fairmints, destructions, pools, pool_deposits, pool_withdrawals, pool_matches) is replaced by the compact integer asset_index foreign key — 1–3 bytes per reference instead of the full asset name. The protocol assets.asset_id and lp_asset columns stay TEXT. The asset name is transparently restored on read (the rowtracer decodes asset_index → name) and re-encoded on write, so consensus hashes and the public API (which still returns/filters by asset name) are unchanged. The State DB keeps asset names (the consolidation decodes index → name while the Ledger DB is attached). Note: invalid records referencing a never-registered asset store NULL.
  • Address normalization (folded into 0010.compact_hash_storage): a new address_list(address_id INTEGER PRIMARY KEY, address TEXT UNIQUE) table assigns every distinct address a compact id, and every address TEXT column (source, destination, address, source_address, destination_address, issuer, feed_address, tx0_address, tx1_address, winner, oracle_address, origin, last_status_tx_source, utxo_address across the ledger tables) is replaced by the compact integer address_id foreign key. The address string is transparently restored on read (the rowtracer decodes address_id → address) and re-encoded on write, so consensus hashes and the public API (which still returns/filters by address) are unchanged. The State DB keeps addresses as strings (the consolidation decodes id → address while the Ledger DB is attached). The existing addresses options-history table is preserved; its address column is FK'd onto address_list. mempool.addresses (a comma-separated list) and mempool_transactions are left as TEXT.
  • UTXO column compaction (folded into 0010.compact_hash_storage): the utxo TEXT column (tx_hash:vout, ~67 chars) on balances, credits and debits is replaced by a compact (utxo_tx_hash BLOB(32), utxo_vout INTEGER) pair (~36 bytes). The tx_hash is stored as a raw BLOB rather than a tx_index foreign key because an attached UTXO may reference any valid bitcoin transaction (not only Counterparty transactions). The utxo string is transparently reconstructed on read by the rowtracer, so consensus hashes and the public API are unchanged.

Bugfixes

  • Close fairminter when hard cap is hit after the soft-cap deadline has passed
  • Close non-pool fairminter when hard cap is hit before the soft-cap deadline (was leaving the fairminter open after escrow distribution)
  • Fix stale-row lookup in get_fairminters_by_soft_cap_deadline (was returning superseded rows)
  • Fix connection_count leak in APSWConnectionPool causing MAINPROCESS_POOL to exhaust over time (per-request threads in APIv1 left cached connections counted forever)
  • Fix NotSupportedTransactionsCache unbounded growth: the in-memory cache of not-supported transactions grew without limit (reaching hundreds of MB) and was rewritten to disk and reloaded across restarts; it is now size-bounded and no longer persisted on every update (#3397)
  • Don't charge an oracle fee when closing a dispenser
  • Preserve subasset ...
Read more

v11.1.0

Choose a tag to compare

@ouziel-slama ouziel-slama released this 20 May 13:38
e712931

Release Notes - Counterparty Core v11.1.0 (2026-05-20)

This release introduces two major new protocol features — Automated Market Maker liquidity pools and indefinite DEX orders — alongside extended inscription support and a substantial hardening pass on the consensus parser, indexer, and API layers. Protocol changes activate at mainnet block 952500.

Upgrading

Upgrade Instructions:

To upgrade, download the latest version of counterparty-core and restart counterparty-server.

With Docker Compose:

cd counterparty-core
git pull
docker compose stop counterparty-core
docker compose --profile mainnet up -d

or use ctrl-c to interrupt the server:

cd counterparty-core
git pull
cd counterparty-rs
pip install -e .
cd ../counterparty-core
pip install -e .
counterparty-server start

The State DB is automatically rebuilt on first start of v11.1.0 (migration 0004 fix).

ChangeLog

Protocol Changes

  • Add AMM (Automated Market Maker) liquidity pools behind a new amm_pools gate, with two new message types: pooldeposit (120) and poolwithdraw (121); BTC pairs are explicitly rejected. Deposits/withdraws use standard constant-product math (LP tokens minted via floor(sqrt(qa*qb)) on first deposit, then proportionally; withdrawals burn LP tokens for proportional reserve shares), support slippage bounds (min_lp_quantity, min_quantity_a/b) and pay an XCP gas fee. The DEX match() loop now interleaves pool fills with the resting book at every step (constant-product, fee-adjusted, with XCP_POOL_FEE_BPS=50 for XCP pairs and 100 otherwise), then sweeps any remainder against the pool in a tail phase. Pool reserves are counted in held() for asset conservation. Five new events (OPEN_POOL, POOL_UPDATE, NEW_POOL_DEPOSIT, NEW_POOL_WITHDRAWAL, POOL_MATCH) and four new tables (pools, pool_deposits, pool_withdrawals, pool_matches) are added via ledger migration 0009.amm_pools.sql and consolidated into the State DB by migration 0014.add_pool_consolidated_tables (registered in MIGRATIONS_AFTER_ROLLBACK, also rebuilds asset_holders / xcp_holders to include pool reserves).
  • Add support for indefinite DEX orders and fix expiration semantics behind a new indefinite_orders gate: expiration=0 now means indefinite (open until filled or cancelled, expire_index = NULL), expiration=N now means exactly N blocks of life (was N+1 due to a long-standing off-by-one), and MAX_EXPIRATION is raised from 8064 (~56 days) to 65535 (the wire-format u16 max, ~455 days). The wire format is unchanged.
  • Allow CBOR map under tag 0x05 for ordinals-style provenance metadata in taproot inscriptions, behind a new ordinals_metadata_support gate. The Counterparty message is extracted from the "xcp" array key; other keys are ordinals metadata ignored by the consensus parser.
  • Extend MIME type support for ordinal-style inscriptions behind a new extended_mime_types_support gate: tolerate MIME parameters (e.g. audio/ogg;codecs=opus), recognise the +json structured suffix as textual, and validate against a deterministic hard-coded allow-list (EXTENDED_MIME_TYPES_VALID) instead of mimetypes.types_map, which read /etc/mime.types / the Windows registry and varied per node

Other Features

  • Support multiple Electrs backends with automatic failover on connection, timeout, or HTTP errors; --electrs-url can now be specified multiple times; default mainnet Electrs backends to both blockstream.info and mempool.space; print a startup warning when using default Electrs URLs (not recommended for production)

Bugfixes

  • Catch struct.error in issuance.unpack to prevent consensus halt
  • Catch NoPriceError in dispense.parse to prevent consensus halt
  • Harden issuance and broadcast parse against CBOR-crafted halt vectors
  • Fix two hand-rolled-tx halt vectors found by fuzzing
  • Fix two asset-name halt vectors found by name-generation audit
  • Reject non-canonical compacted subasset longname behind a new gate
  • Reject non-positive oracle prices in dispense.get_must_give
  • Catch AssetIDError in dispenser.unpack behind a new catch_invalid_dispenser_asset_id gate to prevent consensus halt on invalid dispenser asset ids
  • Reject btcpay where tx destination doesn't match order match counterparty
  • Fix bet match sort no-op behind new fix_sort_bet_matches gate
  • Fix Python truthiness bug in attach OP_RETURN check (gated)
  • Set transactions_status and persist invalid record in sweep.parse
  • Forward tx["block_index"] into gated unpack() and protocol.enabled() calls; hoist fairminter fee to int and forward block_index to issuance fee gates
  • excludes_utxos supports now <txid>:<vout> and <txid> alone
  • Add missing max_mint_per_address parameter in compose_fairminter()
  • Fix shutdown during rate limit backoff
  • Fix missing limit parameter validation in API v2 (was not enforced unlike API v1)
  • Fix MalformedPointError when searching for pubkey in P2WSH multisig witness data
  • Fix Rust BATCH_CLIENT permanently caching failed parent transaction lookups, which could cause valid Counterparty transactions to be silently skipped
  • Add warning log when a parent transaction cannot be found during VIN resolution
  • Fix KeyboardInterrupt raised in the main thread during shutdown that could break the shutdown sequence half-way through (e.g. while joining the Asset Conservation Checker thread on SIGTERM)
  • Fix four u32 underflow patterns in the Rust indexer
  • Fix off-by-one and short-prefix panics in parse_vout
  • Replace expect() in get_funding_block_entries with a typed Error
  • Catch malformed protocol_changes.json shape in software_version()
  • Scope Decimal context changes to localcontext so precision doesn't leak
  • Update BackendHeight.last_check in a finally so RPC failures don't spam
  • Don't let halt-class mempool transactions tear down the BlockchainWatcher; harden it against transient operational failures
  • Reorg + mempool hygiene: stale events, leak, horizon, reparse cache
  • Fix stale mempool/events after RPC catch-up paths (receive_rawblock previous-block-missing branch and handle() ZMQ-late branch): both now sweep the mempool table after catch_up(), matching the streamed receive_rawblock path
  • Clear bitcoind transaction cache on rollback to avoid stale deserialisation; encapsulate in reset_caches() helper
  • Clean orphaned transactions_status rows on rollback and rebuild
  • Close ZMQ sockets/context before reconnect; fix RCVTIMEO typo
  • Make --api-only loop honor api_stop_event for clean shutdown
  • Make UTXOLocks intra-worker thread-safe
  • Concurrency: SingletonMeta double-checked locking; guard reset_caches lru_cache.cache_clear() with hasattr
  • Fix float rounding error in bitcoind.list_unspent (int(amount * UNIT)) that could produce off-by-one sat values, causing SegWit signatures computed from the returned value to be rejected by Bitcoin Core with a misleading mandatory-script-verify-flag-failed (Signature must be zero for failed CHECK(MULTI)SIG operation) error
  • Fix DETACH_FROM_UTXO source field typo in EVENTS_ADDRESS_FIELDS
  • Fix LEFT JOIN in API migration 0004 supplies query
  • Fix dispenser price in API: scale satoshirate / give_quantity by 1e8 when the dispensed asset is divisible, so the reported price matches a per-unit BTC price for both divisible and indivisible assets
  • Improve version check failure message in software_version(): include the PROTOCOL_CHANGES_URL and underlying error in both the log and the VersionCheckError raised to the user
  • Sync description_locked and filter xcp_supply by status in apiwatcher
  • Fix assets_info State DB population (migration 0004) so that description, divisible, mime_type and owner are derived from the latest valid issuance (matching the streamed apiwatcher semantics) instead of an implementation-defined row picked by SQLite from the aggregated set, and so that locked / description_locked are stored as 0/1 booleans (MAX(...)) rather than as SUM(...) integer counts. Snapshot-bootstrapped nodes will now agree with event-streamed nodes for these columns. The State DB is automatically rebuilt on first start of v11.1.0.

API

  • Block APIv1 SQL injection via filter_["field"]; redact secrets in logs
  • New AMM pool endpoints: GET /v2/pools, GET /v2/pools/<asset1>/<asset2> (with /deposits, /withdrawals, /matches, /price_history sub-resources), GET /v2/pools/<asset1>/<asset2>/quote (hybrid pool+book swap quote), /quote/deposit and /quote/withdraw, GET /v2/pool_matches, GET /v2/orders/<order_hash>/pool_matches, GET /v2/addresses/<address>/pools (LP positions), GET /v2/addresses/<address>/pool_deposits and /pool_withdrawals, GET /v2/blocks/<int:block_index>/pool_deposits / pool_withdrawals / pool_matches, plus the compose endpoints POST /v2/addresses/<address>/compose/pooldeposit and compose/poolwithdraw with their estimatexcpfees companions.

Codebase

  • Add fuzz tests
  • Add 10 regression tests for the audit fixes
  • Document expand_subasset_longname 200-byte cap reasoning
  • Document libm cross-platform threshold near gas.py sigmoid

Credits

  • Ouziel Slama
  • Dan Anderson
  • Adam Krellenstein

v11.0.4

Choose a tag to compare

@ouziel-slama ouziel-slama released this 20 Jan 22:19
1e3d8d4

Release Notes - Counterparty Core v11.0.4 (2026-01-20)

This release fixes a bug in UTXO balances cache rebuilding that caused some utxomove transactions to go undetected after a node restart. It also delivers significant performance improvements: startup time has been reduced from 8+ minutes to 33 seconds, and Kubernetes shutdown time from 182 seconds to 21 seconds. New CLI options (--db-connection-pool-size, --db-max-connections, --memory-profile) provide better control over database connections and memory monitoring. Additionally, the sat_per_vbyte parameter now supports sub-1 sat/vByte values (e.g., 0.5) for lower-fee transactions when network conditions permit. The API has been optimized with new indexes and faster case-insensitive asset queries. A rollback to block 926,807 will occur automatically on mainnet.

Upgrading

Upgrade Instructions:

To upgrade, download the latest version of counterparty-core and restart counterparty-server. A rollback to block 926,807 will occur automatically on mainnet.

With Docker Compose:

cd counterparty-core
git pull
docker compose stop counterparty-core
docker compose --profile mainnet up -d

or use ctrl-c to interrupt the server:

cd counterparty-core
git pull
cd counterparty-rs
pip install -e .
cd ../counterparty-core
pip install -e .
counterparty-server start

ChangeLog

Features

  • Support sub-1 sat/vByte fee rates (e.g., 0.5 sat/vByte) for transaction composition

Bugfixes

  • Fix current_commit in API root
  • Fix reorg edge case
  • Fallback to RPC when getzmqnotifications RPC call is not available
  • Fix RSFetcher restart
  • Fix state.db reorg
  • Fix UTXO cache building
  • Fix next_cursor in API results when sort is provided
  • Fix DB config params not being passed to API subprocess (caused connection pool contention)
  • Fix connection leak on pooled connection validation failure
  • Fix RSFetcher restart delay when recovering from errors

Codebase

  • Increase BURN_END_TESTNET3 to 99999999
  • Add graceful SIGTERM handling for Kubernetes deployments (shutdown time: 182s → 21s)
  • Improve Docker build caching for Rust components
  • Add block parsing timing instrumentation at debug level
  • Update Werkzeug to 3.1.4
  • Update PyO3 to 0.24.1
  • Eliminate 8-minute startup delay by storing event column in address_events table (startup time: 8+ min → 33s)
  • Add checkpoint for block 932500
  • Add interruptible sleep in Bitcoin core client for clean shutdown

Performance & Memory

  • Add configurable database connection pool limits (--db-connection-pool-size, --db-max-connections)
  • Add connection pool instrumentation (POOL_STATS logging every 60s with peak tracking and contention warnings)
  • Add memory profiler for monitoring cache sizes and process memory (--memory-profile, lightweight with no tracemalloc)
  • Convert NotSupportedTransactionsCache from O(n) list to O(1) set for faster lookups (backup file limit removed; cache cleared on rollback)
  • AssetCache loads all assets at startup (~70MB for 246k assets)
  • UTXOBalancesCache now cleans up spent UTXOs after each block to prevent unbounded memory growth
  • Improve RSFetcher restart logic

API

  • Fix slow asset lookups by using COLLATE NOCASE instead of UPPER() for case-insensitive queries
  • Add performance indexes for assets_info, balances, and dispensers tables
  • Optimize list deduplication in verbose mode using sets
  • Fix get_balances_by_address_and_asset endpoint

CLI

  • Add --db-connection-pool-size to configure connection pool size (default: 10)
  • Add --db-max-connections to limit total database connections across threads (default: 50, 0=unlimited)
  • Add --memory-profile to enable periodic memory usage logging

Credits

  • Ouziel Slama
  • Adam Krellenstein

v11.0.3

Choose a tag to compare

@ouziel-slama ouziel-slama released this 27 Oct 08:10
c580587

Release Notes - Counterparty Core v11.0.3 (2025-10-27)

This is a minor release that addresses three bugs in Counterparty Core: one in the caching of issuance transactions which can lead to mismatches in consensus hashes across nodes, and two bugs in the API (including another one also related to caching). All users should upgrade as soon as possible.

Upgrading

Upgrade Instructions:

To upgrade, download the latest version of counterparty-core and restart counterparty-server. An reparse to block 911,955 to correct the transaction cache will occur automatically.

With Docker Compose:

cd counterparty-core
git pull
docker compose stop counterparty-core
docker compose --profile mainnet up -d

or use ctrl-c to interrupt the server:

cd counterparty-core
git pull
cd counterparty-rs
pip install -e .
cd ../counterparty-core
pip install -e .
counterparty-server start

ChangeLog

Bugfixes

  • Fix get events by addresses endpoint
  • Exclude /v2/addresses/mempool from cache
  • Don't cache invalid issuances

Codebase

API

CLI

Credits

  • Ouziel Slama
  • Adam Krellenstein

v11.0.2

Choose a tag to compare

@ouziel-slama ouziel-slama released this 28 Aug 07:30
2edbf1a

Release Notes - Counterparty Core v11.0.2 (2025-08-28)

This version is a small-ish release. Most importantly, it fixed a regression in transaction handling where empty descriptions could be incorrectly encoded into issuance transactions of various types (including locking, e.g.) and addressed a bug whereby using the verbose=true parameter could cause the node API to hang. This version also introduces a transaction validity flag and new API filters, improving clarity and queryability; it (finally) adds Bitcoin Core cookie authentication (which is now the recommended method) and updates the official Docker image to use Alpine rather than Ubuntu, which reduces the image size from 1.1 GB to 126 MB.

Upgrading

NOTE: A full database rebuild is required iff you would like to use the new valid parameter to retrieve transactions with the API. Existing databases will show valid=null for historical transactions until re-parsed.

NOTE: There was another accidental regression in v11.01: API booleans divisible, locked, reset, and callable have been returning integers instead of proper JSON booleans (true/false). This regression has been reverted in v11.0.2.

Upgrade Instructions:

To upgrade, download the latest version of counterparty-core and restart counterparty-server.

With Docker Compose:

cd counterparty-core
git pull
docker compose stop counterparty-core
docker compose --profile mainnet up -d

or use ctrl-c to interrupt the server:

cd counterparty-core
git pull
cd counterparty-rs
pip install -e .
cd ../counterparty-core
pip install -e .
counterparty-server start

ChangeLog

Bugfixes

  • Fix regression in issuance handling where empty descriptions could be incorrectly encoded
  • Fix mime_type field in assets_info table
  • Fix API issue when unpacking old transactions
  • Fix a typo in `docker-compose.yml
  • Fix give/get_price in orders API
  • Fix bootstrap: exit with error when a subprocess fails
  • Fix UTXOBalancesCache initialization: restore also invalid attach
  • Remove unnecessary logger.error calls from Enhanced Send unpacking
  • Disable Taproot encoding for legacy sources

Codebase

  • Add current_commit tag in Sentry reports and JSON logs
  • Add transactions_status table filled by the parse() functions of each contract
  • Update the testnet4, signet and mainnet checkpoints

API

  • Fix boolean fields in issuances API
  • Add current_commit field in API root endpoint
  • Add valid parameter for transactions endpoints
  • Optimize the Get Balances by Addresses endpoint

CLI

  • Use Alpine Linux instead of Ubuntu for Docker image and employ a multi-stage build
  • Throw a cleaner error on an unknown CLI argument
  • Report when Bitcoin Core has not yet reached the first Counterparty block
  • Add --backend-cookie-file flag to connect to Bitcoin Core with cookie (recommended)
  • Improve bootstrap and subprocess error handling

Credits

  • Ouziel Slama
  • Adam Krellenstein

v11.0.1

Choose a tag to compare

@ouziel-slama ouziel-slama released this 11 Jun 19:47
26b8473

Release Notes - Counterparty Core v11.0.1 (2025-06-11)

This release is a patch on the v11.0.0 protocol upgrade with the same activation block (902,000). It allows for backwards-compatibility in the transaction encoding format so that CBOR is no longer required for transaction data packing. It also adds support for Bitcoin signet and fixes a few bugs---including one critical bug in the new issuance decoding logic.

NOTE: If a CBOR transaction is incorrectly constructed so that it is invalid, it will be parsed automatically with the original transaction decoding logic, which may lead to unpredictable results.

Upgrading

Upgrade Instructions:

This release is a protocol upgrade. All nodes must upgrade by block 902000.

To upgrade, download the latest version of counterparty-core and restart counterparty-server.

With Docker Compose:

cd counterparty-core
git pull
docker compose stop counterparty-core
docker compose --profile mainnet up -d

or use ctrl-c to interrupt the server:

cd counterparty-core
git pull
cd counterparty-rs
pip install -e .
cd ../counterparty-core
pip install -e .
counterparty-server start

ChangeLog

Protocol

  • Add backward-compatibility to CBOR format (Enhanced Send, Sweep, Fairminter, Fairmint, Issuance and Broadcast)

Bugfixes

  • No Taproot encoding for legacy inputs
  • Handle unpack error for issuances correctly

Codebase

  • Add signet Support

API

CLI

Credits

  • Ouziel Slama
  • Adam Krellenstein

v11.0.0

Choose a tag to compare

@ouziel-slama ouziel-slama released this 27 May 14:11
cfe5baf

Release Notes - Counterparty Core v11.0.0 (2025-05-27)

Counterparty Core v11.0.0 is a large release with numerous protocol upgrades and many miscellaneous improvements to the API, CLI and codebase, including significantly increased test coverage.

Protocol Upgrades:

  • Fix Bech32 address handling—now support P2WSH and P2TR
  • Support for Taproot envelope data encoding, which will significantly reduce transaction fees for larger transactions (and removal of support for P2SH data encoding, which is strictly worse than Taproot)
  • Support for Ordinals Inscription creation when composing an Issuance, Fairminter or Broadcast (API parameters: inscription, mime_type)
  • Allow soft_cap to be equal to hard_cap with Fairminters
  • Add max_mint_per_address parameter to Fairminters (API parameter: max_mint_per_address)

Upgrading

This release is a protocol upgrade. All nodes must upgrade by block 902000.

Upgrade Instructions:
To upgrade, download the latest version of counterparty-core and restart counterparty-server.

With Docker Compose:

cd counterparty-core
git pull
docker compose stop counterparty-core
docker compose --profile mainnet up -d

or use ctrl-c to interrupt the server:

cd counterparty-core
git pull
cd counterparty-rs
pip install -e .
cd ../counterparty-core
pip install -e .
counterparty-server start

ChangeLog

Protocol

  • Fix Bech32 address support
  • Use CBOR encoding format for Sweep, Enhanced Send, Fairminter, Fairmint, Issuance and Broadcast
  • Allow soft_cap to be equal to hard_cap with Fairminters
  • Add max_mint_per_address parameter to Fairminters
  • Ensure Fairminter hard cap is a multiple of the lot size
  • Use asset ID instead of asset name in Fairminter and Fairmint messages
  • Add Taproot envelope data encoding support (disabled for transactions with a destination output and detach)
  • Add support for Taproot change address
  • Remove P2SH data encoding support
  • Use an envelope script compatible with Ordinals when the description/text of a Fairminter, Issuance or Broadcast is not empty

Bugfixes

  • Fix API verbose flag when unpacking fails
  • Fix API verbose flag for the Get Transactions endpoints
  • Handle DatabaseError correctly in API calls
  • Fix is_cachable() function in API v2
  • Fix ledger_state field in API root endpoint
  • Disable Taproot addresses for MPMA sends and dispenser oracles
  • Fix composer for Taproot addresses
  • Fix script_to_address function's handling of taproot addresses
  • Fix testnet4 bootstrap with custom URL
  • Fix address.pack and address.unpack functions' handling of Taproot addresses
  • Make APSWConnectionPool thread-safe
  • Fix typo in composer parameters: mutlisig_pubkey -> multisig_pubkey
  • Fix price_normalized in Fairminters endpoints
  • Fix event name: BET_MATCH_RESOLUTON -> BET_MATCH_RESOLUTION
  • Fix is_segwit value in get_vin_info
  • Fix apsw.IOError when using --rebuild-state-db flag
  • Fix round error in inputs values when composing transaction
  • Fix Fairminter validation
  • Fix SIGHASH collecting
  • Fix create dispenser using subasset name

Codebase

  • Improve test coverage by 10% (from ~78% to ~88%)
  • Clean up hard-coded protocol changes throughout codebase
  • Optimize APSWConnectionPool
  • Add mime_type to issuances, fairminters and broadcasts tables

API

  • When using an Ordinals envelope script, add a dust output for the source address
  • Add asset as an optional parameter to the Get Balances by Addresses endpoint
  • The encoding parameter now accepts a taproot value
  • Ensure that Fairminter's start_block and end_block are greater than the current block
  • In Compose Fairminter, rename price -> lot_price and quantity_by_price -> lot_size
  • In Compose Fairmint, ensure that quantity is a multiple of lot_size
  • Ensure that Fairminter's hard_cap is greater than the sum of premint_quantity and soft_cap
  • POST URL-encoded parameters are now accepted when composing a transaction
  • Add mime_type parameter to compose_issuance, compose_fairminter and compose_broadcast endpoints
  • Remove mandatory fields for broadcast: fee_fraction, value, timestamp
  • Add inscription parameter to the compose API
  • Add category field to functions and arguments in /v2/routes endpoint response

CLI

  • Add support for the SLACK_HOOK environment variable containing a webhook URL called after a rebuild
  • The --profile flag now generates a report every 15 minutes instead of just once at shutdown
  • Add URGENT log level displayed even with --quiet flag
  • Add --enable-all-protocol-changes flag for testing purposes
  • Remove mempoolfullrbf=1 from docker-compose.yml

Credits

  • Ouziel Slama
  • Adam Krellenstein

v11.0.0-beta.1

v11.0.0-beta.1 Pre-release
Pre-release

Choose a tag to compare

@ouziel-slama ouziel-slama released this 18 Apr 16:18
a926b9f

Release Notes - Counterparty Core v11.0.0 (2025-03-??)

Counterparty Core v11.0.0 is a large release with numerous protocol upgrades and many miscellaneous improvements to the API, CLI and codebase, including significantly increased test coverage.

Protocol Upgrades:

  • Fix Bech32 address handling—now support P2WSH and P2TR
  • Support for Taproot envelope data encoding, which will significantly reduce transaction fees for larger transactions (and removal of support for P2SH data encoding, which is strictly worse than Taproot)
  • Support for Ordinals Inscription creation when composing an Issuance, Fairminter or Broadcast (API parameters: inscription, mime_type)
  • Allow soft_cap to be equal to hard_cap with Fairminters
  • Add max_mint_per_address parameter to Fairminters (API parameter: max_mint_per_address)

Upgrading

This release is a protocol upgrade. All nodes must upgrade by block .

Upgrade Instructions:
To upgrade, download the latest version of counterparty-core and restart counterparty-server.

With Docker Compose:

cd counterparty-core
git pull
docker compose stop counterparty-core
docker compose --profile mainnet up -d

or use ctrl-c to interrupt the server:

cd counterparty-core
git pull
cd counterparty-rs
pip install -e .
cd ../counterparty-core
pip install -e .
counterparty-server start

ChangeLog

Protocol

  • Fix Bech32 address support
  • Use CBOR encoding format for Sweep, Enhanced Send, Fairminter, Fairmint, Issuance and Broadcast
  • Allow soft_cap to be equal to hard_cap with Fairminters
  • Add max_mint_per_address parameter to Fairminters
  • Ensure Fairminter hard cap is a multiple of the lot size
  • Use asset ID instead of asset name in Fairminter and Fairmint messages
  • Add Taproot envelope data encoding support
  • Remove P2SH data encoding support
  • Use an envelope script compatible with Ordinals when the description/text of a Fairminter, Issuance or Broadcast is not empty

Bugfixes

  • Fix API verbose flag when unpacking fails
  • Fix API verbose flag for the Get Transactions endpoints
  • Handle DatabaseError correctly in API calls
  • Fix is_cachable() function in API v2
  • Fix ledger_state field in API root endpoint
  • Disable Taproot addresses for MPMA sends and dispenser oracles
  • Fix composer for Taproot addresses
  • Fix script_to_address function's handling of taproot addresses
  • Fix testnet4 bootstrap with custom URL
  • Fix address.pack and address.unpack functions' handling of Taproot addresses
  • Make APSWConnectionPool thread-safe
  • Fix typo in composer parameters: mutlisig_pubkey -> multisig_pubkey
  • Fix price_normalized in Fairminters endpoints
  • Fix event name: BET_MATCH_RESOLUTON -> BET_MATCH_RESOLUTION
  • Fix is_segwit value in get_vin_info
  • Fix apsw.IOError when using --rebuild-state-db flag

Codebase

  • Improve test coverage by 10% (from ~78% to ~88%)
  • Update ledger-hash checkpoints using truncated addresses
  • Clean up hard-coded protocol changes throughout codebase
  • Optimize APSWConnectionPool
  • Add mime_type to issuances, fairminters and broadcasts tables

API

  • When using an Ordinals envelope script, add a dust output for the source address
  • Add asset as an optional parameter to the Get Balances by Addresses endpoint
  • The encoding parameter now accepts a taproot value
  • Ensure that Fairminter's start_block and end_block are greater than the current block
  • In Compose Fairminter, rename price -> lot_price and quantity_by_price -> lot_size
  • In Compose Fairmint, ensure that quantity is a multiple of lot_size
  • Ensure that Fairminter's hard_cap is greater than the sum of premint_quantity and soft_cap
  • POST URL-encoded parameters are now accepted when composing a transaction
  • Add mime_type parameter to compose_issuance, compose_fairminter and compose_broadcast endpoints
  • Remove mandatory fields for broadcast: fee_fraction, value, timestamp
  • Add inscription parameter to the compose API
  • Add category field to functions and arguments in /v2/routes endpoint response

CLI

  • Add support for the SLACK_HOOK environment variable containing a webhook URL called after a rebuild
  • The --profile flag now generates a report every 15 minutes instead of just once at shutdown
  • Add URGENT log level displayed even with --quiet flag
  • Add --enable-all-protocol-changes flag for testing purposes

Credits

  • Ouziel Slama
  • Adam Krellenstein

v10.10.1

Choose a tag to compare

@ouziel-slama ouziel-slama released this 03 Mar 17:27
18de91c

Release Notes - Counterparty Core v10.10.1 (2025-03-03)

This release includes two major improvements to the Counterparty Core codebase: (1) faster and more reliable node shutdown, (2) ~50% faster initial node catchup. It also includes a number of usability improvements to the API and CLI, as well as bugfixes.

Upgrading

Breaking Changes:
The commands get_asset_names and get_asset_longnames have been removed from API v1, as they are buggy and extremely non-performant. If you have been using these endpoints, you should migrate to /v2/assets.

Upgrade Instructions:
To upgrade, download the latest version of counterparty-core and restart counterparty-server.

With Docker Compose:

cd counterparty-core
git pull
docker compose stop counterparty-core
docker compose --profile mainnet up -d

or use ctrl-c to interrupt the server:

cd counterparty-core
git pull
cd counterparty-rs
pip install -e .
cd ../counterparty-core
pip install -e .
counterparty-server start

ChangeLog

Bugfixes

  • Handle subprocess errors correctly when bootstrapping
  • Fix getrawtransaction_batch() for batches greater than config.MAX_RPC_BATCH_SIZE
  • Improve error handling for when a port in use
  • Fix ungraceful ZeroMQ failure
  • Fix Conservation Check failing ungracefully
  • Implement cleaner Gunicorn shutdown
  • Fix ungraceful Waitress shutdown
  • Handle RSFetcher version mismatch error correctly
  • Handle Counterparty Server version checking errors correctly
  • Fix the handling of TypeError in API calls

Codebase

  • Tweak logging during Bitcoin Core catch up
  • Batch getrawtransaction for get_vin_info()
  • Create events indexes after catch up rather than before
  • Make RPC calls to get transaction input info with RSFetcher
  • Make RSFetcher compatible with HTTPS
  • Fix all code scanner alerts (Bandit, CodeQL, Pylint)
  • Only print debug messages about Counterparty being behind Bitcoin Core every 10 seconds
  • Add missing indexes to the sends table

API

  • Check balances when composing detach transaction
  • Add a show_unconfirmed parameter for Get Transactions endpoints
  • Add a count_confirmed parameter for Get Transactions Count endpoints
  • Add a X-LEDGER-STATE header to all API responses
  • Add a ledger_state field in API v2 root endpoint
  • Remove get_asset_names and get_asset_longnames commands from API v1

CLI

  • Accept --catch-up flag before the command
  • Add Locust runner to test local node performance (python3 counterpartycore/test/integration/locustrunner.py will start the Locust web UI on http://localhost:8089/)
  • Add --profile flag that enables cProfile during catchup and dumps results to the console when complete
  • Add --rebuild command to re-sync from scratch and then stop the server
  • Add memory database cache for address_events table

Credits

  • Ouziel Slama
  • Adam Krellenstein

v10.10.0

Choose a tag to compare

@ouziel-slama ouziel-slama released this 14 Feb 20:35
93e6550

Release Notes - Counterparty Core v10.10.0 (2025-02-14)

This release includes a complete rewrite of the entire test harness for Counterparty Core, as well as both restored and all-new integration tests and GitHub workflows for continuous integration. This release also adds support for Python 3.12 and 3.13, which means significantly improved performance overall. There are of course a number of bugfixes, especially for node stability when Bitcoin Core is overloaded.

Upgrading

This upgrade does not include a protocol change and is not mandatory. User-facing changes to the API include a decrease in the default output value for attach and move transactions to 546 satoshis and renaming the --testnet flag to --testnet3.

IMPORTANT

  • If you are running a version lower than 10.9.0, you must first update to 10.9.0 and only then install v10.10.0.

Download the latest version of counterparty-core and restart counterparty-server.

With Docker Compose:

cd counterparty-core
git pull
docker compose stop counterparty-core
docker compose --profile mainnet up -d

or use ctrl-c to interrupt the server:

cd counterparty-core
git pull
cd counterparty-rs
pip install -e .
cd ../counterpaty-core
pip install -e .
counterparty-server start

ChangeLog

Protocol Changes

Bugfixes

  • Don't retry RPC calls in safe_get_utxo_address()
  • Fix error handling in safe_rpc()
  • Raise ValueError instead of PanicException when an error occurs in Rust deserialization
  • Return 400 error on TypeError when composing a transaction
  • Fix bitcoind.search_pubkey_in_transactions()
  • Don't force the existence of a change output
  • Fix heavy HealthZ check
  • Fix search pubkey for SegWit addresses that have never been used
  • Fix Gunicorn shutdown
  • Use the same logfile for all Gunicorn processes
  • Fix duplicate log entries in the API Access file
  • Don't call getblockcount from each API thread or process
  • Reset all caches on rollback and reparse
  • Fix RSFetcher restart on failure
  • Fix the extended_tx_info param in API v1
  • Correctly handle RPC responses with simple strings or with string in error

Codebase

  • Completely rewrite the test suite. See comments in test/mocks/conftest.py.
  • Completely rewrite the GitHub Workflow files
  • Add support for Python 3.12 and 3.13
  • Rename testnet to testnet3 everywhere
  • Add testnet4 and regtest profiles to docker-compose.yaml
  • Restore Docker Compose, Compare Hashes and testnet4 Reparse tests
  • Refactor required actions for automatic upgrades

API

  • Change default value for attach and move to 546 satoshis
  • Add block_index filter for Get Order Matches endpoints
  • Add block_index filter for Get Dispenses by Asset endpoint
  • Add Get Dispense By Hash endpoint
  • Add owner field in assets info

CLI

  • Rename --testnet flag to --testnet3
  • Add testnet4 bootstrap database
  • Add --api-only flag

Credits

  • Ouziel Slama
  • Adam Krellenstein