Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mempool: reject txs that don't fit in an empty mempool #1225

Merged
merged 1 commit into from
Aug 23, 2024

Conversation

amesgen
Copy link
Member

@amesgen amesgen commented Aug 21, 2024

Follow-up to #1168 that makes sure that adding a tx exceeding the per-tx limit does not cause a deadlock which prevents txs from being added to the mempool until the node is restarted.

We accomplish this by validating such transactions and relying on the per-tx limit to reject them.

Comment on lines 191 to 202
maxTotalRefScriptSize = 1024 * 1024 -- 1MiB
, curTotalRefScriptSize + newTxRefScriptSize Prelude.<= maxTotalRefScriptSize
mempoolStaysBelowCapacity =
curTotalRefScriptSize + newTxRefScriptSize Prelude.<= maxTotalRefScriptSize
-- In case the tx exceeds the per-tx limit, let it be rejected by tx
-- validation (such that we are not blocked here forever/for a long
-- time).
--
-- For Babbage, this is 100KiB (see @totalRefScriptsSizeLimit@ in
-- "Ouroboros.Consensus.Shelley.Eras"), and for Conway, this is 200KiB
-- (see @maxRefScriptSizePerTx@ in "Cardano.Ledger.Conway.Rules.Ledger").
txRefScriptSizeTooLarge = newTxRefScriptSize Prelude.> 200 * 1024
, mempoolStaysBelowCapacity || txRefScriptSizeTooLarge
Copy link
Member Author

@amesgen amesgen Aug 21, 2024

Choose a reason for hiding this comment

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

Subtlety: It would also be enough to prevent a hard deadlock by replacing 200 * 1024 with maxTotalRefScriptSize. However, this is still problematic in that honest nodes can be forced to forge very small blocks:

  • Suppose someone first submits a tx A using a very small (eg just one byte) referene script, and then one tx B that includes 1MiB of reference scripts.
  • The tx A would enter the mempool, then potentially a few other txs from other peers, and then adding tx B would block, causing no new transactions to be added, until...
  • ...an SPO mints a block, all txs in the mempool are removed, and the tx B can now be rejected. The problem is that the resulting block only contains very few txs.

The approach taken here makes sure that this can only happen when the mempool already contains 1024 - 200 = 824 KiB of ref scripts, which is already larger than basically all "normal" blocks using reference scripts. This is also similar to how #1175 handles this case.

Copy link
Contributor

@nfrisby nfrisby left a comment

Choose a reason for hiding this comment

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

Approved. Only one suggestion for a small addition in the comment, regarding overflow.

@amesgen amesgen added this pull request to the merge queue Aug 23, 2024
@amesgen amesgen removed this pull request from the merge queue due to a manual request Aug 23, 2024
@amesgen amesgen enabled auto-merge August 23, 2024 12:51
@amesgen amesgen added this pull request to the merge queue Aug 23, 2024
Merged via the queue into main with commit 9351e28 Aug 23, 2024
15 checks passed
@amesgen amesgen deleted the amesgen/mempool-large-tx branch August 23, 2024 13:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants