rpc: add testmempoolaccept dry-run RPC (mempool Phase 6)#3095
Open
PrestackI wants to merge 10 commits into
Open
rpc: add testmempoolaccept dry-run RPC (mempool Phase 6)#3095PrestackI wants to merge 10 commits into
PrestackI wants to merge 10 commits into
Conversation
Lift the pure block/index value types (CBlockHeader, CBlock, CBlockIndex, CDiskBlockIndex, CBlockLocator, BlockHasher, the GRC::MRCFees/MintSummary reports, LOCKTIME_THRESHOLD, FutureDrift, GetTargetSpacing) out of the ~1200-line main.h god-header into a new, main.h-free primitives/block.h, mirroring Bitcoin Core's primitives/block.h. The eight inline methods that reference chain-state globals (pindexBest, mapBlockIndex, pindexGenesisBlock, fUseFastIndex, the genesis hashes) are relocated out-of-line into primitives/block.cpp so the header stays free of main.h. Their EXCLUSIVE_LOCKS_REQUIRED(cs_main) annotations remain on the in-class declarations. consensus/merkle.h and consensus/tx_verify.h now include primitives/block.h instead of main.h, removing the layering inversion where low-level consensus headers dragged in the entire top-of-stack include graph. tx_verify.cpp gains a direct main.h include for the chain-state globals it still uses. main.h keeps functional change.
A quote-include "validation.h" from src/consensus/tx_verify.h resolves to the sibling src/consensus/validation.h (which has no MapPrevTx), not src/validation.h. The original "main.h" include avoided this because there is no src/consensus/main.h. Use angle brackets so the include resolves against -I src to the top-level validation.h that defines MapPrevTx, matching the existing convention in test/script_p2sh_tests.cpp.
validation.h uses CTxIndex by value in the MapPrevTx typedef and the std::map<uint256, CTxIndex> parameters, but only ever compiled because main.h includes index/txindex.h (line 13) before validation.h (line 24). Now that consensus/tx_verify.h pulls validation.h directly, CTxIndex was undeclared, which also broke overload resolution for the CTxIndex ReadTxFromDisk overload at tx_verify.cpp:186. Include index/txindex.h directly (after index/disktxpos.h, since CTxIndex embeds CDiskTxPos), mirroring main.h's existing include order.
Move CTxMemPool, the MemPoolRemovalReason enum, and the global
`mempool` instance out of the main.h/main.cpp god-header into a
dedicated translation unit src/txmempool.{h,cpp}.
This is a pure code move with no behavior change. main.h now
includes txmempool.h, so all existing consumers (including
wallet code using MemPoolRemovalReason) resolve unchanged. It also
serves as Phase 0 of the mempool modernization work (gridcoin-community#3029).
Register txmempool.cpp in the gridcoin_util CMake target.
Phase 1 of the mempool modernization (gridcoin-community#3029). Wrap every pooled transaction in a new CTxMemPoolEntry that caches the fee, size, time, and entry height computed at accept time, plus lightweight Gridcoin contract tags (contract type(s); MRC/beacon CPID; MRC fee and last-block-hash; mandatory-sidestake flag) derived from a single pass over the transaction's contracts. mapTx becomes std::map<uint256, CTxMemPoolEntry>; AcceptToMemoryPool threads its already-computed fee/size into a new addUnchecked(entry); every value-reader of mapTx switches to .GetTx(). The tags are populated but not yet consumed and the five O(n) contract scans are left intact -- they become index lookups in Phase 2. No functional change. Adds src/test/txmempool_tests.cpp covering entry metadata, MRC/beacon/ sidestake tagging, and addUnchecked/mapNextTx/lookup consistency.
…community#3029 Phase 2) Build four secondary indexes on CTxMemPool from the contract tags Phase 1 cached on each entry, maintained in the single addUnchecked/remove/clear paths: m_mrc_by_cpid, m_beacon_by_cpid, a mandatory-sidestake count, and a fee-ordered m_mrc_by_fee view. Replace all five former full-mempool scans with O(log n) lookups, with identical semantics: - MRC duplicate-CPID rejection at accept (DoS=25, offending tx hash still reported) -- removes the "I really hate this check" full scan + bloom filter; m_mrc_bloom / m_mrc_bloom_dirty deleted. - beacon duplicate-CPID check (CheckBeaconTransactionViable). - mandatory-sidestake one-in-pool check (SendContractTx). - stale-MRC eviction on block connect (GetStaleMRCs). - MRC fee-queue ranking for the GUI and getmrcrequestdata RPC (GetMRCQueue). Indexes are maintained only in the add/remove/clear paths, so reorg resurrection (AcceptToMemoryPool replay) rebuilds them automatically. The miner's per-block MRC selection is unchanged. No consensus change. Extends txmempool_tests.cpp with index population/teardown, dedup collision hash, fee-descending queue, and staleness selection.
New src/rpc/mempool.cpp surfacing the Phase 1/2 metadata and indexes:
- getmempoolinfo: tx count, total bytes, and Gridcoin-specific counts
(MRC / beacon / mandatory-sidestake) from the secondary indexes.
- getmempoolentry <txid>: per-entry fee, feerate, size, time, height, and
contract tags; throws if the tx is not pooled.
- getrawmempool ( verbose ): moved out of rpc/blockchain.cpp; verbose=true
returns an object keyed by txid with the same per-entry metadata, default
keeps the plain txid array.
Registered under cat_network in rpc/server.{h,cpp}, getrawmempool's verbose
arg added to the rpc/client.cpp conversion table, rpc/mempool.cpp added to
src/CMakeLists.txt. Adds a CTxMemPoolInfo one-pass stats accessor.
Extends txmempool_tests.cpp with an RPC diagnostics case (info counts,
verbose/non-verbose getrawmempool, getmempoolentry hit + missing-hash throw).
…ommunity#3029 Phase 4) Add a transaction count/size cap and eviction, stacked on the Phase 1-3 mempool work. - CTxMemPool tracks a running m_total_tx_size and a composite eviction index (CTxMemPoolEvictionKey). Because Gridcoin's flat, size-scaled fee makes feerate nearly identical across transactions, victims are ordered: non-contract before contract (contracts evicted last so reward-bearing MRCs survive), then feerate ascending, then newest-first. - DynamicMemoryUsage() = serialized bytes + a fixed per-entry overhead. - TrimToSize(limit) evicts lowest-priority first, routing every removal through remove(..., SIZELIMIT) so all indexes stay consistent. remove() gains a MemPoolRemovalReason argument. - -maxmempool (default 300 MB) is parsed in init.cpp and applied via SetMaxSize(); AcceptToMemoryPool trims after addUnchecked and rejects the incoming tx if it was itself evicted (mempool full). - getmempoolinfo reports usage and maxmempool. Indexes are still maintained only in addUnchecked/remove/clear, so reorg resurrection rebuilds them. No consensus change. txmempool_tests.cpp: eviction order (feerate asc, contracts last) and contract protection when room remains for one.
…Phase 5)
Save the pooled transactions on shutdown and reload them on startup,
stacked on the Phase 1-4 mempool work.
- New node/mempool_persist.{h,cpp}: WriteMempoolEntries/ReadMempoolEntries
serialize transactions plus their entry time to <datadir>/mempool.dat
(versioned, atomic temp-file + rename, corrupt/missing handled via
try/catch). DumpMempool snapshots under the pool lock then writes outside
it; LoadMempool re-validates every transaction through AcceptToMemoryPool,
so stale/invalid txns are dropped and all indexes are rebuilt for free.
- AcceptToMemoryPool gains an optional entry_time argument; LoadMempool
passes each stored time so age / queue ordering survives a restart.
- -persistmempool (default on) gates a shutdown dump (after StopNode, before
the block flush) and a startup load (after the chain + wallet are ready)
in init.cpp.
- New savemempool and importmempool RPCs.
txmempool_tests.cpp: write/read round-trip (incl. an MRC tx and entry times)
and graceful handling of a corrupt and a missing file. The full
dump->restart->re-accept path needs real chain state and is left to a
functional/manual test.
Final phase of the mempool modernization. AcceptToMemoryPool gains a
test_only mode plus fee_out/vsize_out out-params: it runs every check
(version, standardness, contract validation, the Phase 2 dedup index
lookups, conflict, FetchInputs, fee floor, CheckContracts, sequence locks,
ConnectInputs) but skips all mutation -- the storage block, -maxmempool
trim, wallet notifications, and the MRC-changed UI signal.
Reject reasons are now surfaced through CValidationState: the existing
DoS() calls get a reason token (no DoS-score or control-flow change) and a
few standard error()-only rejects become Invalid(reason) (DoS 0, so no new
banning). This gives testmempoolaccept meaningful, Gridcoin-specific
reasons -- invalid-contract, mrc-duplicate-cpid, bad-txns-version,
insufficient-fee, tx-nonstandard, etc. The umbrella invalid-contract token
covers all contract rules; surfacing the specific failing rule (a reason
string out of GRC::ValidateContracts) is left as a follow-up.
New testmempoolaccept RPC (Bitcoin-compatible array input) returns
{txid, allowed, reject-reason?, fees:{base}?, vsize?} per transaction.
Registered under cat_network; rawtxs arg added to the client conversion
table.
txmempool_tests.cpp: a legacy-version tx reports bad-txns-version without
mutating the pool; an already-pooled tx reports txn-already-in-mempool. The
accept-path-with-valid-inputs no-mutation proof needs real chain state and
is left to a functional/manual test.
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.
What
Phase 6 — the final phase of the mempool modernization (#3029) — stacked on Phase 5 (#3094).
AcceptToMemoryPoolgains atest_onlymode plusfee_out/vsize_outout-params: it runs every check (version, standardness, contract validation, the Phase 2 dedup index lookups, conflict,FetchInputs, fee floor,CheckContracts, sequence locks,ConnectInputs) but skips all mutation — the storage block,-maxmempooltrim, wallet notifications, and the MRC-changed UI signal.Reject reasons are now surfaced through
CValidationState: the existingDoS()calls get a reason token (no DoS-score or control-flow change) and a few standarderror()-only rejects becomeInvalid(reason)(DoS 0, so no new banning). This givestestmempoolacceptmeaningful, Gridcoin-specific reasons —invalid-contract,mrc-duplicate-cpid,bad-txns-version,insufficient-fee,tx-nonstandard, etc. The umbrellainvalid-contractcovers all contract rules; surfacing the specific failing rule (a reason string out ofGRC::ValidateContracts) is left as a follow-up.New
testmempoolacceptRPC (Bitcoin-compatible array input) returns{txid, allowed, reject-reason?, fees:{base}?, vsize?}per transaction. Registered undercat_network;rawtxsarg added to the client conversion table.Why
testmempoolacceptlets wallets, explorers, and tooling pre-flight a transaction without submitting it (#1142), and the reject reasons make it genuinely useful on a contract-bearing chain. No consensus change — DoS scores and control flow are identical.Closes #3029
This completes the umbrella roadmap (Phases 1–6: #3090, #3091, #3092, #3093, #3094, this PR). Stacked on #3094 → … → #3072; the diff narrows to just the Phase 6 change once the predecessors land.
Testing
txmempool_tests.cpp: a legacy-version tx reportsbad-txns-versionwithout mutating the pool; an already-pooled tx reportstxn-already-in-mempool. The accept-path-with-valid-inputs no-mutation proof needs real chain state and is left to a functional/manual test. Full localctestsuite green; fork CI matrix green.