Skip to content

Break fee inputs into chunks in collectRewards (#2185) - #2462

Open
Ergologica wants to merge 3 commits into
ergoplatform:masterfrom
Ergologica:fix/chunk-fee-inputs-2185
Open

Break fee inputs into chunks in collectRewards (#2185)#2462
Ergologica wants to merge 3 commits into
ergoplatform:masterfrom
Ergologica:fix/chunk-fee-inputs-2185

Conversation

@Ergologica

Copy link
Copy Markdown
Contributor

Closes #2185.

Problem

CandidateGenerator.collectRewards collects every fee box of a block into one fee transaction:

val inputs = feeBoxes.map(b => new Input(b.id, ProverResult.empty))
Some(ErgoTransaction(inputs.toIndexedSeq, IndexedSeq(), IndexedSeq(minerBox)))

With enough fee-paying transactions in a block, that transaction can grow past the block limits and be invalid, which invalidates the candidate.

Fix

Fee boxes are grouped into chunks of at most MaxFeeBoxesPerTransaction (100), one fee-collecting transaction per chunk. Each chunk gets its own miner box and its own token set truncated at MaxAssetsPerBox, as before.

Chunking collectRewards alone would have had no effect where it counts: collectFees ended in .headOption, and the assembly loop in collectTxs carried the fee transaction as a single Option[CostedTransaction], so every chunk after the first would have been dropped silently. collectFees now returns Seq[ErgoTransaction] and the loop threads Seq[CostedTransaction]. Each chunk is validated on its own with statefulValidity; one failing chunk aborts the step exactly as one failing fee transaction did before, and the cost/size check sees all of them together.

Behaviour is unchanged for any block with 100 fee boxes or fewer, which is every block on mainnet today.

Tests

  • new: fee boxes are collected in chunks of at most MaxFeeBoxesPerTransaction - with more fee boxes than one chunk holds, the transaction count is ceil(n / 100), every fee box is spent exactly once across the chunks, and the miner's total is unchanged.
  • updated: collect reward from both emission box and fees asserted exactly 2 transactions, which stops holding once the generator produces more than 100 fee boxes. It now checks the invariants that survive a split: the emission transaction, per-chunk input bounds, and the total paid to the miner.

sbt "testOnly org.ergoplatform.mining.CandidateGeneratorPropSpec" - 9/9 green.

On the chunk size

100 is a deliberate conservative constant rather than a computed limit. The alternative is to size chunks from the block cost and size parameters in the upcoming context, which would put block-limit arithmetic inside reward collection. Happy to change the number, or to derive it, if you would rather have that.

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.

Put mining fee inputs into multiple transactions when too many of them

1 participant