From 05b0c861899cf3f9f1263278a53ad57a18078e68 Mon Sep 17 00:00:00 2001 From: Phil Windle Date: Thu, 21 May 2026 12:58:23 +0000 Subject: [PATCH 1/4] refactor(slasher): rename ATTESTED_DESCENDANT_OF_INVALID -> PROPOSED_DESCENDANT_OF_INVALID Rename the slashing offence and its associated config knob, env var, helm value, and terraform variable to reflect that the slash now targets the proposer that publishes a descendant checkpoint to L1, not its attestors. Breaking for operators: SLASH_ATTEST_DESCENDANT_OF_INVALID_PENALTY -> SLASH_PROPOSE_DESCENDANT_OF_INVALID_PENALTY (see v5.0.0 changelog). --- .../operators/reference/changelog/v5.md | 34 +++++++++++++++++++ .../slashing-configuration.md | 2 +- .../aztec-node/templates/_pod-template.yaml | 6 ++-- spartan/aztec-node/values.yaml | 2 +- spartan/environments/network-defaults.yml | 10 +++--- spartan/scripts/deploy_network.sh | 2 +- spartan/terraform/deploy-aztec-infra/main.tf | 2 +- .../terraform/deploy-aztec-infra/variables.tf | 4 +-- .../aztec-node/src/aztec-node/server.ts | 2 +- ..._invalid_checkpoint_proposal_slash.test.ts | 2 +- .../src/spartan/invalidate_blocks.test.ts | 8 ++--- yarn-project/foundation/src/config/env_var.ts | 2 +- yarn-project/slasher/README.md | 10 +++--- yarn-project/slasher/src/config.ts | 10 +++--- .../src/slash_offenses_collector.test.ts | 4 +-- .../slasher/src/stores/offenses_store.test.ts | 4 +-- .../attestations_block_watcher.test.ts | 8 ++--- .../watchers/attestations_block_watcher.ts | 6 ++-- .../src/interfaces/aztec-node-admin.test.ts | 2 +- yarn-project/stdlib/src/interfaces/slasher.ts | 4 +-- .../stdlib/src/slashing/helpers.test.ts | 4 +-- yarn-project/stdlib/src/slashing/helpers.ts | 8 ++--- .../stdlib/src/slashing/serialization.test.ts | 4 +-- yarn-project/stdlib/src/slashing/types.ts | 12 +++---- 24 files changed, 93 insertions(+), 59 deletions(-) create mode 100644 docs/docs-operate/operators/reference/changelog/v5.md diff --git a/docs/docs-operate/operators/reference/changelog/v5.md b/docs/docs-operate/operators/reference/changelog/v5.md new file mode 100644 index 000000000000..bb3cfd241e0b --- /dev/null +++ b/docs/docs-operate/operators/reference/changelog/v5.md @@ -0,0 +1,34 @@ +--- +title: v5.0.0 +description: Operator-facing changes for the v5.0.0 release. +--- + +## Overview + +**Migration difficulty**: TODO + +## Breaking changes + +### `SLASH_ATTEST_DESCENDANT_OF_INVALID_PENALTY` renamed to `SLASH_PROPOSE_DESCENDANT_OF_INVALID_PENALTY` + +The slashing offence for building on an invalid checkpoint has been renamed to reflect that the slash targets the proposer of the descendant checkpoint published to L1, not its attestors. + +**v4.x:** + +```bash +SLASH_ATTEST_DESCENDANT_OF_INVALID_PENALTY= +``` + +**v5.0.0:** + +```bash +SLASH_PROPOSE_DESCENDANT_OF_INVALID_PENALTY= +``` + +**Migration**: rename the variable in your node environment, systemd units, helm values, or any deployment scripts. The underlying offence enum (`OffenseType`) has also been renamed from `ATTESTED_DESCENDANT_OF_INVALID` to `PROPOSED_DESCENDANT_OF_INVALID`, which only affects downstream tools that parse offence types from the slasher. + +## New features + +## Changed defaults + +## Troubleshooting diff --git a/docs/docs-operate/operators/sequencer-management/slashing-configuration.md b/docs/docs-operate/operators/sequencer-management/slashing-configuration.md index b6ccfee9757e..05154add3b19 100644 --- a/docs/docs-operate/operators/sequencer-management/slashing-configuration.md +++ b/docs/docs-operate/operators/sequencer-management/slashing-configuration.md @@ -161,7 +161,7 @@ SLASH_DATA_WITHHOLDING_PENALTY=0 # Set to >0 to enable # Invalid attestations and blocks SLASH_PROPOSE_INVALID_ATTESTATIONS_PENALTY=2000000000000000000000 # 2000 tokens -SLASH_ATTEST_DESCENDANT_OF_INVALID_PENALTY=2000000000000000000000 # 2000 tokens +SLASH_PROPOSE_DESCENDANT_OF_INVALID_PENALTY=2000000000000000000000 # 2000 tokens SLASH_INVALID_BLOCK_PENALTY=2000000000000000000000 # 2000 tokens # Offense expiration diff --git a/spartan/aztec-node/templates/_pod-template.yaml b/spartan/aztec-node/templates/_pod-template.yaml index 623199606123..e3c8344285b9 100644 --- a/spartan/aztec-node/templates/_pod-template.yaml +++ b/spartan/aztec-node/templates/_pod-template.yaml @@ -253,9 +253,9 @@ spec: - name: SLASH_DUPLICATE_ATTESTATION_PENALTY value: {{ .Values.node.slash.duplicateAttestationPenalty | quote }} {{- end }} - {{- if .Values.node.slash.attestDescendantOfInvalidPenalty }} - - name: SLASH_ATTEST_DESCENDANT_OF_INVALID_PENALTY - value: {{ .Values.node.slash.attestDescendantOfInvalidPenalty | quote }} + {{- if .Values.node.slash.proposeDescendantOfInvalidPenalty }} + - name: SLASH_PROPOSE_DESCENDANT_OF_INVALID_PENALTY + value: {{ .Values.node.slash.proposeDescendantOfInvalidPenalty | quote }} {{- end }} {{- if .Values.node.slash.attestInvalidCheckpointProposalPenalty }} - name: SLASH_ATTEST_INVALID_CHECKPOINT_PROPOSAL_PENALTY diff --git a/spartan/aztec-node/values.yaml b/spartan/aztec-node/values.yaml index a1219566677b..d85cacedd64e 100644 --- a/spartan/aztec-node/values.yaml +++ b/spartan/aztec-node/values.yaml @@ -154,7 +154,7 @@ node: invalidBlockPenalty: "" invalidCheckpointProposalPenalty: "" proposeInvalidAttestationsPenalty: "" - attestDescendantOfInvalidPenalty: "" + proposeDescendantOfInvalidPenalty: "" attestInvalidCheckpointProposalPenalty: "" unknownPenalty: "" # Slasher behavior configuration diff --git a/spartan/environments/network-defaults.yml b/spartan/environments/network-defaults.yml index af8dd3234471..1342f19dab13 100644 --- a/spartan/environments/network-defaults.yml +++ b/spartan/environments/network-defaults.yml @@ -131,8 +131,8 @@ slasher: &slasher SLASH_INACTIVITY_PENALTY: 10e18 # Penalty for proposing invalid attestations. SLASH_PROPOSE_INVALID_ATTESTATIONS_PENALTY: 10e18 - # Penalty for attesting to a descendant of an invalid block. - SLASH_ATTEST_DESCENDANT_OF_INVALID_PENALTY: 10e18 + # Penalty for proposing a checkpoint that builds on an invalid checkpoint. + SLASH_PROPOSE_DESCENDANT_OF_INVALID_PENALTY: 10e18 # Penalty for attesting to an invalid checkpoint proposal. SLASH_ATTEST_INVALID_CHECKPOINT_PROPOSAL_PENALTY: 10e18 # Penalty for proposing two different block or checkpoint proposal for the same position. @@ -244,7 +244,7 @@ networks: SLASH_PROPOSE_INVALID_ATTESTATIONS_PENALTY: 10e18 SLASH_DUPLICATE_PROPOSAL_PENALTY: 10e18 SLASH_DUPLICATE_ATTESTATION_PENALTY: 10e18 - SLASH_ATTEST_DESCENDANT_OF_INVALID_PENALTY: 10e18 + SLASH_PROPOSE_DESCENDANT_OF_INVALID_PENALTY: 10e18 SLASH_ATTEST_INVALID_CHECKPOINT_PROPOSAL_PENALTY: 10e18 SLASH_UNKNOWN_PENALTY: 10e18 SLASH_INVALID_BLOCK_PENALTY: 10e18 @@ -290,7 +290,7 @@ networks: SLASH_PROPOSE_INVALID_ATTESTATIONS_PENALTY: 10e18 SLASH_DUPLICATE_PROPOSAL_PENALTY: 10e18 SLASH_DUPLICATE_ATTESTATION_PENALTY: 10e18 - SLASH_ATTEST_DESCENDANT_OF_INVALID_PENALTY: 10e18 + SLASH_PROPOSE_DESCENDANT_OF_INVALID_PENALTY: 10e18 SLASH_ATTEST_INVALID_CHECKPOINT_PROPOSAL_PENALTY: 10e18 SLASH_UNKNOWN_PENALTY: 10e18 SLASH_INVALID_BLOCK_PENALTY: 10e18 @@ -350,7 +350,7 @@ networks: SLASH_PROPOSE_INVALID_ATTESTATIONS_PENALTY: 2000e18 SLASH_DUPLICATE_PROPOSAL_PENALTY: 2000e18 SLASH_DUPLICATE_ATTESTATION_PENALTY: 2000e18 - SLASH_ATTEST_DESCENDANT_OF_INVALID_PENALTY: 2000e18 + SLASH_PROPOSE_DESCENDANT_OF_INVALID_PENALTY: 2000e18 SLASH_ATTEST_INVALID_CHECKPOINT_PROPOSAL_PENALTY: 2000e18 SLASH_UNKNOWN_PENALTY: 2000e18 SLASH_INVALID_BLOCK_PENALTY: 2000e18 diff --git a/spartan/scripts/deploy_network.sh b/spartan/scripts/deploy_network.sh index c7003d14e050..8b30e59e0777 100755 --- a/spartan/scripts/deploy_network.sh +++ b/spartan/scripts/deploy_network.sh @@ -591,7 +591,7 @@ SLASH_DATA_WITHHOLDING_TOLERANCE_SLOTS = ${SLASH_DATA_WITHHOLDING_TOLERANCE_SLOT SLASH_PROPOSE_INVALID_ATTESTATIONS_PENALTY = ${SLASH_PROPOSE_INVALID_ATTESTATIONS_PENALTY:-null} SLASH_DUPLICATE_PROPOSAL_PENALTY = ${SLASH_DUPLICATE_PROPOSAL_PENALTY:-null} SLASH_DUPLICATE_ATTESTATION_PENALTY = ${SLASH_DUPLICATE_ATTESTATION_PENALTY:-null} -SLASH_ATTEST_DESCENDANT_OF_INVALID_PENALTY = ${SLASH_ATTEST_DESCENDANT_OF_INVALID_PENALTY:-null} +SLASH_PROPOSE_DESCENDANT_OF_INVALID_PENALTY = ${SLASH_PROPOSE_DESCENDANT_OF_INVALID_PENALTY:-null} SLASH_ATTEST_INVALID_CHECKPOINT_PROPOSAL_PENALTY = ${SLASH_ATTEST_INVALID_CHECKPOINT_PROPOSAL_PENALTY:-null} SLASH_UNKNOWN_PENALTY = ${SLASH_UNKNOWN_PENALTY:-null} SLASH_INVALID_BLOCK_PENALTY = ${SLASH_INVALID_BLOCK_PENALTY:-null} diff --git a/spartan/terraform/deploy-aztec-infra/main.tf b/spartan/terraform/deploy-aztec-infra/main.tf index 159814445998..3f36a8e8d345 100644 --- a/spartan/terraform/deploy-aztec-infra/main.tf +++ b/spartan/terraform/deploy-aztec-infra/main.tf @@ -205,7 +205,7 @@ locals { "validator.slash.proposeInvalidAttestationsPenalty" = var.SLASH_PROPOSE_INVALID_ATTESTATIONS_PENALTY "validator.slash.duplicateProposalPenalty" = var.SLASH_DUPLICATE_PROPOSAL_PENALTY "validator.slash.duplicateAttestationPenalty" = var.SLASH_DUPLICATE_ATTESTATION_PENALTY - "validator.slash.attestDescendantOfInvalidPenalty" = var.SLASH_ATTEST_DESCENDANT_OF_INVALID_PENALTY + "validator.slash.proposeDescendantOfInvalidPenalty" = var.SLASH_PROPOSE_DESCENDANT_OF_INVALID_PENALTY "validator.slash.attestInvalidCheckpointProposalPenalty" = var.SLASH_ATTEST_INVALID_CHECKPOINT_PROPOSAL_PENALTY "validator.slash.unknownPenalty" = var.SLASH_UNKNOWN_PENALTY "validator.slash.invalidBlockPenalty" = var.SLASH_INVALID_BLOCK_PENALTY diff --git a/spartan/terraform/deploy-aztec-infra/variables.tf b/spartan/terraform/deploy-aztec-infra/variables.tf index 79d92e694cb1..7e5c4bc9a5cb 100644 --- a/spartan/terraform/deploy-aztec-infra/variables.tf +++ b/spartan/terraform/deploy-aztec-infra/variables.tf @@ -496,8 +496,8 @@ variable "SLASH_DUPLICATE_ATTESTATION_PENALTY" { nullable = true } -variable "SLASH_ATTEST_DESCENDANT_OF_INVALID_PENALTY" { - description = "The slash attest descendant of invalid penalty" +variable "SLASH_PROPOSE_DESCENDANT_OF_INVALID_PENALTY" { + description = "The slash propose descendant of invalid penalty" type = string nullable = true } diff --git a/yarn-project/aztec-node/src/aztec-node/server.ts b/yarn-project/aztec-node/src/aztec-node/server.ts index d81e57d21cbe..4c8e54c42bb9 100644 --- a/yarn-project/aztec-node/src/aztec-node/server.ts +++ b/yarn-project/aztec-node/src/aztec-node/server.ts @@ -769,7 +769,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, AztecNodeDeb } // We assume we want to slash for invalid attestations unless all max penalties are set to 0 - if (config.slashProposeInvalidAttestationsPenalty > 0n || config.slashAttestDescendantOfInvalidPenalty > 0n) { + if (config.slashProposeInvalidAttestationsPenalty > 0n || config.slashProposeDescendantOfInvalidPenalty > 0n) { attestationsBlockWatcher = new AttestationsBlockWatcher(archiver, epochCache, config); watchers.push(attestationsBlockWatcher); } diff --git a/yarn-project/end-to-end/src/e2e_slashing/broadcasted_invalid_checkpoint_proposal_slash.test.ts b/yarn-project/end-to-end/src/e2e_slashing/broadcasted_invalid_checkpoint_proposal_slash.test.ts index 6a9d4fab22d1..fb436a2e5aa5 100644 --- a/yarn-project/end-to-end/src/e2e_slashing/broadcasted_invalid_checkpoint_proposal_slash.test.ts +++ b/yarn-project/end-to-end/src/e2e_slashing/broadcasted_invalid_checkpoint_proposal_slash.test.ts @@ -236,7 +236,7 @@ describe('e2e_slashing_broadcasted_invalid_checkpoint_proposal_slash', () => { slashDuplicateProposalPenalty: 0n, slashDuplicateAttestationPenalty: 0n, slashProposeInvalidAttestationsPenalty: 0n, - slashAttestDescendantOfInvalidPenalty: 0n, + slashProposeDescendantOfInvalidPenalty: 0n, slashAttestInvalidCheckpointProposalPenalty: 0n, slashUnknownPenalty: 0n, slashSelfAllowed: true, diff --git a/yarn-project/end-to-end/src/spartan/invalidate_blocks.test.ts b/yarn-project/end-to-end/src/spartan/invalidate_blocks.test.ts index 702e30d8ccc1..47f892b0f0d0 100644 --- a/yarn-project/end-to-end/src/spartan/invalidate_blocks.test.ts +++ b/yarn-project/end-to-end/src/spartan/invalidate_blocks.test.ts @@ -43,7 +43,7 @@ describe('invalidate blocks test', () => { let node: AztecNode; let origMinTxsPerBlock: number | undefined; let origSlashProposeInvalidAttestationsPenalty: bigint | undefined; - let origSlashAttestDescendantOfInvalidPenalty: bigint | undefined; + let origSlashProposeDescendantOfInvalidPenalty: bigint | undefined; const health = new ChainHealth(config.NAMESPACE, logger); const waitForSequencersToApplyConfig = async (expected: Partial, description: string) => { @@ -78,7 +78,7 @@ describe('invalidate blocks test', () => { skipCollectingAttestations: false, minTxsPerBlock: origMinTxsPerBlock, slashProposeInvalidAttestationsPenalty: origSlashProposeInvalidAttestationsPenalty, - slashAttestDescendantOfInvalidPenalty: origSlashAttestDescendantOfInvalidPenalty, + slashProposeDescendantOfInvalidPenalty: origSlashProposeDescendantOfInvalidPenalty, }; await updateSequencersConfig(config, restoreConfig); // Ensure config has actually propagated before the next scenario test starts @@ -107,7 +107,7 @@ describe('invalidate blocks test', () => { const first = configs?.[0]; origMinTxsPerBlock = first?.minTxsPerBlock ?? origMinTxsPerBlock; origSlashProposeInvalidAttestationsPenalty = first?.slashProposeInvalidAttestationsPenalty; - origSlashAttestDescendantOfInvalidPenalty = first?.slashAttestDescendantOfInvalidPenalty; + origSlashProposeDescendantOfInvalidPenalty = first?.slashProposeDescendantOfInvalidPenalty; const initialCheckpointNumber = (await monitor.run()).checkpointNumber; @@ -116,7 +116,7 @@ describe('invalidate blocks test', () => { await updateSequencersConfig(config, { skipCollectingAttestations: true, slashProposeInvalidAttestationsPenalty: 0n, - slashAttestDescendantOfInvalidPenalty: 0n, + slashProposeDescendantOfInvalidPenalty: 0n, minTxsPerBlock: 0, }); diff --git a/yarn-project/foundation/src/config/env_var.ts b/yarn-project/foundation/src/config/env_var.ts index 72f23721cc0f..35230c745f85 100644 --- a/yarn-project/foundation/src/config/env_var.ts +++ b/yarn-project/foundation/src/config/env_var.ts @@ -253,7 +253,7 @@ export type EnvVar = | 'SLASH_DUPLICATE_ATTESTATION_PENALTY' | 'SLASH_OVERRIDE_PAYLOAD' | 'SLASH_PROPOSE_INVALID_ATTESTATIONS_PENALTY' - | 'SLASH_ATTEST_DESCENDANT_OF_INVALID_PENALTY' + | 'SLASH_PROPOSE_DESCENDANT_OF_INVALID_PENALTY' | 'SLASH_ATTEST_INVALID_CHECKPOINT_PROPOSAL_PENALTY' | 'SLASH_UNKNOWN_PENALTY' | 'SLASH_GRACE_PERIOD_L2_SLOTS' diff --git a/yarn-project/slasher/README.md b/yarn-project/slasher/README.md index 44e245410813..f556f62c7d81 100644 --- a/yarn-project/slasher/README.md +++ b/yarn-project/slasher/README.md @@ -110,10 +110,10 @@ List of all slashable offenses in the system: **Target**: Block proposer. **Time Unit**: Slot-based offense. -### ATTESTED_DESCENDANT_OF_INVALID -**Description**: A committee member attested to a block built on top of an invalid ancestor. -**Detection**: AttestationsBlockWatcher tracks invalid blocks and their descendants. -**Target**: Committee members who attested to the descendant block. +### PROPOSED_DESCENDANT_OF_INVALID +**Description**: A proposer published a checkpoint to L1 that builds on an invalid checkpoint (one with invalid or insufficient attestations). +**Detection**: AttestationsBlockWatcher tracks invalid checkpoints and their descendants. +**Target**: Proposer of the descendant checkpoint. **Time Unit**: Slot-based offense. ### DUPLICATE_PROPOSAL @@ -174,7 +174,7 @@ with divergent validation limits. - `slashBroadcastedInvalidCheckpointProposalPenalty`: Penalty for BROADCASTED_INVALID_CHECKPOINT_PROPOSAL - `slashDuplicateProposalPenalty`: Penalty for DUPLICATE_PROPOSAL - `slashProposeInvalidAttestationsPenalty`: Penalty for PROPOSED_INSUFFICIENT_ATTESTATIONS and PROPOSED_INCORRECT_ATTESTATIONS -- `slashAttestDescendantOfInvalidPenalty`: Penalty for ATTESTED_DESCENDANT_OF_INVALID +- `slashProposeDescendantOfInvalidPenalty`: Penalty for PROPOSED_DESCENDANT_OF_INVALID - `slashAttestInvalidCheckpointProposalPenalty`: Penalty for ATTESTED_TO_INVALID_CHECKPOINT_PROPOSAL - `slashUnknownPenalty`: Default penalty for unknown offense types - `slashMaxPayloadSize`: Limits the number of **unique validators** (across all committees and epochs in a round) that receive non-zero votes. When this cap is hit, the lowest-severity validator-epoch pairs are zeroed out first, so the most severe slashes are always preserved. Note that multiple offenses for the same validator in the same epoch are summed and counted as a single validator entry against this limit. diff --git a/yarn-project/slasher/src/config.ts b/yarn-project/slasher/src/config.ts index 57a3d96735a7..66f2115adf85 100644 --- a/yarn-project/slasher/src/config.ts +++ b/yarn-project/slasher/src/config.ts @@ -26,7 +26,7 @@ export const DefaultSlasherConfig: SlasherConfig = { slashDuplicateAttestationPenalty: BigInt(slasherDefaultEnv.SLASH_DUPLICATE_ATTESTATION_PENALTY), slashInactivityPenalty: BigInt(slasherDefaultEnv.SLASH_INACTIVITY_PENALTY), slashProposeInvalidAttestationsPenalty: BigInt(slasherDefaultEnv.SLASH_PROPOSE_INVALID_ATTESTATIONS_PENALTY), - slashAttestDescendantOfInvalidPenalty: BigInt(slasherDefaultEnv.SLASH_ATTEST_DESCENDANT_OF_INVALID_PENALTY), + slashProposeDescendantOfInvalidPenalty: BigInt(slasherDefaultEnv.SLASH_PROPOSE_DESCENDANT_OF_INVALID_PENALTY), slashAttestInvalidCheckpointProposalPenalty: BigInt( slasherDefaultEnv.SLASH_ATTEST_INVALID_CHECKPOINT_PROPOSAL_PENALTY, ), @@ -131,11 +131,11 @@ export const slasherConfigMappings: ConfigMappingsType = { description: 'Penalty amount for slashing a proposer that proposed invalid attestations (set to 0 to disable).', ...bigintConfigHelper(DefaultSlasherConfig.slashProposeInvalidAttestationsPenalty), }, - slashAttestDescendantOfInvalidPenalty: { - env: 'SLASH_ATTEST_DESCENDANT_OF_INVALID_PENALTY', + slashProposeDescendantOfInvalidPenalty: { + env: 'SLASH_PROPOSE_DESCENDANT_OF_INVALID_PENALTY', description: - 'Penalty amount for slashing a validator that attested to a descendant of an invalid block (set to 0 to disable).', - ...bigintConfigHelper(DefaultSlasherConfig.slashAttestDescendantOfInvalidPenalty), + 'Penalty amount for slashing a proposer that published a checkpoint building on an invalid checkpoint (set to 0 to disable).', + ...bigintConfigHelper(DefaultSlasherConfig.slashProposeDescendantOfInvalidPenalty), }, slashAttestInvalidCheckpointProposalPenalty: { env: 'SLASH_ATTEST_INVALID_CHECKPOINT_PROPOSAL_PENALTY', diff --git a/yarn-project/slasher/src/slash_offenses_collector.test.ts b/yarn-project/slasher/src/slash_offenses_collector.test.ts index c599ac0866a8..6b0a60269e40 100644 --- a/yarn-project/slasher/src/slash_offenses_collector.test.ts +++ b/yarn-project/slasher/src/slash_offenses_collector.test.ts @@ -164,7 +164,7 @@ describe('SlashOffensesCollector', () => { { validator: validator3, amount: 1500000000000000000n, - offenseType: OffenseType.ATTESTED_DESCENDANT_OF_INVALID, + offenseType: OffenseType.PROPOSED_DESCENDANT_OF_INVALID, epochOrSlot: 175n, // slot 175 >= 110 }, ]; @@ -201,7 +201,7 @@ describe('SlashOffensesCollector', () => { expect(offensesByValidator[validator3.toString()]).toMatchObject({ validator: validator3, amount: 1500000000000000000n, - offenseType: OffenseType.ATTESTED_DESCENDANT_OF_INVALID, + offenseType: OffenseType.PROPOSED_DESCENDANT_OF_INVALID, epochOrSlot: 175n, }); }); diff --git a/yarn-project/slasher/src/stores/offenses_store.test.ts b/yarn-project/slasher/src/stores/offenses_store.test.ts index d195c9386bb1..312700d83ed2 100644 --- a/yarn-project/slasher/src/stores/offenses_store.test.ts +++ b/yarn-project/slasher/src/stores/offenses_store.test.ts @@ -119,7 +119,7 @@ describe('SlasherOffensesStore', () => { it('should preserve offense data across store operations', async () => { const validator = EthAddress.fromString('0x1234567890abcdef1234567890abcdef12345678'); - const offense = createOffense(validator, 12345n, OffenseType.ATTESTED_DESCENDANT_OF_INVALID, 54321n); + const offense = createOffense(validator, 12345n, OffenseType.PROPOSED_DESCENDANT_OF_INVALID, 54321n); await store.addOffense(offense); @@ -127,7 +127,7 @@ describe('SlasherOffensesStore', () => { expect(pendingOffenses).toHaveLength(1); expect(pendingOffenses[0].validator.toString()).toBe(validator.toString()); expect(pendingOffenses[0].amount).toBe(12345n); - expect(pendingOffenses[0].offenseType).toBe(OffenseType.ATTESTED_DESCENDANT_OF_INVALID); + expect(pendingOffenses[0].offenseType).toBe(OffenseType.PROPOSED_DESCENDANT_OF_INVALID); expect(pendingOffenses[0].epochOrSlot).toBe(54321n); }); diff --git a/yarn-project/slasher/src/watchers/attestations_block_watcher.test.ts b/yarn-project/slasher/src/watchers/attestations_block_watcher.test.ts index 5d418ebbd49c..29bf1c91acdc 100644 --- a/yarn-project/slasher/src/watchers/attestations_block_watcher.test.ts +++ b/yarn-project/slasher/src/watchers/attestations_block_watcher.test.ts @@ -176,14 +176,14 @@ describe('AttestationsBlockWatcher', () => { expect(handler).toHaveBeenCalledWith([ { validator: attestor1, - amount: config.slashAttestDescendantOfInvalidPenalty, - offenseType: OffenseType.ATTESTED_DESCENDANT_OF_INVALID, + amount: config.slashProposeDescendantOfInvalidPenalty, + offenseType: OffenseType.PROPOSED_DESCENDANT_OF_INVALID, epochOrSlot: 2n, }, { validator: attestor2, - amount: config.slashAttestDescendantOfInvalidPenalty, - offenseType: OffenseType.ATTESTED_DESCENDANT_OF_INVALID, + amount: config.slashProposeDescendantOfInvalidPenalty, + offenseType: OffenseType.PROPOSED_DESCENDANT_OF_INVALID, epochOrSlot: 2n, }, ] satisfies WantToSlashArgs[]); diff --git a/yarn-project/slasher/src/watchers/attestations_block_watcher.ts b/yarn-project/slasher/src/watchers/attestations_block_watcher.ts index d49825a168dd..bb4c9bc6d3e4 100644 --- a/yarn-project/slasher/src/watchers/attestations_block_watcher.ts +++ b/yarn-project/slasher/src/watchers/attestations_block_watcher.ts @@ -17,7 +17,7 @@ import type { SlasherConfig } from '../config.js'; import { WANT_TO_SLASH_EVENT, type WantToSlashArgs, type Watcher, type WatcherEmitter } from '../watcher.js'; const AttestationsBlockWatcherConfigKeys = [ - 'slashAttestDescendantOfInvalidPenalty', + 'slashProposeDescendantOfInvalidPenalty', 'slashProposeInvalidAttestationsPenalty', ] as const; const MAX_INVALID_CHECKPOINTS = 100; @@ -124,8 +124,8 @@ export class AttestationsBlockWatcher extends (EventEmitter as new () => Watcher WANT_TO_SLASH_EVENT, attestors.map(attestor => ({ validator: attestor, - amount: this.config.slashAttestDescendantOfInvalidPenalty, - offenseType: OffenseType.ATTESTED_DESCENDANT_OF_INVALID, + amount: this.config.slashProposeDescendantOfInvalidPenalty, + offenseType: OffenseType.PROPOSED_DESCENDANT_OF_INVALID, epochOrSlot: BigInt(SlotNumber(checkpoint.slotNumber)), })), ); diff --git a/yarn-project/stdlib/src/interfaces/aztec-node-admin.test.ts b/yarn-project/stdlib/src/interfaces/aztec-node-admin.test.ts index 34963ecf2bb8..3ed365b0ef8d 100644 --- a/yarn-project/stdlib/src/interfaces/aztec-node-admin.test.ts +++ b/yarn-project/stdlib/src/interfaces/aztec-node-admin.test.ts @@ -128,7 +128,7 @@ class MockAztecNodeAdmin implements AztecNodeAdmin { secondsBeforeInvalidatingBlockAsCommitteeMember: 0, secondsBeforeInvalidatingBlockAsNonCommitteeMember: 0, slashProposeInvalidAttestationsPenalty: 1000n, - slashAttestDescendantOfInvalidPenalty: 1000n, + slashProposeDescendantOfInvalidPenalty: 1000n, slashOffenseExpirationRounds: 4, slashMaxPayloadSize: 50, slashUnknownPenalty: 1000n, diff --git a/yarn-project/stdlib/src/interfaces/slasher.ts b/yarn-project/stdlib/src/interfaces/slasher.ts index 6a0d9b757ddc..99d0cf926e65 100644 --- a/yarn-project/stdlib/src/interfaces/slasher.ts +++ b/yarn-project/stdlib/src/interfaces/slasher.ts @@ -23,7 +23,7 @@ export interface SlasherConfig { slashDuplicateProposalPenalty: bigint; slashDuplicateAttestationPenalty: bigint; slashProposeInvalidAttestationsPenalty: bigint; - slashAttestDescendantOfInvalidPenalty: bigint; + slashProposeDescendantOfInvalidPenalty: bigint; slashAttestInvalidCheckpointProposalPenalty: bigint; slashUnknownPenalty: bigint; slashOffenseExpirationRounds: number; // Number of rounds after which pending offenses expire @@ -50,7 +50,7 @@ export const SlasherConfigSchema = zodFor()( slashBroadcastedInvalidCheckpointProposalPenalty: schemas.BigInt.default(0n), slashDuplicateProposalPenalty: schemas.BigInt, slashDuplicateAttestationPenalty: schemas.BigInt, - slashAttestDescendantOfInvalidPenalty: schemas.BigInt, + slashProposeDescendantOfInvalidPenalty: schemas.BigInt, slashAttestInvalidCheckpointProposalPenalty: schemas.BigInt, slashUnknownPenalty: schemas.BigInt, slashOffenseExpirationRounds: z.number(), diff --git a/yarn-project/stdlib/src/slashing/helpers.test.ts b/yarn-project/stdlib/src/slashing/helpers.test.ts index c0386967028a..0208d6466556 100644 --- a/yarn-project/stdlib/src/slashing/helpers.test.ts +++ b/yarn-project/stdlib/src/slashing/helpers.test.ts @@ -197,7 +197,7 @@ describe('SlashingHelpers', () => { describe('getPenaltyForOffense', () => { it('returns the configured penalty for attesting to invalid checkpoint proposal', () => { const penalty = getPenaltyForOffense(OffenseType.ATTESTED_TO_INVALID_CHECKPOINT_PROPOSAL, { - slashAttestDescendantOfInvalidPenalty: 1n, + slashProposeDescendantOfInvalidPenalty: 1n, slashBroadcastedInvalidBlockPenalty: 2n, slashBroadcastedInvalidCheckpointProposalPenalty: 11n, slashDuplicateProposalPenalty: 3n, @@ -214,7 +214,7 @@ describe('SlashingHelpers', () => { it('returns the configured penalty for broadcasting invalid checkpoint proposal', () => { const penalty = getPenaltyForOffense(OffenseType.BROADCASTED_INVALID_CHECKPOINT_PROPOSAL, { - slashAttestDescendantOfInvalidPenalty: 1n, + slashProposeDescendantOfInvalidPenalty: 1n, slashBroadcastedInvalidBlockPenalty: 2n, slashBroadcastedInvalidCheckpointProposalPenalty: 11n, slashDuplicateProposalPenalty: 3n, diff --git a/yarn-project/stdlib/src/slashing/helpers.ts b/yarn-project/stdlib/src/slashing/helpers.ts index b3150e1f4c54..94861c6ce30e 100644 --- a/yarn-project/stdlib/src/slashing/helpers.ts +++ b/yarn-project/stdlib/src/slashing/helpers.ts @@ -48,7 +48,7 @@ export function getPenaltyForOffense( offense: OffenseType, config: Pick< SlasherConfig, - | 'slashAttestDescendantOfInvalidPenalty' + | 'slashProposeDescendantOfInvalidPenalty' | 'slashBroadcastedInvalidBlockPenalty' | 'slashBroadcastedInvalidCheckpointProposalPenalty' | 'slashDuplicateProposalPenalty' @@ -68,8 +68,8 @@ export function getPenaltyForOffense( case OffenseType.PROPOSED_INSUFFICIENT_ATTESTATIONS: case OffenseType.PROPOSED_INCORRECT_ATTESTATIONS: return config.slashProposeInvalidAttestationsPenalty; - case OffenseType.ATTESTED_DESCENDANT_OF_INVALID: - return config.slashAttestDescendantOfInvalidPenalty; + case OffenseType.PROPOSED_DESCENDANT_OF_INVALID: + return config.slashProposeDescendantOfInvalidPenalty; case OffenseType.BROADCASTED_INVALID_BLOCK_PROPOSAL: return config.slashBroadcastedInvalidBlockPenalty; case OffenseType.BROADCASTED_INVALID_CHECKPOINT_PROPOSAL: @@ -92,7 +92,7 @@ export function getPenaltyForOffense( /** Returns whether the `epochOrSlot` field for an offense references an epoch or a slot */ export function getTimeUnitForOffense(offense: OffenseType): 'epoch' | 'slot' { switch (offense) { - case OffenseType.ATTESTED_DESCENDANT_OF_INVALID: + case OffenseType.PROPOSED_DESCENDANT_OF_INVALID: case OffenseType.BROADCASTED_INVALID_BLOCK_PROPOSAL: case OffenseType.DATA_WITHHOLDING: case OffenseType.BROADCASTED_INVALID_CHECKPOINT_PROPOSAL: diff --git a/yarn-project/stdlib/src/slashing/serialization.test.ts b/yarn-project/stdlib/src/slashing/serialization.test.ts index 91de7e0b0108..8673ed7bc780 100644 --- a/yarn-project/stdlib/src/slashing/serialization.test.ts +++ b/yarn-project/stdlib/src/slashing/serialization.test.ts @@ -118,7 +118,7 @@ describe('slashing/serialization', () => { const originalOffense = createOffense( EthAddress.random(), 12345n, - OffenseType.ATTESTED_DESCENDANT_OF_INVALID, + OffenseType.PROPOSED_DESCENDANT_OF_INVALID, 98765n, ); @@ -168,7 +168,7 @@ describe('slashing/serialization', () => { const slotOffenses = [ OffenseType.PROPOSED_INSUFFICIENT_ATTESTATIONS, OffenseType.PROPOSED_INCORRECT_ATTESTATIONS, - OffenseType.ATTESTED_DESCENDANT_OF_INVALID, + OffenseType.PROPOSED_DESCENDANT_OF_INVALID, OffenseType.ATTESTED_TO_INVALID_CHECKPOINT_PROPOSAL, OffenseType.BROADCASTED_INVALID_BLOCK_PROPOSAL, ]; diff --git a/yarn-project/stdlib/src/slashing/types.ts b/yarn-project/stdlib/src/slashing/types.ts index 32c2ff671251..4a210cb15e4e 100644 --- a/yarn-project/stdlib/src/slashing/types.ts +++ b/yarn-project/stdlib/src/slashing/types.ts @@ -16,8 +16,8 @@ export enum OffenseType { PROPOSED_INSUFFICIENT_ATTESTATIONS = 5, /** A proposer pushed to L1 a block with incorrect committee attestations (ie signature from a non-committee member) */ PROPOSED_INCORRECT_ATTESTATIONS = 6, - /** A committee member attested to a block that was built as a descendent of an invalid block (as in a block with invalid attestations) */ - ATTESTED_DESCENDANT_OF_INVALID = 7, + /** A proposer published a checkpoint to L1 that builds on an invalid checkpoint (as in a checkpoint with invalid or insufficient attestations) */ + PROPOSED_DESCENDANT_OF_INVALID = 7, /** A proposer sent duplicate proposals for the same position (slot, indexWithinCheckpoint for blocks or slot for checkpoints) */ DUPLICATE_PROPOSAL = 8, /** A validator signed attestations for different proposals at the same slot (equivocation) */ @@ -42,8 +42,8 @@ export function getOffenseTypeName(offense: OffenseType) { return 'proposed_insufficient_attestations'; case OffenseType.PROPOSED_INCORRECT_ATTESTATIONS: return 'proposed_incorrect_attestations'; - case OffenseType.ATTESTED_DESCENDANT_OF_INVALID: - return 'attested_descendant_of_invalid'; + case OffenseType.PROPOSED_DESCENDANT_OF_INVALID: + return 'proposed_descendant_of_invalid'; case OffenseType.DUPLICATE_PROPOSAL: return 'duplicate_proposal'; case OffenseType.DUPLICATE_ATTESTATION: @@ -66,7 +66,7 @@ export const OffenseToBigInt: Record = { [OffenseType.BROADCASTED_INVALID_BLOCK_PROPOSAL]: 4n, [OffenseType.PROPOSED_INSUFFICIENT_ATTESTATIONS]: 5n, [OffenseType.PROPOSED_INCORRECT_ATTESTATIONS]: 6n, - [OffenseType.ATTESTED_DESCENDANT_OF_INVALID]: 7n, + [OffenseType.PROPOSED_DESCENDANT_OF_INVALID]: 7n, [OffenseType.DUPLICATE_PROPOSAL]: 8n, [OffenseType.DUPLICATE_ATTESTATION]: 9n, [OffenseType.ATTESTED_TO_INVALID_CHECKPOINT_PROPOSAL]: 10n, @@ -88,7 +88,7 @@ export function bigIntToOffense(offense: bigint): OffenseType { case 6n: return OffenseType.PROPOSED_INCORRECT_ATTESTATIONS; case 7n: - return OffenseType.ATTESTED_DESCENDANT_OF_INVALID; + return OffenseType.PROPOSED_DESCENDANT_OF_INVALID; case 8n: return OffenseType.DUPLICATE_PROPOSAL; case 9n: From dc3e9eb86df9d7b87619faa036562e911da45256 Mon Sep 17 00:00:00 2001 From: Phil Windle Date: Thu, 21 May 2026 13:24:08 +0000 Subject: [PATCH 2/4] =?UTF-8?q?fix:=20cspell=20=E2=80=94=20offence=20->=20?= =?UTF-8?q?offense=20in=20v5=20changelog?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/docs-operate/operators/reference/changelog/v5.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/docs-operate/operators/reference/changelog/v5.md b/docs/docs-operate/operators/reference/changelog/v5.md index bb3cfd241e0b..3490a91d3b3d 100644 --- a/docs/docs-operate/operators/reference/changelog/v5.md +++ b/docs/docs-operate/operators/reference/changelog/v5.md @@ -11,7 +11,7 @@ description: Operator-facing changes for the v5.0.0 release. ### `SLASH_ATTEST_DESCENDANT_OF_INVALID_PENALTY` renamed to `SLASH_PROPOSE_DESCENDANT_OF_INVALID_PENALTY` -The slashing offence for building on an invalid checkpoint has been renamed to reflect that the slash targets the proposer of the descendant checkpoint published to L1, not its attestors. +The slashing offense for building on an invalid checkpoint has been renamed to reflect that the slash targets the proposer of the descendant checkpoint published to L1, not its attestors. **v4.x:** @@ -25,7 +25,7 @@ SLASH_ATTEST_DESCENDANT_OF_INVALID_PENALTY= SLASH_PROPOSE_DESCENDANT_OF_INVALID_PENALTY= ``` -**Migration**: rename the variable in your node environment, systemd units, helm values, or any deployment scripts. The underlying offence enum (`OffenseType`) has also been renamed from `ATTESTED_DESCENDANT_OF_INVALID` to `PROPOSED_DESCENDANT_OF_INVALID`, which only affects downstream tools that parse offence types from the slasher. +**Migration**: rename the variable in your node environment, systemd units, helm values, or any deployment scripts. The underlying offense enum (`OffenseType`) has also been renamed from `ATTESTED_DESCENDANT_OF_INVALID` to `PROPOSED_DESCENDANT_OF_INVALID`, which only affects downstream tools that parse offense types from the slasher. ## New features From e1527760c69f883cadf007b3648597221724b136 Mon Sep 17 00:00:00 2001 From: Phil Windle Date: Thu, 21 May 2026 16:02:35 +0000 Subject: [PATCH 3/4] chore: remove v5 changelog stub --- .../operators/reference/changelog/v5.md | 34 ------------------- 1 file changed, 34 deletions(-) delete mode 100644 docs/docs-operate/operators/reference/changelog/v5.md diff --git a/docs/docs-operate/operators/reference/changelog/v5.md b/docs/docs-operate/operators/reference/changelog/v5.md deleted file mode 100644 index 3490a91d3b3d..000000000000 --- a/docs/docs-operate/operators/reference/changelog/v5.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -title: v5.0.0 -description: Operator-facing changes for the v5.0.0 release. ---- - -## Overview - -**Migration difficulty**: TODO - -## Breaking changes - -### `SLASH_ATTEST_DESCENDANT_OF_INVALID_PENALTY` renamed to `SLASH_PROPOSE_DESCENDANT_OF_INVALID_PENALTY` - -The slashing offense for building on an invalid checkpoint has been renamed to reflect that the slash targets the proposer of the descendant checkpoint published to L1, not its attestors. - -**v4.x:** - -```bash -SLASH_ATTEST_DESCENDANT_OF_INVALID_PENALTY= -``` - -**v5.0.0:** - -```bash -SLASH_PROPOSE_DESCENDANT_OF_INVALID_PENALTY= -``` - -**Migration**: rename the variable in your node environment, systemd units, helm values, or any deployment scripts. The underlying offense enum (`OffenseType`) has also been renamed from `ATTESTED_DESCENDANT_OF_INVALID` to `PROPOSED_DESCENDANT_OF_INVALID`, which only affects downstream tools that parse offense types from the slasher. - -## New features - -## Changed defaults - -## Troubleshooting From cb91c41afac169f54a2f70e6da60d92387209234 Mon Sep 17 00:00:00 2001 From: Phil Windle Date: Thu, 21 May 2026 16:17:59 +0000 Subject: [PATCH 4/4] refactor(slasher): use longer-form name PROPOSED_DESCENDANT_OF_CHECKPOINT_WITH_INVALID_ATTESTATIONS Rename the offence (and its config knob, env var, helm value, terraform variable, etc.) from the previous shorter PROPOSED_DESCENDANT_OF_INVALID form to spell out the exact condition: a descendant of a checkpoint that had invalid (or insufficient) attestations. --- .../sequencer-management/slashing-configuration.md | 2 +- spartan/aztec-node/templates/_pod-template.yaml | 6 +++--- spartan/aztec-node/values.yaml | 2 +- spartan/environments/network-defaults.yml | 8 ++++---- spartan/scripts/deploy_network.sh | 2 +- spartan/terraform/deploy-aztec-infra/main.tf | 2 +- spartan/terraform/deploy-aztec-infra/variables.tf | 2 +- yarn-project/aztec-node/src/aztec-node/server.ts | 5 ++++- ...adcasted_invalid_checkpoint_proposal_slash.test.ts | 2 +- .../end-to-end/src/spartan/invalidate_blocks.test.ts | 10 ++++++---- yarn-project/foundation/src/config/env_var.ts | 2 +- yarn-project/slasher/README.md | 4 ++-- yarn-project/slasher/src/config.ts | 10 ++++++---- .../slasher/src/slash_offenses_collector.test.ts | 4 ++-- .../slasher/src/stores/offenses_store.test.ts | 11 +++++++++-- .../src/watchers/attestations_block_watcher.test.ts | 8 ++++---- .../src/watchers/attestations_block_watcher.ts | 6 +++--- .../stdlib/src/interfaces/aztec-node-admin.test.ts | 2 +- yarn-project/stdlib/src/interfaces/slasher.ts | 4 ++-- yarn-project/stdlib/src/slashing/helpers.test.ts | 4 ++-- yarn-project/stdlib/src/slashing/helpers.ts | 8 ++++---- .../stdlib/src/slashing/serialization.test.ts | 4 ++-- yarn-project/stdlib/src/slashing/types.ts | 10 +++++----- 23 files changed, 66 insertions(+), 52 deletions(-) diff --git a/docs/docs-operate/operators/sequencer-management/slashing-configuration.md b/docs/docs-operate/operators/sequencer-management/slashing-configuration.md index 05154add3b19..53a8d0008b62 100644 --- a/docs/docs-operate/operators/sequencer-management/slashing-configuration.md +++ b/docs/docs-operate/operators/sequencer-management/slashing-configuration.md @@ -161,7 +161,7 @@ SLASH_DATA_WITHHOLDING_PENALTY=0 # Set to >0 to enable # Invalid attestations and blocks SLASH_PROPOSE_INVALID_ATTESTATIONS_PENALTY=2000000000000000000000 # 2000 tokens -SLASH_PROPOSE_DESCENDANT_OF_INVALID_PENALTY=2000000000000000000000 # 2000 tokens +SLASH_PROPOSE_DESCENDANT_OF_CHECKPOINT_WITH_INVALID_ATTESTATIONS_PENALTY=2000000000000000000000 # 2000 tokens SLASH_INVALID_BLOCK_PENALTY=2000000000000000000000 # 2000 tokens # Offense expiration diff --git a/spartan/aztec-node/templates/_pod-template.yaml b/spartan/aztec-node/templates/_pod-template.yaml index e3c8344285b9..bfeb7e899cf9 100644 --- a/spartan/aztec-node/templates/_pod-template.yaml +++ b/spartan/aztec-node/templates/_pod-template.yaml @@ -253,9 +253,9 @@ spec: - name: SLASH_DUPLICATE_ATTESTATION_PENALTY value: {{ .Values.node.slash.duplicateAttestationPenalty | quote }} {{- end }} - {{- if .Values.node.slash.proposeDescendantOfInvalidPenalty }} - - name: SLASH_PROPOSE_DESCENDANT_OF_INVALID_PENALTY - value: {{ .Values.node.slash.proposeDescendantOfInvalidPenalty | quote }} + {{- if .Values.node.slash.proposeDescendantOfCheckpointWithInvalidAttestationsPenalty }} + - name: SLASH_PROPOSE_DESCENDANT_OF_CHECKPOINT_WITH_INVALID_ATTESTATIONS_PENALTY + value: {{ .Values.node.slash.proposeDescendantOfCheckpointWithInvalidAttestationsPenalty | quote }} {{- end }} {{- if .Values.node.slash.attestInvalidCheckpointProposalPenalty }} - name: SLASH_ATTEST_INVALID_CHECKPOINT_PROPOSAL_PENALTY diff --git a/spartan/aztec-node/values.yaml b/spartan/aztec-node/values.yaml index d85cacedd64e..b9d8732f434d 100644 --- a/spartan/aztec-node/values.yaml +++ b/spartan/aztec-node/values.yaml @@ -154,7 +154,7 @@ node: invalidBlockPenalty: "" invalidCheckpointProposalPenalty: "" proposeInvalidAttestationsPenalty: "" - proposeDescendantOfInvalidPenalty: "" + proposeDescendantOfCheckpointWithInvalidAttestationsPenalty: "" attestInvalidCheckpointProposalPenalty: "" unknownPenalty: "" # Slasher behavior configuration diff --git a/spartan/environments/network-defaults.yml b/spartan/environments/network-defaults.yml index 1342f19dab13..c918dcddc515 100644 --- a/spartan/environments/network-defaults.yml +++ b/spartan/environments/network-defaults.yml @@ -132,7 +132,7 @@ slasher: &slasher # Penalty for proposing invalid attestations. SLASH_PROPOSE_INVALID_ATTESTATIONS_PENALTY: 10e18 # Penalty for proposing a checkpoint that builds on an invalid checkpoint. - SLASH_PROPOSE_DESCENDANT_OF_INVALID_PENALTY: 10e18 + SLASH_PROPOSE_DESCENDANT_OF_CHECKPOINT_WITH_INVALID_ATTESTATIONS_PENALTY: 10e18 # Penalty for attesting to an invalid checkpoint proposal. SLASH_ATTEST_INVALID_CHECKPOINT_PROPOSAL_PENALTY: 10e18 # Penalty for proposing two different block or checkpoint proposal for the same position. @@ -244,7 +244,7 @@ networks: SLASH_PROPOSE_INVALID_ATTESTATIONS_PENALTY: 10e18 SLASH_DUPLICATE_PROPOSAL_PENALTY: 10e18 SLASH_DUPLICATE_ATTESTATION_PENALTY: 10e18 - SLASH_PROPOSE_DESCENDANT_OF_INVALID_PENALTY: 10e18 + SLASH_PROPOSE_DESCENDANT_OF_CHECKPOINT_WITH_INVALID_ATTESTATIONS_PENALTY: 10e18 SLASH_ATTEST_INVALID_CHECKPOINT_PROPOSAL_PENALTY: 10e18 SLASH_UNKNOWN_PENALTY: 10e18 SLASH_INVALID_BLOCK_PENALTY: 10e18 @@ -290,7 +290,7 @@ networks: SLASH_PROPOSE_INVALID_ATTESTATIONS_PENALTY: 10e18 SLASH_DUPLICATE_PROPOSAL_PENALTY: 10e18 SLASH_DUPLICATE_ATTESTATION_PENALTY: 10e18 - SLASH_PROPOSE_DESCENDANT_OF_INVALID_PENALTY: 10e18 + SLASH_PROPOSE_DESCENDANT_OF_CHECKPOINT_WITH_INVALID_ATTESTATIONS_PENALTY: 10e18 SLASH_ATTEST_INVALID_CHECKPOINT_PROPOSAL_PENALTY: 10e18 SLASH_UNKNOWN_PENALTY: 10e18 SLASH_INVALID_BLOCK_PENALTY: 10e18 @@ -350,7 +350,7 @@ networks: SLASH_PROPOSE_INVALID_ATTESTATIONS_PENALTY: 2000e18 SLASH_DUPLICATE_PROPOSAL_PENALTY: 2000e18 SLASH_DUPLICATE_ATTESTATION_PENALTY: 2000e18 - SLASH_PROPOSE_DESCENDANT_OF_INVALID_PENALTY: 2000e18 + SLASH_PROPOSE_DESCENDANT_OF_CHECKPOINT_WITH_INVALID_ATTESTATIONS_PENALTY: 2000e18 SLASH_ATTEST_INVALID_CHECKPOINT_PROPOSAL_PENALTY: 2000e18 SLASH_UNKNOWN_PENALTY: 2000e18 SLASH_INVALID_BLOCK_PENALTY: 2000e18 diff --git a/spartan/scripts/deploy_network.sh b/spartan/scripts/deploy_network.sh index 8b30e59e0777..96b1f215a407 100755 --- a/spartan/scripts/deploy_network.sh +++ b/spartan/scripts/deploy_network.sh @@ -591,7 +591,7 @@ SLASH_DATA_WITHHOLDING_TOLERANCE_SLOTS = ${SLASH_DATA_WITHHOLDING_TOLERANCE_SLOT SLASH_PROPOSE_INVALID_ATTESTATIONS_PENALTY = ${SLASH_PROPOSE_INVALID_ATTESTATIONS_PENALTY:-null} SLASH_DUPLICATE_PROPOSAL_PENALTY = ${SLASH_DUPLICATE_PROPOSAL_PENALTY:-null} SLASH_DUPLICATE_ATTESTATION_PENALTY = ${SLASH_DUPLICATE_ATTESTATION_PENALTY:-null} -SLASH_PROPOSE_DESCENDANT_OF_INVALID_PENALTY = ${SLASH_PROPOSE_DESCENDANT_OF_INVALID_PENALTY:-null} +SLASH_PROPOSE_DESCENDANT_OF_CHECKPOINT_WITH_INVALID_ATTESTATIONS_PENALTY = ${SLASH_PROPOSE_DESCENDANT_OF_CHECKPOINT_WITH_INVALID_ATTESTATIONS_PENALTY:-null} SLASH_ATTEST_INVALID_CHECKPOINT_PROPOSAL_PENALTY = ${SLASH_ATTEST_INVALID_CHECKPOINT_PROPOSAL_PENALTY:-null} SLASH_UNKNOWN_PENALTY = ${SLASH_UNKNOWN_PENALTY:-null} SLASH_INVALID_BLOCK_PENALTY = ${SLASH_INVALID_BLOCK_PENALTY:-null} diff --git a/spartan/terraform/deploy-aztec-infra/main.tf b/spartan/terraform/deploy-aztec-infra/main.tf index 3f36a8e8d345..e12514973b97 100644 --- a/spartan/terraform/deploy-aztec-infra/main.tf +++ b/spartan/terraform/deploy-aztec-infra/main.tf @@ -205,7 +205,7 @@ locals { "validator.slash.proposeInvalidAttestationsPenalty" = var.SLASH_PROPOSE_INVALID_ATTESTATIONS_PENALTY "validator.slash.duplicateProposalPenalty" = var.SLASH_DUPLICATE_PROPOSAL_PENALTY "validator.slash.duplicateAttestationPenalty" = var.SLASH_DUPLICATE_ATTESTATION_PENALTY - "validator.slash.proposeDescendantOfInvalidPenalty" = var.SLASH_PROPOSE_DESCENDANT_OF_INVALID_PENALTY + "validator.slash.proposeDescendantOfCheckpointWithInvalidAttestationsPenalty" = var.SLASH_PROPOSE_DESCENDANT_OF_CHECKPOINT_WITH_INVALID_ATTESTATIONS_PENALTY "validator.slash.attestInvalidCheckpointProposalPenalty" = var.SLASH_ATTEST_INVALID_CHECKPOINT_PROPOSAL_PENALTY "validator.slash.unknownPenalty" = var.SLASH_UNKNOWN_PENALTY "validator.slash.invalidBlockPenalty" = var.SLASH_INVALID_BLOCK_PENALTY diff --git a/spartan/terraform/deploy-aztec-infra/variables.tf b/spartan/terraform/deploy-aztec-infra/variables.tf index 7e5c4bc9a5cb..ec5898d082d2 100644 --- a/spartan/terraform/deploy-aztec-infra/variables.tf +++ b/spartan/terraform/deploy-aztec-infra/variables.tf @@ -496,7 +496,7 @@ variable "SLASH_DUPLICATE_ATTESTATION_PENALTY" { nullable = true } -variable "SLASH_PROPOSE_DESCENDANT_OF_INVALID_PENALTY" { +variable "SLASH_PROPOSE_DESCENDANT_OF_CHECKPOINT_WITH_INVALID_ATTESTATIONS_PENALTY" { description = "The slash propose descendant of invalid penalty" type = string nullable = true diff --git a/yarn-project/aztec-node/src/aztec-node/server.ts b/yarn-project/aztec-node/src/aztec-node/server.ts index 4c8e54c42bb9..267e4c5332e3 100644 --- a/yarn-project/aztec-node/src/aztec-node/server.ts +++ b/yarn-project/aztec-node/src/aztec-node/server.ts @@ -769,7 +769,10 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, AztecNodeDeb } // We assume we want to slash for invalid attestations unless all max penalties are set to 0 - if (config.slashProposeInvalidAttestationsPenalty > 0n || config.slashProposeDescendantOfInvalidPenalty > 0n) { + if ( + config.slashProposeInvalidAttestationsPenalty > 0n || + config.slashProposeDescendantOfCheckpointWithInvalidAttestationsPenalty > 0n + ) { attestationsBlockWatcher = new AttestationsBlockWatcher(archiver, epochCache, config); watchers.push(attestationsBlockWatcher); } diff --git a/yarn-project/end-to-end/src/e2e_slashing/broadcasted_invalid_checkpoint_proposal_slash.test.ts b/yarn-project/end-to-end/src/e2e_slashing/broadcasted_invalid_checkpoint_proposal_slash.test.ts index fb436a2e5aa5..57b37440cf7a 100644 --- a/yarn-project/end-to-end/src/e2e_slashing/broadcasted_invalid_checkpoint_proposal_slash.test.ts +++ b/yarn-project/end-to-end/src/e2e_slashing/broadcasted_invalid_checkpoint_proposal_slash.test.ts @@ -236,7 +236,7 @@ describe('e2e_slashing_broadcasted_invalid_checkpoint_proposal_slash', () => { slashDuplicateProposalPenalty: 0n, slashDuplicateAttestationPenalty: 0n, slashProposeInvalidAttestationsPenalty: 0n, - slashProposeDescendantOfInvalidPenalty: 0n, + slashProposeDescendantOfCheckpointWithInvalidAttestationsPenalty: 0n, slashAttestInvalidCheckpointProposalPenalty: 0n, slashUnknownPenalty: 0n, slashSelfAllowed: true, diff --git a/yarn-project/end-to-end/src/spartan/invalidate_blocks.test.ts b/yarn-project/end-to-end/src/spartan/invalidate_blocks.test.ts index 47f892b0f0d0..1a6d299dea6d 100644 --- a/yarn-project/end-to-end/src/spartan/invalidate_blocks.test.ts +++ b/yarn-project/end-to-end/src/spartan/invalidate_blocks.test.ts @@ -43,7 +43,7 @@ describe('invalidate blocks test', () => { let node: AztecNode; let origMinTxsPerBlock: number | undefined; let origSlashProposeInvalidAttestationsPenalty: bigint | undefined; - let origSlashProposeDescendantOfInvalidPenalty: bigint | undefined; + let origSlashProposeDescendantOfCheckpointWithInvalidAttestationsPenalty: bigint | undefined; const health = new ChainHealth(config.NAMESPACE, logger); const waitForSequencersToApplyConfig = async (expected: Partial, description: string) => { @@ -78,7 +78,8 @@ describe('invalidate blocks test', () => { skipCollectingAttestations: false, minTxsPerBlock: origMinTxsPerBlock, slashProposeInvalidAttestationsPenalty: origSlashProposeInvalidAttestationsPenalty, - slashProposeDescendantOfInvalidPenalty: origSlashProposeDescendantOfInvalidPenalty, + slashProposeDescendantOfCheckpointWithInvalidAttestationsPenalty: + origSlashProposeDescendantOfCheckpointWithInvalidAttestationsPenalty, }; await updateSequencersConfig(config, restoreConfig); // Ensure config has actually propagated before the next scenario test starts @@ -107,7 +108,8 @@ describe('invalidate blocks test', () => { const first = configs?.[0]; origMinTxsPerBlock = first?.minTxsPerBlock ?? origMinTxsPerBlock; origSlashProposeInvalidAttestationsPenalty = first?.slashProposeInvalidAttestationsPenalty; - origSlashProposeDescendantOfInvalidPenalty = first?.slashProposeDescendantOfInvalidPenalty; + origSlashProposeDescendantOfCheckpointWithInvalidAttestationsPenalty = + first?.slashProposeDescendantOfCheckpointWithInvalidAttestationsPenalty; const initialCheckpointNumber = (await monitor.run()).checkpointNumber; @@ -116,7 +118,7 @@ describe('invalidate blocks test', () => { await updateSequencersConfig(config, { skipCollectingAttestations: true, slashProposeInvalidAttestationsPenalty: 0n, - slashProposeDescendantOfInvalidPenalty: 0n, + slashProposeDescendantOfCheckpointWithInvalidAttestationsPenalty: 0n, minTxsPerBlock: 0, }); diff --git a/yarn-project/foundation/src/config/env_var.ts b/yarn-project/foundation/src/config/env_var.ts index 35230c745f85..e086a79195e7 100644 --- a/yarn-project/foundation/src/config/env_var.ts +++ b/yarn-project/foundation/src/config/env_var.ts @@ -253,7 +253,7 @@ export type EnvVar = | 'SLASH_DUPLICATE_ATTESTATION_PENALTY' | 'SLASH_OVERRIDE_PAYLOAD' | 'SLASH_PROPOSE_INVALID_ATTESTATIONS_PENALTY' - | 'SLASH_PROPOSE_DESCENDANT_OF_INVALID_PENALTY' + | 'SLASH_PROPOSE_DESCENDANT_OF_CHECKPOINT_WITH_INVALID_ATTESTATIONS_PENALTY' | 'SLASH_ATTEST_INVALID_CHECKPOINT_PROPOSAL_PENALTY' | 'SLASH_UNKNOWN_PENALTY' | 'SLASH_GRACE_PERIOD_L2_SLOTS' diff --git a/yarn-project/slasher/README.md b/yarn-project/slasher/README.md index f556f62c7d81..195102a241ab 100644 --- a/yarn-project/slasher/README.md +++ b/yarn-project/slasher/README.md @@ -110,7 +110,7 @@ List of all slashable offenses in the system: **Target**: Block proposer. **Time Unit**: Slot-based offense. -### PROPOSED_DESCENDANT_OF_INVALID +### PROPOSED_DESCENDANT_OF_CHECKPOINT_WITH_INVALID_ATTESTATIONS **Description**: A proposer published a checkpoint to L1 that builds on an invalid checkpoint (one with invalid or insufficient attestations). **Detection**: AttestationsBlockWatcher tracks invalid checkpoints and their descendants. **Target**: Proposer of the descendant checkpoint. @@ -174,7 +174,7 @@ with divergent validation limits. - `slashBroadcastedInvalidCheckpointProposalPenalty`: Penalty for BROADCASTED_INVALID_CHECKPOINT_PROPOSAL - `slashDuplicateProposalPenalty`: Penalty for DUPLICATE_PROPOSAL - `slashProposeInvalidAttestationsPenalty`: Penalty for PROPOSED_INSUFFICIENT_ATTESTATIONS and PROPOSED_INCORRECT_ATTESTATIONS -- `slashProposeDescendantOfInvalidPenalty`: Penalty for PROPOSED_DESCENDANT_OF_INVALID +- `slashProposeDescendantOfCheckpointWithInvalidAttestationsPenalty`: Penalty for PROPOSED_DESCENDANT_OF_CHECKPOINT_WITH_INVALID_ATTESTATIONS - `slashAttestInvalidCheckpointProposalPenalty`: Penalty for ATTESTED_TO_INVALID_CHECKPOINT_PROPOSAL - `slashUnknownPenalty`: Default penalty for unknown offense types - `slashMaxPayloadSize`: Limits the number of **unique validators** (across all committees and epochs in a round) that receive non-zero votes. When this cap is hit, the lowest-severity validator-epoch pairs are zeroed out first, so the most severe slashes are always preserved. Note that multiple offenses for the same validator in the same epoch are summed and counted as a single validator entry against this limit. diff --git a/yarn-project/slasher/src/config.ts b/yarn-project/slasher/src/config.ts index 66f2115adf85..ddc934f02b62 100644 --- a/yarn-project/slasher/src/config.ts +++ b/yarn-project/slasher/src/config.ts @@ -26,7 +26,9 @@ export const DefaultSlasherConfig: SlasherConfig = { slashDuplicateAttestationPenalty: BigInt(slasherDefaultEnv.SLASH_DUPLICATE_ATTESTATION_PENALTY), slashInactivityPenalty: BigInt(slasherDefaultEnv.SLASH_INACTIVITY_PENALTY), slashProposeInvalidAttestationsPenalty: BigInt(slasherDefaultEnv.SLASH_PROPOSE_INVALID_ATTESTATIONS_PENALTY), - slashProposeDescendantOfInvalidPenalty: BigInt(slasherDefaultEnv.SLASH_PROPOSE_DESCENDANT_OF_INVALID_PENALTY), + slashProposeDescendantOfCheckpointWithInvalidAttestationsPenalty: BigInt( + slasherDefaultEnv.SLASH_PROPOSE_DESCENDANT_OF_CHECKPOINT_WITH_INVALID_ATTESTATIONS_PENALTY, + ), slashAttestInvalidCheckpointProposalPenalty: BigInt( slasherDefaultEnv.SLASH_ATTEST_INVALID_CHECKPOINT_PROPOSAL_PENALTY, ), @@ -131,11 +133,11 @@ export const slasherConfigMappings: ConfigMappingsType = { description: 'Penalty amount for slashing a proposer that proposed invalid attestations (set to 0 to disable).', ...bigintConfigHelper(DefaultSlasherConfig.slashProposeInvalidAttestationsPenalty), }, - slashProposeDescendantOfInvalidPenalty: { - env: 'SLASH_PROPOSE_DESCENDANT_OF_INVALID_PENALTY', + slashProposeDescendantOfCheckpointWithInvalidAttestationsPenalty: { + env: 'SLASH_PROPOSE_DESCENDANT_OF_CHECKPOINT_WITH_INVALID_ATTESTATIONS_PENALTY', description: 'Penalty amount for slashing a proposer that published a checkpoint building on an invalid checkpoint (set to 0 to disable).', - ...bigintConfigHelper(DefaultSlasherConfig.slashProposeDescendantOfInvalidPenalty), + ...bigintConfigHelper(DefaultSlasherConfig.slashProposeDescendantOfCheckpointWithInvalidAttestationsPenalty), }, slashAttestInvalidCheckpointProposalPenalty: { env: 'SLASH_ATTEST_INVALID_CHECKPOINT_PROPOSAL_PENALTY', diff --git a/yarn-project/slasher/src/slash_offenses_collector.test.ts b/yarn-project/slasher/src/slash_offenses_collector.test.ts index 6b0a60269e40..01b7957d2fdd 100644 --- a/yarn-project/slasher/src/slash_offenses_collector.test.ts +++ b/yarn-project/slasher/src/slash_offenses_collector.test.ts @@ -164,7 +164,7 @@ describe('SlashOffensesCollector', () => { { validator: validator3, amount: 1500000000000000000n, - offenseType: OffenseType.PROPOSED_DESCENDANT_OF_INVALID, + offenseType: OffenseType.PROPOSED_DESCENDANT_OF_CHECKPOINT_WITH_INVALID_ATTESTATIONS, epochOrSlot: 175n, // slot 175 >= 110 }, ]; @@ -201,7 +201,7 @@ describe('SlashOffensesCollector', () => { expect(offensesByValidator[validator3.toString()]).toMatchObject({ validator: validator3, amount: 1500000000000000000n, - offenseType: OffenseType.PROPOSED_DESCENDANT_OF_INVALID, + offenseType: OffenseType.PROPOSED_DESCENDANT_OF_CHECKPOINT_WITH_INVALID_ATTESTATIONS, epochOrSlot: 175n, }); }); diff --git a/yarn-project/slasher/src/stores/offenses_store.test.ts b/yarn-project/slasher/src/stores/offenses_store.test.ts index 312700d83ed2..2aeba6e6aea7 100644 --- a/yarn-project/slasher/src/stores/offenses_store.test.ts +++ b/yarn-project/slasher/src/stores/offenses_store.test.ts @@ -119,7 +119,12 @@ describe('SlasherOffensesStore', () => { it('should preserve offense data across store operations', async () => { const validator = EthAddress.fromString('0x1234567890abcdef1234567890abcdef12345678'); - const offense = createOffense(validator, 12345n, OffenseType.PROPOSED_DESCENDANT_OF_INVALID, 54321n); + const offense = createOffense( + validator, + 12345n, + OffenseType.PROPOSED_DESCENDANT_OF_CHECKPOINT_WITH_INVALID_ATTESTATIONS, + 54321n, + ); await store.addOffense(offense); @@ -127,7 +132,9 @@ describe('SlasherOffensesStore', () => { expect(pendingOffenses).toHaveLength(1); expect(pendingOffenses[0].validator.toString()).toBe(validator.toString()); expect(pendingOffenses[0].amount).toBe(12345n); - expect(pendingOffenses[0].offenseType).toBe(OffenseType.PROPOSED_DESCENDANT_OF_INVALID); + expect(pendingOffenses[0].offenseType).toBe( + OffenseType.PROPOSED_DESCENDANT_OF_CHECKPOINT_WITH_INVALID_ATTESTATIONS, + ); expect(pendingOffenses[0].epochOrSlot).toBe(54321n); }); diff --git a/yarn-project/slasher/src/watchers/attestations_block_watcher.test.ts b/yarn-project/slasher/src/watchers/attestations_block_watcher.test.ts index 29bf1c91acdc..933362d00cde 100644 --- a/yarn-project/slasher/src/watchers/attestations_block_watcher.test.ts +++ b/yarn-project/slasher/src/watchers/attestations_block_watcher.test.ts @@ -176,14 +176,14 @@ describe('AttestationsBlockWatcher', () => { expect(handler).toHaveBeenCalledWith([ { validator: attestor1, - amount: config.slashProposeDescendantOfInvalidPenalty, - offenseType: OffenseType.PROPOSED_DESCENDANT_OF_INVALID, + amount: config.slashProposeDescendantOfCheckpointWithInvalidAttestationsPenalty, + offenseType: OffenseType.PROPOSED_DESCENDANT_OF_CHECKPOINT_WITH_INVALID_ATTESTATIONS, epochOrSlot: 2n, }, { validator: attestor2, - amount: config.slashProposeDescendantOfInvalidPenalty, - offenseType: OffenseType.PROPOSED_DESCENDANT_OF_INVALID, + amount: config.slashProposeDescendantOfCheckpointWithInvalidAttestationsPenalty, + offenseType: OffenseType.PROPOSED_DESCENDANT_OF_CHECKPOINT_WITH_INVALID_ATTESTATIONS, epochOrSlot: 2n, }, ] satisfies WantToSlashArgs[]); diff --git a/yarn-project/slasher/src/watchers/attestations_block_watcher.ts b/yarn-project/slasher/src/watchers/attestations_block_watcher.ts index bb4c9bc6d3e4..cd02e7312c5b 100644 --- a/yarn-project/slasher/src/watchers/attestations_block_watcher.ts +++ b/yarn-project/slasher/src/watchers/attestations_block_watcher.ts @@ -17,7 +17,7 @@ import type { SlasherConfig } from '../config.js'; import { WANT_TO_SLASH_EVENT, type WantToSlashArgs, type Watcher, type WatcherEmitter } from '../watcher.js'; const AttestationsBlockWatcherConfigKeys = [ - 'slashProposeDescendantOfInvalidPenalty', + 'slashProposeDescendantOfCheckpointWithInvalidAttestationsPenalty', 'slashProposeInvalidAttestationsPenalty', ] as const; const MAX_INVALID_CHECKPOINTS = 100; @@ -124,8 +124,8 @@ export class AttestationsBlockWatcher extends (EventEmitter as new () => Watcher WANT_TO_SLASH_EVENT, attestors.map(attestor => ({ validator: attestor, - amount: this.config.slashProposeDescendantOfInvalidPenalty, - offenseType: OffenseType.PROPOSED_DESCENDANT_OF_INVALID, + amount: this.config.slashProposeDescendantOfCheckpointWithInvalidAttestationsPenalty, + offenseType: OffenseType.PROPOSED_DESCENDANT_OF_CHECKPOINT_WITH_INVALID_ATTESTATIONS, epochOrSlot: BigInt(SlotNumber(checkpoint.slotNumber)), })), ); diff --git a/yarn-project/stdlib/src/interfaces/aztec-node-admin.test.ts b/yarn-project/stdlib/src/interfaces/aztec-node-admin.test.ts index 3ed365b0ef8d..89b3d50fa901 100644 --- a/yarn-project/stdlib/src/interfaces/aztec-node-admin.test.ts +++ b/yarn-project/stdlib/src/interfaces/aztec-node-admin.test.ts @@ -128,7 +128,7 @@ class MockAztecNodeAdmin implements AztecNodeAdmin { secondsBeforeInvalidatingBlockAsCommitteeMember: 0, secondsBeforeInvalidatingBlockAsNonCommitteeMember: 0, slashProposeInvalidAttestationsPenalty: 1000n, - slashProposeDescendantOfInvalidPenalty: 1000n, + slashProposeDescendantOfCheckpointWithInvalidAttestationsPenalty: 1000n, slashOffenseExpirationRounds: 4, slashMaxPayloadSize: 50, slashUnknownPenalty: 1000n, diff --git a/yarn-project/stdlib/src/interfaces/slasher.ts b/yarn-project/stdlib/src/interfaces/slasher.ts index 99d0cf926e65..d3e99d003342 100644 --- a/yarn-project/stdlib/src/interfaces/slasher.ts +++ b/yarn-project/stdlib/src/interfaces/slasher.ts @@ -23,7 +23,7 @@ export interface SlasherConfig { slashDuplicateProposalPenalty: bigint; slashDuplicateAttestationPenalty: bigint; slashProposeInvalidAttestationsPenalty: bigint; - slashProposeDescendantOfInvalidPenalty: bigint; + slashProposeDescendantOfCheckpointWithInvalidAttestationsPenalty: bigint; slashAttestInvalidCheckpointProposalPenalty: bigint; slashUnknownPenalty: bigint; slashOffenseExpirationRounds: number; // Number of rounds after which pending offenses expire @@ -50,7 +50,7 @@ export const SlasherConfigSchema = zodFor()( slashBroadcastedInvalidCheckpointProposalPenalty: schemas.BigInt.default(0n), slashDuplicateProposalPenalty: schemas.BigInt, slashDuplicateAttestationPenalty: schemas.BigInt, - slashProposeDescendantOfInvalidPenalty: schemas.BigInt, + slashProposeDescendantOfCheckpointWithInvalidAttestationsPenalty: schemas.BigInt, slashAttestInvalidCheckpointProposalPenalty: schemas.BigInt, slashUnknownPenalty: schemas.BigInt, slashOffenseExpirationRounds: z.number(), diff --git a/yarn-project/stdlib/src/slashing/helpers.test.ts b/yarn-project/stdlib/src/slashing/helpers.test.ts index 0208d6466556..5820e4aec091 100644 --- a/yarn-project/stdlib/src/slashing/helpers.test.ts +++ b/yarn-project/stdlib/src/slashing/helpers.test.ts @@ -197,7 +197,7 @@ describe('SlashingHelpers', () => { describe('getPenaltyForOffense', () => { it('returns the configured penalty for attesting to invalid checkpoint proposal', () => { const penalty = getPenaltyForOffense(OffenseType.ATTESTED_TO_INVALID_CHECKPOINT_PROPOSAL, { - slashProposeDescendantOfInvalidPenalty: 1n, + slashProposeDescendantOfCheckpointWithInvalidAttestationsPenalty: 1n, slashBroadcastedInvalidBlockPenalty: 2n, slashBroadcastedInvalidCheckpointProposalPenalty: 11n, slashDuplicateProposalPenalty: 3n, @@ -214,7 +214,7 @@ describe('SlashingHelpers', () => { it('returns the configured penalty for broadcasting invalid checkpoint proposal', () => { const penalty = getPenaltyForOffense(OffenseType.BROADCASTED_INVALID_CHECKPOINT_PROPOSAL, { - slashProposeDescendantOfInvalidPenalty: 1n, + slashProposeDescendantOfCheckpointWithInvalidAttestationsPenalty: 1n, slashBroadcastedInvalidBlockPenalty: 2n, slashBroadcastedInvalidCheckpointProposalPenalty: 11n, slashDuplicateProposalPenalty: 3n, diff --git a/yarn-project/stdlib/src/slashing/helpers.ts b/yarn-project/stdlib/src/slashing/helpers.ts index 94861c6ce30e..24df1ee11617 100644 --- a/yarn-project/stdlib/src/slashing/helpers.ts +++ b/yarn-project/stdlib/src/slashing/helpers.ts @@ -48,7 +48,7 @@ export function getPenaltyForOffense( offense: OffenseType, config: Pick< SlasherConfig, - | 'slashProposeDescendantOfInvalidPenalty' + | 'slashProposeDescendantOfCheckpointWithInvalidAttestationsPenalty' | 'slashBroadcastedInvalidBlockPenalty' | 'slashBroadcastedInvalidCheckpointProposalPenalty' | 'slashDuplicateProposalPenalty' @@ -68,8 +68,8 @@ export function getPenaltyForOffense( case OffenseType.PROPOSED_INSUFFICIENT_ATTESTATIONS: case OffenseType.PROPOSED_INCORRECT_ATTESTATIONS: return config.slashProposeInvalidAttestationsPenalty; - case OffenseType.PROPOSED_DESCENDANT_OF_INVALID: - return config.slashProposeDescendantOfInvalidPenalty; + case OffenseType.PROPOSED_DESCENDANT_OF_CHECKPOINT_WITH_INVALID_ATTESTATIONS: + return config.slashProposeDescendantOfCheckpointWithInvalidAttestationsPenalty; case OffenseType.BROADCASTED_INVALID_BLOCK_PROPOSAL: return config.slashBroadcastedInvalidBlockPenalty; case OffenseType.BROADCASTED_INVALID_CHECKPOINT_PROPOSAL: @@ -92,7 +92,7 @@ export function getPenaltyForOffense( /** Returns whether the `epochOrSlot` field for an offense references an epoch or a slot */ export function getTimeUnitForOffense(offense: OffenseType): 'epoch' | 'slot' { switch (offense) { - case OffenseType.PROPOSED_DESCENDANT_OF_INVALID: + case OffenseType.PROPOSED_DESCENDANT_OF_CHECKPOINT_WITH_INVALID_ATTESTATIONS: case OffenseType.BROADCASTED_INVALID_BLOCK_PROPOSAL: case OffenseType.DATA_WITHHOLDING: case OffenseType.BROADCASTED_INVALID_CHECKPOINT_PROPOSAL: diff --git a/yarn-project/stdlib/src/slashing/serialization.test.ts b/yarn-project/stdlib/src/slashing/serialization.test.ts index 8673ed7bc780..f4c6d664acd0 100644 --- a/yarn-project/stdlib/src/slashing/serialization.test.ts +++ b/yarn-project/stdlib/src/slashing/serialization.test.ts @@ -118,7 +118,7 @@ describe('slashing/serialization', () => { const originalOffense = createOffense( EthAddress.random(), 12345n, - OffenseType.PROPOSED_DESCENDANT_OF_INVALID, + OffenseType.PROPOSED_DESCENDANT_OF_CHECKPOINT_WITH_INVALID_ATTESTATIONS, 98765n, ); @@ -168,7 +168,7 @@ describe('slashing/serialization', () => { const slotOffenses = [ OffenseType.PROPOSED_INSUFFICIENT_ATTESTATIONS, OffenseType.PROPOSED_INCORRECT_ATTESTATIONS, - OffenseType.PROPOSED_DESCENDANT_OF_INVALID, + OffenseType.PROPOSED_DESCENDANT_OF_CHECKPOINT_WITH_INVALID_ATTESTATIONS, OffenseType.ATTESTED_TO_INVALID_CHECKPOINT_PROPOSAL, OffenseType.BROADCASTED_INVALID_BLOCK_PROPOSAL, ]; diff --git a/yarn-project/stdlib/src/slashing/types.ts b/yarn-project/stdlib/src/slashing/types.ts index 4a210cb15e4e..45aa9f31dddc 100644 --- a/yarn-project/stdlib/src/slashing/types.ts +++ b/yarn-project/stdlib/src/slashing/types.ts @@ -17,7 +17,7 @@ export enum OffenseType { /** A proposer pushed to L1 a block with incorrect committee attestations (ie signature from a non-committee member) */ PROPOSED_INCORRECT_ATTESTATIONS = 6, /** A proposer published a checkpoint to L1 that builds on an invalid checkpoint (as in a checkpoint with invalid or insufficient attestations) */ - PROPOSED_DESCENDANT_OF_INVALID = 7, + PROPOSED_DESCENDANT_OF_CHECKPOINT_WITH_INVALID_ATTESTATIONS = 7, /** A proposer sent duplicate proposals for the same position (slot, indexWithinCheckpoint for blocks or slot for checkpoints) */ DUPLICATE_PROPOSAL = 8, /** A validator signed attestations for different proposals at the same slot (equivocation) */ @@ -42,8 +42,8 @@ export function getOffenseTypeName(offense: OffenseType) { return 'proposed_insufficient_attestations'; case OffenseType.PROPOSED_INCORRECT_ATTESTATIONS: return 'proposed_incorrect_attestations'; - case OffenseType.PROPOSED_DESCENDANT_OF_INVALID: - return 'proposed_descendant_of_invalid'; + case OffenseType.PROPOSED_DESCENDANT_OF_CHECKPOINT_WITH_INVALID_ATTESTATIONS: + return 'proposed_descendant_of_checkpoint_with_invalid_attestations'; case OffenseType.DUPLICATE_PROPOSAL: return 'duplicate_proposal'; case OffenseType.DUPLICATE_ATTESTATION: @@ -66,7 +66,7 @@ export const OffenseToBigInt: Record = { [OffenseType.BROADCASTED_INVALID_BLOCK_PROPOSAL]: 4n, [OffenseType.PROPOSED_INSUFFICIENT_ATTESTATIONS]: 5n, [OffenseType.PROPOSED_INCORRECT_ATTESTATIONS]: 6n, - [OffenseType.PROPOSED_DESCENDANT_OF_INVALID]: 7n, + [OffenseType.PROPOSED_DESCENDANT_OF_CHECKPOINT_WITH_INVALID_ATTESTATIONS]: 7n, [OffenseType.DUPLICATE_PROPOSAL]: 8n, [OffenseType.DUPLICATE_ATTESTATION]: 9n, [OffenseType.ATTESTED_TO_INVALID_CHECKPOINT_PROPOSAL]: 10n, @@ -88,7 +88,7 @@ export function bigIntToOffense(offense: bigint): OffenseType { case 6n: return OffenseType.PROPOSED_INCORRECT_ATTESTATIONS; case 7n: - return OffenseType.PROPOSED_DESCENDANT_OF_INVALID; + return OffenseType.PROPOSED_DESCENDANT_OF_CHECKPOINT_WITH_INVALID_ATTESTATIONS; case 8n: return OffenseType.DUPLICATE_PROPOSAL; case 9n: