@aztec/slasher 0.0.1-commit.f5d02921e → 0.0.1-commit.f650c0a5c
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 +28 -52
- package/dest/config.d.ts +1 -1
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +0 -12
- package/dest/factory/create_facade.d.ts +2 -2
- package/dest/factory/create_facade.d.ts.map +1 -1
- package/dest/factory/create_facade.js +1 -1
- package/dest/factory/create_implementation.d.ts +4 -6
- package/dest/factory/create_implementation.d.ts.map +1 -1
- package/dest/factory/create_implementation.js +7 -59
- package/dest/factory/get_settings.d.ts +4 -4
- package/dest/factory/get_settings.d.ts.map +1 -1
- package/dest/factory/get_settings.js +3 -3
- package/dest/factory/index.d.ts +2 -2
- package/dest/factory/index.d.ts.map +1 -1
- package/dest/factory/index.js +1 -1
- package/dest/generated/slasher-defaults.d.ts +1 -3
- package/dest/generated/slasher-defaults.d.ts.map +1 -1
- package/dest/generated/slasher-defaults.js +0 -2
- package/dest/index.d.ts +2 -3
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +1 -2
- package/dest/null_slasher_client.d.ts +3 -4
- package/dest/null_slasher_client.d.ts.map +1 -1
- package/dest/null_slasher_client.js +1 -4
- package/dest/slash_offenses_collector.d.ts +1 -7
- package/dest/slash_offenses_collector.d.ts.map +1 -1
- package/dest/slash_offenses_collector.js +7 -16
- package/dest/slasher_client.d.ts +112 -0
- package/dest/slasher_client.d.ts.map +1 -0
- package/dest/{tally_slasher_client.js → slasher_client.js} +20 -34
- package/dest/slasher_client_facade.d.ts +4 -7
- package/dest/slasher_client_facade.d.ts.map +1 -1
- package/dest/slasher_client_facade.js +4 -9
- package/dest/slasher_client_interface.d.ts +7 -21
- package/dest/slasher_client_interface.d.ts.map +1 -1
- package/dest/slasher_client_interface.js +1 -4
- package/dest/stores/offenses_store.d.ts +6 -12
- package/dest/stores/offenses_store.d.ts.map +1 -1
- package/dest/stores/offenses_store.js +5 -24
- package/package.json +9 -9
- package/src/config.ts +0 -12
- package/src/factory/create_facade.ts +1 -2
- package/src/factory/create_implementation.ts +11 -117
- package/src/factory/get_settings.ts +8 -8
- package/src/factory/index.ts +1 -1
- package/src/generated/slasher-defaults.ts +0 -2
- package/src/index.ts +1 -2
- package/src/null_slasher_client.ts +2 -6
- package/src/slash_offenses_collector.ts +8 -17
- package/src/{tally_slasher_client.ts → slasher_client.ts} +25 -42
- package/src/slasher_client_facade.ts +3 -10
- package/src/slasher_client_interface.ts +6 -21
- package/src/stores/offenses_store.ts +8 -33
- package/dest/empire_slasher_client.d.ts +0 -190
- package/dest/empire_slasher_client.d.ts.map +0 -1
- package/dest/empire_slasher_client.js +0 -564
- package/dest/stores/payloads_store.d.ts +0 -29
- package/dest/stores/payloads_store.d.ts.map +0 -1
- package/dest/stores/payloads_store.js +0 -128
- package/dest/tally_slasher_client.d.ts +0 -125
- package/dest/tally_slasher_client.d.ts.map +0 -1
- package/src/empire_slasher_client.ts +0 -649
- package/src/stores/payloads_store.ts +0 -149
|
@@ -1,149 +0,0 @@
|
|
|
1
|
-
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
2
|
-
import type { AztecAsyncKVStore, AztecAsyncMap } from '@aztec/kv-store';
|
|
3
|
-
import {
|
|
4
|
-
type SlashPayload,
|
|
5
|
-
type SlashPayloadRound,
|
|
6
|
-
deserializeSlashPayload,
|
|
7
|
-
serializeSlashPayload,
|
|
8
|
-
} from '@aztec/stdlib/slashing';
|
|
9
|
-
|
|
10
|
-
export class SlasherPayloadsStore {
|
|
11
|
-
/** Map from payload address to payload data */
|
|
12
|
-
private payloads: AztecAsyncMap<string, Buffer>;
|
|
13
|
-
|
|
14
|
-
/** Map from `round:payload` to votes */
|
|
15
|
-
private roundPayloadVotes: AztecAsyncMap<string, bigint>;
|
|
16
|
-
|
|
17
|
-
constructor(
|
|
18
|
-
private kvStore: AztecAsyncKVStore,
|
|
19
|
-
private settings?: {
|
|
20
|
-
slashingPayloadLifetimeInRounds?: number;
|
|
21
|
-
},
|
|
22
|
-
) {
|
|
23
|
-
this.payloads = kvStore.openMap('slash-payloads');
|
|
24
|
-
this.roundPayloadVotes = kvStore.openMap('round-payload-votes');
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
public async getPayloadsForRound(round: bigint): Promise<SlashPayloadRound[]> {
|
|
28
|
-
const payloads: SlashPayloadRound[] = [];
|
|
29
|
-
const votes = await this.getVotesForRound(round);
|
|
30
|
-
for (const [address, votesCount] of votes) {
|
|
31
|
-
const payload = await this.getPayload(address);
|
|
32
|
-
if (payload) {
|
|
33
|
-
payloads.push({ ...payload, votes: votesCount, round });
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
return payloads;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
public async getPayloadAtRound(payloadAddress: EthAddress, round: bigint): Promise<SlashPayloadRound | undefined> {
|
|
40
|
-
const address = payloadAddress.toString();
|
|
41
|
-
const buffer = await this.payloads.getAsync(address);
|
|
42
|
-
if (!buffer) {
|
|
43
|
-
return undefined;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
const data = deserializeSlashPayload(buffer);
|
|
47
|
-
const votes = (await this.roundPayloadVotes.getAsync(this.getPayloadVotesKey(round, address))) ?? 0n;
|
|
48
|
-
|
|
49
|
-
return { ...data, votes, round };
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
private async getVotesForRound(round: bigint): Promise<[string, bigint][]> {
|
|
53
|
-
const votes: [string, bigint][] = [];
|
|
54
|
-
for await (const [fullKey, roundVotes] of this.roundPayloadVotes.entriesAsync(
|
|
55
|
-
this.getPayloadVotesKeyRangeForRound(round),
|
|
56
|
-
)) {
|
|
57
|
-
// Extract just the address part from the key (remove "round:" prefix)
|
|
58
|
-
const address = fullKey.split(':')[1];
|
|
59
|
-
votes.push([address, roundVotes]);
|
|
60
|
-
}
|
|
61
|
-
return votes;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
private getRoundKey(round: bigint): string {
|
|
65
|
-
return round.toString().padStart(16, '0');
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
private getPayloadVotesKey(round: bigint, payloadAddress: EthAddress | string): string {
|
|
69
|
-
return `${this.getRoundKey(round)}:${payloadAddress.toString()}`;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
private getPayloadVotesKeyRangeForRound(round: bigint): { start: string; end: string } {
|
|
73
|
-
const start = `${this.getRoundKey(round)}:`;
|
|
74
|
-
const end = `${this.getRoundKey(round)}:Z`; // 'Z' sorts after any hex address, 0x-prefixed or not
|
|
75
|
-
return { start, end };
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
/**
|
|
79
|
-
* Purge vote payload data for expired rounds. Does not delete actual payload data.
|
|
80
|
-
*/
|
|
81
|
-
public async clearExpiredPayloads(currentRound: bigint): Promise<void> {
|
|
82
|
-
const lifetimeInRounds = this.settings?.slashingPayloadLifetimeInRounds ?? 0;
|
|
83
|
-
if (lifetimeInRounds <= 0) {
|
|
84
|
-
return; // No lifetime configured
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
const expiredBefore = currentRound - BigInt(lifetimeInRounds);
|
|
88
|
-
if (expiredBefore < 0) {
|
|
89
|
-
return; // Not enough rounds have passed to expire anything
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
// Collect expired payload votes by scanning round-payload keys
|
|
93
|
-
const expiredPayloads: string[] = [];
|
|
94
|
-
const expiredVoteKeys: string[] = [];
|
|
95
|
-
|
|
96
|
-
for await (const key of this.roundPayloadVotes.keysAsync({
|
|
97
|
-
end: `${this.getRoundKey(expiredBefore)}:Z`,
|
|
98
|
-
})) {
|
|
99
|
-
const [roundStr, payloadAddress] = key.split(':');
|
|
100
|
-
if (BigInt(roundStr) <= expiredBefore) {
|
|
101
|
-
expiredVoteKeys.push(key);
|
|
102
|
-
expiredPayloads.push(payloadAddress);
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
if (expiredVoteKeys.length === 0) {
|
|
107
|
-
return; // No expired payloads to clean up
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
// Remove expired payload vote records
|
|
111
|
-
// Note that we do not delete payload data since these could be repurposed in future votes
|
|
112
|
-
await this.kvStore.transactionAsync(async () => {
|
|
113
|
-
for (const key of expiredVoteKeys) {
|
|
114
|
-
await this.roundPayloadVotes.delete(key);
|
|
115
|
-
}
|
|
116
|
-
});
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
public async incrementPayloadVotes(payloadAddress: EthAddress, round: bigint): Promise<bigint> {
|
|
120
|
-
const key = this.getPayloadVotesKey(round, payloadAddress);
|
|
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!;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
public async addPayload(payload: SlashPayloadRound): Promise<void> {
|
|
131
|
-
const address = payload.address.toString();
|
|
132
|
-
|
|
133
|
-
await this.kvStore.transactionAsync(async () => {
|
|
134
|
-
await this.payloads.set(address, serializeSlashPayload(payload));
|
|
135
|
-
await this.roundPayloadVotes.set(this.getPayloadVotesKey(payload.round, address), payload.votes);
|
|
136
|
-
});
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
public async getPayload(payloadAddress: EthAddress | string): Promise<SlashPayload | undefined> {
|
|
140
|
-
const address = payloadAddress.toString();
|
|
141
|
-
const buffer = await this.payloads.getAsync(address);
|
|
142
|
-
return buffer ? deserializeSlashPayload(buffer) : undefined;
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
public async hasPayload(payload: EthAddress): Promise<boolean> {
|
|
146
|
-
const address = payload.toString();
|
|
147
|
-
return (await this.payloads.getAsync(address)) !== undefined;
|
|
148
|
-
}
|
|
149
|
-
}
|