@aztec/slasher 0.0.1-commit.f2ce05ee → 0.0.1-commit.f5d02921e
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -11
- package/dest/config.d.ts +1 -1
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +7 -1
- package/dest/factory/create_facade.d.ts +3 -3
- package/dest/factory/create_facade.d.ts.map +1 -1
- package/dest/factory/create_facade.js +25 -2
- package/dest/factory/create_implementation.d.ts +4 -3
- package/dest/factory/create_implementation.d.ts.map +1 -1
- package/dest/factory/create_implementation.js +11 -7
- package/dest/factory/get_settings.d.ts +2 -2
- package/dest/factory/get_settings.d.ts.map +1 -1
- package/dest/generated/slasher-defaults.d.ts +4 -3
- package/dest/generated/slasher-defaults.d.ts.map +1 -1
- package/dest/generated/slasher-defaults.js +3 -2
- package/dest/slash_offenses_collector.d.ts +5 -2
- package/dest/slash_offenses_collector.d.ts.map +1 -1
- package/dest/slash_offenses_collector.js +3 -7
- package/dest/slasher_client_facade.d.ts +4 -3
- package/dest/slasher_client_facade.d.ts.map +1 -1
- package/dest/slasher_client_facade.js +4 -2
- package/dest/tally_slasher_client.d.ts +2 -2
- package/dest/tally_slasher_client.d.ts.map +1 -1
- package/dest/tally_slasher_client.js +6 -6
- package/dest/watchers/epoch_prune_watcher.d.ts +1 -1
- package/dest/watchers/epoch_prune_watcher.d.ts.map +1 -1
- package/dest/watchers/epoch_prune_watcher.js +7 -3
- package/package.json +9 -9
- package/src/config.ts +9 -1
- package/src/factory/create_facade.ts +32 -3
- package/src/factory/create_implementation.ts +29 -4
- package/src/factory/get_settings.ts +2 -2
- package/src/generated/slasher-defaults.ts +3 -2
- package/src/slash_offenses_collector.ts +9 -8
- package/src/slasher_client_facade.ts +3 -1
- package/src/tally_slasher_client.ts +8 -7
- package/src/watchers/epoch_prune_watcher.ts +9 -4
package/README.md
CHANGED
|
@@ -185,7 +185,7 @@ These settings are configured locally on each validator node:
|
|
|
185
185
|
- `slashProposeInvalidAttestationsPenalty`: Penalty for PROPOSED_INSUFFICIENT_ATTESTATIONS and PROPOSED_INCORRECT_ATTESTATIONS
|
|
186
186
|
- `slashAttestDescendantOfInvalidPenalty`: Penalty for ATTESTED_DESCENDANT_OF_INVALID
|
|
187
187
|
- `slashUnknownPenalty`: Default penalty for unknown offense types
|
|
188
|
-
- `slashMaxPayloadSize`: Maximum size of slash payloads
|
|
188
|
+
- `slashMaxPayloadSize`: Maximum size of slash payloads. In the empire model this limits offenses per payload. In the tally model it 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.
|
|
189
189
|
- `slashMinPenaltyPercentage`: Agree to slashes if they are at least this percentage of the configured penalty (empire model)
|
|
190
190
|
- `slashMaxPenaltyPercentage`: Agree to slashes if they are at most this percentage of the configured penalty (empire model)
|
|
191
191
|
|
|
@@ -202,21 +202,24 @@ Details about specific offenses in the system:
|
|
|
202
202
|
|
|
203
203
|
Inactivity slashing is one of the most critical, since it allows purging validators that are not fulfilling their duties, which could potentially bring the chain to a halt. This slashing must be aggressive enough to balance out the rate of the entry queue, in case the queue is filled with inactive validators. Furthermore, if enough inactive validators join the system, it may become impossible to gather enough quorum to pass any governance proposal.
|
|
204
204
|
|
|
205
|
-
Inactivity slashing is handled by the `Sentinel` which monitors performance of all validators slot-by-slot. After each slot, the sentinel assigns one of the following to the
|
|
206
|
-
- `
|
|
207
|
-
- `
|
|
208
|
-
- `
|
|
205
|
+
Inactivity slashing is handled by the `Sentinel` which monitors performance of all validators slot-by-slot. With the multiple-blocks-per-slot model, block proposals and checkpoints are distinct concepts: proposers build multiple blocks per slot, but attestations are only for checkpoints. After each slot, the sentinel assigns one of the following to the proposer for the slot:
|
|
206
|
+
- `checkpoint-mined` if the checkpoint was added to L1
|
|
207
|
+
- `checkpoint-proposed` if the checkpoint received at least one attestation, but didn't make it to L1
|
|
208
|
+
- `checkpoint-missed` if blocks were proposed but the checkpoint received no attestations
|
|
209
|
+
- `blocks-missed` if no block proposals were sent for this slot at all
|
|
209
210
|
|
|
210
|
-
And assigns one of the following to each validator:
|
|
211
|
-
- `attestation-sent` if there was a `
|
|
212
|
-
- `attestation-missed` if there was a `
|
|
213
|
-
- none if the slot was a `
|
|
211
|
+
And assigns one of the following to each validator (these refer to checkpoint attestations):
|
|
212
|
+
- `attestation-sent` if there was a `checkpoint-proposed` or `checkpoint-mined` and a checkpoint attestation from this validator was seen on either on L1 or on the P2P network
|
|
213
|
+
- `attestation-missed` if there was a `checkpoint-proposed` or `checkpoint-mined` but no checkpoint attestation was seen
|
|
214
|
+
- none if the slot was a `blocks-missed`
|
|
215
|
+
|
|
216
|
+
Both `blocks-missed` and `checkpoint-missed` count as proposer inactivity.
|
|
214
217
|
|
|
215
218
|
Once an epoch is proven, the sentinel computes the _proven performance_ for the epoch for each validator. Note that we wait until the epoch is proven so we know that the data for all blocks in the epoch was available, and validators who did not attest were effectively inactive. Then, for each validator such that:
|
|
216
219
|
|
|
217
220
|
```
|
|
218
|
-
total_failures = count(
|
|
219
|
-
total = count(
|
|
221
|
+
total_failures = count(blocks-missed) + count(checkpoint-missed) + count(attestation-missed)
|
|
222
|
+
total = count(checkpoint-*) + count(blocks-*) + count(attestation-*)
|
|
220
223
|
total_failures / total >= slash_inactivity_target_percentage
|
|
221
224
|
```
|
|
222
225
|
|
package/dest/config.d.ts
CHANGED
|
@@ -3,4 +3,4 @@ import type { SlasherConfig } from '@aztec/stdlib/interfaces/server';
|
|
|
3
3
|
export type { SlasherConfig };
|
|
4
4
|
export declare const DefaultSlasherConfig: SlasherConfig;
|
|
5
5
|
export declare const slasherConfigMappings: ConfigMappingsType<SlasherConfig>;
|
|
6
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
6
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uZmlnLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvY29uZmlnLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFRbkUsT0FBTyxLQUFLLEVBQUUsYUFBYSxFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFJckUsWUFBWSxFQUFFLGFBQWEsRUFBRSxDQUFDO0FBRTlCLGVBQU8sTUFBTSxvQkFBb0IsRUFBRSxhQXNCbEMsQ0FBQztBQUVGLGVBQU8sTUFBTSxxQkFBcUIsRUFBRSxrQkFBa0IsQ0FBQyxhQUFhLENBcUluRSxDQUFDIn0=
|
package/dest/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAQnE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAIrE,YAAY,EAAE,aAAa,EAAE,CAAC;AAE9B,eAAO,MAAM,oBAAoB,EAAE,
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAQnE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAIrE,YAAY,EAAE,aAAa,EAAE,CAAC;AAE9B,eAAO,MAAM,oBAAoB,EAAE,aAsBlC,CAAC;AAEF,eAAO,MAAM,qBAAqB,EAAE,kBAAkB,CAAC,aAAa,CAqInE,CAAC"}
|
package/dest/config.js
CHANGED
|
@@ -13,6 +13,7 @@ export const DefaultSlasherConfig = {
|
|
|
13
13
|
slashInactivityConsecutiveEpochThreshold: slasherDefaultEnv.SLASH_INACTIVITY_CONSECUTIVE_EPOCH_THRESHOLD,
|
|
14
14
|
slashBroadcastedInvalidBlockPenalty: BigInt(slasherDefaultEnv.SLASH_INVALID_BLOCK_PENALTY),
|
|
15
15
|
slashDuplicateProposalPenalty: BigInt(slasherDefaultEnv.SLASH_DUPLICATE_PROPOSAL_PENALTY),
|
|
16
|
+
slashDuplicateAttestationPenalty: BigInt(slasherDefaultEnv.SLASH_DUPLICATE_ATTESTATION_PENALTY),
|
|
16
17
|
slashInactivityPenalty: BigInt(slasherDefaultEnv.SLASH_INACTIVITY_PENALTY),
|
|
17
18
|
slashProposeInvalidAttestationsPenalty: BigInt(slasherDefaultEnv.SLASH_PROPOSE_INVALID_ATTESTATIONS_PENALTY),
|
|
18
19
|
slashAttestDescendantOfInvalidPenalty: BigInt(slasherDefaultEnv.SLASH_ATTEST_DESCENDANT_OF_INVALID_PENALTY),
|
|
@@ -72,6 +73,11 @@ export const slasherConfigMappings = {
|
|
|
72
73
|
description: 'Penalty amount for slashing a validator for sending duplicate proposals.',
|
|
73
74
|
...bigintConfigHelper(DefaultSlasherConfig.slashDuplicateProposalPenalty)
|
|
74
75
|
},
|
|
76
|
+
slashDuplicateAttestationPenalty: {
|
|
77
|
+
env: 'SLASH_DUPLICATE_ATTESTATION_PENALTY',
|
|
78
|
+
description: 'Penalty amount for slashing a validator for signing attestations for different proposals at the same slot.',
|
|
79
|
+
...bigintConfigHelper(DefaultSlasherConfig.slashDuplicateAttestationPenalty)
|
|
80
|
+
},
|
|
75
81
|
slashInactivityTargetPercentage: {
|
|
76
82
|
env: 'SLASH_INACTIVITY_TARGET_PERCENTAGE',
|
|
77
83
|
description: 'Missed attestation percentage to trigger creation of inactivity slash payload (0, 1]. Must be greater than 0',
|
|
@@ -124,7 +130,7 @@ export const slasherConfigMappings = {
|
|
|
124
130
|
...numberConfigHelper(DefaultSlasherConfig.slashMaxPayloadSize)
|
|
125
131
|
},
|
|
126
132
|
slashGracePeriodL2Slots: {
|
|
127
|
-
description: 'Number of L2 slots
|
|
133
|
+
description: 'Number of L2 slots after the network upgrade during which slashing offenses are ignored. The upgrade time is determined from the CanonicalRollupUpdated event.',
|
|
128
134
|
env: 'SLASH_GRACE_PERIOD_L2_SLOTS',
|
|
129
135
|
...numberConfigHelper(DefaultSlasherConfig.slashGracePeriodL2Slots)
|
|
130
136
|
},
|
|
@@ -3,14 +3,14 @@ import type { L1ReaderConfig } from '@aztec/ethereum/l1-reader';
|
|
|
3
3
|
import type { ViemClient } from '@aztec/ethereum/types';
|
|
4
4
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
5
5
|
import { DateProvider } from '@aztec/foundation/timer';
|
|
6
|
-
import type { DataStoreConfig } from '@aztec/kv-store/config';
|
|
7
6
|
import type { SlasherConfig } from '@aztec/stdlib/interfaces/server';
|
|
7
|
+
import type { DataStoreConfig } from '@aztec/stdlib/kv-store';
|
|
8
8
|
import type { SlasherClientInterface } from '../slasher_client_interface.js';
|
|
9
9
|
import type { Watcher } from '../watcher.js';
|
|
10
10
|
/** Creates a slasher client facade that updates itself whenever the rollup slasher changes */
|
|
11
11
|
export declare function createSlasherFacade(config: SlasherConfig & DataStoreConfig & {
|
|
12
12
|
ethereumSlotDuration: number;
|
|
13
|
-
}, l1Contracts: Pick<L1ReaderConfig['l1Contracts'], 'rollupAddress' | 'slashFactoryAddress'>, l1Client: ViemClient, watchers: Watcher[], dateProvider: DateProvider, epochCache: EpochCache,
|
|
13
|
+
}, l1Contracts: Pick<L1ReaderConfig['l1Contracts'], 'rollupAddress' | 'slashFactoryAddress' | 'registryAddress'>, l1Client: ViemClient, watchers: Watcher[], dateProvider: DateProvider, epochCache: EpochCache,
|
|
14
14
|
/** List of own validator addresses to add to the slashValidatorNever list unless slashSelfAllowed is true */
|
|
15
15
|
validatorAddresses?: EthAddress[], logger?: import("@aztec/foundation/log").Logger): Promise<SlasherClientInterface>;
|
|
16
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
16
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3JlYXRlX2ZhY2FkZS5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2ZhY3RvcnkvY3JlYXRlX2ZhY2FkZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFFaEQsT0FBTyxLQUFLLEVBQUUsY0FBYyxFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFDaEUsT0FBTyxLQUFLLEVBQUUsVUFBVSxFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFHeEQsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBRTNELE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUd2RCxPQUFPLEtBQUssRUFBRSxhQUFhLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUNyRSxPQUFPLEtBQUssRUFBRSxlQUFlLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUc5RCxPQUFPLEtBQUssRUFBRSxzQkFBc0IsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBRTdFLE9BQU8sS0FBSyxFQUFFLE9BQU8sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUU3Qyw4RkFBOEY7QUFDOUYsd0JBQXNCLG1CQUFtQixDQUN2QyxNQUFNLEVBQUUsYUFBYSxHQUFHLGVBQWUsR0FBRztJQUFFLG9CQUFvQixFQUFFLE1BQU0sQ0FBQTtDQUFFLEVBQzFFLFdBQVcsRUFBRSxJQUFJLENBQUMsY0FBYyxDQUFDLGFBQWEsQ0FBQyxFQUFFLGVBQWUsR0FBRyxxQkFBcUIsR0FBRyxpQkFBaUIsQ0FBQyxFQUM3RyxRQUFRLEVBQUUsVUFBVSxFQUNwQixRQUFRLEVBQUUsT0FBTyxFQUFFLEVBQ25CLFlBQVksRUFBRSxZQUFZLEVBQzFCLFVBQVUsRUFBRSxVQUFVO0FBQ3RCLDZHQUE2RztBQUM3RyxrQkFBa0IsR0FBRSxVQUFVLEVBQU8sRUFDckMsTUFBTSx5Q0FBMEIsR0FDL0IsT0FBTyxDQUFDLHNCQUFzQixDQUFDLENBbURqQyJ9
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create_facade.d.ts","sourceRoot":"","sources":["../../src/factory/create_facade.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAEhD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"create_facade.d.ts","sourceRoot":"","sources":["../../src/factory/create_facade.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAEhD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAGxD,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAE3D,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAGvD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AACrE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAG9D,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAC;AAE7E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAE7C,8FAA8F;AAC9F,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,aAAa,GAAG,eAAe,GAAG;IAAE,oBAAoB,EAAE,MAAM,CAAA;CAAE,EAC1E,WAAW,EAAE,IAAI,CAAC,cAAc,CAAC,aAAa,CAAC,EAAE,eAAe,GAAG,qBAAqB,GAAG,iBAAiB,CAAC,EAC7G,QAAQ,EAAE,UAAU,EACpB,QAAQ,EAAE,OAAO,EAAE,EACnB,YAAY,EAAE,YAAY,EAC1B,UAAU,EAAE,UAAU;AACtB,6GAA6G;AAC7G,kBAAkB,GAAE,UAAU,EAAO,EACrC,MAAM,yCAA0B,GAC/B,OAAO,CAAC,sBAAsB,CAAC,CAmDjC"}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
import { RollupContract } from '@aztec/ethereum/contracts';
|
|
1
|
+
import { RegistryContract, RollupContract } from '@aztec/ethereum/contracts';
|
|
2
|
+
import { SlotNumber } from '@aztec/foundation/branded-types';
|
|
2
3
|
import { unique } from '@aztec/foundation/collection';
|
|
3
4
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
4
5
|
import { createLogger } from '@aztec/foundation/log';
|
|
5
6
|
import { createStore } from '@aztec/kv-store/lmdb-v2';
|
|
7
|
+
import { getSlotAtTimestamp } from '@aztec/stdlib/epoch-helpers';
|
|
6
8
|
import { SlasherClientFacade } from '../slasher_client_facade.js';
|
|
7
9
|
import { SCHEMA_VERSION } from '../stores/schema_version.js';
|
|
8
10
|
/** Creates a slasher client facade that updates itself whenever the rollup slasher changes */ export async function createSlasherFacade(config, l1Contracts, l1Client, watchers, dateProvider, epochCache, /** List of own validator addresses to add to the slashValidatorNever list unless slashSelfAllowed is true */ validatorAddresses = [], logger = createLogger('slasher')) {
|
|
@@ -11,6 +13,27 @@ import { SCHEMA_VERSION } from '../stores/schema_version.js';
|
|
|
11
13
|
}
|
|
12
14
|
const kvStore = await createStore('slasher', SCHEMA_VERSION, config, logger.getBindings());
|
|
13
15
|
const rollup = new RollupContract(l1Client, l1Contracts.rollupAddress);
|
|
16
|
+
// Compute and cache the L2 slot at which the rollup was registered as canonical
|
|
17
|
+
const settingsMap = kvStore.openMap('slasher-settings');
|
|
18
|
+
const cacheKey = `registeredSlot:${l1Contracts.rollupAddress}`;
|
|
19
|
+
let rollupRegisteredAtL2Slot = await settingsMap.getAsync(cacheKey);
|
|
20
|
+
if (rollupRegisteredAtL2Slot === undefined) {
|
|
21
|
+
const registry = new RegistryContract(l1Client, l1Contracts.registryAddress);
|
|
22
|
+
const l1StartBlock = await rollup.getL1StartBlock();
|
|
23
|
+
const registrationTimestamp = await registry.getCanonicalRollupRegistrationTimestamp(l1Contracts.rollupAddress, l1StartBlock);
|
|
24
|
+
if (registrationTimestamp !== undefined) {
|
|
25
|
+
const l1GenesisTime = await rollup.getL1GenesisTime();
|
|
26
|
+
const slotDuration = await rollup.getSlotDuration();
|
|
27
|
+
rollupRegisteredAtL2Slot = getSlotAtTimestamp(registrationTimestamp, {
|
|
28
|
+
l1GenesisTime,
|
|
29
|
+
slotDuration: Number(slotDuration)
|
|
30
|
+
});
|
|
31
|
+
} else {
|
|
32
|
+
rollupRegisteredAtL2Slot = SlotNumber(0);
|
|
33
|
+
}
|
|
34
|
+
await settingsMap.set(cacheKey, rollupRegisteredAtL2Slot);
|
|
35
|
+
logger.info(`Canonical rollup registered at L2 slot ${rollupRegisteredAtL2Slot}`);
|
|
36
|
+
}
|
|
14
37
|
const slashValidatorsNever = config.slashSelfAllowed ? config.slashValidatorsNever : unique([
|
|
15
38
|
...config.slashValidatorsNever,
|
|
16
39
|
...validatorAddresses
|
|
@@ -19,5 +42,5 @@ import { SCHEMA_VERSION } from '../stores/schema_version.js';
|
|
|
19
42
|
...config,
|
|
20
43
|
slashValidatorsNever
|
|
21
44
|
};
|
|
22
|
-
return new SlasherClientFacade(updatedConfig, rollup, l1Client, l1Contracts.slashFactoryAddress, watchers, epochCache, dateProvider, kvStore, logger);
|
|
45
|
+
return new SlasherClientFacade(updatedConfig, rollup, l1Client, l1Contracts.slashFactoryAddress, watchers, epochCache, dateProvider, kvStore, rollupRegisteredAtL2Slot, logger);
|
|
23
46
|
}
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { EpochCache } from '@aztec/epoch-cache';
|
|
2
2
|
import { RollupContract } from '@aztec/ethereum/contracts';
|
|
3
3
|
import type { ViemClient } from '@aztec/ethereum/types';
|
|
4
|
+
import type { SlotNumber } from '@aztec/foundation/branded-types';
|
|
4
5
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
5
6
|
import { DateProvider } from '@aztec/foundation/timer';
|
|
6
|
-
import type { DataStoreConfig } from '@aztec/kv-store/config';
|
|
7
7
|
import { AztecLMDBStoreV2 } from '@aztec/kv-store/lmdb-v2';
|
|
8
8
|
import type { SlasherConfig } from '@aztec/stdlib/interfaces/server';
|
|
9
|
+
import type { DataStoreConfig } from '@aztec/stdlib/kv-store';
|
|
9
10
|
import { EmpireSlasherClient } from '../empire_slasher_client.js';
|
|
10
11
|
import { NullSlasherClient } from '../null_slasher_client.js';
|
|
11
12
|
import { TallySlasherClient } from '../tally_slasher_client.js';
|
|
@@ -13,5 +14,5 @@ import type { Watcher } from '../watcher.js';
|
|
|
13
14
|
/** Creates a slasher client implementation (either tally or empire) based on the slasher proposer type in the rollup */
|
|
14
15
|
export declare function createSlasherImplementation(config: SlasherConfig & DataStoreConfig & {
|
|
15
16
|
ethereumSlotDuration: number;
|
|
16
|
-
}, rollup: RollupContract, l1Client: ViemClient, slashFactoryAddress: EthAddress | undefined, watchers: Watcher[], epochCache: EpochCache, dateProvider: DateProvider, kvStore: AztecLMDBStoreV2, logger?: import("@aztec/foundation/log").Logger): Promise<EmpireSlasherClient | NullSlasherClient | TallySlasherClient>;
|
|
17
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
17
|
+
}, rollup: RollupContract, l1Client: ViemClient, slashFactoryAddress: EthAddress | undefined, watchers: Watcher[], epochCache: EpochCache, dateProvider: DateProvider, kvStore: AztecLMDBStoreV2, rollupRegisteredAtL2Slot: SlotNumber, logger?: import("@aztec/foundation/log").Logger): Promise<EmpireSlasherClient | NullSlasherClient | TallySlasherClient>;
|
|
18
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3JlYXRlX2ltcGxlbWVudGF0aW9uLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvZmFjdG9yeS9jcmVhdGVfaW1wbGVtZW50YXRpb24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQ2hELE9BQU8sRUFFTCxjQUFjLEVBRWYsTUFBTSwyQkFBMkIsQ0FBQztBQUNuQyxPQUFPLEtBQUssRUFBRSxVQUFVLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUN4RCxPQUFPLEtBQUssRUFBRSxVQUFVLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUNsRSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFFM0QsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQ3ZELE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQzNELE9BQU8sS0FBSyxFQUFFLGFBQWEsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBQ3JFLE9BQU8sS0FBSyxFQUFFLGVBQWUsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBRzlELE9BQU8sRUFBRSxtQkFBbUIsRUFBOEIsTUFBTSw2QkFBNkIsQ0FBQztBQUM5RixPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUc5RCxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUNoRSxPQUFPLEtBQUssRUFBRSxPQUFPLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFHN0Msd0hBQXdIO0FBQ3hILHdCQUFzQiwyQkFBMkIsQ0FDL0MsTUFBTSxFQUFFLGFBQWEsR0FBRyxlQUFlLEdBQUc7SUFBRSxvQkFBb0IsRUFBRSxNQUFNLENBQUE7Q0FBRSxFQUMxRSxNQUFNLEVBQUUsY0FBYyxFQUN0QixRQUFRLEVBQUUsVUFBVSxFQUNwQixtQkFBbUIsRUFBRSxVQUFVLEdBQUcsU0FBUyxFQUMzQyxRQUFRLEVBQUUsT0FBTyxFQUFFLEVBQ25CLFVBQVUsRUFBRSxVQUFVLEVBQ3RCLFlBQVksRUFBRSxZQUFZLEVBQzFCLE9BQU8sRUFBRSxnQkFBZ0IsRUFDekIsd0JBQXdCLEVBQUUsVUFBVSxFQUNwQyxNQUFNLHlDQUEwQix5RUFrQ2pDIn0=
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create_implementation.d.ts","sourceRoot":"","sources":["../../src/factory/create_implementation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAEL,cAAc,EAEf,MAAM,2BAA2B,CAAC;AACnC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAE3D,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,
|
|
1
|
+
{"version":3,"file":"create_implementation.d.ts","sourceRoot":"","sources":["../../src/factory/create_implementation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAEL,cAAc,EAEf,MAAM,2BAA2B,CAAC;AACnC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAClE,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAE3D,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AACrE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAG9D,OAAO,EAAE,mBAAmB,EAA8B,MAAM,6BAA6B,CAAC;AAC9F,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAG9D,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAG7C,wHAAwH;AACxH,wBAAsB,2BAA2B,CAC/C,MAAM,EAAE,aAAa,GAAG,eAAe,GAAG;IAAE,oBAAoB,EAAE,MAAM,CAAA;CAAE,EAC1E,MAAM,EAAE,cAAc,EACtB,QAAQ,EAAE,UAAU,EACpB,mBAAmB,EAAE,UAAU,GAAG,SAAS,EAC3C,QAAQ,EAAE,OAAO,EAAE,EACnB,UAAU,EAAE,UAAU,EACtB,YAAY,EAAE,YAAY,EAC1B,OAAO,EAAE,gBAAgB,EACzB,wBAAwB,EAAE,UAAU,EACpC,MAAM,yCAA0B,yEAkCjC"}
|
|
@@ -7,21 +7,21 @@ import { SlasherOffensesStore } from '../stores/offenses_store.js';
|
|
|
7
7
|
import { SlasherPayloadsStore } from '../stores/payloads_store.js';
|
|
8
8
|
import { TallySlasherClient } from '../tally_slasher_client.js';
|
|
9
9
|
import { getTallySlasherSettings } from './get_settings.js';
|
|
10
|
-
/** Creates a slasher client implementation (either tally or empire) based on the slasher proposer type in the rollup */ export async function createSlasherImplementation(config, rollup, l1Client, slashFactoryAddress, watchers, epochCache, dateProvider, kvStore, logger = createLogger('slasher')) {
|
|
10
|
+
/** Creates a slasher client implementation (either tally or empire) based on the slasher proposer type in the rollup */ export async function createSlasherImplementation(config, rollup, l1Client, slashFactoryAddress, watchers, epochCache, dateProvider, kvStore, rollupRegisteredAtL2Slot, logger = createLogger('slasher')) {
|
|
11
11
|
const proposer = await rollup.getSlashingProposer();
|
|
12
12
|
if (!proposer) {
|
|
13
13
|
return new NullSlasherClient(config);
|
|
14
14
|
} else if (proposer.type === 'tally') {
|
|
15
|
-
return createTallySlasher(config, rollup, proposer, watchers, dateProvider, epochCache, kvStore, logger);
|
|
15
|
+
return createTallySlasher(config, rollup, proposer, watchers, dateProvider, epochCache, kvStore, rollupRegisteredAtL2Slot, logger);
|
|
16
16
|
} else {
|
|
17
17
|
if (!slashFactoryAddress || slashFactoryAddress.equals(EthAddress.ZERO)) {
|
|
18
18
|
throw new Error('Cannot initialize an empire-based SlasherClient without a SlashFactory address');
|
|
19
19
|
}
|
|
20
20
|
const slashFactory = new SlashFactoryContract(l1Client, slashFactoryAddress.toString());
|
|
21
|
-
return createEmpireSlasher(config, rollup, proposer, slashFactory, watchers, dateProvider, kvStore, logger);
|
|
21
|
+
return createEmpireSlasher(config, rollup, proposer, slashFactory, watchers, dateProvider, kvStore, rollupRegisteredAtL2Slot, logger);
|
|
22
22
|
}
|
|
23
23
|
}
|
|
24
|
-
async function createEmpireSlasher(config, rollup, slashingProposer, slashFactoryContract, watchers, dateProvider, kvStore, logger = createLogger('slasher')) {
|
|
24
|
+
async function createEmpireSlasher(config, rollup, slashingProposer, slashFactoryContract, watchers, dateProvider, kvStore, rollupRegisteredAtL2Slot, logger = createLogger('slasher')) {
|
|
25
25
|
if (slashingProposer.type !== 'empire') {
|
|
26
26
|
throw new Error('Slashing proposer contract is not of type Empire');
|
|
27
27
|
}
|
|
@@ -48,7 +48,8 @@ async function createEmpireSlasher(config, rollup, slashingProposer, slashFactor
|
|
|
48
48
|
slotDuration: Number(slotDuration),
|
|
49
49
|
l1StartBlock,
|
|
50
50
|
ethereumSlotDuration: config.ethereumSlotDuration,
|
|
51
|
-
slashingAmounts: undefined
|
|
51
|
+
slashingAmounts: undefined,
|
|
52
|
+
rollupRegisteredAtL2Slot
|
|
52
53
|
};
|
|
53
54
|
const payloadsStore = new SlasherPayloadsStore(kvStore, {
|
|
54
55
|
slashingPayloadLifetimeInRounds: settings.slashingPayloadLifetimeInRounds
|
|
@@ -59,11 +60,14 @@ async function createEmpireSlasher(config, rollup, slashingProposer, slashFactor
|
|
|
59
60
|
});
|
|
60
61
|
return new EmpireSlasherClient(config, settings, slashFactoryContract, slashingProposer, slasher, rollup, watchers, dateProvider, offensesStore, payloadsStore, logger);
|
|
61
62
|
}
|
|
62
|
-
async function createTallySlasher(config, rollup, slashingProposer, watchers, dateProvider, epochCache, kvStore, logger = createLogger('slasher')) {
|
|
63
|
+
async function createTallySlasher(config, rollup, slashingProposer, watchers, dateProvider, epochCache, kvStore, rollupRegisteredAtL2Slot, logger = createLogger('slasher')) {
|
|
63
64
|
if (slashingProposer.type !== 'tally') {
|
|
64
65
|
throw new Error('Slashing proposer contract is not of type tally');
|
|
65
66
|
}
|
|
66
|
-
const settings =
|
|
67
|
+
const settings = {
|
|
68
|
+
...await getTallySlasherSettings(rollup, slashingProposer),
|
|
69
|
+
rollupRegisteredAtL2Slot
|
|
70
|
+
};
|
|
67
71
|
const slasher = await rollup.getSlasherContract();
|
|
68
72
|
const offensesStore = new SlasherOffensesStore(kvStore, {
|
|
69
73
|
...settings,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type { RollupContract, TallySlashingProposerContract } from '@aztec/ethereum/contracts';
|
|
2
2
|
import type { TallySlasherSettings } from '../tally_slasher_client.js';
|
|
3
|
-
export declare function getTallySlasherSettings(rollup: RollupContract, slashingProposer?: TallySlashingProposerContract): Promise<TallySlasherSettings
|
|
4
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
3
|
+
export declare function getTallySlasherSettings(rollup: RollupContract, slashingProposer?: TallySlashingProposerContract): Promise<Omit<TallySlasherSettings, 'rollupRegisteredAtL2Slot'>>;
|
|
4
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2V0X3NldHRpbmdzLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvZmFjdG9yeS9nZXRfc2V0dGluZ3MudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLEVBQUUsY0FBYyxFQUFFLDZCQUE2QixFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFFL0YsT0FBTyxLQUFLLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUV2RSx3QkFBc0IsdUJBQXVCLENBQzNDLE1BQU0sRUFBRSxjQUFjLEVBQ3RCLGdCQUFnQixDQUFDLEVBQUUsNkJBQTZCLEdBQy9DLE9BQU8sQ0FBQyxJQUFJLENBQUMsb0JBQW9CLEVBQUUsMEJBQTBCLENBQUMsQ0FBQyxDQWtEakUifQ==
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"get_settings.d.ts","sourceRoot":"","sources":["../../src/factory/get_settings.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,6BAA6B,EAAE,MAAM,2BAA2B,CAAC;AAE/F,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAEvE,wBAAsB,uBAAuB,CAC3C,MAAM,EAAE,cAAc,EACtB,gBAAgB,CAAC,EAAE,6BAA6B,GAC/C,OAAO,CAAC,oBAAoB,CAAC,
|
|
1
|
+
{"version":3,"file":"get_settings.d.ts","sourceRoot":"","sources":["../../src/factory/get_settings.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,6BAA6B,EAAE,MAAM,2BAA2B,CAAC;AAE/F,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAEvE,wBAAsB,uBAAuB,CAC3C,MAAM,EAAE,cAAc,EACtB,gBAAgB,CAAC,EAAE,6BAA6B,GAC/C,OAAO,CAAC,IAAI,CAAC,oBAAoB,EAAE,0BAA0B,CAAC,CAAC,CAkDjE"}
|
|
@@ -3,7 +3,7 @@ export declare const slasherDefaultEnv: {
|
|
|
3
3
|
readonly SLASH_MIN_PENALTY_PERCENTAGE: 0.5;
|
|
4
4
|
readonly SLASH_MAX_PENALTY_PERCENTAGE: 2;
|
|
5
5
|
readonly SLASH_OFFENSE_EXPIRATION_ROUNDS: 4;
|
|
6
|
-
readonly SLASH_MAX_PAYLOAD_SIZE:
|
|
6
|
+
readonly SLASH_MAX_PAYLOAD_SIZE: 80;
|
|
7
7
|
readonly SLASH_EXECUTE_ROUNDS_LOOK_BACK: 4;
|
|
8
8
|
readonly SLASH_PRUNE_PENALTY: 10000000000000000000;
|
|
9
9
|
readonly SLASH_DATA_WITHHOLDING_PENALTY: 10000000000000000000;
|
|
@@ -12,9 +12,10 @@ export declare const slasherDefaultEnv: {
|
|
|
12
12
|
readonly SLASH_INACTIVITY_PENALTY: 10000000000000000000;
|
|
13
13
|
readonly SLASH_PROPOSE_INVALID_ATTESTATIONS_PENALTY: 10000000000000000000;
|
|
14
14
|
readonly SLASH_ATTEST_DESCENDANT_OF_INVALID_PENALTY: 10000000000000000000;
|
|
15
|
-
readonly SLASH_DUPLICATE_PROPOSAL_PENALTY:
|
|
15
|
+
readonly SLASH_DUPLICATE_PROPOSAL_PENALTY: 0;
|
|
16
|
+
readonly SLASH_DUPLICATE_ATTESTATION_PENALTY: 0;
|
|
16
17
|
readonly SLASH_UNKNOWN_PENALTY: 10000000000000000000;
|
|
17
18
|
readonly SLASH_INVALID_BLOCK_PENALTY: 10000000000000000000;
|
|
18
19
|
readonly SLASH_GRACE_PERIOD_L2_SLOTS: 0;
|
|
19
20
|
};
|
|
20
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
21
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2xhc2hlci1kZWZhdWx0cy5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2dlbmVyYXRlZC9zbGFzaGVyLWRlZmF1bHRzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUdBLHFFQUFxRTtBQUNyRSxlQUFPLE1BQU0saUJBQWlCOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Q0FrQnBCLENBQUMifQ==
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"slasher-defaults.d.ts","sourceRoot":"","sources":["../../src/generated/slasher-defaults.ts"],"names":[],"mappings":"AAGA,qEAAqE;AACrE,eAAO,MAAM,iBAAiB
|
|
1
|
+
{"version":3,"file":"slasher-defaults.d.ts","sourceRoot":"","sources":["../../src/generated/slasher-defaults.ts"],"names":[],"mappings":"AAGA,qEAAqE;AACrE,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;CAkBpB,CAAC"}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
SLASH_MIN_PENALTY_PERCENTAGE: 0.5,
|
|
5
5
|
SLASH_MAX_PENALTY_PERCENTAGE: 2,
|
|
6
6
|
SLASH_OFFENSE_EXPIRATION_ROUNDS: 4,
|
|
7
|
-
SLASH_MAX_PAYLOAD_SIZE:
|
|
7
|
+
SLASH_MAX_PAYLOAD_SIZE: 80,
|
|
8
8
|
SLASH_EXECUTE_ROUNDS_LOOK_BACK: 4,
|
|
9
9
|
SLASH_PRUNE_PENALTY: 10000000000000000000,
|
|
10
10
|
SLASH_DATA_WITHHOLDING_PENALTY: 10000000000000000000,
|
|
@@ -13,7 +13,8 @@
|
|
|
13
13
|
SLASH_INACTIVITY_PENALTY: 10000000000000000000,
|
|
14
14
|
SLASH_PROPOSE_INVALID_ATTESTATIONS_PENALTY: 10000000000000000000,
|
|
15
15
|
SLASH_ATTEST_DESCENDANT_OF_INVALID_PENALTY: 10000000000000000000,
|
|
16
|
-
SLASH_DUPLICATE_PROPOSAL_PENALTY:
|
|
16
|
+
SLASH_DUPLICATE_PROPOSAL_PENALTY: 0,
|
|
17
|
+
SLASH_DUPLICATE_ATTESTATION_PENALTY: 0,
|
|
17
18
|
SLASH_UNKNOWN_PENALTY: 10000000000000000000,
|
|
18
19
|
SLASH_INVALID_BLOCK_PENALTY: 10000000000000000000,
|
|
19
20
|
SLASH_GRACE_PERIOD_L2_SLOTS: 0
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { SlotNumber } from '@aztec/foundation/branded-types';
|
|
1
2
|
import type { Prettify } from '@aztec/foundation/types';
|
|
2
3
|
import type { L1RollupConstants } from '@aztec/stdlib/epoch-helpers';
|
|
3
4
|
import type { SlasherConfig } from '@aztec/stdlib/interfaces/server';
|
|
@@ -7,6 +8,8 @@ import { type WantToSlashArgs, type Watcher } from './watcher.js';
|
|
|
7
8
|
export type SlashOffensesCollectorConfig = Prettify<Pick<SlasherConfig, 'slashGracePeriodL2Slots'>>;
|
|
8
9
|
export type SlashOffensesCollectorSettings = Prettify<Pick<L1RollupConstants, 'epochDuration'> & {
|
|
9
10
|
slashingAmounts: [bigint, bigint, bigint] | undefined;
|
|
11
|
+
/** L2 slot at which the rollup was registered as canonical in the Registry. Used to anchor the slash grace period. */
|
|
12
|
+
rollupRegisteredAtL2Slot: SlotNumber;
|
|
10
13
|
}>;
|
|
11
14
|
/**
|
|
12
15
|
* Collects and manages slashable offenses from watchers.
|
|
@@ -39,7 +42,7 @@ export declare class SlashOffensesCollector {
|
|
|
39
42
|
* @param offenses - The offenses to mark as slashed
|
|
40
43
|
*/
|
|
41
44
|
markAsSlashed(offenses: OffenseIdentifier[]): Promise<void>;
|
|
42
|
-
/** Returns whether to skip an offense if it happened during the grace period
|
|
45
|
+
/** Returns whether to skip an offense if it happened during the grace period after the network upgrade */
|
|
43
46
|
private shouldSkipOffense;
|
|
44
47
|
}
|
|
45
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
48
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2xhc2hfb2ZmZW5zZXNfY29sbGVjdG9yLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvc2xhc2hfb2ZmZW5zZXNfY29sbGVjdG9yLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxFQUFFLFVBQVUsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBRWxFLE9BQU8sS0FBSyxFQUFFLFFBQVEsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQ3hELE9BQU8sS0FBSyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFDckUsT0FBTyxLQUFLLEVBQUUsYUFBYSxFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFDckUsT0FBTyxFQUFnQixLQUFLLGlCQUFpQixFQUFxQixNQUFNLHdCQUF3QixDQUFDO0FBRWpHLE9BQU8sS0FBSyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDdkUsT0FBTyxFQUF1QixLQUFLLGVBQWUsRUFBRSxLQUFLLE9BQU8sRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUV2RixNQUFNLE1BQU0sNEJBQTRCLEdBQUcsUUFBUSxDQUFDLElBQUksQ0FBQyxhQUFhLEVBQUUseUJBQXlCLENBQUMsQ0FBQyxDQUFDO0FBQ3BHLE1BQU0sTUFBTSw4QkFBOEIsR0FBRyxRQUFRLENBQ25ELElBQUksQ0FBQyxpQkFBaUIsRUFBRSxlQUFlLENBQUMsR0FBRztJQUN6QyxlQUFlLEVBQUUsQ0FBQyxNQUFNLEVBQUUsTUFBTSxFQUFFLE1BQU0sQ0FBQyxHQUFHLFNBQVMsQ0FBQztJQUN0RCxzSEFBc0g7SUFDdEgsd0JBQXdCLEVBQUUsVUFBVSxDQUFDO0NBQ3RDLENBQ0YsQ0FBQztBQUVGOzs7O0dBSUc7QUFDSCxxQkFBYSxzQkFBc0I7SUFJL0IsT0FBTyxDQUFDLFFBQVEsQ0FBQyxNQUFNO0lBQ3ZCLE9BQU8sQ0FBQyxRQUFRLENBQUMsUUFBUTtJQUN6QixPQUFPLENBQUMsUUFBUSxDQUFDLFFBQVE7SUFDekIsT0FBTyxDQUFDLFFBQVEsQ0FBQyxhQUFhO0lBQzlCLE9BQU8sQ0FBQyxRQUFRLENBQUMsR0FBRztJQVB0QixPQUFPLENBQUMsUUFBUSxDQUFDLGdCQUFnQixDQUFzQjtJQUV2RCxZQUNtQixNQUFNLEVBQUUsNEJBQTRCLEVBQ3BDLFFBQVEsRUFBRSw4QkFBOEIsRUFDeEMsUUFBUSxFQUFFLE9BQU8sRUFBRSxFQUNuQixhQUFhLEVBQUUsb0JBQW9CLEVBQ25DLEdBQUcseUNBQTZDLEVBQy9EO0lBRUcsS0FBSyxrQkFhWDtJQUVNLElBQUksa0JBU1Y7SUFFRDs7OztPQUlHO0lBQ1UsaUJBQWlCLENBQUMsSUFBSSxFQUFFLGVBQWUsRUFBRSxpQkE2QnJEO0lBRUQ7OztPQUdHO0lBQ1UsY0FBYyxDQUFDLEtBQUssRUFBRSxNQUFNLGlCQUt4QztJQUVEOzs7T0FHRztJQUNJLGFBQWEsQ0FBQyxRQUFRLEVBQUUsaUJBQWlCLEVBQUUsaUJBR2pEO0lBRUQsMEdBQTBHO0lBQzFHLE9BQU8sQ0FBQyxpQkFBaUI7Q0FJMUIifQ==
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"slash_offenses_collector.d.ts","sourceRoot":"","sources":["../src/slash_offenses_collector.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"slash_offenses_collector.d.ts","sourceRoot":"","sources":["../src/slash_offenses_collector.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAElE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AACrE,OAAO,EAAgB,KAAK,iBAAiB,EAAqB,MAAM,wBAAwB,CAAC;AAEjG,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AACvE,OAAO,EAAuB,KAAK,eAAe,EAAE,KAAK,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvF,MAAM,MAAM,4BAA4B,GAAG,QAAQ,CAAC,IAAI,CAAC,aAAa,EAAE,yBAAyB,CAAC,CAAC,CAAC;AACpG,MAAM,MAAM,8BAA8B,GAAG,QAAQ,CACnD,IAAI,CAAC,iBAAiB,EAAE,eAAe,CAAC,GAAG;IACzC,eAAe,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAAC;IACtD,sHAAsH;IACtH,wBAAwB,EAAE,UAAU,CAAC;CACtC,CACF,CAAC;AAEF;;;;GAIG;AACH,qBAAa,sBAAsB;IAI/B,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,aAAa;IAC9B,OAAO,CAAC,QAAQ,CAAC,GAAG;IAPtB,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAsB;IAEvD,YACmB,MAAM,EAAE,4BAA4B,EACpC,QAAQ,EAAE,8BAA8B,EACxC,QAAQ,EAAE,OAAO,EAAE,EACnB,aAAa,EAAE,oBAAoB,EACnC,GAAG,yCAA6C,EAC/D;IAEG,KAAK,kBAaX;IAEM,IAAI,kBASV;IAED;;;;OAIG;IACU,iBAAiB,CAAC,IAAI,EAAE,eAAe,EAAE,iBA6BrD;IAED;;;OAGG;IACU,cAAc,CAAC,KAAK,EAAE,MAAM,iBAKxC;IAED;;;OAGG;IACI,aAAa,CAAC,QAAQ,EAAE,iBAAiB,EAAE,iBAGjD;IAED,0GAA0G;IAC1G,OAAO,CAAC,iBAAiB;CAI1B"}
|
|
@@ -65,11 +65,7 @@ import { WANT_TO_SLASH_EVENT } from './watcher.js';
|
|
|
65
65
|
this.log.warn(`Offense amount ${arg.amount} is below minimum slashing amount ${minSlash}`);
|
|
66
66
|
}
|
|
67
67
|
}
|
|
68
|
-
this.log.info(`Adding pending offense for validator ${arg.validator}`,
|
|
69
|
-
...pendingOffense,
|
|
70
|
-
epochOrSlot: pendingOffense.epochOrSlot.toString(),
|
|
71
|
-
amount: pendingOffense.amount.toString()
|
|
72
|
-
});
|
|
68
|
+
this.log.info(`Adding pending offense for validator ${arg.validator}`, pendingOffense);
|
|
73
69
|
await this.offensesStore.addPendingOffense(pendingOffense);
|
|
74
70
|
}
|
|
75
71
|
}
|
|
@@ -91,8 +87,8 @@ import { WANT_TO_SLASH_EVENT } from './watcher.js';
|
|
|
91
87
|
});
|
|
92
88
|
return this.offensesStore.markAsSlashed(offenses);
|
|
93
89
|
}
|
|
94
|
-
/** Returns whether to skip an offense if it happened during the grace period
|
|
90
|
+
/** Returns whether to skip an offense if it happened during the grace period after the network upgrade */ shouldSkipOffense(offense) {
|
|
95
91
|
const offenseSlot = getSlotForOffense(offense, this.settings);
|
|
96
|
-
return offenseSlot < this.config.slashGracePeriodL2Slots;
|
|
92
|
+
return offenseSlot < this.settings.rollupRegisteredAtL2Slot + this.config.slashGracePeriodL2Slots;
|
|
97
93
|
}
|
|
98
94
|
}
|
|
@@ -4,9 +4,9 @@ import type { ViemClient } from '@aztec/ethereum/types';
|
|
|
4
4
|
import type { SlotNumber } from '@aztec/foundation/branded-types';
|
|
5
5
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
6
6
|
import { DateProvider } from '@aztec/foundation/timer';
|
|
7
|
-
import type { DataStoreConfig } from '@aztec/kv-store/config';
|
|
8
7
|
import { AztecLMDBStoreV2 } from '@aztec/kv-store/lmdb-v2';
|
|
9
8
|
import type { SlasherConfig } from '@aztec/stdlib/interfaces/server';
|
|
9
|
+
import type { DataStoreConfig } from '@aztec/stdlib/kv-store';
|
|
10
10
|
import type { Offense, ProposerSlashAction, SlashPayloadRound } from '@aztec/stdlib/slashing';
|
|
11
11
|
import type { SlasherClientInterface } from './slasher_client_interface.js';
|
|
12
12
|
import type { Watcher } from './watcher.js';
|
|
@@ -24,12 +24,13 @@ export declare class SlasherClientFacade implements SlasherClientInterface {
|
|
|
24
24
|
private epochCache;
|
|
25
25
|
private dateProvider;
|
|
26
26
|
private kvStore;
|
|
27
|
+
private rollupRegisteredAtL2Slot;
|
|
27
28
|
private logger;
|
|
28
29
|
private client;
|
|
29
30
|
private unwatch;
|
|
30
31
|
constructor(config: SlasherConfig & DataStoreConfig & {
|
|
31
32
|
ethereumSlotDuration: number;
|
|
32
|
-
}, rollup: RollupContract, l1Client: ViemClient, slashFactoryAddress: EthAddress | undefined, watchers: Watcher[], epochCache: EpochCache, dateProvider: DateProvider, kvStore: AztecLMDBStoreV2, logger?: import("@aztec/foundation/log").Logger);
|
|
33
|
+
}, rollup: RollupContract, l1Client: ViemClient, slashFactoryAddress: EthAddress | undefined, watchers: Watcher[], epochCache: EpochCache, dateProvider: DateProvider, kvStore: AztecLMDBStoreV2, rollupRegisteredAtL2Slot: SlotNumber, logger?: import("@aztec/foundation/log").Logger);
|
|
33
34
|
start(): Promise<void>;
|
|
34
35
|
stop(): Promise<void>;
|
|
35
36
|
getConfig(): SlasherConfig;
|
|
@@ -41,4 +42,4 @@ export declare class SlasherClientFacade implements SlasherClientInterface {
|
|
|
41
42
|
private createSlasherClient;
|
|
42
43
|
private handleSlasherChange;
|
|
43
44
|
}
|
|
44
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
45
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2xhc2hlcl9jbGllbnRfZmFjYWRlLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvc2xhc2hlcl9jbGllbnRfZmFjYWRlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUNoRCxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFDM0QsT0FBTyxLQUFLLEVBQUUsVUFBVSxFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDeEQsT0FBTyxLQUFLLEVBQUUsVUFBVSxFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFDbEUsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBRTNELE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUN2RCxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUMzRCxPQUFPLEtBQUssRUFBRSxhQUFhLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUNyRSxPQUFPLEtBQUssRUFBRSxlQUFlLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUM5RCxPQUFPLEtBQUssRUFBRSxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUc5RixPQUFPLEtBQUssRUFBRSxzQkFBc0IsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBQzVFLE9BQU8sS0FBSyxFQUFFLE9BQU8sRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUU1Qzs7OztHQUlHO0FBQ0gscUJBQWEsbUJBQW9CLFlBQVcsc0JBQXNCO0lBSzlELE9BQU8sQ0FBQyxNQUFNO0lBQ2QsT0FBTyxDQUFDLE1BQU07SUFDZCxPQUFPLENBQUMsUUFBUTtJQUNoQixPQUFPLENBQUMsbUJBQW1CO0lBQzNCLE9BQU8sQ0FBQyxRQUFRO0lBQ2hCLE9BQU8sQ0FBQyxVQUFVO0lBQ2xCLE9BQU8sQ0FBQyxZQUFZO0lBQ3BCLE9BQU8sQ0FBQyxPQUFPO0lBQ2YsT0FBTyxDQUFDLHdCQUF3QjtJQUNoQyxPQUFPLENBQUMsTUFBTTtJQWJoQixPQUFPLENBQUMsTUFBTSxDQUFxQztJQUNuRCxPQUFPLENBQUMsT0FBTyxDQUEyQjtJQUUxQyxZQUNVLE1BQU0sRUFBRSxhQUFhLEdBQUcsZUFBZSxHQUFHO1FBQUUsb0JBQW9CLEVBQUUsTUFBTSxDQUFBO0tBQUUsRUFDMUUsTUFBTSxFQUFFLGNBQWMsRUFDdEIsUUFBUSxFQUFFLFVBQVUsRUFDcEIsbUJBQW1CLEVBQUUsVUFBVSxHQUFHLFNBQVMsRUFDM0MsUUFBUSxFQUFFLE9BQU8sRUFBRSxFQUNuQixVQUFVLEVBQUUsVUFBVSxFQUN0QixZQUFZLEVBQUUsWUFBWSxFQUMxQixPQUFPLEVBQUUsZ0JBQWdCLEVBQ3pCLHdCQUF3QixFQUFFLFVBQVUsRUFDcEMsTUFBTSx5Q0FBMEIsRUFDdEM7SUFFUyxLQUFLLElBQUksT0FBTyxDQUFDLElBQUksQ0FBQyxDQVNsQztJQUVZLElBQUksSUFBSSxPQUFPLENBQUMsSUFBSSxDQUFDLENBSWpDO0lBRU0sU0FBUyxJQUFJLGFBQWEsQ0FFaEM7SUFFTSxZQUFZLENBQUMsTUFBTSxFQUFFLE9BQU8sQ0FBQyxhQUFhLENBQUMsR0FBRyxJQUFJLENBSXhEO0lBRU0sZ0JBQWdCLElBQUksT0FBTyxDQUFDLGlCQUFpQixFQUFFLENBQUMsQ0FFdEQ7SUFFTSxzQkFBc0IsQ0FBQyxLQUFLLENBQUMsRUFBRSxNQUFNLEdBQUcsT0FBTyxDQUFDLE9BQU8sRUFBRSxDQUFDLENBRWhFO0lBRU0sa0JBQWtCLElBQUksT0FBTyxDQUFDLE9BQU8sRUFBRSxDQUFDLENBRTlDO0lBRU0sa0JBQWtCLENBQUMsVUFBVSxFQUFFLFVBQVUsR0FBRyxPQUFPLENBQUMsbUJBQW1CLEVBQUUsQ0FBQyxDQUVoRjtJQUVELE9BQU8sQ0FBQyxtQkFBbUI7WUFlYixtQkFBbUI7Q0FNbEMifQ==
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"slasher_client_facade.d.ts","sourceRoot":"","sources":["../src/slasher_client_facade.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAClE,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAE3D,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,
|
|
1
|
+
{"version":3,"file":"slasher_client_facade.d.ts","sourceRoot":"","sources":["../src/slasher_client_facade.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAClE,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAE3D,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AACrE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,KAAK,EAAE,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAG9F,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AAC5E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAE5C;;;;GAIG;AACH,qBAAa,mBAAoB,YAAW,sBAAsB;IAK9D,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,QAAQ;IAChB,OAAO,CAAC,mBAAmB;IAC3B,OAAO,CAAC,QAAQ;IAChB,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,YAAY;IACpB,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,wBAAwB;IAChC,OAAO,CAAC,MAAM;IAbhB,OAAO,CAAC,MAAM,CAAqC;IACnD,OAAO,CAAC,OAAO,CAA2B;IAE1C,YACU,MAAM,EAAE,aAAa,GAAG,eAAe,GAAG;QAAE,oBAAoB,EAAE,MAAM,CAAA;KAAE,EAC1E,MAAM,EAAE,cAAc,EACtB,QAAQ,EAAE,UAAU,EACpB,mBAAmB,EAAE,UAAU,GAAG,SAAS,EAC3C,QAAQ,EAAE,OAAO,EAAE,EACnB,UAAU,EAAE,UAAU,EACtB,YAAY,EAAE,YAAY,EAC1B,OAAO,EAAE,gBAAgB,EACzB,wBAAwB,EAAE,UAAU,EACpC,MAAM,yCAA0B,EACtC;IAES,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CASlC;IAEY,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAIjC;IAEM,SAAS,IAAI,aAAa,CAEhC;IAEM,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,aAAa,CAAC,GAAG,IAAI,CAIxD;IAEM,gBAAgB,IAAI,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAEtD;IAEM,sBAAsB,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAEhE;IAEM,kBAAkB,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC,CAE9C;IAEM,kBAAkB,CAAC,UAAU,EAAE,UAAU,GAAG,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAEhF;IAED,OAAO,CAAC,mBAAmB;YAeb,mBAAmB;CAMlC"}
|
|
@@ -13,10 +13,11 @@ import { createSlasherImplementation } from './factory/create_implementation.js'
|
|
|
13
13
|
epochCache;
|
|
14
14
|
dateProvider;
|
|
15
15
|
kvStore;
|
|
16
|
+
rollupRegisteredAtL2Slot;
|
|
16
17
|
logger;
|
|
17
18
|
client;
|
|
18
19
|
unwatch;
|
|
19
|
-
constructor(config, rollup, l1Client, slashFactoryAddress, watchers, epochCache, dateProvider, kvStore, logger = createLogger('slasher')){
|
|
20
|
+
constructor(config, rollup, l1Client, slashFactoryAddress, watchers, epochCache, dateProvider, kvStore, rollupRegisteredAtL2Slot, logger = createLogger('slasher')){
|
|
20
21
|
this.config = config;
|
|
21
22
|
this.rollup = rollup;
|
|
22
23
|
this.l1Client = l1Client;
|
|
@@ -25,6 +26,7 @@ import { createSlasherImplementation } from './factory/create_implementation.js'
|
|
|
25
26
|
this.epochCache = epochCache;
|
|
26
27
|
this.dateProvider = dateProvider;
|
|
27
28
|
this.kvStore = kvStore;
|
|
29
|
+
this.rollupRegisteredAtL2Slot = rollupRegisteredAtL2Slot;
|
|
28
30
|
this.logger = logger;
|
|
29
31
|
}
|
|
30
32
|
async start() {
|
|
@@ -65,7 +67,7 @@ import { createSlasherImplementation } from './factory/create_implementation.js'
|
|
|
65
67
|
return this.client?.getProposerActions(slotNumber) ?? Promise.reject(new Error('Slasher client not initialized'));
|
|
66
68
|
}
|
|
67
69
|
createSlasherClient() {
|
|
68
|
-
return createSlasherImplementation(this.config, this.rollup, this.l1Client, this.slashFactoryAddress, this.watchers, this.epochCache, this.dateProvider, this.kvStore, this.logger);
|
|
70
|
+
return createSlasherImplementation(this.config, this.rollup, this.l1Client, this.slashFactoryAddress, this.watchers, this.epochCache, this.dateProvider, this.kvStore, this.rollupRegisteredAtL2Slot, this.logger);
|
|
69
71
|
}
|
|
70
72
|
async handleSlasherChange() {
|
|
71
73
|
this.logger.warn('Slasher contract changed, recreating slasher client');
|
|
@@ -22,7 +22,7 @@ export type TallySlasherSettings = Prettify<SlashRoundMonitorSettings & SlashOff
|
|
|
22
22
|
/** Committee size for block proposal */
|
|
23
23
|
targetCommitteeSize: number;
|
|
24
24
|
}>;
|
|
25
|
-
export type TallySlasherClientConfig = SlashOffensesCollectorConfig & Pick<SlasherConfig, 'slashValidatorsAlways' | 'slashValidatorsNever' | 'slashExecuteRoundsLookBack'>;
|
|
25
|
+
export type TallySlasherClientConfig = SlashOffensesCollectorConfig & Pick<SlasherConfig, 'slashValidatorsAlways' | 'slashValidatorsNever' | 'slashExecuteRoundsLookBack' | 'slashMaxPayloadSize'>;
|
|
26
26
|
/**
|
|
27
27
|
* The Tally Slasher client is responsible for managing slashable offenses using
|
|
28
28
|
* the consensus-based slashing model where proposers vote on individual validator offenses.
|
|
@@ -122,4 +122,4 @@ export declare class TallySlasherClient implements ProposerSlashActionProvider,
|
|
|
122
122
|
*/
|
|
123
123
|
private getSlashedRound;
|
|
124
124
|
}
|
|
125
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
125
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFsbHlfc2xhc2hlcl9jbGllbnQuZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy90YWxseV9zbGFzaGVyX2NsaWVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLEtBQUssRUFBRSxVQUFVLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUNyRCxPQUFPLEVBQUUsY0FBYyxFQUFFLGVBQWUsRUFBRSw2QkFBNkIsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBRTNHLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUc3RCxPQUFPLEtBQUssRUFBRSxZQUFZLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUM1RCxPQUFPLEtBQUssRUFBRSxRQUFRLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUN4RCxPQUFPLEtBQUssRUFBRSxhQUFhLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUNyRSxPQUFPLEVBQ0wsS0FBSyxPQUFPLEVBRVosS0FBSyxtQkFBbUIsRUFDeEIsS0FBSywyQkFBMkIsRUFDaEMsS0FBSyxpQkFBaUIsRUFHdkIsTUFBTSx3QkFBd0IsQ0FBQztBQUVoQyxPQUFPLEtBQUssRUFBRSxHQUFHLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFFaEMsT0FBTyxFQUNMLHNCQUFzQixFQUN0QixLQUFLLDRCQUE0QixFQUNqQyxLQUFLLDhCQUE4QixFQUNwQyxNQUFNLCtCQUErQixDQUFDO0FBQ3ZDLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxLQUFLLHlCQUF5QixFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDN0YsT0FBTyxLQUFLLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUM1RSxPQUFPLEtBQUssRUFBRSxvQkFBb0IsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQ3ZFLE9BQU8sS0FBSyxFQUFFLE9BQU8sRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUU1QyxvR0FBb0c7QUFDcEcsTUFBTSxNQUFNLG9C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
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tally_slasher_client.d.ts","sourceRoot":"","sources":["../src/tally_slasher_client.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,6BAA6B,EAAE,MAAM,2BAA2B,CAAC;AAE3G,OAAO,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAG7D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AACrE,OAAO,EACL,KAAK,OAAO,EAEZ,KAAK,mBAAmB,EACxB,KAAK,2BAA2B,EAChC,KAAK,iBAAiB,EAGvB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,MAAM,CAAC;AAEhC,OAAO,EACL,sBAAsB,EACtB,KAAK,4BAA4B,EACjC,KAAK,8BAA8B,EACpC,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAE,iBAAiB,EAAE,KAAK,yBAAyB,EAAE,MAAM,0BAA0B,CAAC;AAC7F,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AAC5E,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AACvE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAE5C,oGAAoG;AACpG,MAAM,MAAM,oBAAoB,GAAG,QAAQ,CACzC,yBAAyB,GACvB,8BAA8B,GAAG;IAC/B,wBAAwB,EAAE,MAAM,CAAC;IACjC,8BAA8B,EAAE,MAAM,CAAC;IACvC,yBAAyB,EAAE,MAAM,CAAC;IAClC,sBAAsB,EAAE,MAAM,CAAC;IAC/B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,eAAe,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IAC1C,wCAAwC;IACxC,mBAAmB,EAAE,MAAM,CAAC;CAC7B,CACJ,CAAC;AAEF,MAAM,MAAM,wBAAwB,GAAG,4BAA4B,GACjE,IAAI,
|
|
1
|
+
{"version":3,"file":"tally_slasher_client.d.ts","sourceRoot":"","sources":["../src/tally_slasher_client.ts"],"names":[],"mappings":"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"}
|
|
@@ -277,19 +277,19 @@ import { SlashRoundMonitor } from './slash_round_monitor.js';
|
|
|
277
277
|
});
|
|
278
278
|
return undefined;
|
|
279
279
|
}
|
|
280
|
-
const offensesToSlashLog = offensesToSlash.map((offense)=>({
|
|
281
|
-
...offense,
|
|
282
|
-
amount: offense.amount.toString()
|
|
283
|
-
}));
|
|
284
280
|
this.log.info(`Voting to slash ${offensesToSlash.length} offenses`, {
|
|
285
281
|
slotNumber,
|
|
286
282
|
currentRound,
|
|
287
283
|
slashedRound,
|
|
288
|
-
offensesToSlash
|
|
284
|
+
offensesToSlash
|
|
289
285
|
});
|
|
290
286
|
const committees = await this.collectCommitteesActiveDuringRound(slashedRound);
|
|
291
287
|
const epochsForCommittees = getEpochsForRound(slashedRound, this.settings);
|
|
292
|
-
const
|
|
288
|
+
const { slashMaxPayloadSize } = this.config;
|
|
289
|
+
const votes = getSlashConsensusVotesFromOffenses(offensesToSlash, committees, epochsForCommittees.map((e)=>BigInt(e)), {
|
|
290
|
+
...this.settings,
|
|
291
|
+
maxSlashedValidators: slashMaxPayloadSize
|
|
292
|
+
}, this.log);
|
|
293
293
|
if (votes.every((v)=>v === 0)) {
|
|
294
294
|
this.log.warn(`Computed votes for offenses are all zero. Skipping vote.`, {
|
|
295
295
|
slotNumber,
|
|
@@ -36,4 +36,4 @@ export declare class EpochPruneWatcher extends EpochPruneWatcher_base implements
|
|
|
36
36
|
private validatorsToSlashingArgs;
|
|
37
37
|
}
|
|
38
38
|
export {};
|
|
39
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
39
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXBvY2hfcHJ1bmVfd2F0Y2hlci5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3dhdGNoZXJzL2Vwb2NoX3BydW5lX3dhdGNoZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQ2hELE9BQU8sRUFBZSxXQUFXLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUkzRSxPQUFPLEVBRUwsT0FBTyxFQUNQLEtBQUsseUJBQXlCLEVBRy9CLE1BQU0scUJBQXFCLENBQUM7QUFFN0IsT0FBTyxLQUFLLEVBRVYsbUJBQW1CLEVBQ25CLFdBQVcsRUFFWCxhQUFhLEVBQ2QsTUFBTSxpQ0FBaUMsQ0FBQztBQUN6QyxPQUFPLEVBQUUsS0FBSyxtQkFBbUIsRUFBNEIsTUFBTSx5QkFBeUIsQ0FBQztBQVk3RixPQUFPLEVBQTZDLEtBQUssT0FBTyxFQUFFLEtBQUssY0FBYyxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBRTdHLFFBQUEsTUFBTSxvQ0FBb0MsK0RBQWdFLENBQUM7QUFFM0csS0FBSywwQkFBMEIsR0FBRyxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUMsT0FBTyxvQ0FBb0MsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7O0FBRTdHOzs7OztHQUtHO0FBQ0gscUJBQWEsaUJBQWtCLFNBQVEsc0JBQTJDLFlBQVcsT0FBTztJQVNoRyxPQUFPLENBQUMsYUFBYTtJQUNyQixPQUFPLENBQUMsbUJBQW1CO0lBQzNCLE9BQU8sQ0FBQyxVQUFVO0lBQ2xCLE9BQU8sQ0FBQyxVQUFVO0lBQ2xCLE9BQU8sQ0FBQyxrQkFBa0I7SUFaNUIsT0FBTyxDQUFDLEdBQUcsQ0FBK0M7SUFHMUQsT0FBTyxDQUFDLHdCQUF3QixDQUF1QztJQUV2RSxPQUFPLENBQUMsU0FBUyxDQUE2QjtJQUU5QyxZQUNVLGFBQWEsRUFBRSx5QkFBeUIsRUFDeEMsbUJBQW1CLEVBQUUsbUJBQW1CLEVBQ3hDLFVBQVUsRUFBRSxVQUFVLEVBQ3RCLFVBQVUsRUFBRSxJQUFJLENBQUMsV0FBVyxFQUFFLGlCQUFpQixDQUFDLEVBQ2hELGtCQUFrQixFQUFFLG1CQUFtQixFQUMvQyxTQUFTLEVBQUUsMEJBQTBCLEVBT3RDO0lBRU0sS0FBSyxrQkFHWDtJQUVNLElBQUksa0JBR1Y7SUFFTSxZQUFZLENBQUMsTUFBTSxFQUFFLE9BQU8sQ0FBQyxhQUFhLENBQUMsR0FBRyxJQUFJLENBR3hEO0lBRUQsT0FBTyxDQUFDLG1CQUFtQjtZQU9iLGlCQUFpQjtZQVdqQixvQkFBb0I7SUF3QnJCLGNBQWMsQ0FBQyxNQUFNLEVBQUUsT0FBTyxFQUFFLEVBQUUsV0FBVyxFQUFFLFdBQVcsR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLENBK0J0RjtZQUVhLGtCQUFrQjtZQXdDbEIseUJBQXlCO1lBaUN6QixxQkFBcUI7SUFTbkMsT0FBTyxDQUFDLHdCQUF3QjtDQWdCakMifQ==
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"epoch_prune_watcher.d.ts","sourceRoot":"","sources":["../../src/watchers/epoch_prune_watcher.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAe,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAI3E,OAAO,EAEL,OAAO,EACP,KAAK,yBAAyB,EAG/B,MAAM,qBAAqB,CAAC;AAE7B,OAAO,KAAK,EAEV,mBAAmB,EACnB,WAAW,EAEX,aAAa,EACd,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,KAAK,mBAAmB,EAA4B,MAAM,yBAAyB,CAAC;AAY7F,OAAO,EAA6C,KAAK,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,eAAe,CAAC;AAE7G,QAAA,MAAM,oCAAoC,+DAAgE,CAAC;AAE3G,KAAK,0BAA0B,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC,OAAO,oCAAoC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;;AAE7G;;;;;GAKG;AACH,qBAAa,iBAAkB,SAAQ,sBAA2C,YAAW,OAAO;IAShG,OAAO,CAAC,aAAa;IACrB,OAAO,CAAC,mBAAmB;IAC3B,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,kBAAkB;IAZ5B,OAAO,CAAC,GAAG,CAA+C;IAG1D,OAAO,CAAC,wBAAwB,CAAuC;IAEvE,OAAO,CAAC,SAAS,CAA6B;IAE9C,YACU,aAAa,EAAE,yBAAyB,EACxC,mBAAmB,EAAE,mBAAmB,EACxC,UAAU,EAAE,UAAU,EACtB,UAAU,EAAE,IAAI,CAAC,WAAW,EAAE,iBAAiB,CAAC,EAChD,kBAAkB,EAAE,mBAAmB,EAC/C,SAAS,EAAE,0BAA0B,EAOtC;IAEM,KAAK,kBAGX;IAEM,IAAI,kBAGV;IAEM,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,aAAa,CAAC,GAAG,IAAI,CAGxD;IAED,OAAO,CAAC,mBAAmB;YAOb,iBAAiB;YAWjB,oBAAoB;IAwBrB,cAAc,CAAC,MAAM,EAAE,OAAO,EAAE,EAAE,WAAW,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CA+BtF;YAEa,kBAAkB;
|
|
1
|
+
{"version":3,"file":"epoch_prune_watcher.d.ts","sourceRoot":"","sources":["../../src/watchers/epoch_prune_watcher.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAe,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAI3E,OAAO,EAEL,OAAO,EACP,KAAK,yBAAyB,EAG/B,MAAM,qBAAqB,CAAC;AAE7B,OAAO,KAAK,EAEV,mBAAmB,EACnB,WAAW,EAEX,aAAa,EACd,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,KAAK,mBAAmB,EAA4B,MAAM,yBAAyB,CAAC;AAY7F,OAAO,EAA6C,KAAK,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,eAAe,CAAC;AAE7G,QAAA,MAAM,oCAAoC,+DAAgE,CAAC;AAE3G,KAAK,0BAA0B,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC,OAAO,oCAAoC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;;AAE7G;;;;;GAKG;AACH,qBAAa,iBAAkB,SAAQ,sBAA2C,YAAW,OAAO;IAShG,OAAO,CAAC,aAAa;IACrB,OAAO,CAAC,mBAAmB;IAC3B,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,kBAAkB;IAZ5B,OAAO,CAAC,GAAG,CAA+C;IAG1D,OAAO,CAAC,wBAAwB,CAAuC;IAEvE,OAAO,CAAC,SAAS,CAA6B;IAE9C,YACU,aAAa,EAAE,yBAAyB,EACxC,mBAAmB,EAAE,mBAAmB,EACxC,UAAU,EAAE,UAAU,EACtB,UAAU,EAAE,IAAI,CAAC,WAAW,EAAE,iBAAiB,CAAC,EAChD,kBAAkB,EAAE,mBAAmB,EAC/C,SAAS,EAAE,0BAA0B,EAOtC;IAEM,KAAK,kBAGX;IAEM,IAAI,kBAGV;IAEM,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,aAAa,CAAC,GAAG,IAAI,CAGxD;IAED,OAAO,CAAC,mBAAmB;YAOb,iBAAiB;YAWjB,oBAAoB;IAwBrB,cAAc,CAAC,MAAM,EAAE,OAAO,EAAE,EAAE,WAAW,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CA+BtF;YAEa,kBAAkB;YAwClB,yBAAyB;YAiCzB,qBAAqB;IASnC,OAAO,CAAC,wBAAwB;CAgBjC"}
|
|
@@ -91,7 +91,7 @@ const EpochPruneWatcherPenaltiesConfigKeys = [
|
|
|
91
91
|
].sort((a, b)=>a.number - b.number);
|
|
92
92
|
const blocksByCheckpoint = chunkBy(sortedBlocks, (b)=>b.checkpointNumber);
|
|
93
93
|
// Get prior checkpoints in the epoch (in case this was a partial prune) to extract the out hashes
|
|
94
|
-
const priorCheckpointOutHashes = (await this.l2BlockSource.
|
|
94
|
+
const priorCheckpointOutHashes = (await this.l2BlockSource.getCheckpointsDataForEpoch(epochNumber)).filter((c)=>c.checkpointNumber < sortedBlocks[0].checkpointNumber).map((c)=>c.checkpointOutHash);
|
|
95
95
|
let previousCheckpointOutHashes = [
|
|
96
96
|
...priorCheckpointOutHashes
|
|
97
97
|
];
|
|
@@ -121,12 +121,13 @@ const EpochPruneWatcherPenaltiesConfigKeys = [
|
|
|
121
121
|
chainId: gv.chainId,
|
|
122
122
|
version: gv.version,
|
|
123
123
|
slotNumber: gv.slotNumber,
|
|
124
|
+
timestamp: gv.timestamp,
|
|
124
125
|
coinbase: gv.coinbase,
|
|
125
126
|
feeRecipient: gv.feeRecipient,
|
|
126
127
|
gasFees: gv.gasFees
|
|
127
128
|
};
|
|
128
129
|
// Start checkpoint builder once for all blocks in this checkpoint
|
|
129
|
-
const checkpointBuilder = await this.checkpointsBuilder.startCheckpoint(checkpointNumber, constants, l1ToL2Messages, previousCheckpointOutHashes, fork, this.log.getBindings());
|
|
130
|
+
const checkpointBuilder = await this.checkpointsBuilder.startCheckpoint(checkpointNumber, constants, 0n, l1ToL2Messages, previousCheckpointOutHashes, fork, this.log.getBindings());
|
|
130
131
|
// Validate all blocks in the checkpoint sequentially
|
|
131
132
|
for (const block of checkpointBlocks){
|
|
132
133
|
await this.validateBlockInCheckpoint(block, checkpointBuilder);
|
|
@@ -143,7 +144,10 @@ const EpochPruneWatcherPenaltiesConfigKeys = [
|
|
|
143
144
|
throw new TransactionsNotAvailableError(missingTxs);
|
|
144
145
|
}
|
|
145
146
|
const gv = blockFromL1.header.globalVariables;
|
|
146
|
-
const { block, failedTxs, numTxs } = await checkpointBuilder.buildBlock(txs, gv.blockNumber, gv.timestamp, {
|
|
147
|
+
const { block, failedTxs, numTxs } = await checkpointBuilder.buildBlock(txs, gv.blockNumber, gv.timestamp, {
|
|
148
|
+
isBuildingProposal: false,
|
|
149
|
+
minValidTxs: 0
|
|
150
|
+
});
|
|
147
151
|
if (numTxs !== txs.length) {
|
|
148
152
|
// This should be detected by state mismatch, but this makes it easier to debug.
|
|
149
153
|
throw new ValidatorError(`Built block with ${numTxs} txs, expected ${txs.length}`);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aztec/slasher",
|
|
3
|
-
"version": "0.0.1-commit.
|
|
3
|
+
"version": "0.0.1-commit.f5d02921e",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": "./dest/index.js",
|
|
@@ -56,20 +56,20 @@
|
|
|
56
56
|
]
|
|
57
57
|
},
|
|
58
58
|
"dependencies": {
|
|
59
|
-
"@aztec/epoch-cache": "0.0.1-commit.
|
|
60
|
-
"@aztec/ethereum": "0.0.1-commit.
|
|
61
|
-
"@aztec/foundation": "0.0.1-commit.
|
|
62
|
-
"@aztec/kv-store": "0.0.1-commit.
|
|
63
|
-
"@aztec/l1-artifacts": "0.0.1-commit.
|
|
64
|
-
"@aztec/stdlib": "0.0.1-commit.
|
|
65
|
-
"@aztec/telemetry-client": "0.0.1-commit.
|
|
59
|
+
"@aztec/epoch-cache": "0.0.1-commit.f5d02921e",
|
|
60
|
+
"@aztec/ethereum": "0.0.1-commit.f5d02921e",
|
|
61
|
+
"@aztec/foundation": "0.0.1-commit.f5d02921e",
|
|
62
|
+
"@aztec/kv-store": "0.0.1-commit.f5d02921e",
|
|
63
|
+
"@aztec/l1-artifacts": "0.0.1-commit.f5d02921e",
|
|
64
|
+
"@aztec/stdlib": "0.0.1-commit.f5d02921e",
|
|
65
|
+
"@aztec/telemetry-client": "0.0.1-commit.f5d02921e",
|
|
66
66
|
"source-map-support": "^0.5.21",
|
|
67
67
|
"tslib": "^2.4.0",
|
|
68
68
|
"viem": "npm:@aztec/viem@2.38.2",
|
|
69
69
|
"zod": "^3.23.8"
|
|
70
70
|
},
|
|
71
71
|
"devDependencies": {
|
|
72
|
-
"@aztec/aztec.js": "0.0.1-commit.
|
|
72
|
+
"@aztec/aztec.js": "0.0.1-commit.f5d02921e",
|
|
73
73
|
"@jest/globals": "^30.0.0",
|
|
74
74
|
"@types/jest": "^30.0.0",
|
|
75
75
|
"@types/node": "^22.15.17",
|
package/src/config.ts
CHANGED
|
@@ -24,6 +24,7 @@ export const DefaultSlasherConfig: SlasherConfig = {
|
|
|
24
24
|
slashInactivityConsecutiveEpochThreshold: slasherDefaultEnv.SLASH_INACTIVITY_CONSECUTIVE_EPOCH_THRESHOLD,
|
|
25
25
|
slashBroadcastedInvalidBlockPenalty: BigInt(slasherDefaultEnv.SLASH_INVALID_BLOCK_PENALTY),
|
|
26
26
|
slashDuplicateProposalPenalty: BigInt(slasherDefaultEnv.SLASH_DUPLICATE_PROPOSAL_PENALTY),
|
|
27
|
+
slashDuplicateAttestationPenalty: BigInt(slasherDefaultEnv.SLASH_DUPLICATE_ATTESTATION_PENALTY),
|
|
27
28
|
slashInactivityPenalty: BigInt(slasherDefaultEnv.SLASH_INACTIVITY_PENALTY),
|
|
28
29
|
slashProposeInvalidAttestationsPenalty: BigInt(slasherDefaultEnv.SLASH_PROPOSE_INVALID_ATTESTATIONS_PENALTY),
|
|
29
30
|
slashAttestDescendantOfInvalidPenalty: BigInt(slasherDefaultEnv.SLASH_ATTEST_DESCENDANT_OF_INVALID_PENALTY),
|
|
@@ -94,6 +95,12 @@ export const slasherConfigMappings: ConfigMappingsType<SlasherConfig> = {
|
|
|
94
95
|
description: 'Penalty amount for slashing a validator for sending duplicate proposals.',
|
|
95
96
|
...bigintConfigHelper(DefaultSlasherConfig.slashDuplicateProposalPenalty),
|
|
96
97
|
},
|
|
98
|
+
slashDuplicateAttestationPenalty: {
|
|
99
|
+
env: 'SLASH_DUPLICATE_ATTESTATION_PENALTY',
|
|
100
|
+
description:
|
|
101
|
+
'Penalty amount for slashing a validator for signing attestations for different proposals at the same slot.',
|
|
102
|
+
...bigintConfigHelper(DefaultSlasherConfig.slashDuplicateAttestationPenalty),
|
|
103
|
+
},
|
|
97
104
|
slashInactivityTargetPercentage: {
|
|
98
105
|
env: 'SLASH_INACTIVITY_TARGET_PERCENTAGE',
|
|
99
106
|
description:
|
|
@@ -148,7 +155,8 @@ export const slasherConfigMappings: ConfigMappingsType<SlasherConfig> = {
|
|
|
148
155
|
...numberConfigHelper(DefaultSlasherConfig.slashMaxPayloadSize),
|
|
149
156
|
},
|
|
150
157
|
slashGracePeriodL2Slots: {
|
|
151
|
-
description:
|
|
158
|
+
description:
|
|
159
|
+
'Number of L2 slots after the network upgrade during which slashing offenses are ignored. The upgrade time is determined from the CanonicalRollupUpdated event.',
|
|
152
160
|
env: 'SLASH_GRACE_PERIOD_L2_SLOTS',
|
|
153
161
|
...numberConfigHelper(DefaultSlasherConfig.slashGracePeriodL2Slots),
|
|
154
162
|
},
|
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
import { EpochCache } from '@aztec/epoch-cache';
|
|
2
|
-
import { RollupContract } from '@aztec/ethereum/contracts';
|
|
2
|
+
import { RegistryContract, RollupContract } from '@aztec/ethereum/contracts';
|
|
3
3
|
import type { L1ReaderConfig } from '@aztec/ethereum/l1-reader';
|
|
4
4
|
import type { ViemClient } from '@aztec/ethereum/types';
|
|
5
|
+
import { SlotNumber } from '@aztec/foundation/branded-types';
|
|
5
6
|
import { unique } from '@aztec/foundation/collection';
|
|
6
7
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
7
8
|
import { createLogger } from '@aztec/foundation/log';
|
|
8
9
|
import { DateProvider } from '@aztec/foundation/timer';
|
|
9
|
-
import type { DataStoreConfig } from '@aztec/kv-store/config';
|
|
10
10
|
import { createStore } from '@aztec/kv-store/lmdb-v2';
|
|
11
|
+
import { getSlotAtTimestamp } from '@aztec/stdlib/epoch-helpers';
|
|
11
12
|
import type { SlasherConfig } from '@aztec/stdlib/interfaces/server';
|
|
13
|
+
import type { DataStoreConfig } from '@aztec/stdlib/kv-store';
|
|
12
14
|
|
|
13
15
|
import { SlasherClientFacade } from '../slasher_client_facade.js';
|
|
14
16
|
import type { SlasherClientInterface } from '../slasher_client_interface.js';
|
|
@@ -18,7 +20,7 @@ import type { Watcher } from '../watcher.js';
|
|
|
18
20
|
/** Creates a slasher client facade that updates itself whenever the rollup slasher changes */
|
|
19
21
|
export async function createSlasherFacade(
|
|
20
22
|
config: SlasherConfig & DataStoreConfig & { ethereumSlotDuration: number },
|
|
21
|
-
l1Contracts: Pick<L1ReaderConfig['l1Contracts'], 'rollupAddress' | 'slashFactoryAddress'>,
|
|
23
|
+
l1Contracts: Pick<L1ReaderConfig['l1Contracts'], 'rollupAddress' | 'slashFactoryAddress' | 'registryAddress'>,
|
|
22
24
|
l1Client: ViemClient,
|
|
23
25
|
watchers: Watcher[],
|
|
24
26
|
dateProvider: DateProvider,
|
|
@@ -34,6 +36,32 @@ export async function createSlasherFacade(
|
|
|
34
36
|
const kvStore = await createStore('slasher', SCHEMA_VERSION, config, logger.getBindings());
|
|
35
37
|
const rollup = new RollupContract(l1Client, l1Contracts.rollupAddress);
|
|
36
38
|
|
|
39
|
+
// Compute and cache the L2 slot at which the rollup was registered as canonical
|
|
40
|
+
const settingsMap = kvStore.openMap<string, number>('slasher-settings');
|
|
41
|
+
const cacheKey = `registeredSlot:${l1Contracts.rollupAddress}`;
|
|
42
|
+
let rollupRegisteredAtL2Slot = (await settingsMap.getAsync(cacheKey)) as SlotNumber | undefined;
|
|
43
|
+
|
|
44
|
+
if (rollupRegisteredAtL2Slot === undefined) {
|
|
45
|
+
const registry = new RegistryContract(l1Client, l1Contracts.registryAddress);
|
|
46
|
+
const l1StartBlock = await rollup.getL1StartBlock();
|
|
47
|
+
const registrationTimestamp = await registry.getCanonicalRollupRegistrationTimestamp(
|
|
48
|
+
l1Contracts.rollupAddress,
|
|
49
|
+
l1StartBlock,
|
|
50
|
+
);
|
|
51
|
+
if (registrationTimestamp !== undefined) {
|
|
52
|
+
const l1GenesisTime = await rollup.getL1GenesisTime();
|
|
53
|
+
const slotDuration = await rollup.getSlotDuration();
|
|
54
|
+
rollupRegisteredAtL2Slot = getSlotAtTimestamp(registrationTimestamp, {
|
|
55
|
+
l1GenesisTime,
|
|
56
|
+
slotDuration: Number(slotDuration),
|
|
57
|
+
});
|
|
58
|
+
} else {
|
|
59
|
+
rollupRegisteredAtL2Slot = SlotNumber(0);
|
|
60
|
+
}
|
|
61
|
+
await settingsMap.set(cacheKey, rollupRegisteredAtL2Slot);
|
|
62
|
+
logger.info(`Canonical rollup registered at L2 slot ${rollupRegisteredAtL2Slot}`);
|
|
63
|
+
}
|
|
64
|
+
|
|
37
65
|
const slashValidatorsNever = config.slashSelfAllowed
|
|
38
66
|
? config.slashValidatorsNever
|
|
39
67
|
: unique([...config.slashValidatorsNever, ...validatorAddresses].map(a => a.toString())).map(EthAddress.fromString);
|
|
@@ -48,6 +76,7 @@ export async function createSlasherFacade(
|
|
|
48
76
|
epochCache,
|
|
49
77
|
dateProvider,
|
|
50
78
|
kvStore,
|
|
79
|
+
rollupRegisteredAtL2Slot,
|
|
51
80
|
logger,
|
|
52
81
|
);
|
|
53
82
|
}
|
|
@@ -5,12 +5,13 @@ import {
|
|
|
5
5
|
TallySlashingProposerContract,
|
|
6
6
|
} from '@aztec/ethereum/contracts';
|
|
7
7
|
import type { ViemClient } from '@aztec/ethereum/types';
|
|
8
|
+
import type { SlotNumber } from '@aztec/foundation/branded-types';
|
|
8
9
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
9
10
|
import { createLogger } from '@aztec/foundation/log';
|
|
10
11
|
import { DateProvider } from '@aztec/foundation/timer';
|
|
11
|
-
import type { DataStoreConfig } from '@aztec/kv-store/config';
|
|
12
12
|
import { AztecLMDBStoreV2 } from '@aztec/kv-store/lmdb-v2';
|
|
13
13
|
import type { SlasherConfig } from '@aztec/stdlib/interfaces/server';
|
|
14
|
+
import type { DataStoreConfig } from '@aztec/stdlib/kv-store';
|
|
14
15
|
import { SlashFactoryContract } from '@aztec/stdlib/l1-contracts';
|
|
15
16
|
|
|
16
17
|
import { EmpireSlasherClient, type EmpireSlasherSettings } from '../empire_slasher_client.js';
|
|
@@ -31,19 +32,40 @@ export async function createSlasherImplementation(
|
|
|
31
32
|
epochCache: EpochCache,
|
|
32
33
|
dateProvider: DateProvider,
|
|
33
34
|
kvStore: AztecLMDBStoreV2,
|
|
35
|
+
rollupRegisteredAtL2Slot: SlotNumber,
|
|
34
36
|
logger = createLogger('slasher'),
|
|
35
37
|
) {
|
|
36
38
|
const proposer = await rollup.getSlashingProposer();
|
|
37
39
|
if (!proposer) {
|
|
38
40
|
return new NullSlasherClient(config);
|
|
39
41
|
} else if (proposer.type === 'tally') {
|
|
40
|
-
return createTallySlasher(
|
|
42
|
+
return createTallySlasher(
|
|
43
|
+
config,
|
|
44
|
+
rollup,
|
|
45
|
+
proposer,
|
|
46
|
+
watchers,
|
|
47
|
+
dateProvider,
|
|
48
|
+
epochCache,
|
|
49
|
+
kvStore,
|
|
50
|
+
rollupRegisteredAtL2Slot,
|
|
51
|
+
logger,
|
|
52
|
+
);
|
|
41
53
|
} else {
|
|
42
54
|
if (!slashFactoryAddress || slashFactoryAddress.equals(EthAddress.ZERO)) {
|
|
43
55
|
throw new Error('Cannot initialize an empire-based SlasherClient without a SlashFactory address');
|
|
44
56
|
}
|
|
45
57
|
const slashFactory = new SlashFactoryContract(l1Client, slashFactoryAddress.toString());
|
|
46
|
-
return createEmpireSlasher(
|
|
58
|
+
return createEmpireSlasher(
|
|
59
|
+
config,
|
|
60
|
+
rollup,
|
|
61
|
+
proposer,
|
|
62
|
+
slashFactory,
|
|
63
|
+
watchers,
|
|
64
|
+
dateProvider,
|
|
65
|
+
kvStore,
|
|
66
|
+
rollupRegisteredAtL2Slot,
|
|
67
|
+
logger,
|
|
68
|
+
);
|
|
47
69
|
}
|
|
48
70
|
}
|
|
49
71
|
|
|
@@ -55,6 +77,7 @@ async function createEmpireSlasher(
|
|
|
55
77
|
watchers: Watcher[],
|
|
56
78
|
dateProvider: DateProvider,
|
|
57
79
|
kvStore: AztecLMDBStoreV2,
|
|
80
|
+
rollupRegisteredAtL2Slot: SlotNumber,
|
|
58
81
|
logger = createLogger('slasher'),
|
|
59
82
|
): Promise<EmpireSlasherClient> {
|
|
60
83
|
if (slashingProposer.type !== 'empire') {
|
|
@@ -97,6 +120,7 @@ async function createEmpireSlasher(
|
|
|
97
120
|
l1StartBlock,
|
|
98
121
|
ethereumSlotDuration: config.ethereumSlotDuration,
|
|
99
122
|
slashingAmounts: undefined,
|
|
123
|
+
rollupRegisteredAtL2Slot,
|
|
100
124
|
};
|
|
101
125
|
|
|
102
126
|
const payloadsStore = new SlasherPayloadsStore(kvStore, {
|
|
@@ -130,13 +154,14 @@ async function createTallySlasher(
|
|
|
130
154
|
dateProvider: DateProvider,
|
|
131
155
|
epochCache: EpochCache,
|
|
132
156
|
kvStore: AztecLMDBStoreV2,
|
|
157
|
+
rollupRegisteredAtL2Slot: SlotNumber,
|
|
133
158
|
logger = createLogger('slasher'),
|
|
134
159
|
): Promise<TallySlasherClient> {
|
|
135
160
|
if (slashingProposer.type !== 'tally') {
|
|
136
161
|
throw new Error('Slashing proposer contract is not of type tally');
|
|
137
162
|
}
|
|
138
163
|
|
|
139
|
-
const settings = await getTallySlasherSettings(rollup, slashingProposer);
|
|
164
|
+
const settings = { ...(await getTallySlasherSettings(rollup, slashingProposer)), rollupRegisteredAtL2Slot };
|
|
140
165
|
const slasher = await rollup.getSlasherContract();
|
|
141
166
|
|
|
142
167
|
const offensesStore = new SlasherOffensesStore(kvStore, {
|
|
@@ -5,7 +5,7 @@ import type { TallySlasherSettings } from '../tally_slasher_client.js';
|
|
|
5
5
|
export async function getTallySlasherSettings(
|
|
6
6
|
rollup: RollupContract,
|
|
7
7
|
slashingProposer?: TallySlashingProposerContract,
|
|
8
|
-
): Promise<TallySlasherSettings
|
|
8
|
+
): Promise<Omit<TallySlasherSettings, 'rollupRegisteredAtL2Slot'>> {
|
|
9
9
|
if (!slashingProposer) {
|
|
10
10
|
const rollupSlashingProposer = await rollup.getSlashingProposer();
|
|
11
11
|
if (!rollupSlashingProposer || rollupSlashingProposer.type !== 'tally') {
|
|
@@ -40,7 +40,7 @@ export async function getTallySlasherSettings(
|
|
|
40
40
|
rollup.getTargetCommitteeSize(),
|
|
41
41
|
]);
|
|
42
42
|
|
|
43
|
-
const settings: TallySlasherSettings = {
|
|
43
|
+
const settings: Omit<TallySlasherSettings, 'rollupRegisteredAtL2Slot'> = {
|
|
44
44
|
slashingExecutionDelayInRounds: Number(slashingExecutionDelayInRounds),
|
|
45
45
|
slashingRoundSize: Number(slashingRoundSize),
|
|
46
46
|
slashingRoundSizeInEpochs: Number(slashingRoundSizeInEpochs),
|
|
@@ -6,7 +6,7 @@ export const slasherDefaultEnv = {
|
|
|
6
6
|
SLASH_MIN_PENALTY_PERCENTAGE: 0.5,
|
|
7
7
|
SLASH_MAX_PENALTY_PERCENTAGE: 2,
|
|
8
8
|
SLASH_OFFENSE_EXPIRATION_ROUNDS: 4,
|
|
9
|
-
SLASH_MAX_PAYLOAD_SIZE:
|
|
9
|
+
SLASH_MAX_PAYLOAD_SIZE: 80,
|
|
10
10
|
SLASH_EXECUTE_ROUNDS_LOOK_BACK: 4,
|
|
11
11
|
SLASH_PRUNE_PENALTY: 10000000000000000000,
|
|
12
12
|
SLASH_DATA_WITHHOLDING_PENALTY: 10000000000000000000,
|
|
@@ -15,7 +15,8 @@ export const slasherDefaultEnv = {
|
|
|
15
15
|
SLASH_INACTIVITY_PENALTY: 10000000000000000000,
|
|
16
16
|
SLASH_PROPOSE_INVALID_ATTESTATIONS_PENALTY: 10000000000000000000,
|
|
17
17
|
SLASH_ATTEST_DESCENDANT_OF_INVALID_PENALTY: 10000000000000000000,
|
|
18
|
-
SLASH_DUPLICATE_PROPOSAL_PENALTY:
|
|
18
|
+
SLASH_DUPLICATE_PROPOSAL_PENALTY: 0,
|
|
19
|
+
SLASH_DUPLICATE_ATTESTATION_PENALTY: 0,
|
|
19
20
|
SLASH_UNKNOWN_PENALTY: 10000000000000000000,
|
|
20
21
|
SLASH_INVALID_BLOCK_PENALTY: 10000000000000000000,
|
|
21
22
|
SLASH_GRACE_PERIOD_L2_SLOTS: 0,
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { SlotNumber } from '@aztec/foundation/branded-types';
|
|
1
2
|
import { createLogger } from '@aztec/foundation/log';
|
|
2
3
|
import type { Prettify } from '@aztec/foundation/types';
|
|
3
4
|
import type { L1RollupConstants } from '@aztec/stdlib/epoch-helpers';
|
|
@@ -9,7 +10,11 @@ import { WANT_TO_SLASH_EVENT, type WantToSlashArgs, type Watcher } from './watch
|
|
|
9
10
|
|
|
10
11
|
export type SlashOffensesCollectorConfig = Prettify<Pick<SlasherConfig, 'slashGracePeriodL2Slots'>>;
|
|
11
12
|
export type SlashOffensesCollectorSettings = Prettify<
|
|
12
|
-
Pick<L1RollupConstants, 'epochDuration'> & {
|
|
13
|
+
Pick<L1RollupConstants, 'epochDuration'> & {
|
|
14
|
+
slashingAmounts: [bigint, bigint, bigint] | undefined;
|
|
15
|
+
/** L2 slot at which the rollup was registered as canonical in the Registry. Used to anchor the slash grace period. */
|
|
16
|
+
rollupRegisteredAtL2Slot: SlotNumber;
|
|
17
|
+
}
|
|
13
18
|
>;
|
|
14
19
|
|
|
15
20
|
/**
|
|
@@ -85,11 +90,7 @@ export class SlashOffensesCollector {
|
|
|
85
90
|
}
|
|
86
91
|
}
|
|
87
92
|
|
|
88
|
-
this.log.info(`Adding pending offense for validator ${arg.validator}`,
|
|
89
|
-
...pendingOffense,
|
|
90
|
-
epochOrSlot: pendingOffense.epochOrSlot.toString(),
|
|
91
|
-
amount: pendingOffense.amount.toString(),
|
|
92
|
-
});
|
|
93
|
+
this.log.info(`Adding pending offense for validator ${arg.validator}`, pendingOffense);
|
|
93
94
|
await this.offensesStore.addPendingOffense(pendingOffense);
|
|
94
95
|
}
|
|
95
96
|
}
|
|
@@ -114,9 +115,9 @@ export class SlashOffensesCollector {
|
|
|
114
115
|
return this.offensesStore.markAsSlashed(offenses);
|
|
115
116
|
}
|
|
116
117
|
|
|
117
|
-
/** Returns whether to skip an offense if it happened during the grace period
|
|
118
|
+
/** Returns whether to skip an offense if it happened during the grace period after the network upgrade */
|
|
118
119
|
private shouldSkipOffense(offense: Offense): boolean {
|
|
119
120
|
const offenseSlot = getSlotForOffense(offense, this.settings);
|
|
120
|
-
return offenseSlot < this.config.slashGracePeriodL2Slots;
|
|
121
|
+
return offenseSlot < this.settings.rollupRegisteredAtL2Slot + this.config.slashGracePeriodL2Slots;
|
|
121
122
|
}
|
|
122
123
|
}
|
|
@@ -5,9 +5,9 @@ import type { SlotNumber } from '@aztec/foundation/branded-types';
|
|
|
5
5
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
6
6
|
import { createLogger } from '@aztec/foundation/log';
|
|
7
7
|
import { DateProvider } from '@aztec/foundation/timer';
|
|
8
|
-
import type { DataStoreConfig } from '@aztec/kv-store/config';
|
|
9
8
|
import { AztecLMDBStoreV2 } from '@aztec/kv-store/lmdb-v2';
|
|
10
9
|
import type { SlasherConfig } from '@aztec/stdlib/interfaces/server';
|
|
10
|
+
import type { DataStoreConfig } from '@aztec/stdlib/kv-store';
|
|
11
11
|
import type { Offense, ProposerSlashAction, SlashPayloadRound } from '@aztec/stdlib/slashing';
|
|
12
12
|
|
|
13
13
|
import { createSlasherImplementation } from './factory/create_implementation.js';
|
|
@@ -32,6 +32,7 @@ export class SlasherClientFacade implements SlasherClientInterface {
|
|
|
32
32
|
private epochCache: EpochCache,
|
|
33
33
|
private dateProvider: DateProvider,
|
|
34
34
|
private kvStore: AztecLMDBStoreV2,
|
|
35
|
+
private rollupRegisteredAtL2Slot: SlotNumber,
|
|
35
36
|
private logger = createLogger('slasher'),
|
|
36
37
|
) {}
|
|
37
38
|
|
|
@@ -88,6 +89,7 @@ export class SlasherClientFacade implements SlasherClientInterface {
|
|
|
88
89
|
this.epochCache,
|
|
89
90
|
this.dateProvider,
|
|
90
91
|
this.kvStore,
|
|
92
|
+
this.rollupRegisteredAtL2Slot,
|
|
91
93
|
this.logger,
|
|
92
94
|
);
|
|
93
95
|
}
|
|
@@ -46,7 +46,10 @@ export type TallySlasherSettings = Prettify<
|
|
|
46
46
|
>;
|
|
47
47
|
|
|
48
48
|
export type TallySlasherClientConfig = SlashOffensesCollectorConfig &
|
|
49
|
-
Pick<
|
|
49
|
+
Pick<
|
|
50
|
+
SlasherConfig,
|
|
51
|
+
'slashValidatorsAlways' | 'slashValidatorsNever' | 'slashExecuteRoundsLookBack' | 'slashMaxPayloadSize'
|
|
52
|
+
>;
|
|
50
53
|
|
|
51
54
|
/**
|
|
52
55
|
* The Tally Slasher client is responsible for managing slashable offenses using
|
|
@@ -349,24 +352,22 @@ export class TallySlasherClient implements ProposerSlashActionProvider, SlasherC
|
|
|
349
352
|
return undefined;
|
|
350
353
|
}
|
|
351
354
|
|
|
352
|
-
const offensesToSlashLog = offensesToSlash.map(offense => ({
|
|
353
|
-
...offense,
|
|
354
|
-
amount: offense.amount.toString(),
|
|
355
|
-
}));
|
|
356
355
|
this.log.info(`Voting to slash ${offensesToSlash.length} offenses`, {
|
|
357
356
|
slotNumber,
|
|
358
357
|
currentRound,
|
|
359
358
|
slashedRound,
|
|
360
|
-
offensesToSlash
|
|
359
|
+
offensesToSlash,
|
|
361
360
|
});
|
|
362
361
|
|
|
363
362
|
const committees = await this.collectCommitteesActiveDuringRound(slashedRound);
|
|
364
363
|
const epochsForCommittees = getEpochsForRound(slashedRound, this.settings);
|
|
364
|
+
const { slashMaxPayloadSize } = this.config;
|
|
365
365
|
const votes = getSlashConsensusVotesFromOffenses(
|
|
366
366
|
offensesToSlash,
|
|
367
367
|
committees,
|
|
368
368
|
epochsForCommittees.map(e => BigInt(e)),
|
|
369
|
-
this.settings,
|
|
369
|
+
{ ...this.settings, maxSlashedValidators: slashMaxPayloadSize },
|
|
370
|
+
this.log,
|
|
370
371
|
);
|
|
371
372
|
if (votes.every(v => v === 0)) {
|
|
372
373
|
this.log.warn(`Computed votes for offenses are all zero. Skipping vote.`, {
|
|
@@ -132,9 +132,9 @@ export class EpochPruneWatcher extends (EventEmitter as new () => WatcherEmitter
|
|
|
132
132
|
const blocksByCheckpoint = chunkBy(sortedBlocks, b => b.checkpointNumber);
|
|
133
133
|
|
|
134
134
|
// Get prior checkpoints in the epoch (in case this was a partial prune) to extract the out hashes
|
|
135
|
-
const priorCheckpointOutHashes = (await this.l2BlockSource.
|
|
136
|
-
.filter(c => c.
|
|
137
|
-
.map(c => c.
|
|
135
|
+
const priorCheckpointOutHashes = (await this.l2BlockSource.getCheckpointsDataForEpoch(epochNumber))
|
|
136
|
+
.filter(c => c.checkpointNumber < sortedBlocks[0].checkpointNumber)
|
|
137
|
+
.map(c => c.checkpointOutHash);
|
|
138
138
|
let previousCheckpointOutHashes: Fr[] = [...priorCheckpointOutHashes];
|
|
139
139
|
|
|
140
140
|
const fork = await this.checkpointsBuilder.getFork(
|
|
@@ -172,6 +172,7 @@ export class EpochPruneWatcher extends (EventEmitter as new () => WatcherEmitter
|
|
|
172
172
|
chainId: gv.chainId,
|
|
173
173
|
version: gv.version,
|
|
174
174
|
slotNumber: gv.slotNumber,
|
|
175
|
+
timestamp: gv.timestamp,
|
|
175
176
|
coinbase: gv.coinbase,
|
|
176
177
|
feeRecipient: gv.feeRecipient,
|
|
177
178
|
gasFees: gv.gasFees,
|
|
@@ -181,6 +182,7 @@ export class EpochPruneWatcher extends (EventEmitter as new () => WatcherEmitter
|
|
|
181
182
|
const checkpointBuilder = await this.checkpointsBuilder.startCheckpoint(
|
|
182
183
|
checkpointNumber,
|
|
183
184
|
constants,
|
|
185
|
+
0n, // feeAssetPriceModifier is not used for validation of the checkpoint content
|
|
184
186
|
l1ToL2Messages,
|
|
185
187
|
previousCheckpointOutHashes,
|
|
186
188
|
fork,
|
|
@@ -209,7 +211,10 @@ export class EpochPruneWatcher extends (EventEmitter as new () => WatcherEmitter
|
|
|
209
211
|
}
|
|
210
212
|
|
|
211
213
|
const gv = blockFromL1.header.globalVariables;
|
|
212
|
-
const { block, failedTxs, numTxs } = await checkpointBuilder.buildBlock(txs, gv.blockNumber, gv.timestamp, {
|
|
214
|
+
const { block, failedTxs, numTxs } = await checkpointBuilder.buildBlock(txs, gv.blockNumber, gv.timestamp, {
|
|
215
|
+
isBuildingProposal: false,
|
|
216
|
+
minValidTxs: 0,
|
|
217
|
+
});
|
|
213
218
|
|
|
214
219
|
if (numTxs !== txs.length) {
|
|
215
220
|
// This should be detected by state mismatch, but this makes it easier to debug.
|