Skip to content

Toccata transient mass activation and mempool policy refinement#995

Open
michaelsutton wants to merge 14 commits into
kaspanet:toccatafrom
michaelsutton:transient-activation
Open

Toccata transient mass activation and mempool policy refinement#995
michaelsutton wants to merge 14 commits into
kaspanet:toccatafrom
michaelsutton:transient-activation

Conversation

@michaelsutton
Copy link
Copy Markdown
Contributor

Implements the Toccata transient mass activation, including forked block mass limits and delayed mempool adoption of the relaxed transient limit so pre-activation and near-boundary transactions remain safely conservative.

Also polishes mempool policy around the activation:

  • moves template-fit checks out of standardness and into explicit template-limit validation
  • applies relay fee checks over both non-contextual mass dimensions
  • activation logic for signature script length limit change
  • removes obsolete dust standardness checks covered systemically by KIP-9 storage mass (ever since crescendo)
  • adds focused tests for transient mass activation, template selection, and policy behavior across the activation boundary

Add validate_transaction_template_limits as a post-consensus mempool admission
check. It rejects txs that cannot fit in a block template under the current
delayed mempool limits, before standardness-in-context and RBF eviction.

Use raw per-dimension limits for clearer errors: compute, transient, storage,
and gas. Keep mempool_block_mass_limits in Config alongside derived cofactors,
so selectors/RBF still use normalized weights while admission checks raw fit.

Clean standardness tests by removing stale mass/gas cases and decoupling relay
fee arithmetic from the removed standard mass constant. Extend Toccata tests to
cover delayed transient admission and gas rejection even when non-standard txs
are allowed.
base the standard relay fee floor on max(compute, transient) so transient block-space usage has a minimum cost, move fee check out of the loop so it's checked once and not per input and add context-standardness coverage for fee and input script checks.
Set the classic P2SH sigop standardness cap to match the previous 100k compute-mass allowance, and document why compute mass remains the real execution bound.
Remove the redundant is_unspendable branch from dust classification: standardness already rejects non-standard SPKs before dust, and standard SPK classes are spendable.
Drop the relay-fee dust threshold from mempool standardness and remove the mining dust helper. KIP9 storage mass already prices UTXO growth at the system level.
Comment on lines +111 to +118
fn check_transaction_signature_scripts_in_header_context(&self, tx: &Transaction, block_daa_score: u64) -> TxResult<()> {
let max_signature_script_len = self.max_signature_script_len.get(block_daa_score);
if let Some(i) = tx.inputs.iter().position(|input| input.signature_script.len() > max_signature_script_len) {
return Err(TxRuleError::TooBigSignatureScript(i, max_signature_script_len));
}

Ok(())
}
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

You should add the intent of the validation as a comment in this function.

The name check_transaction_signature_scripts_in_header_context doesn't suggest it will only check length but signature scripts as a whole (so perhaps this may check length and something else). The implementation only checks for length.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

it's more like: "do what ever you can do to check_transaction_signature_scripts_in_header_context"

cf transaction_in_isolation where it's simply called check_transaction_signature_scripts

Comment thread consensus/core/src/config/params.rs Outdated
Split template-limit validation into isolation and context phases so gas,
compute and transient limits are rejected before consensus in-context validation.
Keep storage checks after contextual mass is populated and cover the ordering in
Toccata transient mass activation tests.
Use the real contextual storage mass calculation in Toccata mempool tests and
add a tiny-output case that rejects with RejectStorageMass after consensus
in-context validation.
Separate duplicate detection from isolation standardness and rename the local
standardness helpers to std_in_isolation/std_in_context. Reuse the same
transaction-id checks before and after consensus validation to make the
concurrency recheck semantics explicit.
Base the minimum relay fee on max(compute, normalized transient) using stable post-activation cofactors, so activation only changes limits, not unit pricing. Split insufficient-fee errors by dominant mass dimension.

Change devnet/simnet pre-activation transient limits so that devnet/simnet tests and runs trigger the activation case.
Assert that mempool mass cofactors keep the same reference across activation, and document the selector assumption when using the post-activation reference.
@michaelsutton michaelsutton force-pushed the transient-activation branch from 1219408 to 404eb44 Compare May 13, 2026 10:53
Comment thread consensus/core/src/config/params.rs Outdated
&self,
transaction: &MutableTransaction,
rbf_policy: RbfPolicy,
_virtual_daa_score: u64,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Why?

fn get_double_spend_feerate(&self, double_spend: &DoubleSpend) -> RuleResult<f64> {
let owner = self.transaction_pool.get_double_spend_owner(double_spend)?;
match owner.mtx.calculated_feerate(&self.config.block_mass_cofactors) {
let cofactors = self.config.mempool_mass_cofactors.get(owner.added_at_daa_score);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

nit, but doesn't it make more sense to use virtual_daa_score?

owner.mtx.calculated_feerate(&self.config.block_mass_cofactors),
) {
let transaction_cofactors = self.config.mempool_mass_cofactors.get(virtual_daa_score);
let owner_cofactors = self.config.mempool_mass_cofactors.get(owner.added_at_daa_score);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

nit, but doesn't it make more sense to use virtual_daa_score?


// Create a tx with transient mass over the block limit
txx.payload = vec![0; (config.params.block_mass_limits.transient / TRANSIENT_BYTE_TO_MASS_FACTOR + 100) as usize];
txx.payload = vec![0; (config.params.block_mass_limits().after().transient / TRANSIENT_BYTE_TO_MASS_FACTOR + 100) as usize];
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Why do we use .after() if toccata is not activated on devnet? (Same question for the rest of the test)

Comment on lines -457 to -481
Test {
name: "Transaction gas exceeds the per-lane limit",
mtx: new_mtx(
Transaction::new(
TX_VERSION,
vec![dummy_tx_input.clone()],
vec![dummy_tx_out.clone()],
0,
SUBNETWORK_ID_NATIVE,
DEFAULT_GAS_PER_LANE_LIMIT + 1,
vec![],
),
1000,
),
is_standard: false,
},
Test {
name: "Transaction size is too large",
mtx: new_mtx(
Transaction::new(
TX_VERSION,
vec![dummy_tx_input.clone()],
vec![TransactionOutput::new(
0u64,
ScriptPublicKey::new(
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Do we want to move these tests somewhere else? Maybe to MiningManager.validate_and_insert_transaction?

Comment thread mining/src/mempool/check_transaction_standard.rs Outdated
Ok(())
}

fn check_transaction_signature_scripts_in_header_context(&self, tx: &Transaction, block_daa_score: u64) -> TxResult<()> {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Add a TODO(post-toccata) to remove it

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.

3 participants