Skip to content

tx_memory_pool: quick abort on block templates for too-young FCMP txs#220

Draft
jeffro256 wants to merge 2 commits intoseraphis-migration:fcmp++-stagefrom
jeffro256:tx_meta_ready_to_go
Draft

tx_memory_pool: quick abort on block templates for too-young FCMP txs#220
jeffro256 wants to merge 2 commits intoseraphis-migration:fcmp++-stagefrom
jeffro256:tx_meta_ready_to_go

Conversation

@jeffro256
Copy link
Collaborator

No description provided.

@jeffro256 jeffro256 marked this pull request as draft November 6, 2025 18:07
if (txd.hard_height_requirement)
{
const uint64_t curr_height = m_blockchain.get_current_blockchain_height();
if (txd.max_used_block_height + CRYPTONOTE_DEFAULT_TX_SPENDABLE_AGE > curr_height)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Idea: if you have max_used_block_height=reference_block for FCMP++ txs, you can just check txd.max_used_block_height >= curr_height here

We wouldn't need the hard_height_requirement field, and can call this for any tx. It also avoids any issues surrounding off-by-1 logic

It introduces a difference on what max_used_block_height means for pre and post FCMP++ txs (which affects the if for // enforce min output age in blockchain.cpp), so I would accept if you prefer not to do that

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We wouldn't need the hard_height_requirement field, and can call this for any tx. It also avoids any issues surrounding off-by-1 logic

We can't use that height without re-checking for ring signature transactions because a reorg can change the height of referenced ring members. It's different for FCMP++ txs because the reference height is explicitly a height value and isn't allowed by consensus any lower than at least 1 block after the reference block height.

For example. if the top ring member gets re-orged from height H to height H-1, this code would skip over this transaction in the block template for the next block. Eventually, this would be eligible again, so maybe it's okay?

It introduces a difference on what max_used_block_height means for pre and post FCMP++ txs (which affects the if for // enforce min output age in blockchain.cpp), so I would accept if you prefer not to do that

This is also one of the main reasons why I chose to do it this way: I wanted to behavior to match what's happening with the ring signature transactions.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, you're right. As is is ok with me, will review closer for off-by-1

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, always tricky

Copy link
Collaborator

@j-berman j-berman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Small nit on passing db height into is_transaction_meta_ready_to_go, otherwise LGTM

return ret;
}
//---------------------------------------------------------------------------------
bool tx_memory_pool::is_transaction_meta_ready_to_go(const txpool_tx_meta_t& txd) const
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could pass in the db height to prevent the db read for height for all txs in a loop

Comment on lines +3889 to +3890
*pmax_used_block_height = tx.rct_signatures.p.reference_block
- std::min<std::uint64_t>(tx.rct_signatures.p.reference_block, CRYPTONOTE_DEFAULT_TX_SPENDABLE_AGE - 1);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note for self:

I use a similar pattern in db_lmdb.cpp here

I think it would be good to use a helper function for this logic just so it's consolidated somewhere / makes it easier to manage if there is some change down the road

I can do it in a separate PR

if (txd.hard_height_requirement)
{
const uint64_t curr_height = m_blockchain.get_current_blockchain_height();
if (txd.max_used_block_height + CRYPTONOTE_DEFAULT_TX_SPENDABLE_AGE > curr_height)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, always tricky

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants