Repository navigation
fix(firo): private spends are not coinbase, mempool parse, Spark fees, EX addresses - #33
Merged
Merged
Conversation
…, EX addresses - Lelantus/Spark/Zerocoin/Sigma spend inputs keep their scriptSig and no longer carry coinbase data. GetAddressUtxo asks the parser (optional bchain.PrivateSpendParser) before flagging a UTXO coinbase, so outputs paid by private spends are not locked for 100 confirmations. Other coins keep the index heuristic without loading the tx. - FiroParser.ParseTx decodes the v3 extra payload: correct txids for special txs in the mempool and no error on quorum commitments. - Spark spend fees (types 9 and 11) are read from the spend payload or the sparkData of firod's JSON. Lelantus/Sigma/Zerocoin fees stay 0. - OP_EXCHANGEADDR outputs decode to searchable EX addresses and EX addresses are accepted as input (prefixes from firod chainparams.cpp). - Tx cache records written by the old parser are normalized in UnpackTx.
…ror first FiroDecode allocated whatever length the payload varint claimed, and GetTransaction set CoinSpecificData on a nil tx when ParseTxFromJson failed.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Four Firo problems found by an audit. Fixing them lets the FIRO Insight explorer move to Blockbook's native Insight listener without changing what the ZelCore wallet sees.
1. Private-spend payouts were flagged coinbase
GetAddressUtxotreats "one input, no address, zero value" in the index as coinbase. Lelantus (type 8), Spark (types 9/11), Sigma and Zerocoin spends look exactly like that. ZelCore refuses coinbase UTXOs under 100 confirmations, so funds received from a private spend would have stayed locked.parseFiroTx(bchain/coins/firo/firoparser.go) now gives private-spend inputs an empty txid and no coinbase data, and keeps the scriptSig. It mirrors firod'sCTransaction::IsCoinBase, which checks the opcodes c2/c4/c7/c8/c9/d3. Inputs with an empty txid are still skipped by the indexer, so no fake previous output is ever looked up (mempool included). InsightisCoinBasefollows from this.bchain.PrivateSpendParser(bchain/types.go).api/worker.goisCoinbaseTxloads the tx and asks the parser, but only for a coin whose parser implements the interface (Firo) and only for UTXOs that are under the coinbase-maturity limit and that the index heuristic already flags. For other coins nothing changes: a test runs a BTC worker with no chain and no tx cache and gets the same result.UnpackTxnormalizes tx-cache records written by the old parser, so no cache flush is needed.2. Mempool parse
FiroParser.ParseTxdecodes the v3 extra payload the same wayParseBlockdoes. Special txs in the mempool now get the correct txid, and a type 6 quorum commitment no longer fails to parse.3. Fees of private spends
fofspark::SpendTransaction. It comes from the raw extra payload or from thesparkDatain firod's JSON. V1 and V2 layouts are both handled (libspark/spend_transaction.h). When a tx comes from the tx cache, the worker fetches the JSON once (GetTransactionSpecific). Verified against firodnFeesand against stock Insight (insight-api-zcoinon .69:3001): 526e7a05… = 0.00003115, 3c667f00… = 0.00006351, 7842d789… = 0.00003115. All match.fees: 0. Stock Insight returns nofeesfor these either: checked Lelantus 4d36244e, 2e96152d, 72e40fa4; Sigma 200204f6, 1fd01e81, b11bc3a9; Zerocoin c2a2e51b. The values agree (0 vs absent); only the representation differs.valueInstays the transparent input sum (stock: null).feesin Insight address tx lists still comes from the index (inputs minus outputs). Private-spend fees there stay 0.4. Exchange addresses (EX…)
OP_EXCHANGEADDR(0xe0) + P2PKH scripts now decode to searchableEX…addresses, andGetAddrDescFromAddressaccepts them. The 3-byte prefixes come from firodsrc/chainparams.cppEXCHANGE_PUBKEY_ADDRESS: main01 b9 bb, test01 b9 b1, regtest01 b9 ac. Checked against firod: a8156ab6… vout 3 →EXXaSB8H9NUcFscQFuEMeKYTAKpq2BYjxdVS.Reindex
None needed. The index keys by script bytes, so EX outputs are already indexed. Private-spend inputs were already stored without a txid. Fees and coinbase flags are computed when read.
Not done
addr: "Sparkspend","Lelantusjsplit", …). These are optional and the wallet does not use them.Tests
Table tests use real mainnet hex/JSON (
bchain/coins/firo/testdata/mainnet_special_txs.json): ParseTx txids for types 0/1/5/6/8/9/11, IsCoinbaseTx for raw, JSON and legacy-cache formats, Spark fees with invalid-payload cases, EX addresses on main and test. Worker tests index real txs and check UTXO coinbase flags and fees in the tx, cache and mempool paths.go test -tags unittest ./bchain/coins/firo/ ./api/ ./server/ ./build/tools/ . ./bchain/ ./bchain/coins/btc/ ./db/all pass; gofmt and vet are clean.