Releases: CounterpartyXCP/counterparty-core
Release list
v11.2.0
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 -dor 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 startThe 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
400error 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_setvalues, duplicate or out-of-range UTXOs, dispense quantity and memo types are now validated. Previously-tolerated invalid values now return a clean400instead of being coerced or causing a500. compose/dispenseresponse change: in the returnedparams,sourceis renamed toaddressanddestinationtodispenser, andquantity_normalizedis added.- The non-functional
sortparameter 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 sweepflags, 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 (theissuance_callability_parameters_removalguard 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 aminted_asset_commissionbetween 0 and 0.0000001 (which would round to zero).- Add fairmint pool seeding behind a new
fairmint_poolgate:compose_fairminteraccepts two new optional fields —pool_quantity(tokens to reserve for the AMM pool) andlp_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 withpool_quantityof the minted asset and the corresponding XCP proceeds;hard_capmust equalexisting_supply + premint_quantity + pool_quantity + soft_cap(all mintable supply is reserved for buyers or the pool),burn_paymentis disallowed, and the issuer must hold sufficient XCP to cover the pool-deposit gas fee at compose time; pool creation is deferred to theafter_blockhook 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 redundantquantity_a * quantity_b > MAX_INToverflow check inpooldeposit.validate()that rejected otherwise-valid large AMM deposits — it capped each side of a balanced divisible pair atfloor(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: atx_hash:voutUTXO reference whosevoutexceeds0xFFFFFFFF(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 throughstr(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 runsVACUUMafterwards; a newhashcodecmodule 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-chartx0hash_tx1hashTEXT match id is replaced by an integer(tx0_index, tx1_index)foreign-key pair onorder_matches,bet_matches,rps_matches, the three*_match_expirationstables,bet_match_resolutions,btcpaysandrpsresolves. The textualid/*_match_idis 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): theassetstable gains a compact, sequentially-assignedasset_index INTEGER PRIMARY KEYsurrogate, and every asset-name TEXT column (asset,give_asset,get_asset,forward_asset,backward_asset,dividend_asset,asset_parent,asset_a,asset_bonbalances,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 integerasset_indexforeign key — 1–3 bytes per reference instead of the full asset name. The protocolassets.asset_idandlp_assetcolumns stay TEXT. The asset name is transparently restored on read (therowtracerdecodesasset_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 storeNULL. - Address normalization (folded into
0010.compact_hash_storage): a newaddress_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_addressacross the ledger tables) is replaced by the compact integeraddress_idforeign key. The address string is transparently restored on read (therowtracerdecodesaddress_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 existingaddressesoptions-history table is preserved; itsaddresscolumn is FK'd ontoaddress_list.mempool.addresses(a comma-separated list) andmempool_transactionsare left as TEXT. - UTXO column compaction (folded into
0010.compact_hash_storage): theutxo TEXTcolumn (tx_hash:vout, ~67 chars) onbalances,creditsanddebitsis replaced by a compact(utxo_tx_hash BLOB(32), utxo_vout INTEGER)pair (~36 bytes). Thetx_hashis stored as a raw BLOB rather than atx_indexforeign key because an attached UTXO may reference any valid bitcoin transaction (not only Counterparty transactions). Theutxostring is transparently reconstructed on read by therowtracer, 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_countleak inAPSWConnectionPoolcausingMAINPROCESS_POOLto exhaust over time (per-request threads in APIv1 left cached connections counted forever) - Fix
NotSupportedTransactionsCacheunbounded 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 ...
v11.1.0
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 -dor 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 startThe 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_poolsgate, with two new message types:pooldeposit(120) andpoolwithdraw(121); BTC pairs are explicitly rejected. Deposits/withdraws use standard constant-product math (LP tokens minted viafloor(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 DEXmatch()loop now interleaves pool fills with the resting book at every step (constant-product, fee-adjusted, withXCP_POOL_FEE_BPS=50for XCP pairs and100otherwise), then sweeps any remainder against the pool in a tail phase. Pool reserves are counted inheld()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 migration0009.amm_pools.sqland consolidated into the State DB by migration0014.add_pool_consolidated_tables(registered inMIGRATIONS_AFTER_ROLLBACK, also rebuildsasset_holders/xcp_holdersto include pool reserves). - Add support for indefinite DEX orders and fix
expirationsemantics behind a newindefinite_ordersgate:expiration=0now means indefinite (open until filled or cancelled,expire_index = NULL),expiration=Nnow means exactly N blocks of life (was N+1 due to a long-standing off-by-one), andMAX_EXPIRATIONis raised from 8064 (~56 days) to 65535 (the wire-format u16 max, ~455 days). The wire format is unchanged. - Allow CBOR map under tag
0x05for ordinals-style provenance metadata in taproot inscriptions, behind a newordinals_metadata_supportgate. 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_supportgate: tolerate MIME parameters (e.g.audio/ogg;codecs=opus), recognise the+jsonstructured suffix as textual, and validate against a deterministic hard-coded allow-list (EXTENDED_MIME_TYPES_VALID) instead ofmimetypes.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-urlcan now be specified multiple times; default mainnet Electrs backends to bothblockstream.infoandmempool.space; print a startup warning when using default Electrs URLs (not recommended for production)
Bugfixes
- Catch
struct.errorinissuance.unpackto prevent consensus halt - Catch
NoPriceErrorindispense.parseto prevent consensus halt - Harden
issuanceandbroadcastparse 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
AssetIDErrorindispenser.unpackbehind a newcatch_invalid_dispenser_asset_idgate to prevent consensus halt on invalid dispenser asset ids - Reject
btcpaywhere tx destination doesn't match order match counterparty - Fix bet match sort no-op behind new
fix_sort_bet_matchesgate - Fix Python truthiness bug in
attachOP_RETURN check (gated) - Set
transactions_statusand persist invalid record insweep.parse - Forward
tx["block_index"]into gatedunpack()andprotocol.enabled()calls; hoist fairminter fee tointand forwardblock_indexto issuance fee gates excludes_utxossupports now<txid>:<vout>and<txid>alone- Add missing
max_mint_per_addressparameter incompose_fairminter() - Fix shutdown during rate limit backoff
- Fix missing
limitparameter validation in API v2 (was not enforced unlike API v1) - Fix
MalformedPointErrorwhen searching for pubkey in P2WSH multisig witness data - Fix Rust
BATCH_CLIENTpermanently 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
KeyboardInterruptraised 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
u32underflow patterns in the Rust indexer - Fix off-by-one and short-prefix panics in
parse_vout - Replace
expect()inget_funding_block_entrieswith a typedError - Catch malformed
protocol_changes.jsonshape insoftware_version() - Scope
Decimalcontext changes tolocalcontextso precision doesn't leak - Update
BackendHeight.last_checkin afinallyso 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/eventsafter RPC catch-up paths (receive_rawblockprevious-block-missing branch andhandle()ZMQ-late branch): both now sweep the mempool table aftercatch_up(), matching the streamedreceive_rawblockpath - Clear bitcoind transaction cache on rollback to avoid stale deserialisation; encapsulate in
reset_caches()helper - Clean orphaned
transactions_statusrows on rollback and rebuild - Close ZMQ sockets/context before reconnect; fix
RCVTIMEOtypo - Make
--api-onlyloop honorapi_stop_eventfor clean shutdown - Make
UTXOLocksintra-worker thread-safe - Concurrency:
SingletonMetadouble-checked locking; guardreset_cacheslru_cache.cache_clear()withhasattr - 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 returnedvalueto be rejected by Bitcoin Core with a misleadingmandatory-script-verify-flag-failed (Signature must be zero for failed CHECK(MULTI)SIG operation)error - Fix
DETACH_FROM_UTXOsource field typo inEVENTS_ADDRESS_FIELDS - Fix
LEFT JOINin API migration 0004 supplies query - Fix dispenser
pricein API: scalesatoshirate / give_quantityby1e8when 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 thePROTOCOL_CHANGES_URLand underlying error in both the log and theVersionCheckErrorraised to the user - Sync
description_lockedand filterxcp_supplyby status inapiwatcher - Fix
assets_infoState DB population (migration 0004) so thatdescription,divisible,mime_typeandownerare derived from the latest valid issuance (matching the streamedapiwatchersemantics) instead of an implementation-defined row picked by SQLite from the aggregated set, and so thatlocked/description_lockedare stored as 0/1 booleans (MAX(...)) rather than asSUM(...)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_historysub-resources),GET /v2/pools/<asset1>/<asset2>/quote(hybrid pool+book swap quote),/quote/depositand/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_depositsand/pool_withdrawals,GET /v2/blocks/<int:block_index>/pool_deposits/pool_withdrawals/pool_matches, plus the compose endpointsPOST /v2/addresses/<address>/compose/pooldepositandcompose/poolwithdrawwith theirestimatexcpfeescompanions.
Codebase
- Add fuzz tests
- Add 10 regression tests for the audit fixes
- Document
expand_subasset_longname200-byte cap reasoning - Document libm cross-platform threshold near
gas.pysigmoid
Credits
- Ouziel Slama
- Dan Anderson
- Adam Krellenstein
v11.0.4
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 -dor 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 startChangeLog
Features
- Support sub-1 sat/vByte fee rates (e.g., 0.5 sat/vByte) for transaction composition
Bugfixes
- Fix
current_commitin API root - Fix reorg edge case
- Fallback to RPC when
getzmqnotificationsRPC call is not available - Fix RSFetcher restart
- Fix state.db reorg
- Fix UTXO cache building
- Fix
next_cursorin API results whensortis 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 NOCASEinstead ofUPPER()for case-insensitive queries - Add performance indexes for
assets_info,balances, anddispenserstables - Optimize list deduplication in verbose mode using sets
- Fix
get_balances_by_address_and_assetendpoint
CLI
- Add
--db-connection-pool-sizeto configure connection pool size (default: 10) - Add
--db-max-connectionsto limit total database connections across threads (default: 50, 0=unlimited) - Add
--memory-profileto enable periodic memory usage logging
Credits
- Ouziel Slama
- Adam Krellenstein
v11.0.3
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 -dor 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 startChangeLog
Bugfixes
- Fix get events by addresses endpoint
- Exclude
/v2/addresses/mempoolfrom cache - Don't cache invalid issuances
Codebase
API
CLI
Credits
- Ouziel Slama
- Adam Krellenstein
v11.0.2
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 -dor 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 startChangeLog
Bugfixes
- Fix regression in issuance handling where empty descriptions could be incorrectly encoded
- Fix
mime_typefield inassets_infotable - 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
UTXOBalancesCacheinitialization: restore also invalidattach - Remove unnecessary
logger.errorcalls from Enhanced Send unpacking - Disable Taproot encoding for legacy sources
Codebase
- Add
current_committag in Sentry reports and JSON logs - Add
transactions_statustable filled by theparse()functions of each contract - Update the
testnet4,signetandmainnetcheckpoints
API
- Fix boolean fields in issuances API
- Add
current_commitfield in API root endpoint - Add
validparameter 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-fileflag to connect to Bitcoin Core with cookie (recommended) - Improve bootstrap and subprocess error handling
Credits
- Ouziel Slama
- Adam Krellenstein
v11.0.1
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 -dor 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 startChangeLog
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
signetSupport
API
CLI
Credits
- Ouziel Slama
- Adam Krellenstein
v11.0.0
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_capto be equal tohard_capwith Fairminters - Add
max_mint_per_addressparameter 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 -dor 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 startChangeLog
Protocol
- Fix Bech32 address support
- Use CBOR encoding format for Sweep, Enhanced Send, Fairminter, Fairmint, Issuance and Broadcast
- Allow
soft_capto be equal tohard_capwith Fairminters - Add
max_mint_per_addressparameter 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
DatabaseErrorcorrectly in API calls - Fix
is_cachable()function in API v2 - Fix
ledger_statefield in API root endpoint - Disable Taproot addresses for MPMA sends and dispenser oracles
- Fix composer for Taproot addresses
- Fix
script_to_addressfunction's handling of taproot addresses - Fix
testnet4bootstrap with custom URL - Fix
address.packandaddress.unpackfunctions' handling of Taproot addresses - Make
APSWConnectionPoolthread-safe - Fix typo in composer parameters:
mutlisig_pubkey->multisig_pubkey - Fix
price_normalizedin Fairminters endpoints - Fix event name:
BET_MATCH_RESOLUTON->BET_MATCH_RESOLUTION - Fix
is_segwitvalue inget_vin_info - Fix
apsw.IOErrorwhen using--rebuild-state-dbflag - 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_typetoissuances,fairmintersandbroadcaststables
API
- When using an Ordinals envelope script, add a dust output for the source address
- Add
assetas an optional parameter to the Get Balances by Addresses endpoint - The
encodingparameter now accepts ataprootvalue - Ensure that Fairminter's
start_blockandend_blockare greater than the current block - In Compose Fairminter, rename
price->lot_priceandquantity_by_price->lot_size - In Compose Fairmint, ensure that
quantityis a multiple oflot_size - Ensure that Fairminter's
hard_capis greater than the sum ofpremint_quantityandsoft_cap POSTURL-encoded parameters are now accepted when composing a transaction- Add
mime_typeparameter tocompose_issuance,compose_fairminterandcompose_broadcastendpoints - Remove mandatory fields for broadcast:
fee_fraction,value,timestamp - Add
inscriptionparameter to the compose API - Add
categoryfield to functions and arguments in/v2/routesendpoint response
CLI
- Add support for the
SLACK_HOOKenvironment variable containing a webhook URL called after a rebuild - The
--profileflag now generates a report every 15 minutes instead of just once at shutdown - Add
URGENTlog level displayed even with--quietflag - Add
--enable-all-protocol-changesflag for testing purposes - Remove
mempoolfullrbf=1fromdocker-compose.yml
Credits
- Ouziel Slama
- Adam Krellenstein
v11.0.0-beta.1
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_capto be equal tohard_capwith Fairminters - Add
max_mint_per_addressparameter 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 -dor 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 startChangeLog
Protocol
- Fix Bech32 address support
- Use CBOR encoding format for Sweep, Enhanced Send, Fairminter, Fairmint, Issuance and Broadcast
- Allow
soft_capto be equal tohard_capwith Fairminters - Add
max_mint_per_addressparameter 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
DatabaseErrorcorrectly in API calls - Fix
is_cachable()function in API v2 - Fix
ledger_statefield in API root endpoint - Disable Taproot addresses for MPMA sends and dispenser oracles
- Fix composer for Taproot addresses
- Fix
script_to_addressfunction's handling of taproot addresses - Fix
testnet4bootstrap with custom URL - Fix
address.packandaddress.unpackfunctions' handling of Taproot addresses - Make
APSWConnectionPoolthread-safe - Fix typo in composer parameters:
mutlisig_pubkey->multisig_pubkey - Fix
price_normalizedin Fairminters endpoints - Fix event name:
BET_MATCH_RESOLUTON->BET_MATCH_RESOLUTION - Fix
is_segwitvalue inget_vin_info - Fix
apsw.IOErrorwhen using--rebuild-state-dbflag
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_typetoissuances,fairmintersandbroadcaststables
API
- When using an Ordinals envelope script, add a dust output for the source address
- Add
assetas an optional parameter to the Get Balances by Addresses endpoint - The
encodingparameter now accepts ataprootvalue - Ensure that Fairminter's
start_blockandend_blockare greater than the current block - In Compose Fairminter, rename
price->lot_priceandquantity_by_price->lot_size - In Compose Fairmint, ensure that
quantityis a multiple oflot_size - Ensure that Fairminter's
hard_capis greater than the sum ofpremint_quantityandsoft_cap POSTURL-encoded parameters are now accepted when composing a transaction- Add
mime_typeparameter tocompose_issuance,compose_fairminterandcompose_broadcastendpoints - Remove mandatory fields for broadcast:
fee_fraction,value,timestamp - Add
inscriptionparameter to the compose API - Add
categoryfield to functions and arguments in/v2/routesendpoint response
CLI
- Add support for the
SLACK_HOOKenvironment variable containing a webhook URL called after a rebuild - The
--profileflag now generates a report every 15 minutes instead of just once at shutdown - Add
URGENTlog level displayed even with--quietflag - Add
--enable-all-protocol-changesflag for testing purposes
Credits
- Ouziel Slama
- Adam Krellenstein
v10.10.1
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 -dor 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 startChangeLog
Bugfixes
- Handle subprocess errors correctly when bootstrapping
- Fix
getrawtransaction_batch()for batches greater thanconfig.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
TypeErrorin API calls
Codebase
- Tweak logging during Bitcoin Core catch up
- Batch
getrawtransactionforget_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
sendstable
API
- Check balances when composing
detachtransaction - Add a
show_unconfirmedparameter for Get Transactions endpoints - Add a
count_confirmedparameter for Get Transactions Count endpoints - Add a
X-LEDGER-STATEheader to all API responses - Add a
ledger_statefield in API v2 root endpoint - Remove
get_asset_namesandget_asset_longnamescommands from API v1
CLI
- Accept
--catch-upflag before the command - Add Locust runner to test local node performance (
python3 counterpartycore/test/integration/locustrunner.pywill start the Locust web UI on http://localhost:8089/) - Add
--profileflag that enables cProfile during catchup and dumps results to the console when complete - Add
--rebuildcommand to re-sync from scratch and then stop the server - Add memory database cache for
address_eventstable
Credits
- Ouziel Slama
- Adam Krellenstein
v10.10.0
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 -dor 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 startChangeLog
Protocol Changes
Bugfixes
- Don't retry RPC calls in
safe_get_utxo_address() - Fix error handling in
safe_rpc() - Raise
ValueErrorinstead ofPanicExceptionwhen an error occurs in Rust deserialization - Return
400error onTypeErrorwhen 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
getblockcountfrom each API thread or process - Reset all caches on rollback and reparse
- Fix RSFetcher restart on failure
- Fix the
extended_tx_infoparam 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
testnettotestnet3everywhere - Add
testnet4andregtestprofiles todocker-compose.yaml - Restore Docker Compose, Compare Hashes and testnet4 Reparse tests
- Refactor required actions for automatic upgrades
API
- Change default value for
attachandmoveto 546 satoshis - Add
block_indexfilter for Get Order Matches endpoints - Add
block_indexfilter for Get Dispenses by Asset endpoint - Add Get Dispense By Hash endpoint
- Add
ownerfield in assets info
CLI
- Rename
--testnetflag to--testnet3 - Add testnet4 bootstrap database
- Add
--api-onlyflag
Credits
- Ouziel Slama
- Adam Krellenstein