From 5bb169cb5c45abec1a31eb240b64bc0dfd9c3797 Mon Sep 17 00:00:00 2001 From: Amin Sammara <84764772+aminsammara@users.noreply.github.com> Date: Fri, 13 Mar 2026 11:45:24 +0000 Subject: [PATCH 1/2] chore: tune mainnet slasher penalties and sequencer allocation (#21451) ## Summary - Lower `SLASH_INACTIVITY_TARGET_PERCENTAGE` from 0.8 to 0.7 - Disable `SLASH_DUPLICATE_PROPOSAL_PENALTY` and `SLASH_DUPLICATE_ATTESTATION_PENALTY` (set to 0) - Increase `SLASH_GRACE_PERIOD_L2_SLOTS` from 1200 to 8400 - Reduce `perBlockAllocationMultiplier` from 2 to 1.2 ## Test plan - Verify generated config files are updated after running `yarn generate` in relevant packages - Deploy to devnet/testnet and confirm slasher behavior matches new parameters --------- Co-authored-by: Aztec Bot <49558828+AztecBot@users.noreply.github.com> --- spartan/environments/network-defaults.yml | 29 +++++++++---------- .../e2e_deploy_contract/deploy_method.test.ts | 2 +- .../src/e2e_p2p/gossip_network.test.ts | 10 +++++-- .../src/client/sequencer-client.test.ts | 22 +++++++------- yarn-project/sequencer-client/src/config.ts | 2 +- 5 files changed, 34 insertions(+), 31 deletions(-) diff --git a/spartan/environments/network-defaults.yml b/spartan/environments/network-defaults.yml index 6618a189e3cf..4b1f05acf5c2 100644 --- a/spartan/environments/network-defaults.yml +++ b/spartan/environments/network-defaults.yml @@ -112,8 +112,7 @@ l1-contracts: &l1-contracts-defaults # These configure the slasher node's operational behavior. # Used by yarn-project/slasher for penalty calculation and offense tracking. -slasher: &slasher - # Minimum penalty percentage multiplier. +slasher: &slasher # Minimum penalty percentage multiplier. SLASH_MIN_PENALTY_PERCENTAGE: 0.5 # Maximum penalty percentage multiplier. SLASH_MAX_PENALTY_PERCENTAGE: 2.0 @@ -215,16 +214,16 @@ networks: AZTEC_LAG_IN_EPOCHS_FOR_RANDAO: 1 AZTEC_SLASHING_EXECUTION_DELAY_IN_ROUNDS: 1 # Network identity - L1_CHAIN_ID: 11155111 # Sepolia + L1_CHAIN_ID: 11155111 # Sepolia # Genesis state - TEST_ACCOUNTS: true # Fund test accounts with fee juice - SPONSORED_FPC: true # Fund sponsored FPC with fee juice + TEST_ACCOUNTS: true # Fund test accounts with fee juice + SPONSORED_FPC: true # Fund sponsored FPC with fee juice TRANSACTIONS_DISABLED: false # Sequencer SEQ_MAX_TX_PER_BLOCK: 18 # Prover - PROVER_REAL_PROOFS: false # Use mock proofs - PXE_PROVER_ENABLED: false # Disable PXE proving + PROVER_REAL_PROOFS: false # Use mock proofs + PXE_PROVER_ENABLED: false # Disable PXE proving # Sync SYNC_SNAPSHOTS_URLS: "" SKIP_ARCHIVER_INITIAL_SYNC: false @@ -269,7 +268,7 @@ networks: AZTEC_SLASH_AMOUNT_MEDIUM: 100000e18 AZTEC_SLASH_AMOUNT_LARGE: 100000e18 # Network identity - L1_CHAIN_ID: 11155111 # Sepolia + L1_CHAIN_ID: 11155111 # Sepolia # Genesis state TEST_ACCOUNTS: false SPONSORED_FPC: false @@ -314,15 +313,15 @@ networks: AZTEC_GOVERNANCE_PROPOSER_ROUND_SIZE: 1000 AZTEC_MANA_TARGET: 75000000 AZTEC_PROVING_COST_PER_MANA: 25000000 - AZTEC_EXIT_DELAY_SECONDS: 345600 # 4 days - AZTEC_SLASHING_DISABLE_DURATION: 259200 # 3 days + AZTEC_EXIT_DELAY_SECONDS: 345600 # 4 days + AZTEC_SLASHING_DISABLE_DURATION: 259200 # 3 days AZTEC_ENTRY_QUEUE_BOOTSTRAP_VALIDATOR_SET_SIZE: 500 AZTEC_ENTRY_QUEUE_BOOTSTRAP_FLUSH_SIZE: 500 AZTEC_ENTRY_QUEUE_FLUSH_SIZE_MIN: 1 AZTEC_ENTRY_QUEUE_FLUSH_SIZE_QUOTIENT: 400 AZTEC_ENTRY_QUEUE_MAX_FLUSH_SIZE: 4 # Network identity - L1_CHAIN_ID: 1 # Ethereum mainnet + L1_CHAIN_ID: 1 # Ethereum mainnet # Genesis state - no test accounts, no sponsored FPC TEST_ACCOUNTS: false SPONSORED_FPC: false @@ -343,13 +342,13 @@ networks: # Slasher penalties - more lenient initially SLASH_PRUNE_PENALTY: 0 SLASH_DATA_WITHHOLDING_PENALTY: 0 - SLASH_INACTIVITY_TARGET_PERCENTAGE: 0.8 + SLASH_INACTIVITY_TARGET_PERCENTAGE: 0.7 SLASH_INACTIVITY_CONSECUTIVE_EPOCH_THRESHOLD: 2 SLASH_INACTIVITY_PENALTY: 2000e18 SLASH_PROPOSE_INVALID_ATTESTATIONS_PENALTY: 2000e18 - SLASH_DUPLICATE_PROPOSAL_PENALTY: 2000e18 - SLASH_DUPLICATE_ATTESTATION_PENALTY: 2000e18 + SLASH_DUPLICATE_PROPOSAL_PENALTY: 0 + SLASH_DUPLICATE_ATTESTATION_PENALTY: 0 SLASH_ATTEST_DESCENDANT_OF_INVALID_PENALTY: 2000e18 SLASH_UNKNOWN_PENALTY: 2000e18 SLASH_INVALID_BLOCK_PENALTY: 2000e18 - SLASH_GRACE_PERIOD_L2_SLOTS: 1200 + SLASH_GRACE_PERIOD_L2_SLOTS: 8400 diff --git a/yarn-project/end-to-end/src/e2e_deploy_contract/deploy_method.test.ts b/yarn-project/end-to-end/src/e2e_deploy_contract/deploy_method.test.ts index ed7cfba703fb..708215460821 100644 --- a/yarn-project/end-to-end/src/e2e_deploy_contract/deploy_method.test.ts +++ b/yarn-project/end-to-end/src/e2e_deploy_contract/deploy_method.test.ts @@ -157,7 +157,7 @@ describe('e2e_deploy_contract deploy method', () => { // First send the deploy transaction // Pay priority fee to ensure the deployment transaction gets processed first. - const maxPriorityFeesPerGas = new GasFees(1n, 0n); + const maxPriorityFeesPerGas = new GasFees(0n, 1n); const deployTxPromise = deployTx.send({ from: defaultAccountAddress, fee: { gasSettings: { maxPriorityFeesPerGas } }, diff --git a/yarn-project/end-to-end/src/e2e_p2p/gossip_network.test.ts b/yarn-project/end-to-end/src/e2e_p2p/gossip_network.test.ts index ff561ecfff69..eba29fcf1e3b 100644 --- a/yarn-project/end-to-end/src/e2e_p2p/gossip_network.test.ts +++ b/yarn-project/end-to-end/src/e2e_p2p/gossip_network.test.ts @@ -30,6 +30,8 @@ const CHECK_ALERTS = process.env.CHECK_ALERTS === 'true'; const NUM_VALIDATORS = 4; const NUM_TXS_PER_NODE = 2; const BOOT_NODE_UDP_PORT = 4500; +const AZTEC_SLOT_DURATION = 36; +const AZTEC_EPOCH_DURATION = 4; const DATA_DIR = fs.mkdtempSync(path.join(os.tmpdir(), 'gossip-')); @@ -61,8 +63,8 @@ describe('e2e_p2p_network', () => { startProverNode: false, // we'll start our own using p2p initialConfig: { ...SHORTENED_BLOCK_TIME_CONFIG_NO_PRUNES, - aztecSlotDuration: 36, - aztecEpochDuration: 4, + aztecSlotDuration: AZTEC_SLOT_DURATION, + aztecEpochDuration: AZTEC_EPOCH_DURATION, slashingRoundSizeInEpochs: 2, slashingQuorum: 5, listenAddress: '127.0.0.1', @@ -205,13 +207,15 @@ describe('e2e_p2p_network', () => { } // Ensure prover node did its job and collected txs from p2p + // Timeout must exceed one full epoch (aztecSlotDuration * aztecEpochDuration = 36 * 4 = 144s) + // plus time for the prover to generate and submit the proof. await retryUntil( async () => { const provenBlock = await nodes[0].getProvenBlockNumber(); return provenBlock > 0; }, 'proven block', - 120, + 300, ); }); }); diff --git a/yarn-project/sequencer-client/src/client/sequencer-client.test.ts b/yarn-project/sequencer-client/src/client/sequencer-client.test.ts index e325cefca47d..fde8ab830cfa 100644 --- a/yarn-project/sequencer-client/src/client/sequencer-client.test.ts +++ b/yarn-project/sequencer-client/src/client/sequencer-client.test.ts @@ -22,8 +22,8 @@ describe('computeBlockLimits', () => { describe('L2 gas', () => { it('derives maxL2BlockGas from rollupManaLimit when not explicitly set', () => { const rollupManaLimit = 1_000_000; - // Single block mode (maxNumberOfBlocks=1), default multiplier=2: - // min(1_000_000, ceil(1_000_000 / 1 * 2)) = min(1_000_000, 2_000_000) = 1_000_000 + // Single block mode (maxNumberOfBlocks=1), default multiplier=1.2: + // min(1_000_000, ceil(1_000_000 / 1 * 1.2)) = min(1_000_000, 1_200_000) = 1_000_000 const result = computeBlockLimits(makeConfig(), rollupManaLimit, 12, log); expect(result.maxL2BlockGas).toBe(rollupManaLimit); }); @@ -43,8 +43,8 @@ describe('computeBlockLimits', () => { const daLimit = MAX_PROCESSABLE_DA_GAS_PER_CHECKPOINT; it('derives maxDABlockGas from DA checkpoint limit when not explicitly set', () => { - // Single block mode (maxNumberOfBlocks=1), default multiplier=2: - // min(daLimit, ceil(daLimit / 1 * 2)) = min(daLimit, daLimit * 2) = daLimit + // Single block mode (maxNumberOfBlocks=1), default multiplier=1.2: + // min(daLimit, ceil(daLimit / 1 * 1.2)) = min(daLimit, daLimit * 1.2) = daLimit const result = computeBlockLimits(makeConfig(), 1_000_000, 12, log); expect(result.maxDABlockGas).toBe(daLimit); }); @@ -78,14 +78,14 @@ describe('computeBlockLimits', () => { }); it('derives maxTxsPerBlock from maxTxsPerCheckpoint when per-block not set', () => { - // Multi-block mode with maxNumberOfBlocks=5, multiplier=2: - // min(100, ceil(100 / 5 * 2)) = min(100, 40) = 40 + // Multi-block mode with maxNumberOfBlocks=5, multiplier=1.2: + // min(100, ceil(100 / 5 * 1.2)) = min(100, 24) = 24 const config = makeConfig({ maxTxsPerCheckpoint: 100, blockDurationMs: 8000, }); const result = computeBlockLimits(config, 1_000_000, 12, log); - expect(result.maxTxsPerBlock).toBe(40); + expect(result.maxTxsPerBlock).toBe(24); }); }); @@ -97,14 +97,14 @@ describe('computeBlockLimits', () => { // timeReservedAtEnd = 8 + 19 = 27 // timeAvailableForBlocks = 72 - 1 - 27 = 44 // maxNumberOfBlocks = floor(44 / 8) = 5 - // With multiplier=2 and rollupManaLimit=1_000_000: - // maxL2BlockGas = min(1_000_000, ceil(1_000_000 / 5 * 2)) = min(1_000_000, 400_000) = 400_000 + // With multiplier=1.2 and rollupManaLimit=1_000_000: + // maxL2BlockGas = min(1_000_000, ceil(1_000_000 / 5 * 1.2)) = min(1_000_000, 240_000) = 240_000 const config = makeConfig({ blockDurationMs: 8000 }); const result = computeBlockLimits(config, 1_000_000, 12, log); - expect(result.maxL2BlockGas).toBe(400_000); + expect(result.maxL2BlockGas).toBe(240_000); const daLimit = MAX_PROCESSABLE_DA_GAS_PER_CHECKPOINT; - expect(result.maxDABlockGas).toBe(Math.min(daLimit, Math.ceil((daLimit / 5) * 2))); + expect(result.maxDABlockGas).toBe(Math.min(daLimit, Math.ceil((daLimit / 5) * 1.2))); }); }); }); diff --git a/yarn-project/sequencer-client/src/config.ts b/yarn-project/sequencer-client/src/config.ts index 117839911491..489bbfefba01 100644 --- a/yarn-project/sequencer-client/src/config.ts +++ b/yarn-project/sequencer-client/src/config.ts @@ -40,7 +40,7 @@ export const DefaultSequencerConfig = { minTxsPerBlock: 1, buildCheckpointIfEmpty: false, publishTxsWithProposals: false, - perBlockAllocationMultiplier: 2, + perBlockAllocationMultiplier: 1.2, enforceTimeTable: true, attestationPropagationTime: DEFAULT_P2P_PROPAGATION_TIME, secondsBeforeInvalidatingBlockAsCommitteeMember: 144, // 12 L1 blocks From 45ba1c40405ba9f752cedc5cbbfcba03d975a1f0 Mon Sep 17 00:00:00 2001 From: AztecBot Date: Fri, 13 Mar 2026 12:12:35 +0000 Subject: [PATCH 2/2] fix: resolve merge conflict markers from v4 into v4-next sync --- .../sequencer-client/src/client/sequencer-client.test.ts | 3 --- yarn-project/sequencer-client/src/config.ts | 3 --- 2 files changed, 6 deletions(-) diff --git a/yarn-project/sequencer-client/src/client/sequencer-client.test.ts b/yarn-project/sequencer-client/src/client/sequencer-client.test.ts index 07edcb8de369..f2eb896e4746 100644 --- a/yarn-project/sequencer-client/src/client/sequencer-client.test.ts +++ b/yarn-project/sequencer-client/src/client/sequencer-client.test.ts @@ -105,15 +105,12 @@ describe('computeBlockLimits', () => { const daLimit = MAX_PROCESSABLE_DA_GAS_PER_CHECKPOINT; expect(result.maxDABlockGas).toBe(Math.min(daLimit, Math.ceil((daLimit / 5) * 1.2))); -<<<<<<< HEAD }); it('returns maxBlocksPerCheckpoint from timetable', () => { const config = makeConfig({ blockDurationMs: 8000 }); const result = computeBlockLimits(config, 1_000_000, 12, log); expect(result.maxBlocksPerCheckpoint).toBe(5); -======= ->>>>>>> origin/v4 }); }); }); diff --git a/yarn-project/sequencer-client/src/config.ts b/yarn-project/sequencer-client/src/config.ts index 75eed0051343..e0ce28583791 100644 --- a/yarn-project/sequencer-client/src/config.ts +++ b/yarn-project/sequencer-client/src/config.ts @@ -41,10 +41,7 @@ export const DefaultSequencerConfig = { buildCheckpointIfEmpty: false, publishTxsWithProposals: false, perBlockAllocationMultiplier: 1.2, -<<<<<<< HEAD redistributeCheckpointBudget: true, -======= ->>>>>>> origin/v4 enforceTimeTable: true, attestationPropagationTime: DEFAULT_P2P_PROPAGATION_TIME, secondsBeforeInvalidatingBlockAsCommitteeMember: 144, // 12 L1 blocks