@aztec/stdlib 2.0.0-nightly.20250822 → 2.0.0-nightly.20250823
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/dest/block/l2_block.d.ts +2 -0
- package/dest/block/l2_block.d.ts.map +1 -1
- package/dest/block/l2_block.js +6 -0
- package/dest/interfaces/aztec-node-admin.d.ts +29 -15
- package/dest/interfaces/aztec-node-admin.d.ts.map +1 -1
- package/dest/interfaces/aztec-node-admin.js +7 -2
- package/dest/interfaces/epoch-prover.d.ts +1 -1
- package/dest/interfaces/slasher.d.ts +33 -17
- package/dest/interfaces/slasher.d.ts.map +1 -1
- package/dest/interfaces/slasher.js +8 -4
- package/dest/interfaces/world_state.d.ts +4 -4
- package/dest/interfaces/world_state.js +1 -1
- package/dest/l1-contracts/index.d.ts +2 -0
- package/dest/l1-contracts/index.d.ts.map +1 -0
- package/dest/l1-contracts/index.js +1 -0
- package/dest/l1-contracts/slash_factory.d.ts +44 -0
- package/dest/l1-contracts/slash_factory.d.ts.map +1 -0
- package/dest/l1-contracts/slash_factory.js +157 -0
- package/dest/slashing/empire.d.ts +31 -0
- package/dest/slashing/empire.d.ts.map +1 -0
- package/dest/slashing/empire.js +84 -0
- package/dest/slashing/helpers.d.ts +31 -0
- package/dest/slashing/helpers.d.ts.map +1 -0
- package/dest/slashing/helpers.js +62 -0
- package/dest/slashing/index.d.ts +6 -50
- package/dest/slashing/index.d.ts.map +1 -1
- package/dest/slashing/index.js +6 -54
- package/dest/slashing/interfaces.d.ts +11 -0
- package/dest/slashing/interfaces.d.ts.map +1 -0
- package/dest/slashing/interfaces.js +1 -0
- package/dest/slashing/serialization.d.ts +8 -0
- package/dest/slashing/serialization.d.ts.map +1 -0
- package/dest/slashing/serialization.js +78 -0
- package/dest/slashing/tally.d.ts +17 -0
- package/dest/slashing/tally.d.ts.map +1 -0
- package/dest/slashing/tally.js +36 -0
- package/dest/slashing/types.d.ts +161 -0
- package/dest/slashing/types.d.ts.map +1 -0
- package/dest/slashing/types.js +66 -0
- package/dest/stats/stats.d.ts +2 -2
- package/package.json +10 -8
- package/src/block/l2_block.ts +8 -0
- package/src/interfaces/aztec-node-admin.ts +11 -4
- package/src/interfaces/epoch-prover.ts +1 -1
- package/src/interfaces/slasher.ts +18 -9
- package/src/interfaces/world_state.ts +2 -2
- package/src/l1-contracts/index.ts +1 -0
- package/src/l1-contracts/slash_factory.ts +177 -0
- package/src/slashing/empire.ts +100 -0
- package/src/slashing/helpers.ts +87 -0
- package/src/slashing/index.ts +6 -74
- package/src/slashing/interfaces.ts +11 -0
- package/src/slashing/serialization.ts +103 -0
- package/src/slashing/tally.ts +51 -0
- package/src/slashing/types.ts +129 -0
- package/src/stats/stats.ts +2 -2
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { getRoundForSlot, getRoundsForEpoch } from './helpers.js';
|
|
2
|
+
import { OffenseType } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Returns true if the offense is uncontroversial as in it can be verified via L1 data alone,
|
|
5
|
+
* and does not depend on the local view of the node of the L2 p2p network.
|
|
6
|
+
* @param offense - The offense type to check
|
|
7
|
+
*/ export function isOffenseUncontroversial(offense) {
|
|
8
|
+
return offense === OffenseType.PROPOSED_INSUFFICIENT_ATTESTATIONS || offense === OffenseType.PROPOSED_INCORRECT_ATTESTATIONS || offense === OffenseType.ATTESTED_DESCENDANT_OF_INVALID;
|
|
9
|
+
}
|
|
10
|
+
/** Extracts offense identifiers (validator, epoch, offense type) from an Empire-based SlashPayload */ export function getOffenseIdentifiersFromPayload(payload) {
|
|
11
|
+
return payload.slashes.flatMap((slash)=>slash.offenses.map((o)=>({
|
|
12
|
+
validator: slash.validator,
|
|
13
|
+
offenseType: o.offenseType,
|
|
14
|
+
epochOrSlot: o.epochOrSlot
|
|
15
|
+
})));
|
|
16
|
+
}
|
|
17
|
+
/** Creates ValidatorSlashes used to create an Empire-based SlashPayload from a set of Offenses */ export function offensesToValidatorSlash(offenses) {
|
|
18
|
+
return offenses.map((offense)=>({
|
|
19
|
+
validator: offense.validator,
|
|
20
|
+
amount: offense.amount,
|
|
21
|
+
offenses: [
|
|
22
|
+
{
|
|
23
|
+
epochOrSlot: offense.epochOrSlot,
|
|
24
|
+
offenseType: offense.offenseType
|
|
25
|
+
}
|
|
26
|
+
]
|
|
27
|
+
}));
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Sorts offense data by:
|
|
31
|
+
* - Uncontroversial offenses first
|
|
32
|
+
* - Slash amount (descending)
|
|
33
|
+
* - Epoch or slot (ascending, ie oldest first)
|
|
34
|
+
* - Validator address (ascending)
|
|
35
|
+
* - Offense type (descending)
|
|
36
|
+
*/ export function offenseDataComparator(a, b) {
|
|
37
|
+
return Number(isOffenseUncontroversial(b.offenseType)) - Number(isOffenseUncontroversial(a.offenseType)) || Number(b.amount - a.amount) || Number(a.epochOrSlot - b.epochOrSlot) || a.validator.toString().localeCompare(b.validator.toString()) || Number(b.offenseType) - Number(a.offenseType);
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Returns the first round in which the offense is eligible for being included in an Empire-based slash payload.
|
|
41
|
+
* Should be equal to to the first round that starts strictly after the offense becomes detectable.
|
|
42
|
+
*/ export function getFirstEligibleRoundForOffense(offense, constants) {
|
|
43
|
+
// TODO(palla/slash): Check for off-by-ones
|
|
44
|
+
switch(offense.offenseType){
|
|
45
|
+
// Inactivity is detected at the end of the epoch, so we flag it as detected in the first fresh round for the next epoch
|
|
46
|
+
case OffenseType.INACTIVITY:
|
|
47
|
+
{
|
|
48
|
+
const epoch = offense.epochOrSlot;
|
|
49
|
+
const detectedEpoch = epoch + 1n;
|
|
50
|
+
return getRoundsForEpoch(detectedEpoch, constants)[0] + 1n;
|
|
51
|
+
}
|
|
52
|
+
// These offenses are detected once an epoch is pruned, which happens after the proof submission window
|
|
53
|
+
case OffenseType.VALID_EPOCH_PRUNED:
|
|
54
|
+
case OffenseType.DATA_WITHHOLDING:
|
|
55
|
+
{
|
|
56
|
+
// TODO(palla/slash): Check for off-by-ones especially here
|
|
57
|
+
const epoch = offense.epochOrSlot;
|
|
58
|
+
const detectedEpoch = epoch + BigInt(constants.proofSubmissionEpochs);
|
|
59
|
+
return getRoundsForEpoch(detectedEpoch, constants)[0] + 1n;
|
|
60
|
+
}
|
|
61
|
+
// These offenses are detected immediately in the slot they occur, so we assume they are detected in the first round for the following slot
|
|
62
|
+
case OffenseType.PROPOSED_INSUFFICIENT_ATTESTATIONS:
|
|
63
|
+
case OffenseType.PROPOSED_INCORRECT_ATTESTATIONS:
|
|
64
|
+
case OffenseType.ATTESTED_DESCENDANT_OF_INVALID:
|
|
65
|
+
case OffenseType.BROADCASTED_INVALID_BLOCK_PROPOSAL:
|
|
66
|
+
{
|
|
67
|
+
const slot = offense.epochOrSlot;
|
|
68
|
+
const detectedSlot = slot + 1n;
|
|
69
|
+
return getRoundForSlot(detectedSlot, constants).round + 1n;
|
|
70
|
+
}
|
|
71
|
+
// Assume these are epoch-based offenses, even though we should never have to process these
|
|
72
|
+
case OffenseType.UNKNOWN:
|
|
73
|
+
{
|
|
74
|
+
const epoch = offense.epochOrSlot;
|
|
75
|
+
const detectedEpoch = epoch + 1n;
|
|
76
|
+
return getRoundsForEpoch(detectedEpoch, constants)[0] + 1n;
|
|
77
|
+
}
|
|
78
|
+
default:
|
|
79
|
+
{
|
|
80
|
+
const _ = offense.offenseType;
|
|
81
|
+
throw new Error(`Unknown offense type: ${offense.offenseType}`);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { type L1RollupConstants } from '../epoch-helpers/index.js';
|
|
2
|
+
import { type Offense, OffenseType } from './types.js';
|
|
3
|
+
/** Returns the voting round number and voting slot within the round for a given L2 slot. */
|
|
4
|
+
export declare function getRoundForSlot(slot: bigint, constants: {
|
|
5
|
+
slashingRoundSize: number;
|
|
6
|
+
}): {
|
|
7
|
+
round: bigint;
|
|
8
|
+
votingSlot: bigint;
|
|
9
|
+
};
|
|
10
|
+
/** Returns the voting round(s) lower and upper bounds (inclusive) covered by the given epoch */
|
|
11
|
+
export declare function getRoundsForEpoch(epoch: bigint, constants: {
|
|
12
|
+
slashingRoundSize: number;
|
|
13
|
+
epochDuration: number;
|
|
14
|
+
}): [bigint, bigint];
|
|
15
|
+
/** Returns the epochs spanned during a given slashing round */
|
|
16
|
+
export declare function getEpochsForRound(round: bigint, constants: {
|
|
17
|
+
slashingRoundSize: number;
|
|
18
|
+
epochDuration: number;
|
|
19
|
+
}): bigint[];
|
|
20
|
+
/** Returns whether the `epochOrSlot` field for an offense references an epoch or a slot */
|
|
21
|
+
export declare function getTimeUnitForOffense(offense: OffenseType): 'epoch' | 'slot';
|
|
22
|
+
/** Returns the slot for a given offense. If the offense references an epoch, returns the first slot of the epoch. */
|
|
23
|
+
export declare function getSlotForOffense(offense: Pick<Offense, 'epochOrSlot' | 'offenseType'>, constants: Pick<L1RollupConstants, 'epochDuration'>): bigint;
|
|
24
|
+
/** Returns the epoch for a given offense. */
|
|
25
|
+
export declare function getEpochForOffense(offense: Pick<Offense, 'epochOrSlot' | 'offenseType'>, constants: Pick<L1RollupConstants, 'epochDuration'>): bigint;
|
|
26
|
+
/** Returns the slashing round in which a given offense occurred. */
|
|
27
|
+
export declare function getRoundForOffense(offense: Pick<Offense, 'epochOrSlot' | 'offenseType'>, constants: {
|
|
28
|
+
slashingRoundSize: number;
|
|
29
|
+
epochDuration: number;
|
|
30
|
+
}): bigint;
|
|
31
|
+
//# sourceMappingURL=helpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../src/slashing/helpers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,iBAAiB,EAAwC,MAAM,2BAA2B,CAAC;AACzG,OAAO,EAAE,KAAK,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEvD,4FAA4F;AAC5F,wBAAgB,eAAe,CAC7B,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE;IAAE,iBAAiB,EAAE,MAAM,CAAA;CAAE,GACvC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAKvC;AAED,gGAAgG;AAChG,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,MAAM,EACb,SAAS,EAAE;IAAE,iBAAiB,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE,GAC9D,CAAC,MAAM,EAAE,MAAM,CAAC,CAKlB;AAED,+DAA+D;AAC/D,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,MAAM,EACb,SAAS,EAAE;IAAE,iBAAiB,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE,GAC9D,MAAM,EAAE,CAUV;AAED,2FAA2F;AAC3F,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,GAAG,MAAM,CAiB5E;AAED,qHAAqH;AACrH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,aAAa,GAAG,aAAa,CAAC,EACrD,SAAS,EAAE,IAAI,CAAC,iBAAiB,EAAE,eAAe,CAAC,GAClD,MAAM,CAGR;AAED,6CAA6C;AAC7C,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,aAAa,GAAG,aAAa,CAAC,EACrD,SAAS,EAAE,IAAI,CAAC,iBAAiB,EAAE,eAAe,CAAC,GAClD,MAAM,CAGR;AAED,oEAAoE;AACpE,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,aAAa,GAAG,aAAa,CAAC,EACrD,SAAS,EAAE;IAAE,iBAAiB,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE,GAC9D,MAAM,CAGR"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { getEpochAtSlot, getSlotRangeForEpoch } from '../epoch-helpers/index.js';
|
|
2
|
+
import { OffenseType } from './types.js';
|
|
3
|
+
/** Returns the voting round number and voting slot within the round for a given L2 slot. */ export function getRoundForSlot(slot, constants) {
|
|
4
|
+
const roundSize = BigInt(constants.slashingRoundSize);
|
|
5
|
+
const round = slot / roundSize;
|
|
6
|
+
const votingSlot = slot % roundSize;
|
|
7
|
+
return {
|
|
8
|
+
round,
|
|
9
|
+
votingSlot
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
/** Returns the voting round(s) lower and upper bounds (inclusive) covered by the given epoch */ export function getRoundsForEpoch(epoch, constants) {
|
|
13
|
+
const [start, end] = getSlotRangeForEpoch(epoch, constants);
|
|
14
|
+
const startRound = getRoundForSlot(start, constants).round;
|
|
15
|
+
const endRound = getRoundForSlot(end, constants).round;
|
|
16
|
+
return [
|
|
17
|
+
startRound,
|
|
18
|
+
endRound
|
|
19
|
+
];
|
|
20
|
+
}
|
|
21
|
+
/** Returns the epochs spanned during a given slashing round */ export function getEpochsForRound(round, constants) {
|
|
22
|
+
const epochs = [];
|
|
23
|
+
const firstSlot = round * BigInt(constants.slashingRoundSize);
|
|
24
|
+
const lastSlot = firstSlot + BigInt(constants.slashingRoundSize) - 1n;
|
|
25
|
+
const startEpoch = getEpochAtSlot(firstSlot, constants);
|
|
26
|
+
const endEpoch = getEpochAtSlot(lastSlot, constants);
|
|
27
|
+
for(let epoch = startEpoch; epoch <= endEpoch; epoch++){
|
|
28
|
+
epochs.push(epoch);
|
|
29
|
+
}
|
|
30
|
+
return epochs;
|
|
31
|
+
}
|
|
32
|
+
/** Returns whether the `epochOrSlot` field for an offense references an epoch or a slot */ export function getTimeUnitForOffense(offense) {
|
|
33
|
+
switch(offense){
|
|
34
|
+
case OffenseType.ATTESTED_DESCENDANT_OF_INVALID:
|
|
35
|
+
case OffenseType.BROADCASTED_INVALID_BLOCK_PROPOSAL:
|
|
36
|
+
case OffenseType.PROPOSED_INCORRECT_ATTESTATIONS:
|
|
37
|
+
case OffenseType.PROPOSED_INSUFFICIENT_ATTESTATIONS:
|
|
38
|
+
return 'slot';
|
|
39
|
+
case OffenseType.INACTIVITY:
|
|
40
|
+
case OffenseType.DATA_WITHHOLDING:
|
|
41
|
+
case OffenseType.UNKNOWN:
|
|
42
|
+
case OffenseType.VALID_EPOCH_PRUNED:
|
|
43
|
+
return 'epoch';
|
|
44
|
+
default:
|
|
45
|
+
{
|
|
46
|
+
const _ = offense;
|
|
47
|
+
throw new Error(`Unknown offense type: ${offense}`);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
/** Returns the slot for a given offense. If the offense references an epoch, returns the first slot of the epoch. */ export function getSlotForOffense(offense, constants) {
|
|
52
|
+
const { epochOrSlot, offenseType } = offense;
|
|
53
|
+
return getTimeUnitForOffense(offenseType) === 'epoch' ? epochOrSlot * BigInt(constants.epochDuration) : epochOrSlot;
|
|
54
|
+
}
|
|
55
|
+
/** Returns the epoch for a given offense. */ export function getEpochForOffense(offense, constants) {
|
|
56
|
+
const { epochOrSlot, offenseType } = offense;
|
|
57
|
+
return getTimeUnitForOffense(offenseType) === 'epoch' ? epochOrSlot : epochOrSlot / BigInt(constants.epochDuration);
|
|
58
|
+
}
|
|
59
|
+
/** Returns the slashing round in which a given offense occurred. */ export function getRoundForOffense(offense, constants) {
|
|
60
|
+
const slot = getSlotForOffense(offense, constants);
|
|
61
|
+
return getRoundForSlot(slot, constants).round;
|
|
62
|
+
}
|
package/dest/slashing/index.d.ts
CHANGED
|
@@ -1,51 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
export
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
VALID_EPOCH_PRUNED = 2,
|
|
8
|
-
INACTIVITY = 3,
|
|
9
|
-
/** A proposer sent an invalid block proposal over the p2p network to the committee */
|
|
10
|
-
BROADCASTED_INVALID_BLOCK_PROPOSAL = 4,
|
|
11
|
-
/** A proposer pushed to L1 a block with insufficient committee attestations */
|
|
12
|
-
PROPOSED_INSUFFICIENT_ATTESTATIONS = 5,
|
|
13
|
-
/** A proposer pushed to L1 a block with incorrect committee attestations (ie signature from a non-committee member) */
|
|
14
|
-
PROPOSED_INCORRECT_ATTESTATIONS = 6,
|
|
15
|
-
/** A committee member attested to a block that was built as a descendent of an invalid block (as in a block with invalid attestations) */
|
|
16
|
-
ATTESTED_DESCENDANT_OF_INVALID = 7
|
|
17
|
-
}
|
|
18
|
-
export declare const OffenseSchema: z.ZodNativeEnum<typeof Offense>;
|
|
19
|
-
export type MonitoredSlashPayload = {
|
|
20
|
-
payloadAddress: EthAddress;
|
|
21
|
-
validators: readonly EthAddress[];
|
|
22
|
-
amounts: readonly bigint[];
|
|
23
|
-
offenses: readonly Offense[];
|
|
24
|
-
observedAtSeconds: number;
|
|
25
|
-
totalAmount: bigint;
|
|
26
|
-
};
|
|
27
|
-
export declare const MonitoredSlashPayloadSchema: z.ZodObject<{
|
|
28
|
-
payloadAddress: ZodFor<EthAddress>;
|
|
29
|
-
validators: z.ZodArray<ZodFor<EthAddress>, "many">;
|
|
30
|
-
amounts: z.ZodArray<z.ZodPipeline<z.ZodUnion<[z.ZodBigInt, z.ZodNumber, z.ZodString]>, z.ZodBigInt>, "many">;
|
|
31
|
-
offenses: z.ZodArray<z.ZodNativeEnum<typeof Offense>, "many">;
|
|
32
|
-
observedAtSeconds: z.ZodNumber;
|
|
33
|
-
totalAmount: z.ZodPipeline<z.ZodUnion<[z.ZodBigInt, z.ZodNumber, z.ZodString]>, z.ZodBigInt>;
|
|
34
|
-
}, "strip", z.ZodTypeAny, {
|
|
35
|
-
payloadAddress: EthAddress;
|
|
36
|
-
validators: EthAddress[];
|
|
37
|
-
amounts: bigint[];
|
|
38
|
-
offenses: Offense[];
|
|
39
|
-
observedAtSeconds: number;
|
|
40
|
-
totalAmount: bigint;
|
|
41
|
-
}, {
|
|
42
|
-
validators: any[];
|
|
43
|
-
amounts: (string | number | bigint)[];
|
|
44
|
-
offenses: Offense[];
|
|
45
|
-
observedAtSeconds: number;
|
|
46
|
-
totalAmount: string | number | bigint;
|
|
47
|
-
payloadAddress?: any;
|
|
48
|
-
}>;
|
|
49
|
-
export declare const OffenseToBigInt: Record<Offense, bigint>;
|
|
50
|
-
export declare function bigIntToOffense(offense: bigint): Offense;
|
|
1
|
+
export * from './types.js';
|
|
2
|
+
export * from './interfaces.js';
|
|
3
|
+
export * from './helpers.js';
|
|
4
|
+
export * from './empire.js';
|
|
5
|
+
export * from './tally.js';
|
|
6
|
+
export * from './serialization.js';
|
|
51
7
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/slashing/index.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/slashing/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,iBAAiB,CAAC;AAChC,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,oBAAoB,CAAC"}
|
package/dest/slashing/index.js
CHANGED
|
@@ -1,54 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
export
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
Offense[Offense["INACTIVITY"] = 3] = "INACTIVITY";
|
|
8
|
-
/** A proposer sent an invalid block proposal over the p2p network to the committee */ Offense[Offense["BROADCASTED_INVALID_BLOCK_PROPOSAL"] = 4] = "BROADCASTED_INVALID_BLOCK_PROPOSAL";
|
|
9
|
-
/** A proposer pushed to L1 a block with insufficient committee attestations */ Offense[Offense["PROPOSED_INSUFFICIENT_ATTESTATIONS"] = 5] = "PROPOSED_INSUFFICIENT_ATTESTATIONS";
|
|
10
|
-
/** A proposer pushed to L1 a block with incorrect committee attestations (ie signature from a non-committee member) */ Offense[Offense["PROPOSED_INCORRECT_ATTESTATIONS"] = 6] = "PROPOSED_INCORRECT_ATTESTATIONS";
|
|
11
|
-
/** A committee member attested to a block that was built as a descendent of an invalid block (as in a block with invalid attestations) */ Offense[Offense["ATTESTED_DESCENDANT_OF_INVALID"] = 7] = "ATTESTED_DESCENDANT_OF_INVALID";
|
|
12
|
-
return Offense;
|
|
13
|
-
}({});
|
|
14
|
-
export const OffenseSchema = z.nativeEnum(Offense);
|
|
15
|
-
export const MonitoredSlashPayloadSchema = z.object({
|
|
16
|
-
payloadAddress: schemas.EthAddress,
|
|
17
|
-
validators: z.array(schemas.EthAddress),
|
|
18
|
-
amounts: z.array(schemas.BigInt),
|
|
19
|
-
offenses: z.array(OffenseSchema),
|
|
20
|
-
observedAtSeconds: z.number(),
|
|
21
|
-
totalAmount: schemas.BigInt
|
|
22
|
-
});
|
|
23
|
-
export const OffenseToBigInt = {
|
|
24
|
-
[0]: 0n,
|
|
25
|
-
[1]: 1n,
|
|
26
|
-
[2]: 2n,
|
|
27
|
-
[3]: 3n,
|
|
28
|
-
[4]: 4n,
|
|
29
|
-
[5]: 5n,
|
|
30
|
-
[6]: 6n,
|
|
31
|
-
[7]: 7n
|
|
32
|
-
};
|
|
33
|
-
export function bigIntToOffense(offense) {
|
|
34
|
-
switch(offense){
|
|
35
|
-
case 0n:
|
|
36
|
-
return 0;
|
|
37
|
-
case 1n:
|
|
38
|
-
return 1;
|
|
39
|
-
case 2n:
|
|
40
|
-
return 2;
|
|
41
|
-
case 3n:
|
|
42
|
-
return 3;
|
|
43
|
-
case 4n:
|
|
44
|
-
return 4;
|
|
45
|
-
case 5n:
|
|
46
|
-
return 5;
|
|
47
|
-
case 6n:
|
|
48
|
-
return 6;
|
|
49
|
-
case 7n:
|
|
50
|
-
return 7;
|
|
51
|
-
default:
|
|
52
|
-
throw new Error(`Unknown offense: ${offense}`);
|
|
53
|
-
}
|
|
54
|
-
}
|
|
1
|
+
export * from './types.js';
|
|
2
|
+
export * from './interfaces.js';
|
|
3
|
+
export * from './helpers.js';
|
|
4
|
+
export * from './empire.js';
|
|
5
|
+
export * from './tally.js';
|
|
6
|
+
export * from './serialization.js';
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ProposerSlashAction } from './types.js';
|
|
2
|
+
export interface ProposerSlashActionProvider {
|
|
3
|
+
/**
|
|
4
|
+
* Returns the actions to take for the proposer in the current slot.
|
|
5
|
+
* This can include creating a slash payload or other actions.
|
|
6
|
+
* @param slotNumber - The current slot number
|
|
7
|
+
* @returns The actions to take
|
|
8
|
+
*/
|
|
9
|
+
getProposerActions(slotNumber: bigint): Promise<ProposerSlashAction[]>;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=interfaces.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interfaces.d.ts","sourceRoot":"","sources":["../../src/slashing/interfaces.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAEtD,MAAM,WAAW,2BAA2B;IAC1C;;;;;OAKG;IACH,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAAC;CACxE"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Offense, SlashPayload, SlashPayloadRound } from './types.js';
|
|
2
|
+
export declare function serializeOffense(offense: Offense): Buffer;
|
|
3
|
+
export declare function deserializeOffense(buffer: Buffer): Offense;
|
|
4
|
+
export declare function serializeSlashPayload(payload: SlashPayload): Buffer;
|
|
5
|
+
export declare function deserializeSlashPayload(buffer: Buffer): SlashPayload;
|
|
6
|
+
export declare function serializeSlashPayloadRound(payload: SlashPayloadRound): Buffer;
|
|
7
|
+
export declare function deserializeSlashPayloadRound(buffer: Buffer): SlashPayloadRound;
|
|
8
|
+
//# sourceMappingURL=serialization.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serialization.d.ts","sourceRoot":"","sources":["../../src/slashing/serialization.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,OAAO,EAEP,YAAY,EACZ,iBAAiB,EAGlB,MAAM,YAAY,CAAC;AAEpB,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAOzD;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAQ1D;AAiCD,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,YAAY,GAAG,MAAM,CAOnE;AAED,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,MAAM,GAAG,YAAY,CAOpE;AAED,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,iBAAiB,GAAG,MAAM,CAS7E;AAED,wBAAgB,4BAA4B,CAAC,MAAM,EAAE,MAAM,GAAG,iBAAiB,CAU9E"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { times } from '@aztec/foundation/collection';
|
|
2
|
+
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
3
|
+
import { BufferReader, bigintToUInt64BE, bigintToUInt128BE, serializeToBuffer } from '@aztec/foundation/serialize';
|
|
4
|
+
export function serializeOffense(offense) {
|
|
5
|
+
return serializeToBuffer(offense.validator, bigintToUInt128BE(offense.amount), offense.offenseType, bigintToUInt64BE(offense.epochOrSlot));
|
|
6
|
+
}
|
|
7
|
+
export function deserializeOffense(buffer) {
|
|
8
|
+
const reader = BufferReader.asReader(buffer);
|
|
9
|
+
const validator = reader.readObject(EthAddress);
|
|
10
|
+
const amount = reader.readUInt128();
|
|
11
|
+
const offense = reader.readNumber();
|
|
12
|
+
const epochOrSlot = reader.readUInt64();
|
|
13
|
+
return {
|
|
14
|
+
validator,
|
|
15
|
+
amount,
|
|
16
|
+
offenseType: offense,
|
|
17
|
+
epochOrSlot
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
function serializeValidatorSlashOffense(offense) {
|
|
21
|
+
return serializeToBuffer(bigintToUInt64BE(offense.epochOrSlot), offense.offenseType);
|
|
22
|
+
}
|
|
23
|
+
function deserializeValidatorSlashOffense(buffer) {
|
|
24
|
+
const reader = BufferReader.asReader(buffer);
|
|
25
|
+
return {
|
|
26
|
+
epochOrSlot: reader.readUInt64(),
|
|
27
|
+
offenseType: reader.readNumber()
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
function serializeValidatorSlash(slash) {
|
|
31
|
+
return serializeToBuffer(slash.validator, bigintToUInt128BE(slash.amount), slash.offenses.length, slash.offenses.map(serializeValidatorSlashOffense));
|
|
32
|
+
}
|
|
33
|
+
function deserializeValidatorSlash(buffer) {
|
|
34
|
+
const reader = BufferReader.asReader(buffer);
|
|
35
|
+
const validator = reader.readObject(EthAddress);
|
|
36
|
+
const amount = reader.readUInt128();
|
|
37
|
+
const offensesCount = reader.readNumber();
|
|
38
|
+
const offenses = times(offensesCount, ()=>deserializeValidatorSlashOffense(reader));
|
|
39
|
+
return {
|
|
40
|
+
validator,
|
|
41
|
+
amount,
|
|
42
|
+
offenses
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
export function serializeSlashPayload(payload) {
|
|
46
|
+
return serializeToBuffer(payload.address, payload.slashes.length, payload.slashes.map(serializeValidatorSlash), bigintToUInt64BE(payload.timestamp));
|
|
47
|
+
}
|
|
48
|
+
export function deserializeSlashPayload(buffer) {
|
|
49
|
+
const reader = BufferReader.asReader(buffer);
|
|
50
|
+
const address = reader.readObject(EthAddress);
|
|
51
|
+
const slashesCount = reader.readNumber();
|
|
52
|
+
const slashes = times(slashesCount, ()=>deserializeValidatorSlash(reader));
|
|
53
|
+
const timestamp = reader.readUInt64();
|
|
54
|
+
return {
|
|
55
|
+
address,
|
|
56
|
+
slashes,
|
|
57
|
+
timestamp
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
export function serializeSlashPayloadRound(payload) {
|
|
61
|
+
return serializeToBuffer(payload.address, payload.slashes.length, payload.slashes.map(serializeValidatorSlash), bigintToUInt64BE(payload.timestamp), Number(payload.votes), bigintToUInt64BE(payload.round));
|
|
62
|
+
}
|
|
63
|
+
export function deserializeSlashPayloadRound(buffer) {
|
|
64
|
+
const reader = BufferReader.asReader(buffer);
|
|
65
|
+
const address = reader.readObject(EthAddress);
|
|
66
|
+
const slashesCount = reader.readNumber();
|
|
67
|
+
const slashes = times(slashesCount, ()=>deserializeValidatorSlash(reader));
|
|
68
|
+
const timestamp = reader.readUInt64();
|
|
69
|
+
const votes = BigInt(reader.readNumber());
|
|
70
|
+
const round = reader.readUInt64();
|
|
71
|
+
return {
|
|
72
|
+
address,
|
|
73
|
+
slashes,
|
|
74
|
+
timestamp,
|
|
75
|
+
votes,
|
|
76
|
+
round
|
|
77
|
+
};
|
|
78
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { EthAddress } from '@aztec/foundation/eth-address';
|
|
2
|
+
import type { Offense, ValidatorSlashVote } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Creates a consensus-slash vote for a given set of committees based on a set of Offenses
|
|
5
|
+
* @returns Array of ValidatorSlashVote, where each vote is how many slash units the validator in that position should be slashed
|
|
6
|
+
*/
|
|
7
|
+
export declare function getSlashConsensusVotesFromOffenses(offenses: Offense[], committees: EthAddress[][], settings: {
|
|
8
|
+
slashingUnit: bigint;
|
|
9
|
+
}): ValidatorSlashVote[];
|
|
10
|
+
/**
|
|
11
|
+
* Encodes a set of slash votes into a Buffer for use in a consensus slashing vote transaction.
|
|
12
|
+
* Each vote is represented as a 2-bit value, which represents how many slashing units the validator should be slashed.
|
|
13
|
+
* @param votes - The array of slash votes to encode
|
|
14
|
+
* @returns A Buffer containing the encoded slash votes
|
|
15
|
+
*/
|
|
16
|
+
export declare function encodeSlashConsensusVotes(votes: ValidatorSlashVote[]): Buffer;
|
|
17
|
+
//# sourceMappingURL=tally.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tally.d.ts","sourceRoot":"","sources":["../../src/slashing/tally.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAEhE,OAAO,KAAK,EAAE,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAK9D;;;GAGG;AACH,wBAAgB,kCAAkC,CAChD,QAAQ,EAAE,OAAO,EAAE,EACnB,UAAU,EAAE,UAAU,EAAE,EAAE,EAC1B,QAAQ,EAAE;IAAE,YAAY,EAAE,MAAM,CAAA;CAAE,GACjC,kBAAkB,EAAE,CAgBtB;AAED;;;;;GAKG;AACH,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,kBAAkB,EAAE,GAAG,MAAM,CAU7E"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { minBigint, sumBigint } from '@aztec/foundation/bigint';
|
|
2
|
+
/** How many slashing units a validator can be slashed in consensus-based slashing */ const MAX_SLASH_UNITS_PER_VALIDATOR = 3n;
|
|
3
|
+
/**
|
|
4
|
+
* Creates a consensus-slash vote for a given set of committees based on a set of Offenses
|
|
5
|
+
* @returns Array of ValidatorSlashVote, where each vote is how many slash units the validator in that position should be slashed
|
|
6
|
+
*/ export function getSlashConsensusVotesFromOffenses(offenses, committees, settings) {
|
|
7
|
+
const { slashingUnit } = settings;
|
|
8
|
+
const slashed = new Set();
|
|
9
|
+
const votes = committees.flatMap((committee)=>committee.map((validator)=>{
|
|
10
|
+
if (slashed.has(validator.toString())) {
|
|
11
|
+
return 0; // Already voted for slashing this validator
|
|
12
|
+
}
|
|
13
|
+
const validatorOffenses = offenses.filter((o)=>o.validator.equals(validator));
|
|
14
|
+
const slashAmount = sumBigint(validatorOffenses.map((o)=>o.amount));
|
|
15
|
+
const slashUnits = minBigint(slashAmount / slashingUnit, MAX_SLASH_UNITS_PER_VALIDATOR);
|
|
16
|
+
slashed.add(validator.toString());
|
|
17
|
+
return Number(slashUnits);
|
|
18
|
+
}));
|
|
19
|
+
return votes;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Encodes a set of slash votes into a Buffer for use in a consensus slashing vote transaction.
|
|
23
|
+
* Each vote is represented as a 2-bit value, which represents how many slashing units the validator should be slashed.
|
|
24
|
+
* @param votes - The array of slash votes to encode
|
|
25
|
+
* @returns A Buffer containing the encoded slash votes
|
|
26
|
+
*/ export function encodeSlashConsensusVotes(votes) {
|
|
27
|
+
if (votes.length % 4 !== 0) {
|
|
28
|
+
throw new Error('Votes array must have a length that is a multiple of 4');
|
|
29
|
+
}
|
|
30
|
+
const buffer = Buffer.alloc(votes.length / 4);
|
|
31
|
+
for(let i = 0; i < votes.length; i += 4){
|
|
32
|
+
const voteByte = votes[i] << 6 | votes[i + 1] << 4 | votes[i + 2] << 2 | votes[i + 3]; // Combine four votes into one byte
|
|
33
|
+
buffer.writeUInt8(voteByte, i / 4);
|
|
34
|
+
}
|
|
35
|
+
return buffer;
|
|
36
|
+
}
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { type ZodFor } from '../schemas/index.js';
|
|
4
|
+
export declare enum OffenseType {
|
|
5
|
+
UNKNOWN = 0,
|
|
6
|
+
/** The data for proving an epoch was not publicly available, we slash its committee */
|
|
7
|
+
DATA_WITHHOLDING = 1,
|
|
8
|
+
/** An epoch was not successfully proven in time, we slash its committee */
|
|
9
|
+
VALID_EPOCH_PRUNED = 2,
|
|
10
|
+
/** A proposer failed to attest or propose during an epoch according to the Sentinel */
|
|
11
|
+
INACTIVITY = 3,
|
|
12
|
+
/** A proposer sent an invalid block proposal over the p2p network to the committee */
|
|
13
|
+
BROADCASTED_INVALID_BLOCK_PROPOSAL = 4,
|
|
14
|
+
/** A proposer pushed to L1 a block with insufficient committee attestations */
|
|
15
|
+
PROPOSED_INSUFFICIENT_ATTESTATIONS = 5,
|
|
16
|
+
/** A proposer pushed to L1 a block with incorrect committee attestations (ie signature from a non-committee member) */
|
|
17
|
+
PROPOSED_INCORRECT_ATTESTATIONS = 6,
|
|
18
|
+
/** A committee member attested to a block that was built as a descendent of an invalid block (as in a block with invalid attestations) */
|
|
19
|
+
ATTESTED_DESCENDANT_OF_INVALID = 7
|
|
20
|
+
}
|
|
21
|
+
export declare const OffenseTypeSchema: z.ZodNativeEnum<typeof OffenseType>;
|
|
22
|
+
export declare const OffenseToBigInt: Record<OffenseType, bigint>;
|
|
23
|
+
export declare function bigIntToOffense(offense: bigint): OffenseType;
|
|
24
|
+
export type Offense = {
|
|
25
|
+
validator: EthAddress;
|
|
26
|
+
amount: bigint;
|
|
27
|
+
offenseType: OffenseType;
|
|
28
|
+
epochOrSlot: bigint;
|
|
29
|
+
};
|
|
30
|
+
export type OffenseIdentifier = Pick<Offense, 'validator' | 'offenseType' | 'epochOrSlot'>;
|
|
31
|
+
export declare const OffenseSchema: z.ZodObject<{
|
|
32
|
+
validator: ZodFor<EthAddress>;
|
|
33
|
+
amount: z.ZodPipeline<z.ZodUnion<[z.ZodBigInt, z.ZodNumber, z.ZodString]>, z.ZodBigInt>;
|
|
34
|
+
offenseType: z.ZodNativeEnum<typeof OffenseType>;
|
|
35
|
+
epochOrSlot: z.ZodPipeline<z.ZodUnion<[z.ZodBigInt, z.ZodNumber, z.ZodString]>, z.ZodBigInt>;
|
|
36
|
+
}, "strip", z.ZodTypeAny, {
|
|
37
|
+
amount: bigint;
|
|
38
|
+
validator: EthAddress;
|
|
39
|
+
offenseType: OffenseType;
|
|
40
|
+
epochOrSlot: bigint;
|
|
41
|
+
}, {
|
|
42
|
+
amount: string | number | bigint;
|
|
43
|
+
offenseType: OffenseType;
|
|
44
|
+
epochOrSlot: string | number | bigint;
|
|
45
|
+
validator?: any;
|
|
46
|
+
}>;
|
|
47
|
+
/** Offense by a validator in the context of a slash payload */
|
|
48
|
+
export type ValidatorSlashOffense = {
|
|
49
|
+
epochOrSlot: bigint;
|
|
50
|
+
offenseType: OffenseType;
|
|
51
|
+
};
|
|
52
|
+
/** Slashed amount and total offenses by a validator in the context of a slash payload */
|
|
53
|
+
export type ValidatorSlash = {
|
|
54
|
+
validator: EthAddress;
|
|
55
|
+
amount: bigint;
|
|
56
|
+
offenses: ValidatorSlashOffense[];
|
|
57
|
+
};
|
|
58
|
+
/** Slash payload as published by the empire slash proposer */
|
|
59
|
+
export type SlashPayload = {
|
|
60
|
+
address: EthAddress;
|
|
61
|
+
slashes: ValidatorSlash[];
|
|
62
|
+
timestamp: bigint;
|
|
63
|
+
};
|
|
64
|
+
/** Slash payload with round information from empire slash proposer */
|
|
65
|
+
export type SlashPayloadRound = SlashPayload & {
|
|
66
|
+
votes: bigint;
|
|
67
|
+
round: bigint;
|
|
68
|
+
};
|
|
69
|
+
export declare const SlashPayloadRoundSchema: z.ZodObject<{
|
|
70
|
+
address: ZodFor<EthAddress>;
|
|
71
|
+
timestamp: z.ZodPipeline<z.ZodUnion<[z.ZodBigInt, z.ZodNumber, z.ZodString]>, z.ZodBigInt>;
|
|
72
|
+
votes: z.ZodPipeline<z.ZodUnion<[z.ZodBigInt, z.ZodNumber, z.ZodString]>, z.ZodBigInt>;
|
|
73
|
+
round: z.ZodPipeline<z.ZodUnion<[z.ZodBigInt, z.ZodNumber, z.ZodString]>, z.ZodBigInt>;
|
|
74
|
+
slashes: z.ZodArray<z.ZodObject<{
|
|
75
|
+
validator: ZodFor<EthAddress>;
|
|
76
|
+
amount: z.ZodPipeline<z.ZodUnion<[z.ZodBigInt, z.ZodNumber, z.ZodString]>, z.ZodBigInt>;
|
|
77
|
+
offenses: z.ZodArray<z.ZodObject<{
|
|
78
|
+
offenseType: z.ZodNativeEnum<typeof OffenseType>;
|
|
79
|
+
epochOrSlot: z.ZodPipeline<z.ZodUnion<[z.ZodBigInt, z.ZodNumber, z.ZodString]>, z.ZodBigInt>;
|
|
80
|
+
}, "strip", z.ZodTypeAny, {
|
|
81
|
+
offenseType: OffenseType;
|
|
82
|
+
epochOrSlot: bigint;
|
|
83
|
+
}, {
|
|
84
|
+
offenseType: OffenseType;
|
|
85
|
+
epochOrSlot: string | number | bigint;
|
|
86
|
+
}>, "many">;
|
|
87
|
+
}, "strip", z.ZodTypeAny, {
|
|
88
|
+
amount: bigint;
|
|
89
|
+
validator: EthAddress;
|
|
90
|
+
offenses: {
|
|
91
|
+
offenseType: OffenseType;
|
|
92
|
+
epochOrSlot: bigint;
|
|
93
|
+
}[];
|
|
94
|
+
}, {
|
|
95
|
+
amount: string | number | bigint;
|
|
96
|
+
offenses: {
|
|
97
|
+
offenseType: OffenseType;
|
|
98
|
+
epochOrSlot: string | number | bigint;
|
|
99
|
+
}[];
|
|
100
|
+
validator?: any;
|
|
101
|
+
}>, "many">;
|
|
102
|
+
}, "strip", z.ZodTypeAny, {
|
|
103
|
+
timestamp: bigint;
|
|
104
|
+
address: EthAddress;
|
|
105
|
+
votes: bigint;
|
|
106
|
+
round: bigint;
|
|
107
|
+
slashes: {
|
|
108
|
+
amount: bigint;
|
|
109
|
+
validator: EthAddress;
|
|
110
|
+
offenses: {
|
|
111
|
+
offenseType: OffenseType;
|
|
112
|
+
epochOrSlot: bigint;
|
|
113
|
+
}[];
|
|
114
|
+
}[];
|
|
115
|
+
}, {
|
|
116
|
+
timestamp: string | number | bigint;
|
|
117
|
+
votes: string | number | bigint;
|
|
118
|
+
round: string | number | bigint;
|
|
119
|
+
slashes: {
|
|
120
|
+
amount: string | number | bigint;
|
|
121
|
+
offenses: {
|
|
122
|
+
offenseType: OffenseType;
|
|
123
|
+
epochOrSlot: string | number | bigint;
|
|
124
|
+
}[];
|
|
125
|
+
validator?: any;
|
|
126
|
+
}[];
|
|
127
|
+
address?: any;
|
|
128
|
+
}>;
|
|
129
|
+
/** Votes for a validator slash in the consensus slash proposer */
|
|
130
|
+
export type ValidatorSlashVote = number;
|
|
131
|
+
export type ProposerSlashAction =
|
|
132
|
+
/** Create a new slash payload on an empire-based slash proposer */
|
|
133
|
+
{
|
|
134
|
+
type: 'create-empire-payload';
|
|
135
|
+
data: ValidatorSlash[];
|
|
136
|
+
}
|
|
137
|
+
/** Vote for a slashing payload on an empire-based slash proposer */
|
|
138
|
+
| {
|
|
139
|
+
type: 'vote-empire-payload';
|
|
140
|
+
payload: EthAddress;
|
|
141
|
+
}
|
|
142
|
+
/** Execute a slashing payload on an empire-based slash proposer */
|
|
143
|
+
| {
|
|
144
|
+
type: 'execute-empire-payload';
|
|
145
|
+
round: bigint;
|
|
146
|
+
}
|
|
147
|
+
/** Vote for offenses on a consensus slashing proposer */
|
|
148
|
+
| {
|
|
149
|
+
type: 'vote-offenses';
|
|
150
|
+
votes: ValidatorSlashVote[];
|
|
151
|
+
committees: EthAddress[][];
|
|
152
|
+
round: bigint;
|
|
153
|
+
}
|
|
154
|
+
/** Execute a slashing round on a consensus slashing proposer */
|
|
155
|
+
| {
|
|
156
|
+
type: 'execute-slash';
|
|
157
|
+
committees: EthAddress[][];
|
|
158
|
+
round: bigint;
|
|
159
|
+
};
|
|
160
|
+
export type ProposerSlashActionType = ProposerSlashAction['type'];
|
|
161
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/slashing/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAE3D,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,KAAK,MAAM,EAAW,MAAM,qBAAqB,CAAC;AAE3D,oBAAY,WAAW;IACrB,OAAO,IAAI;IACX,uFAAuF;IACvF,gBAAgB,IAAI;IACpB,2EAA2E;IAC3E,kBAAkB,IAAI;IACtB,uFAAuF;IACvF,UAAU,IAAI;IACd,sFAAsF;IACtF,kCAAkC,IAAI;IACtC,+EAA+E;IAC/E,kCAAkC,IAAI;IACtC,uHAAuH;IACvH,+BAA+B,IAAI;IACnC,0IAA0I;IAC1I,8BAA8B,IAAI;CACnC;AAED,eAAO,MAAM,iBAAiB,qCAA4B,CAAC;AAE3D,eAAO,MAAM,eAAe,EAAE,MAAM,CAAC,WAAW,EAAE,MAAM,CASvD,CAAC;AAEF,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW,CAqB5D;AAED,MAAM,MAAM,OAAO,GAAG;IACpB,SAAS,EAAE,UAAU,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,WAAW,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG,IAAI,CAAC,OAAO,EAAE,WAAW,GAAG,aAAa,GAAG,aAAa,CAAC,CAAC;AAE3F,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;EAKE,CAAC;AAE7B,+DAA+D;AAC/D,MAAM,MAAM,qBAAqB,GAAG;IAClC,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,WAAW,CAAC;CAC1B,CAAC;AAEF,yFAAyF;AACzF,MAAM,MAAM,cAAc,GAAG;IAC3B,SAAS,EAAE,UAAU,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,qBAAqB,EAAE,CAAC;CACnC,CAAC;AAEF,8DAA8D;AAC9D,MAAM,MAAM,YAAY,GAAG;IACzB,OAAO,EAAE,UAAU,CAAC;IACpB,OAAO,EAAE,cAAc,EAAE,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,sEAAsE;AACtE,MAAM,MAAM,iBAAiB,GAAG,YAAY,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAEhF,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAYE,CAAC;AAEvC,kEAAkE;AAClE,MAAM,MAAM,kBAAkB,GAAG,MAAM,CAAC;AAExC,MAAM,MAAM,mBAAmB;AAC7B,mEAAmE;AACjE;IAAE,IAAI,EAAE,uBAAuB,CAAC;IAAC,IAAI,EAAE,cAAc,EAAE,CAAA;CAAE;AAC3D,oEAAoE;GAClE;IAAE,IAAI,EAAE,qBAAqB,CAAC;IAAC,OAAO,EAAE,UAAU,CAAA;CAAE;AACtD,mEAAmE;GACjE;IAAE,IAAI,EAAE,wBAAwB,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE;AACnD,yDAAyD;GACvD;IAAE,IAAI,EAAE,eAAe,CAAC;IAAC,KAAK,EAAE,kBAAkB,EAAE,CAAC;IAAC,UAAU,EAAE,UAAU,EAAE,EAAE,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE;AACnG,gEAAgE;GAC9D;IAAE,IAAI,EAAE,eAAe,CAAC;IAAC,UAAU,EAAE,UAAU,EAAE,EAAE,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAEzE,MAAM,MAAM,uBAAuB,GAAG,mBAAmB,CAAC,MAAM,CAAC,CAAC"}
|