This release fetches announced blocks through their headers, as BCHN does, cuts the memory --slpgraphsearch needs to about a fifth, and has the gRPC address calls return the address's number of transactions. Nodes with --addrindex should read the upgrade notes first.
Performance
--slpgraphsearchkeeps about 210 bytes per SLP transaction instead of the whole transaction (about 1,000 bytes for a typical SEND, more for larger ones), and reads the transactions a search returns from the memory pool or the transaction index.- Loading
--slpgraphsearchtakes about a third less memory at its peak, about 280 MB less per million SLP transactions.
Consensus & Network
- Catching up with a competing chain that overtakes the node's own no longer takes two minutes per block.
- Add the
chipnet-seed.bchd.cashDNS seed. - A peer disconnected just as one of its messages arrived no longer leaves a goroutine behind.
- A synced node no longer downloads and stores the blocks of lower-work forks that peers announce.
- A compact block with an invalid header now costs the peer BCHN's ban score, and compact blocks go only to peers known to have the parent's header.
RPC & gRPC
- gRPC
GetAddressTransactionsandGetRawAddressTransactionsreturn the address's number of confirmed transactions inconfirmed_count. - On 32-bit builds,
GetAddressTransactionsandGetRawAddressTransactionswith annb_skipof 2^31 or more return no confirmed transactions instead of the newest ones. - gRPC
GetAddressTransactionsandGetRawAddressTransactionsno longer list a just-confirmed transaction as unconfirmed too. - The gRPC SLP calls no longer treat a transaction that left the memory pool unconfirmed as valid after the next block.
- The gRPC SLP calls no longer treat as valid a transaction that a reorg disconnected and the memory pool didn't take back.
GetSlpGraphSearchand the graph search count ofGetSlpTrustedValidationanswer bad client input withInvalidArgumentorNotFoundinstead ofInternalorAborted.GetSlpGraphSearchandGetSlpTrustedValidationanswer a transaction the SLP index does not hold withNotFound, and a failure to read the index withInternal, rather than both withAborted.GetSlpTrustedValidationanswers a query hash of the wrong length withInvalidArgumentrather thanAborted.GetSlpTokenMetadataanswers a token with no GENESIS or metadata in the SLP index withNotFound, a failure to read the index withInternal, and a token ID of the wrong length withInvalidArgument, instead ofAborted.CheckSlpTransactionandSubmitTransactionanswerInternalwhen the SLP index cannot read an input's entry, rather than taking the input for one without tokens.- When the SLP index fails to read a transaction's SLP data,
GetTransaction,GetBlock,GetMempoolandGetAddressTransactionsanswerInternal, and the subscriptions send the transaction asUNKNOWN_OR_INVALID, instead of reporting an invalid SLP transaction that burns its inputs. - An SLP transaction in the memory pool whose check hits a database failure is checked again at the next block, instead of staying invalid to the SLP calls while it is in the pool.
GetUnspentOutput,GetAddressUnspentOutputsandGetTransactionanswerInternalwhen the SLP index fails to read a token or its metadata, rather than leaving it out.GetUnspentOutputreturns the SLP token and token metadata of a confirmed output, not only of an unconfirmed one.- A memory pool transaction spending an output whose SLP index entry is corrupt is logged as an error, with advice to rebuild the index, and left unjudged instead of judged invalid.
- An output or transaction whose SLP index entry is corrupt fails the gRPC call with
Internal, and streams send it with its SLP state unknown, instead of answering without its token or token metadata. GetUnspentOutputreturns an output's SLP token metadata only wheninclude_token_metadatais set, asGetAddressUnspentOutputsdoes, so clients that read it must now set the flag.GetSlpTokenMetadatano longer reports a mint baton that a block burned while confirming, from the memory pool, the GENESIS or MINT that created it.GetSlpTokenMetadatareports a token's mint baton ended once a MINT ending it is in the memory pool, as it does once the MINT is confirmed, instead of the baton the MINT spent.searchrawtransactions, the websocket address filters andnotifyreceived, and the gRPC address calls and transaction filters refuse a legacy address from another network, such as a testnet address on mainnet, instead of reading it as this network's address with the same hash.- On systems that don't allow reading the network interfaces, such as Android, bchd creates its RPC certificate without their addresses instead of failing to start.
Database
- A block spending an output whose SLP index entry is corrupt stops the node with advice to rebuild the index with
--dropslpindex, instead of storing the spending transaction as invalid for good. - A corrupt SLP token metadata record stops the node with advice to rebuild the index, or fails the gRPC call that reads it, instead of crashing the node.
- When an index fails on a block, the log names the index instead of reporting a failure to write the chain state.
- When an index fails to catch up at startup, the error names the index.
Build & Packaging
- Update dependencies, including gRPC v1.85.0, protobuf v1.36.12, grpc-gateway v2.33.0 and the Prometheus client v1.25.0, and regenerate
bchrpc/pbwith them.
Other
- txscript can sign inputs that spend CashTokens, and sign with
SIGHASH_UTXOS.SignTxOutputWithSigHashes,SignatureScriptWithSigHashes,RawTxInECDSASignatureWithSigHashesandRawTxInSchnorrSignatureWithSigHashestake the transaction's signature hashes, computed once for all its inputs, which must include the outputs it spends (NewTxSigHashes(tx).WithUtxos(tx, utxos)) for those. The functions without them can't see the spent outputs, so they now return an error forSIGHASH_UTXOSinstead of a signature the network refuses. - txscript's signing functions return an error, instead of panicking or making an invalid signature, for signature hashes that don't fit the transaction and for
SIGHASH_UTXOSwithSIGHASH_ANYONECANPAY. - txscript's
SignTxOutputandSignTxOutputWithSigHashessign P2SH32 inputs. - txscript's
SignTxOutputkeeps a P2PKH or P2PK signature frompreviousScriptonly if it is valid, and no longer returns an invalid script when re-signing one wrapped in P2SH. - txscript's
CalcSignatureHashreturns an error forSIGHASH_UTXOSunless the signature hashes include all the outputs the transaction spends. --slpgraphsearchno longer logs an error for each SLP transaction that arrives while the graph loads.- txscript's
SignTxOutputdrops multisig signatures inpreviousScriptwhose hash type the network refuses, and returns an error for apreviousScriptin Schnorr multisig mode instead of losing its signatures. - txscript's signing functions return an error for a hash type the network refuses, such as
SigHashOld, instead of a signature it rejects. - txscript's
SignTxOutputreturns an error for a P2SH or P2SH32 input whose redeem script is itself P2SH or P2SH32, instead of an invalid script.
Upgrade notes
- Address index. On first start, and after an earlier release has run with
--addrindex, nodes with it read the address index once to count the transactions of large addresses: under a second on chipnet, a few minutes at most on mainnet.