AI-generated analysisPublished automatically and not human-verified. Validated context appears in community notes below.
← Watch feed
Low 39 Cryptographic libraries

cryptonote_core: cache input verification results directly in mempool

Public commit record

What the developer wrote

Authored by jeffro256

91/100 · Strong
cryptonote_core: cache input verification results directly in mempool

This replaces `ver_rct_non_semantics_simple_cached()` with an API that offloads
the responsibility of tracking input verification successes to the caller. The
main caller of this function in the codebase, `cryptonote::Blockchain()` instead
keeps track of the verification results for transaction in the mempool by
storing a "verification ID" in the mempool metadata table (with `txpool_tx_meta_t`).
This has several benefits, including:

* When the mempool is large (>8192 txs), we no longer experience cache misses and unnecessarily re-verify ring signatures. This greatly improves block propagation time for FCMP++ blocks under load
* For the same reason, reorg handling can be sped up by storing verification IDs of transactions popped from the chain
* Speeds up re-validating every mempool transaction on fork change (monerod revalidates the whole tx-pool on HFs #10142)
* Caches results for every single type of Monero transaction, not just latest RCT type
* Cache persists over a node restart
* Uses 512KiB less RAM (8192*2*32B)
* No additional storage or DB migration required since `txpool_tx_meta_t` already had padding allocated
* Moves more verification logic out of `cryptonote::Blockchain`

Furthermore, this opens the door to future multi-threaded block verification
speed-ups. Right now, transactions' input proof verification is limited to one
transaction at a time. However, one can imagine a scenario with verification IDs
where input proofs are optimistically multi-threaded in advance of block
processing. Then, even though ring member fetching and verification is
single-threaded inside of `cryptonote::Blockchain::check_tx_inputs()`, the
single thread can skip the CPU-intensive cryptographic code if the verification
ID allows it.

Also changes the default log category in `tx_verification_utils.cpp` from "blockchain" to "verify".
✓ Specific, descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context✓ Mentions testing or verification✓ Links an issue, advisory, or supporting reference
The short version

What changed, and why it matters

This commit is a performance refactor of how Monero nodes cache expensive ring-signature verification results for transactions sitting in the memory pool (mempool). It replaces an in-memory cache limited to 8,192 entries with a persistent verification ID stored in each mempool transaction's metadata. The change is described by the author as improving block propagation and reorg handling, not as a security fix. The main risk is that if the verification ID is ever set incorrectly or reused with the wrong mix-ring data, a node could skip cryptographic checks on a bad transaction, which would be a consensus bug. The diff includes careful checks and unit tests, but it is a large, complex change touching core consensus code.

Recommended action

Treat this as a high-risk consensus refactor rather than an active vulnerability. Reviewers should verify that `make_input_verification_id()` uniquely identifies the exact mix-ring data used in verification, that the ID is never copied from an untrusted source, that `check_tx_inputs()` cannot return true with a stale or mismatched ID, and that the padding/alignment changes in `txpool_tx_meta_t` do not break existing database records. Run the new unit tests and, if possible, the disabled heavy-block benchmark on a testnet.

Security signals we found

01

Replaces in-memory verification cache with persistent mempool metadata field

02

Introduces `valid_input_verification_id` in `txpool_tx_meta_t` using previously reserved padding

03

Adds `make_input_verification_id()` hashing tx hash + dereferenced mix ring with domain separation

04

Adds `ver_input_proofs_rings()` covering v1 ring signatures, RCTTypeFull, and simple/RCTTypeBulletproof/CLSAG/BulletproofPlus

05

Skips cryptographic verification when stored ID matches recomputed ID

06

Sets ID only after successful verification; resets to null on failure

07

Removes threaded v1 ring-signature checking from `blockchain.cpp` and moves it into `tx_verification_utils.cpp`

08

Adds unit tests for ID uniqueness and tamper detection

09

Adds disabled benchmark for heavy block propagation under large mempool

Risk score

Why this scored 39/100

Our methodology →
Potential impact 8/30
Exploitability 5/25
Stealth signal 6/15
Affected reach 10/15
Confidence 6/10
Evidence quality 4/5
Human-validated context

Community notes

Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.

No validated notes yet.

The AI analysis stands alone for now. Submit a note if you can add evidence or important context.