@aztec/p2p 3.0.0-nightly.20251127 → 3.0.0-nightly.20251201.2
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/bootstrap/bootstrap.d.ts +1 -1
- package/dest/bootstrap/bootstrap.d.ts.map +1 -1
- package/dest/client/factory.d.ts +1 -1
- package/dest/client/index.d.ts +1 -1
- package/dest/client/interface.d.ts +1 -1
- package/dest/client/p2p_client.d.ts +3 -22
- package/dest/client/p2p_client.d.ts.map +1 -1
- package/dest/client/p2p_client.js +5 -4
- package/dest/config.d.ts +56 -56
- package/dest/enr/generate-enr.d.ts +1 -1
- package/dest/enr/index.d.ts +1 -1
- package/dest/errors/attestation-pool.error.d.ts +1 -1
- package/dest/errors/attestation-pool.error.d.ts.map +1 -1
- package/dest/errors/reqresp.error.d.ts +1 -1
- package/dest/errors/reqresp.error.d.ts.map +1 -1
- package/dest/index.d.ts +1 -1
- package/dest/mem_pools/attestation_pool/attestation_pool.d.ts +7 -6
- package/dest/mem_pools/attestation_pool/attestation_pool.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.d.ts +1 -1
- package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.js +33 -32
- package/dest/mem_pools/attestation_pool/index.d.ts +1 -1
- package/dest/mem_pools/attestation_pool/kv_attestation_pool.d.ts +9 -8
- package/dest/mem_pools/attestation_pool/kv_attestation_pool.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/kv_attestation_pool.js +19 -20
- package/dest/mem_pools/attestation_pool/memory_attestation_pool.d.ts +9 -8
- package/dest/mem_pools/attestation_pool/memory_attestation_pool.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/memory_attestation_pool.js +12 -10
- package/dest/mem_pools/attestation_pool/mocks.d.ts +224 -3
- package/dest/mem_pools/attestation_pool/mocks.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/mocks.js +1 -1
- package/dest/mem_pools/index.d.ts +1 -1
- package/dest/mem_pools/instrumentation.d.ts +1 -1
- package/dest/mem_pools/instrumentation.d.ts.map +1 -1
- package/dest/mem_pools/interface.d.ts +1 -1
- package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts +1 -36
- package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool/index.d.ts +1 -1
- package/dest/mem_pools/tx_pool/memory_tx_pool.d.ts +1 -1
- package/dest/mem_pools/tx_pool/memory_tx_pool.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool/priority.d.ts +1 -1
- package/dest/mem_pools/tx_pool/tx_pool.d.ts +1 -1
- package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts +1 -1
- package/dest/msg_validators/attestation_validator/attestation_validator.d.ts +1 -1
- package/dest/msg_validators/attestation_validator/attestation_validator.d.ts.map +1 -1
- package/dest/msg_validators/attestation_validator/attestation_validator.js +11 -11
- package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts +1 -1
- package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts.map +1 -1
- package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.js +1 -1
- package/dest/msg_validators/attestation_validator/index.d.ts +1 -1
- package/dest/msg_validators/block_proposal_validator/block_proposal_validator.d.ts +1 -1
- package/dest/msg_validators/block_proposal_validator/block_proposal_validator.d.ts.map +1 -1
- package/dest/msg_validators/block_proposal_validator/block_proposal_validator.js +8 -8
- package/dest/msg_validators/block_proposal_validator/index.d.ts +1 -1
- package/dest/msg_validators/index.d.ts +1 -1
- package/dest/msg_validators/msg_seen_validator/msg_seen_validator.d.ts +1 -1
- package/dest/msg_validators/msg_seen_validator/msg_seen_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/aggregate_tx_validator.d.ts +1 -1
- package/dest/msg_validators/tx_validator/aggregate_tx_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/allowed_public_setup.d.ts +1 -1
- package/dest/msg_validators/tx_validator/archive_cache.d.ts +1 -1
- package/dest/msg_validators/tx_validator/archive_cache.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/block_header_validator.d.ts +1 -1
- package/dest/msg_validators/tx_validator/block_header_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/data_validator.d.ts +1 -1
- package/dest/msg_validators/tx_validator/data_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/double_spend_validator.d.ts +1 -1
- package/dest/msg_validators/tx_validator/double_spend_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/factory.d.ts +1 -1
- package/dest/msg_validators/tx_validator/gas_validator.d.ts +1 -1
- package/dest/msg_validators/tx_validator/gas_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/index.d.ts +1 -1
- package/dest/msg_validators/tx_validator/metadata_validator.d.ts +1 -1
- package/dest/msg_validators/tx_validator/metadata_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/phases_validator.d.ts +1 -1
- package/dest/msg_validators/tx_validator/phases_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/test_utils.d.ts +1 -1
- package/dest/msg_validators/tx_validator/timestamp_validator.d.ts +1 -1
- package/dest/msg_validators/tx_validator/timestamp_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/tx_permitted_validator.d.ts +1 -1
- package/dest/msg_validators/tx_validator/tx_permitted_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/tx_proof_validator.d.ts +1 -1
- package/dest/msg_validators/tx_validator/tx_proof_validator.d.ts.map +1 -1
- package/dest/services/data_store.d.ts +1 -1
- package/dest/services/data_store.d.ts.map +1 -1
- package/dest/services/discv5/discV5_service.d.ts +1 -1
- package/dest/services/discv5/discV5_service.d.ts.map +1 -1
- package/dest/services/dummy_service.d.ts +1 -1
- package/dest/services/dummy_service.d.ts.map +1 -1
- package/dest/services/encoding.d.ts +1 -1
- package/dest/services/encoding.d.ts.map +1 -1
- package/dest/services/gossipsub/scoring.d.ts +1 -1
- package/dest/services/index.d.ts +1 -1
- package/dest/services/libp2p/instrumentation.d.ts +1 -1
- package/dest/services/libp2p/instrumentation.d.ts.map +1 -1
- package/dest/services/libp2p/libp2p_service.d.ts +1 -76
- package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
- package/dest/services/libp2p/libp2p_service.js +14 -13
- package/dest/services/peer-manager/interface.d.ts +1 -1
- package/dest/services/peer-manager/metrics.d.ts +1 -1
- package/dest/services/peer-manager/metrics.d.ts.map +1 -1
- package/dest/services/peer-manager/peer_manager.d.ts +1 -32
- package/dest/services/peer-manager/peer_manager.d.ts.map +1 -1
- package/dest/services/peer-manager/peer_scoring.d.ts +1 -1
- package/dest/services/peer-manager/peer_scoring.d.ts.map +1 -1
- package/dest/services/reqresp/config.d.ts +1 -1
- package/dest/services/reqresp/connection-sampler/batch_connection_sampler.d.ts +1 -1
- package/dest/services/reqresp/connection-sampler/batch_connection_sampler.d.ts.map +1 -1
- package/dest/services/reqresp/connection-sampler/connection_sampler.d.ts +1 -4
- package/dest/services/reqresp/connection-sampler/connection_sampler.d.ts.map +1 -1
- package/dest/services/reqresp/index.d.ts +1 -1
- package/dest/services/reqresp/interface.d.ts +1 -1
- package/dest/services/reqresp/interface.d.ts.map +1 -1
- package/dest/services/reqresp/metrics.d.ts +1 -1
- package/dest/services/reqresp/metrics.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/auth.d.ts +1 -1
- package/dest/services/reqresp/protocols/auth.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/block.d.ts +1 -1
- package/dest/services/reqresp/protocols/block_txs/bitvector.d.ts +1 -1
- package/dest/services/reqresp/protocols/block_txs/bitvector.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/block_txs/block_txs_handler.d.ts +1 -1
- package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.d.ts +3 -5
- package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/block_txs/index.d.ts +1 -1
- package/dest/services/reqresp/protocols/goodbye.d.ts +1 -1
- package/dest/services/reqresp/protocols/goodbye.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/index.d.ts +1 -1
- package/dest/services/reqresp/protocols/ping.d.ts +1 -1
- package/dest/services/reqresp/protocols/status.d.ts +2 -2
- package/dest/services/reqresp/protocols/status.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/tx.d.ts +1 -1
- package/dest/services/reqresp/rate-limiter/index.d.ts +1 -1
- package/dest/services/reqresp/rate-limiter/rate_limiter.d.ts +2 -2
- package/dest/services/reqresp/rate-limiter/rate_limiter.d.ts.map +1 -1
- package/dest/services/reqresp/rate-limiter/rate_limits.d.ts +1 -1
- package/dest/services/reqresp/reqresp.d.ts +1 -41
- package/dest/services/reqresp/reqresp.d.ts.map +1 -1
- package/dest/services/reqresp/status.d.ts +2 -2
- package/dest/services/reqresp/status.d.ts.map +1 -1
- package/dest/services/service.d.ts +1 -1
- package/dest/services/tx_collection/config.d.ts +1 -1
- package/dest/services/tx_collection/fast_tx_collection.d.ts +1 -7
- package/dest/services/tx_collection/fast_tx_collection.d.ts.map +1 -1
- package/dest/services/tx_collection/index.d.ts +1 -1
- package/dest/services/tx_collection/instrumentation.d.ts +1 -1
- package/dest/services/tx_collection/instrumentation.d.ts.map +1 -1
- package/dest/services/tx_collection/slow_tx_collection.d.ts +1 -3
- package/dest/services/tx_collection/slow_tx_collection.d.ts.map +1 -1
- package/dest/services/tx_collection/slow_tx_collection.js +2 -1
- package/dest/services/tx_collection/tx_collection.d.ts +1 -2
- package/dest/services/tx_collection/tx_collection.d.ts.map +1 -1
- package/dest/services/tx_collection/tx_collection_sink.d.ts +3 -3
- package/dest/services/tx_collection/tx_collection_sink.d.ts.map +1 -1
- package/dest/services/tx_collection/tx_source.d.ts +1 -1
- package/dest/services/tx_collection/tx_source.d.ts.map +1 -1
- package/dest/services/tx_provider.d.ts +1 -1
- package/dest/services/tx_provider.d.ts.map +1 -1
- package/dest/services/tx_provider_instrumentation.d.ts +1 -1
- package/dest/services/tx_provider_instrumentation.d.ts.map +1 -1
- package/dest/test-helpers/generate-peer-id-private-keys.d.ts +1 -1
- package/dest/test-helpers/get-ports.d.ts +1 -1
- package/dest/test-helpers/get-ports.d.ts.map +1 -1
- package/dest/test-helpers/index.d.ts +1 -1
- package/dest/test-helpers/make-enrs.d.ts +1 -1
- package/dest/test-helpers/make-test-p2p-clients.d.ts +2 -2
- package/dest/test-helpers/make-test-p2p-clients.d.ts.map +1 -1
- package/dest/test-helpers/mock-pubsub.d.ts +4 -4
- package/dest/test-helpers/mock-pubsub.d.ts.map +1 -1
- package/dest/test-helpers/mock-tx-helpers.d.ts +2 -2
- package/dest/test-helpers/mock-tx-helpers.d.ts.map +1 -1
- package/dest/test-helpers/reqresp-nodes.d.ts +1 -1
- package/dest/test-helpers/reqresp-nodes.d.ts.map +1 -1
- package/dest/testbench/p2p_client_testbench_worker.d.ts +1 -1
- package/dest/testbench/p2p_client_testbench_worker.js +8 -7
- package/dest/testbench/parse_log_file.d.ts +1 -1
- package/dest/testbench/testbench.d.ts +1 -1
- package/dest/testbench/worker_client_manager.d.ts +1 -1
- package/dest/testbench/worker_client_manager.d.ts.map +1 -1
- package/dest/types/index.d.ts +1 -1
- package/dest/util.d.ts +1 -1
- package/dest/versioning.d.ts +1 -1
- package/package.json +18 -17
- package/src/client/p2p_client.ts +6 -5
- package/src/mem_pools/attestation_pool/attestation_pool.ts +6 -5
- package/src/mem_pools/attestation_pool/attestation_pool_test_suite.ts +45 -32
- package/src/mem_pools/attestation_pool/kv_attestation_pool.ts +28 -29
- package/src/mem_pools/attestation_pool/memory_attestation_pool.ts +26 -22
- package/src/mem_pools/attestation_pool/mocks.ts +1 -1
- package/src/msg_validators/attestation_validator/attestation_validator.ts +11 -13
- package/src/msg_validators/attestation_validator/fisherman_attestation_validator.ts +1 -1
- package/src/msg_validators/block_proposal_validator/block_proposal_validator.ts +8 -8
- package/src/services/libp2p/libp2p_service.ts +14 -13
- package/src/services/tx_collection/slow_tx_collection.ts +3 -2
- package/src/testbench/p2p_client_testbench_worker.ts +6 -5
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { SlotNumber } from '@aztec/foundation/branded-types';
|
|
1
2
|
import { createLogger } from '@aztec/foundation/log';
|
|
2
3
|
import type { BlockAttestation, BlockProposal } from '@aztec/stdlib/p2p';
|
|
3
4
|
import { type TelemetryClient, getTelemetryClient } from '@aztec/telemetry-client';
|
|
@@ -9,7 +10,11 @@ import { ATTESTATION_CAP_BUFFER, MAX_PROPOSALS_PER_SLOT } from './kv_attestation
|
|
|
9
10
|
export class InMemoryAttestationPool implements AttestationPool {
|
|
10
11
|
private metrics: PoolInstrumentation<BlockAttestation>;
|
|
11
12
|
|
|
12
|
-
|
|
13
|
+
// eslint-disable-next-line aztec-custom/no-non-primitive-in-collections
|
|
14
|
+
private attestations: Map<
|
|
15
|
+
/*slot=*/ SlotNumber,
|
|
16
|
+
Map</*proposalId*/ string, Map</*address=*/ string, BlockAttestation>>
|
|
17
|
+
>;
|
|
13
18
|
private proposals: Map<string, BlockProposal>;
|
|
14
19
|
|
|
15
20
|
constructor(
|
|
@@ -31,7 +36,7 @@ export class InMemoryAttestationPool implements AttestationPool {
|
|
|
31
36
|
return Promise.resolve(this.attestations.size === 0);
|
|
32
37
|
}
|
|
33
38
|
|
|
34
|
-
public getAttestationsForSlot(slot:
|
|
39
|
+
public getAttestationsForSlot(slot: SlotNumber): Promise<BlockAttestation[]> {
|
|
35
40
|
return Promise.resolve(
|
|
36
41
|
Array.from(this.attestations.get(slot)?.values() ?? []).flatMap(proposalAttestationMap =>
|
|
37
42
|
Array.from(proposalAttestationMap.values()),
|
|
@@ -39,7 +44,7 @@ export class InMemoryAttestationPool implements AttestationPool {
|
|
|
39
44
|
);
|
|
40
45
|
}
|
|
41
46
|
|
|
42
|
-
public getAttestationsForSlotAndProposal(slot:
|
|
47
|
+
public getAttestationsForSlotAndProposal(slot: SlotNumber, proposalId: string): Promise<BlockAttestation[]> {
|
|
43
48
|
const slotAttestationMap = this.attestations.get(slot);
|
|
44
49
|
if (slotAttestationMap) {
|
|
45
50
|
const proposalAttestationMap = slotAttestationMap.get(proposalId);
|
|
@@ -60,7 +65,7 @@ export class InMemoryAttestationPool implements AttestationPool {
|
|
|
60
65
|
|
|
61
66
|
// Skip attestations with invalid signatures
|
|
62
67
|
if (!sender) {
|
|
63
|
-
this.log.warn(`Skipping attestation with invalid signature for slot ${slotNumber
|
|
68
|
+
this.log.warn(`Skipping attestation with invalid signature for slot ${slotNumber}`, {
|
|
64
69
|
signature: attestation.signature.toString(),
|
|
65
70
|
slotNumber,
|
|
66
71
|
proposalId,
|
|
@@ -68,11 +73,11 @@ export class InMemoryAttestationPool implements AttestationPool {
|
|
|
68
73
|
continue;
|
|
69
74
|
}
|
|
70
75
|
|
|
71
|
-
const slotAttestationMap = getSlotOrDefault(this.attestations, slotNumber
|
|
76
|
+
const slotAttestationMap = getSlotOrDefault(this.attestations, slotNumber);
|
|
72
77
|
const proposalAttestationMap = getProposalOrDefault(slotAttestationMap, proposalId);
|
|
73
78
|
proposalAttestationMap.set(sender.toString(), attestation);
|
|
74
79
|
|
|
75
|
-
this.log.verbose(`Added attestation for slot ${slotNumber
|
|
80
|
+
this.log.verbose(`Added attestation for slot ${slotNumber} from ${sender}`, {
|
|
76
81
|
signature: attestation.signature.toString(),
|
|
77
82
|
slotNumber,
|
|
78
83
|
address: sender,
|
|
@@ -83,7 +88,7 @@ export class InMemoryAttestationPool implements AttestationPool {
|
|
|
83
88
|
return Promise.resolve();
|
|
84
89
|
}
|
|
85
90
|
|
|
86
|
-
#getNumberOfAttestationsInSlot(slot:
|
|
91
|
+
#getNumberOfAttestationsInSlot(slot: SlotNumber): number {
|
|
87
92
|
let total = 0;
|
|
88
93
|
const slotAttestationMap = getSlotOrDefault(this.attestations, slot);
|
|
89
94
|
|
|
@@ -95,7 +100,7 @@ export class InMemoryAttestationPool implements AttestationPool {
|
|
|
95
100
|
return total;
|
|
96
101
|
}
|
|
97
102
|
|
|
98
|
-
public async deleteAttestationsOlderThan(oldestSlot:
|
|
103
|
+
public async deleteAttestationsOlderThan(oldestSlot: SlotNumber): Promise<void> {
|
|
99
104
|
const olderThan = [];
|
|
100
105
|
|
|
101
106
|
// Entries are iterated in insertion order, so we can break as soon as we find a slot that is older than the oldestSlot.
|
|
@@ -116,7 +121,7 @@ export class InMemoryAttestationPool implements AttestationPool {
|
|
|
116
121
|
return Promise.resolve();
|
|
117
122
|
}
|
|
118
123
|
|
|
119
|
-
public deleteAttestationsForSlot(slot:
|
|
124
|
+
public deleteAttestationsForSlot(slot: SlotNumber): Promise<void> {
|
|
120
125
|
// We count the number of attestations we are removing
|
|
121
126
|
const numberOfAttestations = this.#getNumberOfAttestationsInSlot(slot);
|
|
122
127
|
const proposalIdsToDelete = this.attestations.get(slot)?.keys();
|
|
@@ -134,7 +139,7 @@ export class InMemoryAttestationPool implements AttestationPool {
|
|
|
134
139
|
return Promise.resolve();
|
|
135
140
|
}
|
|
136
141
|
|
|
137
|
-
public deleteAttestationsForSlotAndProposal(slot:
|
|
142
|
+
public deleteAttestationsForSlotAndProposal(slot: SlotNumber, proposalId: string): Promise<void> {
|
|
138
143
|
const slotAttestationMap = getSlotOrDefault(this.attestations, slot);
|
|
139
144
|
if (slotAttestationMap) {
|
|
140
145
|
if (slotAttestationMap.has(proposalId)) {
|
|
@@ -153,7 +158,7 @@ export class InMemoryAttestationPool implements AttestationPool {
|
|
|
153
158
|
public deleteAttestations(attestations: BlockAttestation[]): Promise<void> {
|
|
154
159
|
for (const attestation of attestations) {
|
|
155
160
|
const slotNumber = attestation.payload.header.slotNumber;
|
|
156
|
-
const slotAttestationMap = this.attestations.get(slotNumber
|
|
161
|
+
const slotAttestationMap = this.attestations.get(slotNumber);
|
|
157
162
|
if (slotAttestationMap) {
|
|
158
163
|
const proposalId = attestation.archive.toString();
|
|
159
164
|
const proposalAttestationMap = getProposalOrDefault(slotAttestationMap, proposalId);
|
|
@@ -162,7 +167,7 @@ export class InMemoryAttestationPool implements AttestationPool {
|
|
|
162
167
|
|
|
163
168
|
// Skip attestations with invalid signatures
|
|
164
169
|
if (!sender) {
|
|
165
|
-
this.log.warn(`Skipping deletion of attestation with invalid signature for slot ${slotNumber
|
|
170
|
+
this.log.warn(`Skipping deletion of attestation with invalid signature for slot ${slotNumber}`);
|
|
166
171
|
continue;
|
|
167
172
|
}
|
|
168
173
|
|
|
@@ -184,7 +189,7 @@ export class InMemoryAttestationPool implements AttestationPool {
|
|
|
184
189
|
return Promise.resolve(false);
|
|
185
190
|
}
|
|
186
191
|
|
|
187
|
-
const slotAttestationMap = this.attestations.get(slotNumber
|
|
192
|
+
const slotAttestationMap = this.attestations.get(slotNumber);
|
|
188
193
|
if (!slotAttestationMap) {
|
|
189
194
|
return Promise.resolve(false);
|
|
190
195
|
}
|
|
@@ -200,7 +205,7 @@ export class InMemoryAttestationPool implements AttestationPool {
|
|
|
200
205
|
public addBlockProposal(blockProposal: BlockProposal): Promise<void> {
|
|
201
206
|
// We initialize slot-proposal mapping if it does not exist
|
|
202
207
|
// This is important to ensure we can delete this proposal if there were not attestations for it
|
|
203
|
-
const slotProposalMapping = getSlotOrDefault(this.attestations, blockProposal.slotNumber
|
|
208
|
+
const slotProposalMapping = getSlotOrDefault(this.attestations, blockProposal.slotNumber);
|
|
204
209
|
slotProposalMapping.set(blockProposal.payload.archive.toString(), new Map<string, BlockAttestation>());
|
|
205
210
|
|
|
206
211
|
this.proposals.set(blockProposal.payload.archive.toString(), blockProposal);
|
|
@@ -216,27 +221,25 @@ export class InMemoryAttestationPool implements AttestationPool {
|
|
|
216
221
|
return Promise.resolve(this.proposals.has(id));
|
|
217
222
|
}
|
|
218
223
|
|
|
219
|
-
public hasReachedProposalCap(slot:
|
|
224
|
+
public hasReachedProposalCap(slot: SlotNumber): Promise<boolean> {
|
|
220
225
|
const slotAttestationMap = this.attestations.get(slot);
|
|
221
226
|
const proposalCount = slotAttestationMap?.size ?? 0;
|
|
222
227
|
return Promise.resolve(proposalCount >= MAX_PROPOSALS_PER_SLOT);
|
|
223
228
|
}
|
|
224
229
|
|
|
225
|
-
public hasReachedAttestationCap(slot:
|
|
230
|
+
public hasReachedAttestationCap(slot: SlotNumber, proposalId: string, committeeSize: number): Promise<boolean> {
|
|
226
231
|
const limit = committeeSize + ATTESTATION_CAP_BUFFER;
|
|
227
232
|
const count = this.attestations.get(slot)?.get(proposalId)?.size ?? 0;
|
|
228
233
|
return Promise.resolve(limit <= 0 || count >= limit);
|
|
229
234
|
}
|
|
230
235
|
|
|
231
236
|
public async canAddProposal(block: BlockProposal): Promise<boolean> {
|
|
232
|
-
return (
|
|
233
|
-
this.proposals.has(block.archive.toString()) || !(await this.hasReachedProposalCap(block.slotNumber.toBigInt()))
|
|
234
|
-
);
|
|
237
|
+
return this.proposals.has(block.archive.toString()) || !(await this.hasReachedProposalCap(block.slotNumber));
|
|
235
238
|
}
|
|
236
239
|
|
|
237
240
|
public async canAddAttestation(attestation: BlockAttestation, committeeSize: number): Promise<boolean> {
|
|
238
241
|
const sender = attestation.getSender();
|
|
239
|
-
const slot = attestation.payload.header.slotNumber
|
|
242
|
+
const slot = attestation.payload.header.slotNumber;
|
|
240
243
|
const pid = attestation.archive.toString();
|
|
241
244
|
return (
|
|
242
245
|
!!sender &&
|
|
@@ -255,8 +258,9 @@ export class InMemoryAttestationPool implements AttestationPool {
|
|
|
255
258
|
* @returns The slot mapping
|
|
256
259
|
*/
|
|
257
260
|
function getSlotOrDefault(
|
|
258
|
-
|
|
259
|
-
|
|
261
|
+
// eslint-disable-next-line aztec-custom/no-non-primitive-in-collections
|
|
262
|
+
map: Map<SlotNumber, Map<string, Map<string, BlockAttestation>>>,
|
|
263
|
+
slot: SlotNumber,
|
|
260
264
|
): Map<string, Map<string, BlockAttestation>> {
|
|
261
265
|
if (!map.has(slot)) {
|
|
262
266
|
map.set(slot, new Map<string, Map<string, BlockAttestation>>());
|
|
@@ -33,7 +33,7 @@ export const mockAttestation = (
|
|
|
33
33
|
): BlockAttestation => {
|
|
34
34
|
// Use arbitrary numbers for all other than slot
|
|
35
35
|
const header = makeL2BlockHeader(1, 2, slot);
|
|
36
|
-
const payload = new ConsensusPayload(header.toCheckpointHeader(), archive
|
|
36
|
+
const payload = new ConsensusPayload(header.toCheckpointHeader(), archive);
|
|
37
37
|
|
|
38
38
|
const attestationHash = getHashedSignaturePayloadEthSignedMessage(payload, SignatureDomainSeparator.blockAttestation);
|
|
39
39
|
const attestationSignature = signer.sign(attestationHash);
|
|
@@ -13,47 +13,45 @@ export class AttestationValidator implements P2PValidator<BlockAttestation> {
|
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
async validate(message: BlockAttestation): Promise<PeerErrorSeverity | undefined> {
|
|
16
|
-
const
|
|
16
|
+
const slotNumber = message.payload.header.slotNumber;
|
|
17
17
|
|
|
18
18
|
try {
|
|
19
19
|
const { currentProposer, nextProposer, currentSlot, nextSlot } =
|
|
20
20
|
await this.epochCache.getProposerAttesterAddressInCurrentOrNextSlot();
|
|
21
21
|
|
|
22
|
-
if (
|
|
23
|
-
this.logger.warn(
|
|
24
|
-
`Attestation slot ${slotNumberBigInt} is not current (${currentSlot}) or next (${nextSlot}) slot`,
|
|
25
|
-
);
|
|
22
|
+
if (slotNumber !== currentSlot && slotNumber !== nextSlot) {
|
|
23
|
+
this.logger.warn(`Attestation slot ${slotNumber} is not current (${currentSlot}) or next (${nextSlot}) slot`);
|
|
26
24
|
return PeerErrorSeverity.HighToleranceError;
|
|
27
25
|
}
|
|
28
26
|
|
|
29
27
|
// Verify the signature is valid
|
|
30
28
|
const attester = message.getSender();
|
|
31
29
|
if (attester === undefined) {
|
|
32
|
-
this.logger.warn(`Invalid signature in attestation for slot ${
|
|
30
|
+
this.logger.warn(`Invalid signature in attestation for slot ${slotNumber}`);
|
|
33
31
|
return PeerErrorSeverity.LowToleranceError;
|
|
34
32
|
}
|
|
35
33
|
|
|
36
34
|
// Verify the attester is in the committee for this slot
|
|
37
|
-
if (!(await this.epochCache.isInCommittee(
|
|
38
|
-
this.logger.warn(`Attester ${attester.toString()} is not in committee for slot ${
|
|
35
|
+
if (!(await this.epochCache.isInCommittee(slotNumber, attester))) {
|
|
36
|
+
this.logger.warn(`Attester ${attester.toString()} is not in committee for slot ${slotNumber}`);
|
|
39
37
|
return PeerErrorSeverity.HighToleranceError;
|
|
40
38
|
}
|
|
41
39
|
|
|
42
40
|
// Verify the proposer signature matches the expected proposer for this slot
|
|
43
41
|
const proposer = message.getProposer();
|
|
44
|
-
const expectedProposer =
|
|
42
|
+
const expectedProposer = slotNumber === currentSlot ? currentProposer : nextProposer;
|
|
45
43
|
if (!expectedProposer) {
|
|
46
|
-
this.logger.warn(`No proposer defined for slot ${
|
|
44
|
+
this.logger.warn(`No proposer defined for slot ${slotNumber}`);
|
|
47
45
|
return PeerErrorSeverity.HighToleranceError;
|
|
48
46
|
}
|
|
49
47
|
if (!proposer) {
|
|
50
|
-
this.logger.warn(`Invalid proposer signature in attestation for slot ${
|
|
48
|
+
this.logger.warn(`Invalid proposer signature in attestation for slot ${slotNumber}`);
|
|
51
49
|
return PeerErrorSeverity.LowToleranceError;
|
|
52
50
|
}
|
|
53
51
|
if (!proposer.equals(expectedProposer)) {
|
|
54
52
|
this.logger.warn(
|
|
55
53
|
`Proposer signature mismatch in attestation. ` +
|
|
56
|
-
`Expected ${expectedProposer?.toString() ?? 'none'} but got ${proposer.toString()} for slot ${
|
|
54
|
+
`Expected ${expectedProposer?.toString() ?? 'none'} but got ${proposer.toString()} for slot ${slotNumber}`,
|
|
57
55
|
);
|
|
58
56
|
return PeerErrorSeverity.HighToleranceError;
|
|
59
57
|
}
|
|
@@ -62,7 +60,7 @@ export class AttestationValidator implements P2PValidator<BlockAttestation> {
|
|
|
62
60
|
} catch (e) {
|
|
63
61
|
// People shouldn't be sending us attestations if the committee doesn't exist
|
|
64
62
|
if (e instanceof NoCommitteeError) {
|
|
65
|
-
this.logger.warn(`No committee exists for attestation for slot ${
|
|
63
|
+
this.logger.warn(`No committee exists for attestation for slot ${slotNumber}`);
|
|
66
64
|
return PeerErrorSeverity.LowToleranceError;
|
|
67
65
|
}
|
|
68
66
|
throw e;
|
|
@@ -43,7 +43,7 @@ export class FishermanAttestationValidator extends AttestationValidator {
|
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
// fisherman validation: verify attestation payload matches proposal payload
|
|
46
|
-
const slotNumberBigInt = message.payload.header.slotNumber
|
|
46
|
+
const slotNumberBigInt = message.payload.header.slotNumber;
|
|
47
47
|
const attester = message.getSender();
|
|
48
48
|
const proposer = message.getProposer();
|
|
49
49
|
|
|
@@ -51,15 +51,15 @@ export class BlockProposalValidator implements P2PValidator<BlockProposal> {
|
|
|
51
51
|
await this.epochCache.getProposerAttesterAddressInCurrentOrNextSlot();
|
|
52
52
|
|
|
53
53
|
// Check that the attestation is for the current or next slot
|
|
54
|
-
const
|
|
55
|
-
if (
|
|
56
|
-
this.logger.debug(`Penalizing peer for invalid slot number ${
|
|
54
|
+
const slotNumber = block.payload.header.slotNumber;
|
|
55
|
+
if (slotNumber !== currentSlot && slotNumber !== nextSlot) {
|
|
56
|
+
this.logger.debug(`Penalizing peer for invalid slot number ${slotNumber}`, { currentSlot, nextSlot });
|
|
57
57
|
return PeerErrorSeverity.HighToleranceError;
|
|
58
58
|
}
|
|
59
59
|
|
|
60
60
|
// Check that the block proposal is from the current or next proposer
|
|
61
|
-
if (
|
|
62
|
-
this.logger.debug(`Penalizing peer for invalid proposer for current slot ${
|
|
61
|
+
if (slotNumber === currentSlot && currentProposer !== undefined && !proposer.equals(currentProposer)) {
|
|
62
|
+
this.logger.debug(`Penalizing peer for invalid proposer for current slot ${slotNumber}`, {
|
|
63
63
|
currentProposer,
|
|
64
64
|
nextProposer,
|
|
65
65
|
proposer: proposer.toString(),
|
|
@@ -67,8 +67,8 @@ export class BlockProposalValidator implements P2PValidator<BlockProposal> {
|
|
|
67
67
|
return PeerErrorSeverity.MidToleranceError;
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
-
if (
|
|
71
|
-
this.logger.debug(`Penalizing peer for invalid proposer for next slot ${
|
|
70
|
+
if (slotNumber === nextSlot && nextProposer !== undefined && !proposer.equals(nextProposer)) {
|
|
71
|
+
this.logger.debug(`Penalizing peer for invalid proposer for next slot ${slotNumber}`, {
|
|
72
72
|
currentProposer,
|
|
73
73
|
nextProposer,
|
|
74
74
|
proposer: proposer.toString(),
|
|
@@ -80,7 +80,7 @@ export class BlockProposalValidator implements P2PValidator<BlockProposal> {
|
|
|
80
80
|
if (!(await Promise.all(block.txs?.map(tx => tx.validateTxHash()) ?? [])).every(v => v)) {
|
|
81
81
|
this.logger.warn(`Penalizing peer for invalid tx hashes in block proposal`, {
|
|
82
82
|
proposer,
|
|
83
|
-
slotNumber
|
|
83
|
+
slotNumber,
|
|
84
84
|
});
|
|
85
85
|
return PeerErrorSeverity.LowToleranceError;
|
|
86
86
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { EpochCacheInterface } from '@aztec/epoch-cache';
|
|
2
|
+
import { SlotNumber } from '@aztec/foundation/branded-types';
|
|
2
3
|
import { randomInt } from '@aztec/foundation/crypto';
|
|
3
4
|
import { Fr } from '@aztec/foundation/fields';
|
|
4
5
|
import { type Logger, createLibp2pComponentLogger, createLogger } from '@aztec/foundation/log';
|
|
@@ -192,7 +193,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
192
193
|
|
|
193
194
|
this.blockReceivedCallback = async (block: BlockProposal): Promise<BlockAttestation[] | undefined> => {
|
|
194
195
|
this.logger.debug(
|
|
195
|
-
`Handler not yet registered: Block received callback not set. Received block for slot ${block.slotNumber
|
|
196
|
+
`Handler not yet registered: Block received callback not set. Received block for slot ${block.slotNumber} from peer.`,
|
|
196
197
|
{ p2pMessageIdentifier: await block.p2pMessageLoggingIdentifier() },
|
|
197
198
|
);
|
|
198
199
|
return undefined;
|
|
@@ -814,7 +815,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
814
815
|
|
|
815
816
|
let canAdd = true;
|
|
816
817
|
if (isValid && !exists) {
|
|
817
|
-
const slot = attestation.payload.header.slotNumber
|
|
818
|
+
const slot = attestation.payload.header.slotNumber;
|
|
818
819
|
const { committee } = await this.epochCache.getCommittee(slot);
|
|
819
820
|
const committeeSize = committee?.length ?? 0;
|
|
820
821
|
canAdd = await pool.canAddAttestation(attestation, committeeSize);
|
|
@@ -856,10 +857,10 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
856
857
|
}
|
|
857
858
|
|
|
858
859
|
this.logger.debug(
|
|
859
|
-
`Received attestation for slot ${attestation.slotNumber
|
|
860
|
+
`Received attestation for slot ${attestation.slotNumber} from external peer ${source.toString()}`,
|
|
860
861
|
{
|
|
861
862
|
p2pMessageIdentifier: await attestation.p2pMessageLoggingIdentifier(),
|
|
862
|
-
slot: attestation.slotNumber
|
|
863
|
+
slot: attestation.slotNumber,
|
|
863
864
|
archive: attestation.archive.toString(),
|
|
864
865
|
source: source.toString(),
|
|
865
866
|
},
|
|
@@ -920,16 +921,16 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
920
921
|
|
|
921
922
|
// REVIEW: callback pattern https://github.com/AztecProtocol/aztec-packages/issues/7963
|
|
922
923
|
@trackSpan('Libp2pService.processValidBlockProposal', async block => ({
|
|
923
|
-
[Attributes.SLOT_NUMBER]: block.slotNumber
|
|
924
|
+
[Attributes.SLOT_NUMBER]: block.slotNumber,
|
|
924
925
|
[Attributes.BLOCK_ARCHIVE]: block.archive.toString(),
|
|
925
926
|
[Attributes.P2P_ID]: await block.p2pMessageLoggingIdentifier().then(i => i.toString()),
|
|
926
927
|
}))
|
|
927
928
|
private async processValidBlockProposal(block: BlockProposal, sender: PeerId) {
|
|
928
|
-
const slot = block.slotNumber
|
|
929
|
-
const previousSlot = slot -
|
|
929
|
+
const slot = block.slotNumber;
|
|
930
|
+
const previousSlot = SlotNumber(slot - 1);
|
|
930
931
|
this.logger.verbose(`Received block proposal for slot ${slot} from external peer ${sender.toString()}.`, {
|
|
931
932
|
p2pMessageIdentifier: await block.p2pMessageLoggingIdentifier(),
|
|
932
|
-
slot: block.slotNumber
|
|
933
|
+
slot: block.slotNumber,
|
|
933
934
|
archive: block.archive.toString(),
|
|
934
935
|
source: sender.toString(),
|
|
935
936
|
});
|
|
@@ -945,7 +946,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
945
946
|
// Drop proposals if we hit per-slot cap in the attestation pool; rethrow unknown errors
|
|
946
947
|
if (err instanceof ProposalSlotCapExceededError) {
|
|
947
948
|
this.logger.warn(`Dropping block proposal due to per-slot proposal cap`, {
|
|
948
|
-
slot: slot
|
|
949
|
+
slot: String(slot),
|
|
949
950
|
archive: block.archive.toString(),
|
|
950
951
|
error: (err as Error).message,
|
|
951
952
|
});
|
|
@@ -960,9 +961,9 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
960
961
|
// The attestation can be undefined if no handler is registered / the validator deems the block invalid / in fisherman mode
|
|
961
962
|
if (attestations?.length) {
|
|
962
963
|
for (const attestation of attestations) {
|
|
963
|
-
this.logger.verbose(`Broadcasting attestation for slot ${attestation.slotNumber
|
|
964
|
+
this.logger.verbose(`Broadcasting attestation for slot ${attestation.slotNumber}`, {
|
|
964
965
|
p2pMessageIdentifier: await attestation.p2pMessageLoggingIdentifier(),
|
|
965
|
-
slot: attestation.slotNumber
|
|
966
|
+
slot: attestation.slotNumber,
|
|
966
967
|
archive: attestation.archive.toString(),
|
|
967
968
|
});
|
|
968
969
|
await this.broadcastAttestation(attestation);
|
|
@@ -975,7 +976,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
975
976
|
* @param attestation - The attestation to broadcast.
|
|
976
977
|
*/
|
|
977
978
|
@trackSpan('Libp2pService.broadcastAttestation', async attestation => ({
|
|
978
|
-
[Attributes.SLOT_NUMBER]: attestation.payload.header.slotNumber
|
|
979
|
+
[Attributes.SLOT_NUMBER]: attestation.payload.header.slotNumber,
|
|
979
980
|
[Attributes.BLOCK_ARCHIVE]: attestation.archive.toString(),
|
|
980
981
|
[Attributes.P2P_ID]: await attestation.p2pMessageLoggingIdentifier().then(i => i.toString()),
|
|
981
982
|
}))
|
|
@@ -1371,7 +1372,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
1371
1372
|
* @returns True if the attestation is valid, false otherwise.
|
|
1372
1373
|
*/
|
|
1373
1374
|
@trackSpan('Libp2pService.validateAttestation', async (_, attestation) => ({
|
|
1374
|
-
[Attributes.SLOT_NUMBER]: attestation.payload.header.slotNumber
|
|
1375
|
+
[Attributes.SLOT_NUMBER]: attestation.payload.header.slotNumber,
|
|
1375
1376
|
[Attributes.BLOCK_ARCHIVE]: attestation.archive.toString(),
|
|
1376
1377
|
[Attributes.P2P_ID]: await attestation.p2pMessageLoggingIdentifier().then(i => i.toString()),
|
|
1377
1378
|
}))
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { EpochNumber, SlotNumber } from '@aztec/foundation/branded-types';
|
|
1
2
|
import { chunk } from '@aztec/foundation/collection';
|
|
2
3
|
import { type Logger, createLogger } from '@aztec/foundation/log';
|
|
3
4
|
import { boundInclusive } from '@aztec/foundation/number';
|
|
@@ -223,9 +224,9 @@ export class SlowTxCollection {
|
|
|
223
224
|
}
|
|
224
225
|
|
|
225
226
|
/** Computes the proof submission deadline for a given slot, a tx mined in this slot is no longer interesting after this deadline */
|
|
226
|
-
private getDeadlineForSlot(slotNumber:
|
|
227
|
+
private getDeadlineForSlot(slotNumber: SlotNumber): Date {
|
|
227
228
|
const epoch = getEpochAtSlot(slotNumber, this.constants);
|
|
228
|
-
const submissionEndEpoch = epoch +
|
|
229
|
+
const submissionEndEpoch = EpochNumber(epoch + this.constants.proofSubmissionEpochs);
|
|
229
230
|
const submissionEndTimestamp = getTimestampRangeForEpoch(submissionEndEpoch, this.constants)[1];
|
|
230
231
|
return new Date(Number(submissionEndTimestamp) * 1000);
|
|
231
232
|
}
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { MockL2BlockSource } from '@aztec/archiver/test';
|
|
7
7
|
import type { EpochCacheInterface } from '@aztec/epoch-cache';
|
|
8
|
+
import { EpochNumber, SlotNumber } from '@aztec/foundation/branded-types';
|
|
8
9
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
9
10
|
import { createLogger } from '@aztec/foundation/log';
|
|
10
11
|
import { sleep } from '@aztec/foundation/sleep';
|
|
@@ -81,18 +82,18 @@ function mockAttestationPool(): AttestationPool {
|
|
|
81
82
|
|
|
82
83
|
function mockEpochCache(): EpochCacheInterface {
|
|
83
84
|
return {
|
|
84
|
-
getCommittee: () => Promise.resolve({ committee: [], seed: 1n, epoch:
|
|
85
|
+
getCommittee: () => Promise.resolve({ committee: [], seed: 1n, epoch: EpochNumber.ZERO }),
|
|
85
86
|
getProposerIndexEncoding: () => '0x' as `0x${string}`,
|
|
86
|
-
getEpochAndSlotNow: () => ({ epoch:
|
|
87
|
+
getEpochAndSlotNow: () => ({ epoch: EpochNumber.ZERO, slot: SlotNumber.ZERO, ts: 0n }),
|
|
87
88
|
computeProposerIndex: () => 0n,
|
|
88
89
|
getProposerAttesterAddressInCurrentOrNextSlot: () =>
|
|
89
90
|
Promise.resolve({
|
|
90
91
|
currentProposer: EthAddress.ZERO,
|
|
91
92
|
nextProposer: EthAddress.ZERO,
|
|
92
|
-
currentSlot:
|
|
93
|
-
nextSlot:
|
|
93
|
+
currentSlot: SlotNumber.ZERO,
|
|
94
|
+
nextSlot: SlotNumber.ZERO,
|
|
94
95
|
}),
|
|
95
|
-
getEpochAndSlotInNextL1Slot: () => ({ epoch:
|
|
96
|
+
getEpochAndSlotInNextL1Slot: () => ({ epoch: EpochNumber.ZERO, slot: SlotNumber.ZERO, ts: 0n, now: 0n }),
|
|
96
97
|
isInCommittee: () => Promise.resolve(false),
|
|
97
98
|
getRegisteredValidators: () => Promise.resolve([]),
|
|
98
99
|
filterInCommittee: () => Promise.resolve([]),
|