@aztec/slasher 0.0.1-commit.f295ac2 → 0.0.1-commit.f2ce05ee
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 +10 -3
- package/dest/config.d.ts +1 -1
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +6 -0
- package/dest/empire_slasher_client.d.ts +1 -1
- package/dest/empire_slasher_client.d.ts.map +1 -1
- package/dest/empire_slasher_client.js +0 -8
- package/dest/factory/create_facade.js +1 -1
- package/dest/generated/slasher-defaults.d.ts +2 -1
- package/dest/generated/slasher-defaults.d.ts.map +1 -1
- package/dest/generated/slasher-defaults.js +1 -0
- package/dest/slash_offenses_collector.d.ts +1 -1
- package/dest/slash_offenses_collector.d.ts.map +1 -1
- package/dest/slash_offenses_collector.js +5 -1
- package/dest/stores/offenses_store.d.ts +1 -1
- package/dest/stores/offenses_store.d.ts.map +1 -1
- package/dest/stores/offenses_store.js +4 -2
- package/dest/stores/payloads_store.d.ts +1 -1
- package/dest/stores/payloads_store.d.ts.map +1 -1
- package/dest/stores/payloads_store.js +6 -3
- package/dest/tally_slasher_client.d.ts +1 -1
- package/dest/tally_slasher_client.d.ts.map +1 -1
- package/dest/tally_slasher_client.js +10 -5
- package/dest/watchers/epoch_prune_watcher.d.ts +7 -6
- package/dest/watchers/epoch_prune_watcher.d.ts.map +1 -1
- package/dest/watchers/epoch_prune_watcher.js +42 -25
- package/package.json +9 -9
- package/src/config.ts +6 -0
- package/src/empire_slasher_client.ts +0 -8
- package/src/factory/create_facade.ts +1 -1
- package/src/generated/slasher-defaults.ts +1 -0
- package/src/slash_offenses_collector.ts +5 -1
- package/src/stores/offenses_store.ts +4 -2
- package/src/stores/payloads_store.ts +7 -4
- package/src/tally_slasher_client.ts +10 -5
- package/src/watchers/epoch_prune_watcher.ts +58 -27
package/README.md
CHANGED
|
@@ -137,9 +137,15 @@ List of all slashable offenses in the system:
|
|
|
137
137
|
**Time Unit**: Slot-based offense.
|
|
138
138
|
|
|
139
139
|
### ATTESTED_DESCENDANT_OF_INVALID
|
|
140
|
-
**Description**: A committee member attested to a block built on top of an invalid ancestor.
|
|
141
|
-
**Detection**: AttestationsBlockWatcher tracks invalid blocks and their descendants.
|
|
142
|
-
**Target**: Committee members who attested to the descendant block.
|
|
140
|
+
**Description**: A committee member attested to a block built on top of an invalid ancestor.
|
|
141
|
+
**Detection**: AttestationsBlockWatcher tracks invalid blocks and their descendants.
|
|
142
|
+
**Target**: Committee members who attested to the descendant block.
|
|
143
|
+
**Time Unit**: Slot-based offense.
|
|
144
|
+
|
|
145
|
+
### DUPLICATE_PROPOSAL
|
|
146
|
+
**Description**: A proposer sent multiple block or checkpoint proposals for the same position (slot and indexWithinCheckpoint for blocks, or slot for checkpoints) with different content. Since each slot has exactly one designated proposer, sending conflicting proposals is equivocation.
|
|
147
|
+
**Detection**: Detected in the P2P layer when proposals are received. The AttestationPool tracks proposals by position; when a second proposal arrives for the same position with a different archive, it flags the duplicate. The first duplicate is propagated (Accept) so other validators can witness the offense.
|
|
148
|
+
**Target**: Proposer who broadcast the duplicate proposal.
|
|
143
149
|
**Time Unit**: Slot-based offense.
|
|
144
150
|
|
|
145
151
|
## Configuration
|
|
@@ -175,6 +181,7 @@ These settings are configured locally on each validator node:
|
|
|
175
181
|
- `slashDataWithholdingPenalty`: Penalty for DATA_WITHHOLDING
|
|
176
182
|
- `slashInactivityPenalty`: Penalty for INACTIVITY
|
|
177
183
|
- `slashBroadcastedInvalidBlockPenalty`: Penalty for BROADCASTED_INVALID_BLOCK_PROPOSAL
|
|
184
|
+
- `slashDuplicateProposalPenalty`: Penalty for DUPLICATE_PROPOSAL
|
|
178
185
|
- `slashProposeInvalidAttestationsPenalty`: Penalty for PROPOSED_INSUFFICIENT_ATTESTATIONS and PROPOSED_INCORRECT_ATTESTATIONS
|
|
179
186
|
- `slashAttestDescendantOfInvalidPenalty`: Penalty for ATTESTED_DESCENDANT_OF_INVALID
|
|
180
187
|
- `slashUnknownPenalty`: Default penalty for unknown offense types
|
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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uZmlnLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvY29uZmlnLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFRbkUsT0FBTyxLQUFLLEVBQUUsYUFBYSxFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFJckUsWUFBWSxFQUFFLGFBQWEsRUFBRSxDQUFDO0FBRTlCLGVBQU8sTUFBTSxvQkFBb0IsRUFBRSxhQXFCbEMsQ0FBQztBQUVGLGVBQU8sTUFBTSxxQkFBcUIsRUFBRSxrQkFBa0IsQ0FBQyxhQUFhLENBOEhuRSxDQUFDIn0=
|
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,aAqBlC,CAAC;AAEF,eAAO,MAAM,qBAAqB,EAAE,kBAAkB,CAAC,aAAa,CA8HnE,CAAC"}
|
package/dest/config.js
CHANGED
|
@@ -12,6 +12,7 @@ export const DefaultSlasherConfig = {
|
|
|
12
12
|
slashInactivityTargetPercentage: slasherDefaultEnv.SLASH_INACTIVITY_TARGET_PERCENTAGE,
|
|
13
13
|
slashInactivityConsecutiveEpochThreshold: slasherDefaultEnv.SLASH_INACTIVITY_CONSECUTIVE_EPOCH_THRESHOLD,
|
|
14
14
|
slashBroadcastedInvalidBlockPenalty: BigInt(slasherDefaultEnv.SLASH_INVALID_BLOCK_PENALTY),
|
|
15
|
+
slashDuplicateProposalPenalty: BigInt(slasherDefaultEnv.SLASH_DUPLICATE_PROPOSAL_PENALTY),
|
|
15
16
|
slashInactivityPenalty: BigInt(slasherDefaultEnv.SLASH_INACTIVITY_PENALTY),
|
|
16
17
|
slashProposeInvalidAttestationsPenalty: BigInt(slasherDefaultEnv.SLASH_PROPOSE_INVALID_ATTESTATIONS_PENALTY),
|
|
17
18
|
slashAttestDescendantOfInvalidPenalty: BigInt(slasherDefaultEnv.SLASH_ATTEST_DESCENDANT_OF_INVALID_PENALTY),
|
|
@@ -66,6 +67,11 @@ export const slasherConfigMappings = {
|
|
|
66
67
|
description: 'Penalty amount for slashing a validator for an invalid block proposed via p2p.',
|
|
67
68
|
...bigintConfigHelper(DefaultSlasherConfig.slashBroadcastedInvalidBlockPenalty)
|
|
68
69
|
},
|
|
70
|
+
slashDuplicateProposalPenalty: {
|
|
71
|
+
env: 'SLASH_DUPLICATE_PROPOSAL_PENALTY',
|
|
72
|
+
description: 'Penalty amount for slashing a validator for sending duplicate proposals.',
|
|
73
|
+
...bigintConfigHelper(DefaultSlasherConfig.slashDuplicateProposalPenalty)
|
|
74
|
+
},
|
|
69
75
|
slashInactivityTargetPercentage: {
|
|
70
76
|
env: 'SLASH_INACTIVITY_TARGET_PERCENTAGE',
|
|
71
77
|
description: 'Missed attestation percentage to trigger creation of inactivity slash payload (0, 1]. Must be greater than 0',
|
|
@@ -187,4 +187,4 @@ export declare class EmpireSlasherClient implements ProposerSlashActionProvider,
|
|
|
187
187
|
/** Get maximum acceptable amount for an offense type */
|
|
188
188
|
private getMaxAmountForOffense;
|
|
189
189
|
}
|
|
190
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
190
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW1waXJlX3NsYXNoZXJfY2xpZW50LmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvZW1waXJlX3NsYXNoZXJfY2xpZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSw4QkFBOEIsRUFBRSxjQUFjLEVBQUUsZUFBZSxFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFFNUcsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBRTdELE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUUzRCxPQUFPLEtBQUssRUFBRSxZQUFZLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUM1RCxPQUFPLEtBQUssRUFBRSxpQkFBaUIsRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBQ3JFLE9BQU8sS0FBSyxFQUFFLGFBQWEsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBQ3JFLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQ2xFLE9BQU8sRUFDTCxLQUFLLE9BQU8sRUFHWixLQUFLLG1CQUFtQixFQUN4QixLQUFLLDJCQUEyQixFQUNoQyxLQUFLLFlBQVksRUFDakIsS0FBSyxpQkFBaUIsRUFRdkIsTUFBTSx3QkFBd0IsQ0FBQztBQUVoQyxPQUFPLEVBQTBCLEtBQUssOEJBQThCLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUU1RyxPQUFPLEtBQUssRUFBRSxzQkFBc0IsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBQzVFLE9BQU8sS0FBSyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDdkUsT0FBTyxLQUFLLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUN2RSxPQUFPLEtBQUssRUFBRSxPQUFPLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFFNUMsdURBQXVEO0FBQ3ZELE1BQU0sTUFBTSxnQkFBZ0IsR0FBRztJQUM3QixPQUFPLEVBQUUsVUFB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
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"empire_slasher_client.d.ts","sourceRoot":"","sources":["../src/empire_slasher_client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,8BAA8B,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAE5G,OAAO,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAE7D,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;
|
|
1
|
+
{"version":3,"file":"empire_slasher_client.d.ts","sourceRoot":"","sources":["../src/empire_slasher_client.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,7 +2,6 @@ import { sumBigint } from '@aztec/foundation/bigint';
|
|
|
2
2
|
import { compactArray, filterAsync, maxBy, pick } from '@aztec/foundation/collection';
|
|
3
3
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
4
4
|
import { createLogger } from '@aztec/foundation/log';
|
|
5
|
-
import { sleep } from '@aztec/foundation/sleep';
|
|
6
5
|
import { getFirstEligibleRoundForOffense, getOffenseIdentifiersFromPayload, getPenaltyForOffense, isOffenseUncontroversial, offenseDataComparator, offensesToValidatorSlash } from '@aztec/stdlib/slashing';
|
|
7
6
|
import { SlashOffensesCollector } from './slash_offenses_collector.js';
|
|
8
7
|
import { SlashRoundMonitor } from './slash_round_monitor.js';
|
|
@@ -130,13 +129,6 @@ import { SlashRoundMonitor } from './slash_round_monitor.js';
|
|
|
130
129
|
}
|
|
131
130
|
this.roundMonitor.stop();
|
|
132
131
|
await this.offensesCollector.stop();
|
|
133
|
-
// Viem calls eth_uninstallFilter under the hood when uninstalling event watchers, but these calls are not awaited,
|
|
134
|
-
// meaning that any error that happens during the uninstallation will not be caught. This causes errors during jest teardowns,
|
|
135
|
-
// where we stop anvil after all other processes are stopped, so sometimes the eth_uninstallFilter call fails because anvil
|
|
136
|
-
// is already stopped. We add a sleep here to give the uninstallation some time to complete, but the proper fix is for
|
|
137
|
-
// viem to await the eth_uninstallFilter calls, or to catch any errors that happen during the uninstallation.
|
|
138
|
-
// See https://github.com/wevm/viem/issues/3714.
|
|
139
|
-
await sleep(2000);
|
|
140
132
|
this.log.info('Empire Slasher client stopped');
|
|
141
133
|
}
|
|
142
134
|
/** Returns the current config */ getConfig() {
|
|
@@ -9,7 +9,7 @@ import { SCHEMA_VERSION } from '../stores/schema_version.js';
|
|
|
9
9
|
if (!l1Contracts.rollupAddress || l1Contracts.rollupAddress.equals(EthAddress.ZERO)) {
|
|
10
10
|
throw new Error('Cannot initialize SlasherClient without a Rollup address');
|
|
11
11
|
}
|
|
12
|
-
const kvStore = await createStore('slasher', SCHEMA_VERSION, config,
|
|
12
|
+
const kvStore = await createStore('slasher', SCHEMA_VERSION, config, logger.getBindings());
|
|
13
13
|
const rollup = new RollupContract(l1Client, l1Contracts.rollupAddress);
|
|
14
14
|
const slashValidatorsNever = config.slashSelfAllowed ? config.slashValidatorsNever : unique([
|
|
15
15
|
...config.slashValidatorsNever,
|
|
@@ -12,8 +12,9 @@ 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: 10000000000000000000;
|
|
15
16
|
readonly SLASH_UNKNOWN_PENALTY: 10000000000000000000;
|
|
16
17
|
readonly SLASH_INVALID_BLOCK_PENALTY: 10000000000000000000;
|
|
17
18
|
readonly SLASH_GRACE_PERIOD_L2_SLOTS: 0;
|
|
18
19
|
};
|
|
19
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
20
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2xhc2hlci1kZWZhdWx0cy5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2dlbmVyYXRlZC9zbGFzaGVyLWRlZmF1bHRzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUdBLHFFQUFxRTtBQUNyRSxlQUFPLE1BQU0saUJBQWlCOzs7Ozs7Ozs7Ozs7Ozs7OztDQWlCcEIsQ0FBQyJ9
|
|
@@ -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;;;;;;;;;;;;;;;;;CAiBpB,CAAC"}
|
|
@@ -13,6 +13,7 @@
|
|
|
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: 10000000000000000000,
|
|
16
17
|
SLASH_UNKNOWN_PENALTY: 10000000000000000000,
|
|
17
18
|
SLASH_INVALID_BLOCK_PENALTY: 10000000000000000000,
|
|
18
19
|
SLASH_GRACE_PERIOD_L2_SLOTS: 0
|
|
@@ -42,4 +42,4 @@ export declare class SlashOffensesCollector {
|
|
|
42
42
|
/** Returns whether to skip an offense if it happened during the grace period at the beginning of the chain */
|
|
43
43
|
private shouldSkipOffense;
|
|
44
44
|
}
|
|
45
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
45
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2xhc2hfb2ZmZW5zZXNfY29sbGVjdG9yLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvc2xhc2hfb2ZmZW5zZXNfY29sbGVjdG9yLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBLE9BQU8sS0FBSyxFQUFFLFFBQVEsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQ3hELE9BQU8sS0FBSyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFDckUsT0FBTyxLQUFLLEVBQUUsYUFBYSxFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFDckUsT0FBTyxFQUFnQixLQUFLLGlCQUFpQixFQUFxQixNQUFNLHdCQUF3QixDQUFDO0FBRWpHLE9BQU8sS0FBSyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDdkUsT0FBTyxFQUF1QixLQUFLLGVBQWUsRUFBRSxLQUFLLE9BQU8sRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUV2RixNQUFNLE1BQU0sNEJBQTRCLEdBQUcsUUFBUSxDQUFDLElBQUksQ0FBQyxhQUFhLEVBQUUseUJBQXlCLENBQUMsQ0FBQyxDQUFDO0FBQ3BHLE1BQU0sTUFBTSw4QkFBOEIsR0FBRyxRQUFRLENBQ25ELElBQUksQ0FBQyxpQkFBaUIsRUFBRSxlQUFlLENBQUMsR0FBRztJQUFFLGVBQWUsRUFBRSxDQUFDLE1BQU0sRUFBRSxNQUFNLEVBQUUsTUFBTSxDQUFDLEdBQUcsU0FBUyxDQUFBO0NBQUUsQ0FDckcsQ0FBQztBQUVGOzs7O0dBSUc7QUFDSCxxQkFBYSxzQkFBc0I7SUFJL0IsT0FBTyxDQUFDLFFBQVEsQ0FBQyxNQUFNO0lBQ3ZCLE9BQU8sQ0FBQyxRQUFRLENBQUMsUUFBUTtJQUN6QixPQUFPLENBQUMsUUFBUSxDQUFDLFFBQVE7SUFDekIsT0FBTyxDQUFDLFFBQVEsQ0FBQyxhQUFhO0lBQzlCLE9BQU8sQ0FBQyxRQUFRLENBQUMsR0FBRztJQVB0QixPQUFPLENBQUMsUUFBUSxDQUFDLGdCQUFnQixDQUFzQjtJQUV2RCxZQUNtQixNQUFNLEVBQUUsNEJBQTRCLEVBQ3BDLFFBQVEsRUFBRSw4QkFBOEIsRUFDeEMsUUFBUSxFQUFFLE9BQU8sRUFBRSxFQUNuQixhQUFhLEVBQUUsb0JBQW9CLEVBQ25DLEdBQUcseUNBQTZDLEVBQy9EO0lBRUcsS0FBSyxrQkFhWDtJQUVNLElBQUksa0JBU1Y7SUFFRDs7OztPQUlHO0lBQ1UsaUJBQWlCLENBQUMsSUFBSSxFQUFFLGVBQWUsRUFBRSxpQkFpQ3JEO0lBRUQ7OztPQUdHO0lBQ1UsY0FBYyxDQUFDLEtBQUssRUFBRSxNQUFNLGlCQUt4QztJQUVEOzs7T0FHRztJQUNJLGFBQWEsQ0FBQyxRQUFRLEVBQUUsaUJBQWlCLEVBQUUsaUJBR2pEO0lBRUQsOEdBQThHO0lBQzlHLE9BQU8sQ0FBQyxpQkFBaUI7Q0FJMUIifQ==
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"slash_offenses_collector.d.ts","sourceRoot":"","sources":["../src/slash_offenses_collector.ts"],"names":[],"mappings":"AACA,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;IAAE,eAAe,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAAA;CAAE,CACrG,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,
|
|
1
|
+
{"version":3,"file":"slash_offenses_collector.d.ts","sourceRoot":"","sources":["../src/slash_offenses_collector.ts"],"names":[],"mappings":"AACA,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;IAAE,eAAe,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAAA;CAAE,CACrG,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,iBAiCrD;IAED;;;OAGG;IACU,cAAc,CAAC,KAAK,EAAE,MAAM,iBAKxC;IAED;;;OAGG;IACI,aAAa,CAAC,QAAQ,EAAE,iBAAiB,EAAE,iBAGjD;IAED,8GAA8G;IAC9G,OAAO,CAAC,iBAAiB;CAI1B"}
|
|
@@ -65,7 +65,11 @@ 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}`,
|
|
68
|
+
this.log.info(`Adding pending offense for validator ${arg.validator}`, {
|
|
69
|
+
...pendingOffense,
|
|
70
|
+
epochOrSlot: pendingOffense.epochOrSlot.toString(),
|
|
71
|
+
amount: pendingOffense.amount.toString()
|
|
72
|
+
});
|
|
69
73
|
await this.offensesStore.addPendingOffense(pendingOffense);
|
|
70
74
|
}
|
|
71
75
|
}
|
|
@@ -34,4 +34,4 @@ export declare class SlasherOffensesStore {
|
|
|
34
34
|
private getOffenseKey;
|
|
35
35
|
private getRoundKey;
|
|
36
36
|
}
|
|
37
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
37
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib2ZmZW5zZXNfc3RvcmUuZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zdG9yZXMvb2ZmZW5zZXNfc3RvcmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxLQUFLLEVBQUUsaUJBQWlCLEVBQW9ELE1BQU0saUJBQWlCLENBQUM7QUFDM0csT0FBTyxFQUNMLEtBQUssT0FBTyxFQUNaLEtBQUssaUJBQWlCLEVBSXZCLE1BQU0sd0JBQXdCLENBQUM7QUFFaEMsZUFBTyxNQUFNLGNBQWMsSUFBSSxDQUFDO0FBRWhDLHFCQUFhLG9CQUFvQjtJQWE3QixPQUFPLENBQUMsT0FBTztJQUNmLE9BQU8sQ0FBQyxRQUFRO0lBYmxCLDJDQUEyQztJQUMzQyxPQUFPLENBQUMsUUFBUSxDQUFnQztJQUVoRCwwR0FBMEc7SUFDMUcsT0FBTyxDQUFDLGVBQWUsQ0FBd0I7SUFFL0MsbUZBQW1GO0lBQ25GLE9BQU8sQ0FBQyxjQUFjLENBQXFDO0lBRTNELE9BQU8sQ0FBQyxHQUFHLENBQTBDO0lBRXJELFlBQ1UsT0FBTyxFQUFFLGlCQUFpQixFQUMxQixRQUFRLEVBQUU7UUFDaEIsaUJBQWlCLEVBQUUsTUFBTSxDQUFDO1FBQzFCLGFBQWEsRUFBRSxNQUFNLENBQUM7UUFDdEIsNEJBQTRCLENBQUMsRUFBRSxNQUFNLENBQUM7S0FDdkMsRUFLRjtJQUVELGlEQUFpRDtJQUNwQyxrQkFBa0IsSUFBSSxPQUFPLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FVcEQ7SUFFRCx1REFBdUQ7SUFDMUMsbUJBQW1CLENBQUMsS0FBSyxFQUFFLE1BQU0sR0FBRyxPQUFPLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FVbEU7SUFFRCx1RUFBdUU7SUFDMUQsaUJBQWlCLENBQUMsT0FBTyxFQUFFLGlCQUFpQixHQUFHLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FHM0U7SUFFRCxnREFBZ0Q7SUFDbkMsVUFBVSxDQUFDLE9BQU8sRUFBRSxpQkFBaUIsR0FBRyxPQUFPLENBQUMsT0FBTyxDQUFDLENBR3BFO0lBRUQsNEdBQTRHO0lBQy9GLGlCQUFpQixDQUFDLE9BQU8sRUFBRSxPQUFPLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQyxDQVE5RDtJQUVELHlGQUF5RjtJQUM1RSxhQUFhLENBQUMsUUFBUSxFQUFFLGlCQUFpQixFQUFFLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQyxDQU92RTtJQUVELGlEQUFpRDtJQUNwQyxvQkFBb0IsQ0FBQyxZQUFZLEVBQUUsTUFBTSxHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0F1Q3ZFO0lBRUQsMkNBQTJDO0lBQzNDLE9BQU8sQ0FBQyxhQUFhO0lBSXJCLE9BQU8sQ0FBQyxXQUFXO0NBR3BCIn0=
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"offenses_store.d.ts","sourceRoot":"","sources":["../../src/stores/offenses_store.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAoD,MAAM,iBAAiB,CAAC;AAC3G,OAAO,EACL,KAAK,OAAO,EACZ,KAAK,iBAAiB,EAIvB,MAAM,wBAAwB,CAAC;AAEhC,eAAO,MAAM,cAAc,IAAI,CAAC;AAEhC,qBAAa,oBAAoB;IAa7B,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,QAAQ;IAblB,2CAA2C;IAC3C,OAAO,CAAC,QAAQ,CAAgC;IAEhD,0GAA0G;IAC1G,OAAO,CAAC,eAAe,CAAwB;IAE/C,mFAAmF;IACnF,OAAO,CAAC,cAAc,CAAqC;IAE3D,OAAO,CAAC,GAAG,CAA0C;IAErD,YACU,OAAO,EAAE,iBAAiB,EAC1B,QAAQ,EAAE;QAChB,iBAAiB,EAAE,MAAM,CAAC;QAC1B,aAAa,EAAE,MAAM,CAAC;QACtB,4BAA4B,CAAC,EAAE,MAAM,CAAC;KACvC,EAKF;IAED,iDAAiD;IACpC,kBAAkB,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC,CAUpD;IAED,uDAAuD;IAC1C,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAUlE;IAED,uEAAuE;IAC1D,iBAAiB,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,OAAO,CAAC,CAG3E;IAED,gDAAgD;IACnC,UAAU,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,OAAO,CAAC,CAGpE;IAED,4GAA4G;IAC/F,iBAAiB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"offenses_store.d.ts","sourceRoot":"","sources":["../../src/stores/offenses_store.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAoD,MAAM,iBAAiB,CAAC;AAC3G,OAAO,EACL,KAAK,OAAO,EACZ,KAAK,iBAAiB,EAIvB,MAAM,wBAAwB,CAAC;AAEhC,eAAO,MAAM,cAAc,IAAI,CAAC;AAEhC,qBAAa,oBAAoB;IAa7B,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,QAAQ;IAblB,2CAA2C;IAC3C,OAAO,CAAC,QAAQ,CAAgC;IAEhD,0GAA0G;IAC1G,OAAO,CAAC,eAAe,CAAwB;IAE/C,mFAAmF;IACnF,OAAO,CAAC,cAAc,CAAqC;IAE3D,OAAO,CAAC,GAAG,CAA0C;IAErD,YACU,OAAO,EAAE,iBAAiB,EAC1B,QAAQ,EAAE;QAChB,iBAAiB,EAAE,MAAM,CAAC;QAC1B,aAAa,EAAE,MAAM,CAAC;QACtB,4BAA4B,CAAC,EAAE,MAAM,CAAC;KACvC,EAKF;IAED,iDAAiD;IACpC,kBAAkB,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC,CAUpD;IAED,uDAAuD;IAC1C,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAUlE;IAED,uEAAuE;IAC1D,iBAAiB,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,OAAO,CAAC,CAG3E;IAED,gDAAgD;IACnC,UAAU,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,OAAO,CAAC,CAGpE;IAED,4GAA4G;IAC/F,iBAAiB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAQ9D;IAED,yFAAyF;IAC5E,aAAa,CAAC,QAAQ,EAAE,iBAAiB,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAOvE;IAED,iDAAiD;IACpC,oBAAoB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAuCvE;IAED,2CAA2C;IAC3C,OAAO,CAAC,aAAa;IAIrB,OAAO,CAAC,WAAW;CAGpB"}
|
|
@@ -48,9 +48,11 @@ export class SlasherOffensesStore {
|
|
|
48
48
|
}
|
|
49
49
|
/** Adds a new offense (defaults to pending, but will be slashed if markAsSlashed had been called for it) */ async addPendingOffense(offense) {
|
|
50
50
|
const key = this.getOffenseKey(offense);
|
|
51
|
-
await this.offenses.set(key, serializeOffense(offense));
|
|
52
51
|
const round = getRoundForOffense(offense, this.settings);
|
|
53
|
-
await this.
|
|
52
|
+
await this.kvStore.transactionAsync(async ()=>{
|
|
53
|
+
await this.offenses.set(key, serializeOffense(offense));
|
|
54
|
+
await this.roundsOffenses.set(this.getRoundKey(round), key);
|
|
55
|
+
});
|
|
54
56
|
this.log.trace(`Adding pending offense ${key} for round ${round}`);
|
|
55
57
|
}
|
|
56
58
|
/** Marks the given offenses as slashed (regardless of whether they are known or not) */ async markAsSlashed(offenses) {
|
|
@@ -26,4 +26,4 @@ export declare class SlasherPayloadsStore {
|
|
|
26
26
|
getPayload(payloadAddress: EthAddress | string): Promise<SlashPayload | undefined>;
|
|
27
27
|
hasPayload(payload: EthAddress): Promise<boolean>;
|
|
28
28
|
}
|
|
29
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
29
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGF5bG9hZHNfc3RvcmUuZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zdG9yZXMvcGF5bG9hZHNfc3RvcmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBQzNELE9BQU8sS0FBSyxFQUFFLGlCQUFpQixFQUFpQixNQUFNLGlCQUFpQixDQUFDO0FBQ3hFLE9BQU8sRUFDTCxLQUFLLFlBQVksRUFDakIsS0FBSyxpQkFBaUIsRUFHdkIsTUFBTSx3QkFBd0IsQ0FBQztBQUVoQyxxQkFBYSxvQkFBb0I7SUFRN0IsT0FBTyxDQUFDLE9BQU87SUFDZixPQUFPLENBQUMsUUFBUSxDQUFDO0lBUm5CLCtDQUErQztJQUMvQyxPQUFPLENBQUMsUUFBUSxDQUFnQztJQUVoRCx3Q0FBd0M7SUFDeEMsT0FBTyxDQUFDLGlCQUFpQixDQUFnQztJQUV6RCxZQUNVLE9BQU8sRUFBRSxpQkFBaUIsRUFDMUIsUUFBUSxDQUFDOztpQkFFaEIsRUFJRjtJQUVZLG1CQUFtQixDQUFDLEtBQUssRUFBRSxNQUFNLEdBQUcsT0FBTyxDQUFDLGlCQUFpQixFQUFFLENBQUMsQ0FVNUU7SUFFWSxpQkFBaUIsQ0FBQyxjQUFjLEVBQUUsVUFBVSxFQUFFLEtBQUssRUFBRSxNQUFNLEdBQUcsT0FBTyxDQUFDLGlCQUFpQixHQUFHLFNBQVMsQ0FBQyxDQVdoSDtZQUVhLGdCQUFnQjtJQVk5QixPQUFPLENBQUMsV0FBVztJQUluQixPQUFPLENBQUMsa0JBQWtCO0lBSTFCLE9BQU8sQ0FBQywrQkFBK0I7SUFNdkM7O09BRUc7SUFDVSxvQkFBb0IsQ0FBQyxZQUFZLEVBQUUsTUFBTSxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FvQ3JFO0lBRVkscUJBQXFCLENBQUMsY0FBYyxFQUFFLFVBQVUsRUFBRSxLQUFLLEVBQUUsTUFBTSxHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FTN0Y7SUFFWSxVQUFVLENBQUMsT0FBTyxFQUFFLGlCQUFpQixHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FPakU7SUFFWSxVQUFVLENBQUMsY0FBYyxFQUFFLFVBQVUsR0FBRyxNQUFNLEdBQUcsT0FBTyxDQUFDLFlBQVksR0FBRyxTQUFTLENBQUMsQ0FJOUY7SUFFWSxVQUFVLENBQUMsT0FBTyxFQUFFLFVBQVUsR0FBRyxPQUFPLENBQUMsT0FBTyxDQUFDLENBRzdEO0NBQ0YifQ==
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"payloads_store.d.ts","sourceRoot":"","sources":["../../src/stores/payloads_store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAC3D,OAAO,KAAK,EAAE,iBAAiB,EAAiB,MAAM,iBAAiB,CAAC;AACxE,OAAO,EACL,KAAK,YAAY,EACjB,KAAK,iBAAiB,EAGvB,MAAM,wBAAwB,CAAC;AAEhC,qBAAa,oBAAoB;IAQ7B,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,QAAQ,CAAC;IARnB,+CAA+C;IAC/C,OAAO,CAAC,QAAQ,CAAgC;IAEhD,wCAAwC;IACxC,OAAO,CAAC,iBAAiB,CAAgC;IAEzD,YACU,OAAO,EAAE,iBAAiB,EAC1B,QAAQ,CAAC;;iBAEhB,EAIF;IAEY,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAU5E;IAEY,iBAAiB,CAAC,cAAc,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,GAAG,SAAS,CAAC,CAWhH;YAEa,gBAAgB;IAY9B,OAAO,CAAC,WAAW;IAInB,OAAO,CAAC,kBAAkB;IAI1B,OAAO,CAAC,+BAA+B;IAMvC;;OAEG;IACU,oBAAoB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAoCrE;IAEY,qBAAqB,CAAC,cAAc,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,
|
|
1
|
+
{"version":3,"file":"payloads_store.d.ts","sourceRoot":"","sources":["../../src/stores/payloads_store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAC3D,OAAO,KAAK,EAAE,iBAAiB,EAAiB,MAAM,iBAAiB,CAAC;AACxE,OAAO,EACL,KAAK,YAAY,EACjB,KAAK,iBAAiB,EAGvB,MAAM,wBAAwB,CAAC;AAEhC,qBAAa,oBAAoB;IAQ7B,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,QAAQ,CAAC;IARnB,+CAA+C;IAC/C,OAAO,CAAC,QAAQ,CAAgC;IAEhD,wCAAwC;IACxC,OAAO,CAAC,iBAAiB,CAAgC;IAEzD,YACU,OAAO,EAAE,iBAAiB,EAC1B,QAAQ,CAAC;;iBAEhB,EAIF;IAEY,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAU5E;IAEY,iBAAiB,CAAC,cAAc,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,GAAG,SAAS,CAAC,CAWhH;YAEa,gBAAgB;IAY9B,OAAO,CAAC,WAAW;IAInB,OAAO,CAAC,kBAAkB;IAI1B,OAAO,CAAC,+BAA+B;IAMvC;;OAEG;IACU,oBAAoB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAoCrE;IAEY,qBAAqB,CAAC,cAAc,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAS7F;IAEY,UAAU,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAOjE;IAEY,UAAU,CAAC,cAAc,EAAE,UAAU,GAAG,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC,CAI9F;IAEY,UAAU,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,CAG7D;CACF"}
|
|
@@ -101,9 +101,12 @@ export class SlasherPayloadsStore {
|
|
|
101
101
|
}
|
|
102
102
|
async incrementPayloadVotes(payloadAddress, round) {
|
|
103
103
|
const key = this.getPayloadVotesKey(round, payloadAddress);
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
104
|
+
let newVotes;
|
|
105
|
+
await this.kvStore.transactionAsync(async ()=>{
|
|
106
|
+
const currentVotes = await this.roundPayloadVotes.getAsync(key) || 0n;
|
|
107
|
+
newVotes = currentVotes + 1n;
|
|
108
|
+
await this.roundPayloadVotes.set(key, newVotes);
|
|
109
|
+
});
|
|
107
110
|
return newVotes;
|
|
108
111
|
}
|
|
109
112
|
async addPayload(payload) {
|
|
@@ -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;
|
|
1
|
+
{"version":3,"file":"tally_slasher_client.d.ts","sourceRoot":"","sources":["../src/tally_slasher_client.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,7 +2,6 @@ import { EthAddress } from '@aztec/aztec.js/addresses';
|
|
|
2
2
|
import { maxBigint } from '@aztec/foundation/bigint';
|
|
3
3
|
import { compactArray, partition, times } from '@aztec/foundation/collection';
|
|
4
4
|
import { createLogger } from '@aztec/foundation/log';
|
|
5
|
-
import { sleep } from '@aztec/foundation/sleep';
|
|
6
5
|
import { OffenseType, getEpochsForRound, getSlashConsensusVotesFromOffenses } from '@aztec/stdlib/slashing';
|
|
7
6
|
import { SlashOffensesCollector } from './slash_offenses_collector.js';
|
|
8
7
|
import { SlashRoundMonitor } from './slash_round_monitor.js';
|
|
@@ -84,8 +83,6 @@ import { SlashRoundMonitor } from './slash_round_monitor.js';
|
|
|
84
83
|
}
|
|
85
84
|
this.roundMonitor.stop();
|
|
86
85
|
await this.offensesCollector.stop();
|
|
87
|
-
// Sleeping to sidestep viem issue with unwatching events
|
|
88
|
-
await sleep(2000);
|
|
89
86
|
this.log.info('Tally Slasher client stopped');
|
|
90
87
|
}
|
|
91
88
|
/** Returns the current config */ getConfig() {
|
|
@@ -210,8 +207,12 @@ import { SlashRoundMonitor } from './slash_round_monitor.js';
|
|
|
210
207
|
});
|
|
211
208
|
return undefined;
|
|
212
209
|
}
|
|
210
|
+
const slashActionsWithAmounts = slashActions.map((action)=>({
|
|
211
|
+
validator: action.validator.toString(),
|
|
212
|
+
slashAmount: action.slashAmount.toString()
|
|
213
|
+
}));
|
|
213
214
|
this.log.info(`Round ${executableRound} is ready to execute with ${slashActions.length} slashes`, {
|
|
214
|
-
slashActions,
|
|
215
|
+
slashActions: slashActionsWithAmounts,
|
|
215
216
|
payloadAddress: payload.address.toString(),
|
|
216
217
|
...logData
|
|
217
218
|
});
|
|
@@ -276,11 +277,15 @@ import { SlashRoundMonitor } from './slash_round_monitor.js';
|
|
|
276
277
|
});
|
|
277
278
|
return undefined;
|
|
278
279
|
}
|
|
280
|
+
const offensesToSlashLog = offensesToSlash.map((offense)=>({
|
|
281
|
+
...offense,
|
|
282
|
+
amount: offense.amount.toString()
|
|
283
|
+
}));
|
|
279
284
|
this.log.info(`Voting to slash ${offensesToSlash.length} offenses`, {
|
|
280
285
|
slotNumber,
|
|
281
286
|
currentRound,
|
|
282
287
|
slashedRound,
|
|
283
|
-
offensesToSlash
|
|
288
|
+
offensesToSlash: offensesToSlashLog
|
|
284
289
|
});
|
|
285
290
|
const committees = await this.collectCommitteesActiveDuringRound(slashedRound);
|
|
286
291
|
const epochsForCommittees = getEpochsForRound(slashedRound, this.settings);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { EpochCache } from '@aztec/epoch-cache';
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
4
|
-
import type { ICheckpointsBuilder, ITxProvider,
|
|
2
|
+
import { EpochNumber } from '@aztec/foundation/branded-types';
|
|
3
|
+
import { L2Block, type L2BlockSourceEventEmitter } from '@aztec/stdlib/block';
|
|
4
|
+
import type { ICheckpointsBuilder, ITxProvider, SlasherConfig } from '@aztec/stdlib/interfaces/server';
|
|
5
5
|
import { type L1ToL2MessageSource } from '@aztec/stdlib/messaging';
|
|
6
6
|
import { type Watcher, type WatcherEmitter } from '../watcher.js';
|
|
7
7
|
declare const EpochPruneWatcherPenaltiesConfigKeys: readonly ["slashPrunePenalty", "slashDataWithholdingPenalty"];
|
|
@@ -29,10 +29,11 @@ export declare class EpochPruneWatcher extends EpochPruneWatcher_base implements
|
|
|
29
29
|
private handlePruneL2Blocks;
|
|
30
30
|
private emitSlashForEpoch;
|
|
31
31
|
private processPruneL2Blocks;
|
|
32
|
-
validateBlocks(blocks:
|
|
33
|
-
|
|
32
|
+
validateBlocks(blocks: L2Block[], epochNumber: EpochNumber): Promise<void>;
|
|
33
|
+
private validateCheckpoint;
|
|
34
|
+
private validateBlockInCheckpoint;
|
|
34
35
|
private getValidatorsForEpoch;
|
|
35
36
|
private validatorsToSlashingArgs;
|
|
36
37
|
}
|
|
37
38
|
export {};
|
|
38
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
39
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXBvY2hfcHJ1bmVfd2F0Y2hlci5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3dhdGNoZXJzL2Vwb2NoX3BydW5lX3dhdGNoZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQ2hELE9BQU8sRUFBZSxXQUFXLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUkzRSxPQUFPLEVBRUwsT0FBTyxFQUNQLEtBQUsseUJBQXlCLEVBRy9CLE1BQU0scUJBQXFCLENBQUM7QUFFN0IsT0FBTyxLQUFLLEVBRVYsbUJBQW1CLEVBQ25CLFdBQVcsRUFFWCxhQUFhLEVBQ2QsTUFBTSxpQ0FBaUMsQ0FBQztBQUN6QyxPQUFPLEVBQUUsS0FBSyxtQkFBbUIsRUFBNEIsTUFBTSx5QkFBeUIsQ0FBQztBQVk3RixPQUFPLEVBQTZDLEtBQUssT0FBTyxFQUFFLEtBQUssY0FBYyxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBRTdHLFFBQUEsTUFBTSxvQ0FBb0MsK0RBQWdFLENBQUM7QUFFM0csS0FBSywwQkFBMEIsR0FBRyxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUMsT0FBTyxvQ0FBb0MsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7O0FBRTdHOzs7OztHQUtHO0FBQ0gscUJBQWEsaUJBQWtCLFNBQVEsc0JBQTJDLFlBQVcsT0FBTztJQVNoRyxPQUFPLENBQUMsYUFBYTtJQUNyQixPQUFPLENBQUMsbUJBQW1CO0lBQzNCLE9BQU8sQ0FBQyxVQUFVO0lBQ2xCLE9BQU8sQ0FBQyxVQUFVO0lBQ2xCLE9BQU8sQ0FBQyxrQkFBa0I7SUFaNUIsT0FBTyxDQUFDLEdBQUcsQ0FBK0M7SUFHMUQsT0FBTyxDQUFDLHdCQUF3QixDQUF1QztJQUV2RSxPQUFPLENBQUMsU0FBUyxDQUE2QjtJQUU5QyxZQUNVLGFBQWEsRUFBRSx5QkFBeUIsRUFDeEMsbUJBQW1CLEVBQUUsbUJBQW1CLEVBQ3hDLFVBQVUsRUFBRSxVQUFVLEVBQ3RCLFVBQVUsRUFBRSxJQUFJLENBQUMsV0FBVyxFQUFFLGlCQUFpQixDQUFDLEVBQ2hELGtCQUFrQixFQUFFLG1CQUFtQixFQUMvQyxTQUFTLEVBQUUsMEJBQTBCLEVBT3RDO0lBRU0sS0FBSyxrQkFHWDtJQUVNLElBQUksa0JBR1Y7SUFFTSxZQUFZLENBQUMsTUFBTSxFQUFFLE9BQU8sQ0FBQyxhQUFhLENBQUMsR0FBRyxJQUFJLENBR3hEO0lBRUQsT0FBTyxDQUFDLG1CQUFtQjtZQU9iLGlCQUFpQjtZQVdqQixvQkFBb0I7SUF3QnJCLGNBQWMsQ0FBQyxNQUFNLEVBQUUsT0FBTyxFQUFFLEVBQUUsV0FBVyxFQUFFLFdBQVcsR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLENBK0J0RjtZQUVhLGtCQUFrQjtZQXNDbEIseUJBQXlCO1lBOEJ6QixxQkFBcUI7SUFTbkMsT0FBTyxDQUFDLHdCQUF3QjtDQWdCakMifQ==
|
|
@@ -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;
|
|
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;YAsClB,yBAAyB;YA8BzB,qBAAqB;IASnC,OAAO,CAAC,wBAAwB;CAgBjC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { BlockNumber
|
|
2
|
-
import { merge, pick } from '@aztec/foundation/collection';
|
|
1
|
+
import { BlockNumber } from '@aztec/foundation/branded-types';
|
|
2
|
+
import { chunkBy, merge, pick } from '@aztec/foundation/collection';
|
|
3
3
|
import { createLogger } from '@aztec/foundation/log';
|
|
4
4
|
import { L2BlockSourceEvents } from '@aztec/stdlib/block';
|
|
5
5
|
import { getEpochAtSlot } from '@aztec/stdlib/epoch-helpers';
|
|
@@ -67,7 +67,7 @@ const EpochPruneWatcherPenaltiesConfigKeys = [
|
|
|
67
67
|
this.log.info(`Detected chain prune. Validating epoch ${epochNumber} with blocks ${epochBlocks[0]?.number} to ${epochBlocks[epochBlocks.length - 1]?.number}.`, {
|
|
68
68
|
blocks: epochBlocks.map((b)=>b.toBlockInfo())
|
|
69
69
|
});
|
|
70
|
-
await this.validateBlocks(epochBlocks);
|
|
70
|
+
await this.validateBlocks(epochBlocks, epochNumber);
|
|
71
71
|
this.log.info(`Pruned epoch ${epochNumber} was valid. Want to slash committee for not having it proven.`);
|
|
72
72
|
await this.emitSlashForEpoch(OffenseType.VALID_EPOCH_PRUNED, epochNumber);
|
|
73
73
|
} catch (error) {
|
|
@@ -81,19 +81,26 @@ const EpochPruneWatcherPenaltiesConfigKeys = [
|
|
|
81
81
|
}
|
|
82
82
|
}
|
|
83
83
|
}
|
|
84
|
-
async validateBlocks(blocks) {
|
|
84
|
+
async validateBlocks(blocks, epochNumber) {
|
|
85
85
|
if (blocks.length === 0) {
|
|
86
86
|
return;
|
|
87
87
|
}
|
|
88
|
-
|
|
89
|
-
const
|
|
88
|
+
// Sort blocks by block number and group by checkpoint
|
|
89
|
+
const sortedBlocks = [
|
|
90
|
+
...blocks
|
|
91
|
+
].sort((a, b)=>a.number - b.number);
|
|
92
|
+
const blocksByCheckpoint = chunkBy(sortedBlocks, (b)=>b.checkpointNumber);
|
|
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.getCheckpointsForEpoch(epochNumber)).filter((c)=>c.number < sortedBlocks[0].checkpointNumber).map((c)=>c.getCheckpointOutHash());
|
|
95
|
+
let previousCheckpointOutHashes = [
|
|
96
|
+
...priorCheckpointOutHashes
|
|
97
|
+
];
|
|
98
|
+
const fork = await this.checkpointsBuilder.getFork(BlockNumber(sortedBlocks[0].header.globalVariables.blockNumber - 1));
|
|
90
99
|
try {
|
|
91
|
-
for (const
|
|
92
|
-
await this.
|
|
93
|
-
//
|
|
94
|
-
const checkpointOutHash = computeCheckpointOutHash(
|
|
95
|
-
block.body.txEffects.map((tx)=>tx.l2ToL1Msgs)
|
|
96
|
-
]);
|
|
100
|
+
for (const checkpointBlocks of blocksByCheckpoint){
|
|
101
|
+
await this.validateCheckpoint(checkpointBlocks, previousCheckpointOutHashes, fork);
|
|
102
|
+
// Compute checkpoint out hash from all blocks in this checkpoint
|
|
103
|
+
const checkpointOutHash = computeCheckpointOutHash(checkpointBlocks.map((b)=>b.body.txEffects.map((tx)=>tx.l2ToL1Msgs)));
|
|
97
104
|
previousCheckpointOutHashes = [
|
|
98
105
|
...previousCheckpointOutHashes,
|
|
99
106
|
checkpointOutHash
|
|
@@ -103,7 +110,29 @@ const EpochPruneWatcherPenaltiesConfigKeys = [
|
|
|
103
110
|
await fork.close();
|
|
104
111
|
}
|
|
105
112
|
}
|
|
106
|
-
async
|
|
113
|
+
async validateCheckpoint(checkpointBlocks, previousCheckpointOutHashes, fork) {
|
|
114
|
+
const checkpointNumber = checkpointBlocks[0].checkpointNumber;
|
|
115
|
+
this.log.debug(`Validating pruned checkpoint ${checkpointNumber} with ${checkpointBlocks.length} blocks`);
|
|
116
|
+
// Get L1ToL2Messages once for the entire checkpoint
|
|
117
|
+
const l1ToL2Messages = await this.l1ToL2MessageSource.getL1ToL2Messages(checkpointNumber);
|
|
118
|
+
// Build checkpoint constants from first block's global variables
|
|
119
|
+
const gv = checkpointBlocks[0].header.globalVariables;
|
|
120
|
+
const constants = {
|
|
121
|
+
chainId: gv.chainId,
|
|
122
|
+
version: gv.version,
|
|
123
|
+
slotNumber: gv.slotNumber,
|
|
124
|
+
coinbase: gv.coinbase,
|
|
125
|
+
feeRecipient: gv.feeRecipient,
|
|
126
|
+
gasFees: gv.gasFees
|
|
127
|
+
};
|
|
128
|
+
// 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
|
+
// Validate all blocks in the checkpoint sequentially
|
|
131
|
+
for (const block of checkpointBlocks){
|
|
132
|
+
await this.validateBlockInCheckpoint(block, checkpointBuilder);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
async validateBlockInCheckpoint(blockFromL1, checkpointBuilder) {
|
|
107
136
|
this.log.debug(`Validating pruned block ${blockFromL1.header.globalVariables.blockNumber}`);
|
|
108
137
|
const txHashes = blockFromL1.body.txEffects.map((txEffect)=>txEffect.txHash);
|
|
109
138
|
// We load txs from the mempool directly, since the TxCollector running in the background has already been
|
|
@@ -113,19 +142,7 @@ const EpochPruneWatcherPenaltiesConfigKeys = [
|
|
|
113
142
|
if (missingTxs && missingTxs.length > 0) {
|
|
114
143
|
throw new TransactionsNotAvailableError(missingTxs);
|
|
115
144
|
}
|
|
116
|
-
const checkpointNumber = CheckpointNumber.fromBlockNumber(blockFromL1.number);
|
|
117
|
-
const l1ToL2Messages = await this.l1ToL2MessageSource.getL1ToL2Messages(checkpointNumber);
|
|
118
145
|
const gv = blockFromL1.header.globalVariables;
|
|
119
|
-
const constants = {
|
|
120
|
-
chainId: gv.chainId,
|
|
121
|
-
version: gv.version,
|
|
122
|
-
slotNumber: gv.slotNumber,
|
|
123
|
-
coinbase: gv.coinbase,
|
|
124
|
-
feeRecipient: gv.feeRecipient,
|
|
125
|
-
gasFees: gv.gasFees
|
|
126
|
-
};
|
|
127
|
-
// Use checkpoint builder to validate the block
|
|
128
|
-
const checkpointBuilder = await this.checkpointsBuilder.startCheckpoint(checkpointNumber, constants, l1ToL2Messages, previousCheckpointOutHashes, fork);
|
|
129
146
|
const { block, failedTxs, numTxs } = await checkpointBuilder.buildBlock(txs, gv.blockNumber, gv.timestamp, {});
|
|
130
147
|
if (numTxs !== txs.length) {
|
|
131
148
|
// This should be detected by state mismatch, but this makes it easier to debug.
|
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.f2ce05ee",
|
|
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.f2ce05ee",
|
|
60
|
+
"@aztec/ethereum": "0.0.1-commit.f2ce05ee",
|
|
61
|
+
"@aztec/foundation": "0.0.1-commit.f2ce05ee",
|
|
62
|
+
"@aztec/kv-store": "0.0.1-commit.f2ce05ee",
|
|
63
|
+
"@aztec/l1-artifacts": "0.0.1-commit.f2ce05ee",
|
|
64
|
+
"@aztec/stdlib": "0.0.1-commit.f2ce05ee",
|
|
65
|
+
"@aztec/telemetry-client": "0.0.1-commit.f2ce05ee",
|
|
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.f2ce05ee",
|
|
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
|
@@ -23,6 +23,7 @@ export const DefaultSlasherConfig: SlasherConfig = {
|
|
|
23
23
|
slashInactivityTargetPercentage: slasherDefaultEnv.SLASH_INACTIVITY_TARGET_PERCENTAGE,
|
|
24
24
|
slashInactivityConsecutiveEpochThreshold: slasherDefaultEnv.SLASH_INACTIVITY_CONSECUTIVE_EPOCH_THRESHOLD,
|
|
25
25
|
slashBroadcastedInvalidBlockPenalty: BigInt(slasherDefaultEnv.SLASH_INVALID_BLOCK_PENALTY),
|
|
26
|
+
slashDuplicateProposalPenalty: BigInt(slasherDefaultEnv.SLASH_DUPLICATE_PROPOSAL_PENALTY),
|
|
26
27
|
slashInactivityPenalty: BigInt(slasherDefaultEnv.SLASH_INACTIVITY_PENALTY),
|
|
27
28
|
slashProposeInvalidAttestationsPenalty: BigInt(slasherDefaultEnv.SLASH_PROPOSE_INVALID_ATTESTATIONS_PENALTY),
|
|
28
29
|
slashAttestDescendantOfInvalidPenalty: BigInt(slasherDefaultEnv.SLASH_ATTEST_DESCENDANT_OF_INVALID_PENALTY),
|
|
@@ -88,6 +89,11 @@ export const slasherConfigMappings: ConfigMappingsType<SlasherConfig> = {
|
|
|
88
89
|
description: 'Penalty amount for slashing a validator for an invalid block proposed via p2p.',
|
|
89
90
|
...bigintConfigHelper(DefaultSlasherConfig.slashBroadcastedInvalidBlockPenalty),
|
|
90
91
|
},
|
|
92
|
+
slashDuplicateProposalPenalty: {
|
|
93
|
+
env: 'SLASH_DUPLICATE_PROPOSAL_PENALTY',
|
|
94
|
+
description: 'Penalty amount for slashing a validator for sending duplicate proposals.',
|
|
95
|
+
...bigintConfigHelper(DefaultSlasherConfig.slashDuplicateProposalPenalty),
|
|
96
|
+
},
|
|
91
97
|
slashInactivityTargetPercentage: {
|
|
92
98
|
env: 'SLASH_INACTIVITY_TARGET_PERCENTAGE',
|
|
93
99
|
description:
|
|
@@ -4,7 +4,6 @@ import { SlotNumber } from '@aztec/foundation/branded-types';
|
|
|
4
4
|
import { compactArray, filterAsync, maxBy, pick } from '@aztec/foundation/collection';
|
|
5
5
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
6
6
|
import { createLogger } from '@aztec/foundation/log';
|
|
7
|
-
import { sleep } from '@aztec/foundation/sleep';
|
|
8
7
|
import type { DateProvider } from '@aztec/foundation/timer';
|
|
9
8
|
import type { L1RollupConstants } from '@aztec/stdlib/epoch-helpers';
|
|
10
9
|
import type { SlasherConfig } from '@aztec/stdlib/interfaces/server';
|
|
@@ -196,13 +195,6 @@ export class EmpireSlasherClient implements ProposerSlashActionProvider, Slasher
|
|
|
196
195
|
this.roundMonitor.stop();
|
|
197
196
|
await this.offensesCollector.stop();
|
|
198
197
|
|
|
199
|
-
// Viem calls eth_uninstallFilter under the hood when uninstalling event watchers, but these calls are not awaited,
|
|
200
|
-
// meaning that any error that happens during the uninstallation will not be caught. This causes errors during jest teardowns,
|
|
201
|
-
// where we stop anvil after all other processes are stopped, so sometimes the eth_uninstallFilter call fails because anvil
|
|
202
|
-
// is already stopped. We add a sleep here to give the uninstallation some time to complete, but the proper fix is for
|
|
203
|
-
// viem to await the eth_uninstallFilter calls, or to catch any errors that happen during the uninstallation.
|
|
204
|
-
// See https://github.com/wevm/viem/issues/3714.
|
|
205
|
-
await sleep(2000);
|
|
206
198
|
this.log.info('Empire Slasher client stopped');
|
|
207
199
|
}
|
|
208
200
|
|
|
@@ -31,7 +31,7 @@ export async function createSlasherFacade(
|
|
|
31
31
|
throw new Error('Cannot initialize SlasherClient without a Rollup address');
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
-
const kvStore = await createStore('slasher', SCHEMA_VERSION, config,
|
|
34
|
+
const kvStore = await createStore('slasher', SCHEMA_VERSION, config, logger.getBindings());
|
|
35
35
|
const rollup = new RollupContract(l1Client, l1Contracts.rollupAddress);
|
|
36
36
|
|
|
37
37
|
const slashValidatorsNever = config.slashSelfAllowed
|
|
@@ -15,6 +15,7 @@ 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: 10000000000000000000,
|
|
18
19
|
SLASH_UNKNOWN_PENALTY: 10000000000000000000,
|
|
19
20
|
SLASH_INVALID_BLOCK_PENALTY: 10000000000000000000,
|
|
20
21
|
SLASH_GRACE_PERIOD_L2_SLOTS: 0,
|
|
@@ -85,7 +85,11 @@ export class SlashOffensesCollector {
|
|
|
85
85
|
}
|
|
86
86
|
}
|
|
87
87
|
|
|
88
|
-
this.log.info(`Adding pending offense for validator ${arg.validator}`,
|
|
88
|
+
this.log.info(`Adding pending offense for validator ${arg.validator}`, {
|
|
89
|
+
...pendingOffense,
|
|
90
|
+
epochOrSlot: pendingOffense.epochOrSlot.toString(),
|
|
91
|
+
amount: pendingOffense.amount.toString(),
|
|
92
|
+
});
|
|
89
93
|
await this.offensesStore.addPendingOffense(pendingOffense);
|
|
90
94
|
}
|
|
91
95
|
}
|
|
@@ -76,9 +76,11 @@ export class SlasherOffensesStore {
|
|
|
76
76
|
/** Adds a new offense (defaults to pending, but will be slashed if markAsSlashed had been called for it) */
|
|
77
77
|
public async addPendingOffense(offense: Offense): Promise<void> {
|
|
78
78
|
const key = this.getOffenseKey(offense);
|
|
79
|
-
await this.offenses.set(key, serializeOffense(offense));
|
|
80
79
|
const round = getRoundForOffense(offense, this.settings);
|
|
81
|
-
await this.
|
|
80
|
+
await this.kvStore.transactionAsync(async () => {
|
|
81
|
+
await this.offenses.set(key, serializeOffense(offense));
|
|
82
|
+
await this.roundsOffenses.set(this.getRoundKey(round), key);
|
|
83
|
+
});
|
|
82
84
|
this.log.trace(`Adding pending offense ${key} for round ${round}`);
|
|
83
85
|
}
|
|
84
86
|
|
|
@@ -118,10 +118,13 @@ export class SlasherPayloadsStore {
|
|
|
118
118
|
|
|
119
119
|
public async incrementPayloadVotes(payloadAddress: EthAddress, round: bigint): Promise<bigint> {
|
|
120
120
|
const key = this.getPayloadVotesKey(round, payloadAddress);
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
121
|
+
let newVotes: bigint;
|
|
122
|
+
await this.kvStore.transactionAsync(async () => {
|
|
123
|
+
const currentVotes = (await this.roundPayloadVotes.getAsync(key)) || 0n;
|
|
124
|
+
newVotes = currentVotes + 1n;
|
|
125
|
+
await this.roundPayloadVotes.set(key, newVotes);
|
|
126
|
+
});
|
|
127
|
+
return newVotes!;
|
|
125
128
|
}
|
|
126
129
|
|
|
127
130
|
public async addPayload(payload: SlashPayloadRound): Promise<void> {
|
|
@@ -5,7 +5,6 @@ import { maxBigint } from '@aztec/foundation/bigint';
|
|
|
5
5
|
import { SlotNumber } from '@aztec/foundation/branded-types';
|
|
6
6
|
import { compactArray, partition, times } from '@aztec/foundation/collection';
|
|
7
7
|
import { createLogger } from '@aztec/foundation/log';
|
|
8
|
-
import { sleep } from '@aztec/foundation/sleep';
|
|
9
8
|
import type { DateProvider } from '@aztec/foundation/timer';
|
|
10
9
|
import type { Prettify } from '@aztec/foundation/types';
|
|
11
10
|
import type { SlasherConfig } from '@aztec/stdlib/interfaces/server';
|
|
@@ -138,8 +137,6 @@ export class TallySlasherClient implements ProposerSlashActionProvider, SlasherC
|
|
|
138
137
|
this.roundMonitor.stop();
|
|
139
138
|
await this.offensesCollector.stop();
|
|
140
139
|
|
|
141
|
-
// Sleeping to sidestep viem issue with unwatching events
|
|
142
|
-
await sleep(2000);
|
|
143
140
|
this.log.info('Tally Slasher client stopped');
|
|
144
141
|
}
|
|
145
142
|
|
|
@@ -281,8 +278,12 @@ export class TallySlasherClient implements ProposerSlashActionProvider, SlasherC
|
|
|
281
278
|
return undefined;
|
|
282
279
|
}
|
|
283
280
|
|
|
281
|
+
const slashActionsWithAmounts = slashActions.map(action => ({
|
|
282
|
+
validator: action.validator.toString(),
|
|
283
|
+
slashAmount: action.slashAmount.toString(),
|
|
284
|
+
}));
|
|
284
285
|
this.log.info(`Round ${executableRound} is ready to execute with ${slashActions.length} slashes`, {
|
|
285
|
-
slashActions,
|
|
286
|
+
slashActions: slashActionsWithAmounts,
|
|
286
287
|
payloadAddress: payload.address.toString(),
|
|
287
288
|
...logData,
|
|
288
289
|
});
|
|
@@ -348,11 +349,15 @@ export class TallySlasherClient implements ProposerSlashActionProvider, SlasherC
|
|
|
348
349
|
return undefined;
|
|
349
350
|
}
|
|
350
351
|
|
|
352
|
+
const offensesToSlashLog = offensesToSlash.map(offense => ({
|
|
353
|
+
...offense,
|
|
354
|
+
amount: offense.amount.toString(),
|
|
355
|
+
}));
|
|
351
356
|
this.log.info(`Voting to slash ${offensesToSlash.length} offenses`, {
|
|
352
357
|
slotNumber,
|
|
353
358
|
currentRound,
|
|
354
359
|
slashedRound,
|
|
355
|
-
offensesToSlash,
|
|
360
|
+
offensesToSlash: offensesToSlashLog,
|
|
356
361
|
});
|
|
357
362
|
|
|
358
363
|
const committees = await this.collectCommitteesActiveDuringRound(slashedRound);
|
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
import { EpochCache } from '@aztec/epoch-cache';
|
|
2
|
-
import { BlockNumber,
|
|
3
|
-
import { merge, pick } from '@aztec/foundation/collection';
|
|
2
|
+
import { BlockNumber, EpochNumber } from '@aztec/foundation/branded-types';
|
|
3
|
+
import { chunkBy, merge, pick } from '@aztec/foundation/collection';
|
|
4
4
|
import type { Fr } from '@aztec/foundation/curves/bn254';
|
|
5
5
|
import { type Logger, createLogger } from '@aztec/foundation/log';
|
|
6
6
|
import {
|
|
7
7
|
EthAddress,
|
|
8
|
-
|
|
8
|
+
L2Block,
|
|
9
9
|
type L2BlockSourceEventEmitter,
|
|
10
10
|
L2BlockSourceEvents,
|
|
11
11
|
type L2PruneUnprovenEvent,
|
|
12
12
|
} from '@aztec/stdlib/block';
|
|
13
13
|
import { getEpochAtSlot } from '@aztec/stdlib/epoch-helpers';
|
|
14
14
|
import type {
|
|
15
|
+
ICheckpointBlockBuilder,
|
|
15
16
|
ICheckpointsBuilder,
|
|
16
17
|
ITxProvider,
|
|
17
18
|
MerkleTreeWriteOperations,
|
|
@@ -97,7 +98,7 @@ export class EpochPruneWatcher extends (EventEmitter as new () => WatcherEmitter
|
|
|
97
98
|
this.emit(WANT_TO_SLASH_EVENT, args);
|
|
98
99
|
}
|
|
99
100
|
|
|
100
|
-
private async processPruneL2Blocks(blocks:
|
|
101
|
+
private async processPruneL2Blocks(blocks: L2Block[], epochNumber: EpochNumber): Promise<void> {
|
|
101
102
|
try {
|
|
102
103
|
const l1Constants = this.epochCache.getL1Constants();
|
|
103
104
|
const epochBlocks = blocks.filter(b => getEpochAtSlot(b.header.getSlot(), l1Constants) === epochNumber);
|
|
@@ -106,7 +107,7 @@ export class EpochPruneWatcher extends (EventEmitter as new () => WatcherEmitter
|
|
|
106
107
|
{ blocks: epochBlocks.map(b => b.toBlockInfo()) },
|
|
107
108
|
);
|
|
108
109
|
|
|
109
|
-
await this.validateBlocks(epochBlocks);
|
|
110
|
+
await this.validateBlocks(epochBlocks, epochNumber);
|
|
110
111
|
this.log.info(`Pruned epoch ${epochNumber} was valid. Want to slash committee for not having it proven.`);
|
|
111
112
|
await this.emitSlashForEpoch(OffenseType.VALID_EPOCH_PRUNED, epochNumber);
|
|
112
113
|
} catch (error) {
|
|
@@ -121,19 +122,32 @@ export class EpochPruneWatcher extends (EventEmitter as new () => WatcherEmitter
|
|
|
121
122
|
}
|
|
122
123
|
}
|
|
123
124
|
|
|
124
|
-
public async validateBlocks(blocks:
|
|
125
|
+
public async validateBlocks(blocks: L2Block[], epochNumber: EpochNumber): Promise<void> {
|
|
125
126
|
if (blocks.length === 0) {
|
|
126
127
|
return;
|
|
127
128
|
}
|
|
128
129
|
|
|
129
|
-
|
|
130
|
-
const
|
|
130
|
+
// Sort blocks by block number and group by checkpoint
|
|
131
|
+
const sortedBlocks = [...blocks].sort((a, b) => a.number - b.number);
|
|
132
|
+
const blocksByCheckpoint = chunkBy(sortedBlocks, b => b.checkpointNumber);
|
|
133
|
+
|
|
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.getCheckpointsForEpoch(epochNumber))
|
|
136
|
+
.filter(c => c.number < sortedBlocks[0].checkpointNumber)
|
|
137
|
+
.map(c => c.getCheckpointOutHash());
|
|
138
|
+
let previousCheckpointOutHashes: Fr[] = [...priorCheckpointOutHashes];
|
|
139
|
+
|
|
140
|
+
const fork = await this.checkpointsBuilder.getFork(
|
|
141
|
+
BlockNumber(sortedBlocks[0].header.globalVariables.blockNumber - 1),
|
|
142
|
+
);
|
|
131
143
|
try {
|
|
132
|
-
for (const
|
|
133
|
-
await this.
|
|
144
|
+
for (const checkpointBlocks of blocksByCheckpoint) {
|
|
145
|
+
await this.validateCheckpoint(checkpointBlocks, previousCheckpointOutHashes, fork);
|
|
134
146
|
|
|
135
|
-
//
|
|
136
|
-
const checkpointOutHash = computeCheckpointOutHash(
|
|
147
|
+
// Compute checkpoint out hash from all blocks in this checkpoint
|
|
148
|
+
const checkpointOutHash = computeCheckpointOutHash(
|
|
149
|
+
checkpointBlocks.map(b => b.body.txEffects.map(tx => tx.l2ToL1Msgs)),
|
|
150
|
+
);
|
|
137
151
|
previousCheckpointOutHashes = [...previousCheckpointOutHashes, checkpointOutHash];
|
|
138
152
|
}
|
|
139
153
|
} finally {
|
|
@@ -141,25 +155,19 @@ export class EpochPruneWatcher extends (EventEmitter as new () => WatcherEmitter
|
|
|
141
155
|
}
|
|
142
156
|
}
|
|
143
157
|
|
|
144
|
-
|
|
145
|
-
|
|
158
|
+
private async validateCheckpoint(
|
|
159
|
+
checkpointBlocks: L2Block[],
|
|
146
160
|
previousCheckpointOutHashes: Fr[],
|
|
147
161
|
fork: MerkleTreeWriteOperations,
|
|
148
162
|
): Promise<void> {
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
// We load txs from the mempool directly, since the TxCollector running in the background has already been
|
|
152
|
-
// trying to fetch them from nodes or via reqresp. If we haven't managed to collect them by now,
|
|
153
|
-
// it's likely that they are not available in the network at all.
|
|
154
|
-
const { txs, missingTxs } = await this.txProvider.getAvailableTxs(txHashes);
|
|
155
|
-
|
|
156
|
-
if (missingTxs && missingTxs.length > 0) {
|
|
157
|
-
throw new TransactionsNotAvailableError(missingTxs);
|
|
158
|
-
}
|
|
163
|
+
const checkpointNumber = checkpointBlocks[0].checkpointNumber;
|
|
164
|
+
this.log.debug(`Validating pruned checkpoint ${checkpointNumber} with ${checkpointBlocks.length} blocks`);
|
|
159
165
|
|
|
160
|
-
|
|
166
|
+
// Get L1ToL2Messages once for the entire checkpoint
|
|
161
167
|
const l1ToL2Messages = await this.l1ToL2MessageSource.getL1ToL2Messages(checkpointNumber);
|
|
162
|
-
|
|
168
|
+
|
|
169
|
+
// Build checkpoint constants from first block's global variables
|
|
170
|
+
const gv = checkpointBlocks[0].header.globalVariables;
|
|
163
171
|
const constants: CheckpointGlobalVariables = {
|
|
164
172
|
chainId: gv.chainId,
|
|
165
173
|
version: gv.version,
|
|
@@ -169,15 +177,38 @@ export class EpochPruneWatcher extends (EventEmitter as new () => WatcherEmitter
|
|
|
169
177
|
gasFees: gv.gasFees,
|
|
170
178
|
};
|
|
171
179
|
|
|
172
|
-
//
|
|
180
|
+
// Start checkpoint builder once for all blocks in this checkpoint
|
|
173
181
|
const checkpointBuilder = await this.checkpointsBuilder.startCheckpoint(
|
|
174
182
|
checkpointNumber,
|
|
175
183
|
constants,
|
|
176
184
|
l1ToL2Messages,
|
|
177
185
|
previousCheckpointOutHashes,
|
|
178
186
|
fork,
|
|
187
|
+
this.log.getBindings(),
|
|
179
188
|
);
|
|
180
189
|
|
|
190
|
+
// Validate all blocks in the checkpoint sequentially
|
|
191
|
+
for (const block of checkpointBlocks) {
|
|
192
|
+
await this.validateBlockInCheckpoint(block, checkpointBuilder);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
private async validateBlockInCheckpoint(
|
|
197
|
+
blockFromL1: L2Block,
|
|
198
|
+
checkpointBuilder: ICheckpointBlockBuilder,
|
|
199
|
+
): Promise<void> {
|
|
200
|
+
this.log.debug(`Validating pruned block ${blockFromL1.header.globalVariables.blockNumber}`);
|
|
201
|
+
const txHashes = blockFromL1.body.txEffects.map(txEffect => txEffect.txHash);
|
|
202
|
+
// We load txs from the mempool directly, since the TxCollector running in the background has already been
|
|
203
|
+
// trying to fetch them from nodes or via reqresp. If we haven't managed to collect them by now,
|
|
204
|
+
// it's likely that they are not available in the network at all.
|
|
205
|
+
const { txs, missingTxs } = await this.txProvider.getAvailableTxs(txHashes);
|
|
206
|
+
|
|
207
|
+
if (missingTxs && missingTxs.length > 0) {
|
|
208
|
+
throw new TransactionsNotAvailableError(missingTxs);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
const gv = blockFromL1.header.globalVariables;
|
|
181
212
|
const { block, failedTxs, numTxs } = await checkpointBuilder.buildBlock(txs, gv.blockNumber, gv.timestamp, {});
|
|
182
213
|
|
|
183
214
|
if (numTxs !== txs.length) {
|