@aztec/p2p 1.2.1 → 2.0.0-nightly.20250813
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/client/factory.d.ts +5 -1
- package/dest/client/factory.d.ts.map +1 -1
- package/dest/client/factory.js +29 -12
- package/dest/client/interface.d.ts +8 -13
- package/dest/client/interface.d.ts.map +1 -1
- package/dest/client/p2p_client.d.ts +18 -22
- package/dest/client/p2p_client.d.ts.map +1 -1
- package/dest/client/p2p_client.js +86 -83
- package/dest/config.d.ts +30 -1
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +34 -1
- package/dest/index.d.ts +1 -0
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +1 -0
- package/dest/mem_pools/attestation_pool/attestation_pool.d.ts +13 -1
- 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.map +1 -1
- package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.js +117 -10
- package/dest/mem_pools/attestation_pool/kv_attestation_pool.d.ts +4 -1
- package/dest/mem_pools/attestation_pool/kv_attestation_pool.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/kv_attestation_pool.js +22 -1
- package/dest/mem_pools/attestation_pool/memory_attestation_pool.d.ts +4 -1
- package/dest/mem_pools/attestation_pool/memory_attestation_pool.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/memory_attestation_pool.js +21 -1
- package/dest/mem_pools/attestation_pool/mocks.d.ts +1 -2
- package/dest/mem_pools/attestation_pool/mocks.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/mocks.js +2 -10
- package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts +8 -3
- package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.js +64 -37
- package/dest/mem_pools/tx_pool/memory_tx_pool.d.ts +8 -3
- package/dest/mem_pools/tx_pool/memory_tx_pool.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool/memory_tx_pool.js +18 -10
- package/dest/mem_pools/tx_pool/tx_pool.d.ts +11 -2
- package/dest/mem_pools/tx_pool/tx_pool.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool/tx_pool_test_suite.js +73 -44
- package/dest/msg_validators/attestation_validator/attestation_validator.js +1 -1
- package/dest/msg_validators/tx_validator/block_header_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/block_header_validator.js +2 -2
- package/dest/msg_validators/tx_validator/data_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/data_validator.js +35 -59
- package/dest/msg_validators/tx_validator/double_spend_validator.js +2 -2
- package/dest/msg_validators/tx_validator/gas_validator.js +4 -4
- package/dest/msg_validators/tx_validator/metadata_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/metadata_validator.js +21 -21
- package/dest/msg_validators/tx_validator/phases_validator.js +3 -3
- package/dest/msg_validators/tx_validator/tx_proof_validator.js +3 -3
- package/dest/services/discv5/discV5_service.d.ts.map +1 -1
- package/dest/services/discv5/discV5_service.js +4 -1
- package/dest/services/dummy_service.d.ts +13 -3
- package/dest/services/dummy_service.d.ts.map +1 -1
- package/dest/services/dummy_service.js +26 -3
- package/dest/services/index.d.ts +3 -1
- package/dest/services/index.d.ts.map +1 -1
- package/dest/services/index.js +3 -1
- package/dest/services/libp2p/libp2p_service.d.ts +13 -20
- package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
- package/dest/services/libp2p/libp2p_service.js +123 -46
- package/dest/services/peer-manager/interface.d.ts +8 -1
- package/dest/services/peer-manager/interface.d.ts.map +1 -1
- package/dest/services/peer-manager/peer_manager.d.ts +70 -3
- package/dest/services/peer-manager/peer_manager.d.ts.map +1 -1
- package/dest/services/peer-manager/peer_manager.js +369 -39
- package/dest/services/reqresp/config.d.ts +3 -3
- package/dest/services/reqresp/config.d.ts.map +1 -1
- package/dest/services/reqresp/config.js +3 -3
- package/dest/services/reqresp/connection-sampler/connection_sampler.d.ts +3 -4
- package/dest/services/reqresp/connection-sampler/connection_sampler.d.ts.map +1 -1
- package/dest/services/reqresp/connection-sampler/connection_sampler.js +35 -52
- package/dest/services/reqresp/index.d.ts +2 -1
- package/dest/services/reqresp/index.d.ts.map +1 -1
- package/dest/services/reqresp/index.js +2 -1
- package/dest/services/reqresp/interface.d.ts +61 -10
- package/dest/services/reqresp/interface.d.ts.map +1 -1
- package/dest/services/reqresp/interface.js +41 -6
- package/dest/services/reqresp/protocols/auth.d.ts +43 -0
- package/dest/services/reqresp/protocols/auth.d.ts.map +1 -0
- package/dest/services/reqresp/protocols/auth.js +71 -0
- package/dest/services/reqresp/protocols/block.d.ts +5 -0
- package/dest/services/reqresp/protocols/block.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/block.js +28 -5
- package/dest/services/reqresp/protocols/block_txs/bitvector.d.ts +30 -0
- package/dest/services/reqresp/protocols/block_txs/bitvector.d.ts.map +1 -0
- package/dest/services/reqresp/protocols/block_txs/bitvector.js +75 -0
- package/dest/services/reqresp/protocols/block_txs/block_txs_handler.d.ts +11 -0
- package/dest/services/reqresp/protocols/block_txs/block_txs_handler.d.ts.map +1 -0
- package/dest/services/reqresp/protocols/block_txs/block_txs_handler.js +39 -0
- package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.d.ts +49 -0
- package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.d.ts.map +1 -0
- package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.js +75 -0
- package/dest/services/reqresp/protocols/block_txs/index.d.ts +4 -0
- package/dest/services/reqresp/protocols/block_txs/index.d.ts.map +1 -0
- package/dest/services/reqresp/protocols/block_txs/index.js +3 -0
- package/dest/services/reqresp/protocols/goodbye.js +3 -5
- package/dest/services/reqresp/protocols/index.d.ts +2 -0
- package/dest/services/reqresp/protocols/index.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/index.js +2 -0
- package/dest/services/reqresp/protocols/status.d.ts +2 -0
- package/dest/services/reqresp/protocols/status.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/status.js +7 -0
- package/dest/services/reqresp/protocols/tx.d.ts +12 -1
- package/dest/services/reqresp/protocols/tx.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/tx.js +34 -6
- package/dest/services/reqresp/rate-limiter/rate_limits.d.ts.map +1 -1
- package/dest/services/reqresp/rate-limiter/rate_limits.js +20 -0
- package/dest/services/reqresp/reqresp.d.ts +37 -39
- package/dest/services/reqresp/reqresp.d.ts.map +1 -1
- package/dest/services/reqresp/reqresp.js +220 -220
- package/dest/services/reqresp/status.d.ts +8 -3
- package/dest/services/reqresp/status.d.ts.map +1 -1
- package/dest/services/reqresp/status.js +6 -2
- package/dest/services/service.d.ts +10 -10
- package/dest/services/service.d.ts.map +1 -1
- package/dest/services/tx_collection/config.d.ts +25 -0
- package/dest/services/tx_collection/config.d.ts.map +1 -0
- package/dest/services/tx_collection/config.js +58 -0
- package/dest/services/tx_collection/fast_tx_collection.d.ts +56 -0
- package/dest/services/tx_collection/fast_tx_collection.d.ts.map +1 -0
- package/dest/services/tx_collection/fast_tx_collection.js +295 -0
- package/dest/services/tx_collection/index.d.ts +3 -0
- package/dest/services/tx_collection/index.d.ts.map +1 -0
- package/dest/services/tx_collection/index.js +2 -0
- package/dest/services/tx_collection/instrumentation.d.ts +10 -0
- package/dest/services/tx_collection/instrumentation.d.ts.map +1 -0
- package/dest/services/tx_collection/instrumentation.js +34 -0
- package/dest/services/tx_collection/slow_tx_collection.d.ts +54 -0
- package/dest/services/tx_collection/slow_tx_collection.d.ts.map +1 -0
- package/dest/services/tx_collection/slow_tx_collection.js +176 -0
- package/dest/services/tx_collection/tx_collection.d.ts +109 -0
- package/dest/services/tx_collection/tx_collection.d.ts.map +1 -0
- package/dest/services/tx_collection/tx_collection.js +127 -0
- package/dest/services/tx_collection/tx_collection_sink.d.ts +30 -0
- package/dest/services/tx_collection/tx_collection_sink.d.ts.map +1 -0
- package/dest/services/tx_collection/tx_collection_sink.js +81 -0
- package/dest/services/tx_collection/tx_source.d.ts +18 -0
- package/dest/services/tx_collection/tx_source.d.ts.map +1 -0
- package/dest/services/tx_collection/tx_source.js +31 -0
- package/dest/services/tx_provider.d.ts +49 -0
- package/dest/services/tx_provider.d.ts.map +1 -0
- package/dest/services/tx_provider.js +206 -0
- package/dest/services/{tx_collect_instrumentation.d.ts → tx_provider_instrumentation.d.ts} +2 -2
- package/dest/services/tx_provider_instrumentation.d.ts.map +1 -0
- package/dest/services/{tx_collect_instrumentation.js → tx_provider_instrumentation.js} +5 -5
- package/dest/test-helpers/make-test-p2p-clients.d.ts.map +1 -1
- package/dest/test-helpers/make-test-p2p-clients.js +4 -3
- package/dest/test-helpers/mock-pubsub.d.ts +2 -1
- package/dest/test-helpers/mock-pubsub.d.ts.map +1 -1
- package/dest/test-helpers/mock-pubsub.js +2 -1
- package/dest/test-helpers/reqresp-nodes.d.ts.map +1 -1
- package/dest/test-helpers/reqresp-nodes.js +8 -4
- package/dest/testbench/p2p_client_testbench_worker.js +11 -5
- package/dest/util.d.ts +1 -1
- package/dest/util.d.ts.map +1 -1
- package/package.json +14 -15
- package/src/client/factory.ts +87 -12
- package/src/client/interface.ts +19 -15
- package/src/client/p2p_client.ts +108 -92
- package/src/config.ts +52 -1
- package/src/index.ts +1 -0
- package/src/mem_pools/attestation_pool/attestation_pool.ts +15 -1
- package/src/mem_pools/attestation_pool/attestation_pool_test_suite.ts +155 -4
- package/src/mem_pools/attestation_pool/kv_attestation_pool.ts +28 -1
- package/src/mem_pools/attestation_pool/memory_attestation_pool.ts +28 -2
- package/src/mem_pools/attestation_pool/mocks.ts +1 -3
- package/src/mem_pools/tx_pool/aztec_kv_tx_pool.ts +59 -41
- package/src/mem_pools/tx_pool/memory_tx_pool.ts +19 -9
- package/src/mem_pools/tx_pool/tx_pool.ts +7 -2
- package/src/mem_pools/tx_pool/tx_pool_test_suite.ts +63 -40
- package/src/msg_validators/attestation_validator/attestation_validator.ts +1 -1
- package/src/msg_validators/tx_validator/block_header_validator.ts +2 -2
- package/src/msg_validators/tx_validator/data_validator.ts +36 -27
- package/src/msg_validators/tx_validator/double_spend_validator.ts +2 -2
- package/src/msg_validators/tx_validator/gas_validator.ts +4 -4
- package/src/msg_validators/tx_validator/metadata_validator.ts +22 -28
- package/src/msg_validators/tx_validator/phases_validator.ts +2 -2
- package/src/msg_validators/tx_validator/tx_proof_validator.ts +2 -2
- package/src/services/discv5/discV5_service.ts +4 -1
- package/src/services/dummy_service.ts +44 -4
- package/src/services/index.ts +3 -1
- package/src/services/libp2p/libp2p_service.ts +147 -55
- package/src/services/peer-manager/interface.ts +10 -1
- package/src/services/peer-manager/peer_manager.ts +441 -41
- package/src/services/reqresp/config.ts +3 -3
- package/src/services/reqresp/connection-sampler/connection_sampler.ts +38 -63
- package/src/services/reqresp/index.ts +2 -0
- package/src/services/reqresp/interface.ts +63 -17
- package/src/services/reqresp/protocols/auth.ts +83 -0
- package/src/services/reqresp/protocols/block.ts +24 -3
- package/src/services/reqresp/protocols/block_txs/bitvector.ts +90 -0
- package/src/services/reqresp/protocols/block_txs/block_txs_handler.ts +53 -0
- package/src/services/reqresp/protocols/block_txs/block_txs_reqresp.ts +79 -0
- package/src/services/reqresp/protocols/block_txs/index.ts +3 -0
- package/src/services/reqresp/protocols/goodbye.ts +3 -3
- package/src/services/reqresp/protocols/index.ts +2 -0
- package/src/services/reqresp/protocols/status.ts +20 -0
- package/src/services/reqresp/protocols/tx.ts +35 -6
- package/src/services/reqresp/rate-limiter/rate_limits.ts +20 -0
- package/src/services/reqresp/reqresp.ts +294 -264
- package/src/services/reqresp/status.ts +9 -3
- package/src/services/service.ts +23 -14
- package/src/services/tx_collection/config.ts +84 -0
- package/src/services/tx_collection/fast_tx_collection.ts +338 -0
- package/src/services/tx_collection/index.ts +2 -0
- package/src/services/tx_collection/instrumentation.ts +43 -0
- package/src/services/tx_collection/slow_tx_collection.ts +232 -0
- package/src/services/tx_collection/tx_collection.ts +214 -0
- package/src/services/tx_collection/tx_collection_sink.ts +98 -0
- package/src/services/tx_collection/tx_source.ts +37 -0
- package/src/services/tx_provider.ts +215 -0
- package/src/services/{tx_collect_instrumentation.ts → tx_provider_instrumentation.ts} +5 -5
- package/src/test-helpers/make-test-p2p-clients.ts +4 -2
- package/src/test-helpers/mock-pubsub.ts +1 -0
- package/src/test-helpers/reqresp-nodes.ts +7 -1
- package/src/testbench/p2p_client_testbench_worker.ts +9 -2
- package/src/util.ts +1 -1
- package/dest/services/tx_collect_instrumentation.d.ts.map +0 -1
- package/dest/services/tx_collector.d.ts +0 -23
- package/dest/services/tx_collector.d.ts.map +0 -1
- package/dest/services/tx_collector.js +0 -95
- package/src/services/tx_collector.ts +0 -134
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { Secp256k1Signer } from '@aztec/foundation/crypto';
|
|
2
2
|
import { Fr } from '@aztec/foundation/fields';
|
|
3
|
+
import { BlockProposal as BlockProposalClass, ConsensusPayload, SignatureDomainSeparator, getHashedSignaturePayloadEthSignedMessage } from '@aztec/stdlib/p2p';
|
|
4
|
+
import { makeHeader } from '@aztec/stdlib/testing';
|
|
3
5
|
import { TxHash } from '@aztec/stdlib/tx';
|
|
4
6
|
import { jest } from '@jest/globals';
|
|
5
7
|
import { mock } from 'jest-mock-extended';
|
|
@@ -23,6 +25,18 @@ export function describeAttestationPool(getAttestationPool) {
|
|
|
23
25
|
const archive = Fr.random();
|
|
24
26
|
return signers.map((signer)=>mockAttestation(signer, slotNumber, archive));
|
|
25
27
|
};
|
|
28
|
+
const mockBlockProposal = (signer, slotNumber, archive = Fr.random())=>{
|
|
29
|
+
const blockNumber = 1;
|
|
30
|
+
const header = makeHeader(1, 2, slotNumber);
|
|
31
|
+
const payload = new ConsensusPayload(header.toPropose(), archive, header.state);
|
|
32
|
+
const hash = getHashedSignaturePayloadEthSignedMessage(payload, SignatureDomainSeparator.blockProposal);
|
|
33
|
+
const signature = signer.sign(hash);
|
|
34
|
+
const txHashes = [
|
|
35
|
+
TxHash.random(),
|
|
36
|
+
TxHash.random()
|
|
37
|
+
]; // Mock tx hashes
|
|
38
|
+
return new BlockProposalClass(blockNumber, payload, signature, txHashes);
|
|
39
|
+
};
|
|
26
40
|
// We compare buffers as the objects can have cached values attached to them which are not serialised
|
|
27
41
|
// using array containing as the kv store does not respect insertion order
|
|
28
42
|
const compareAttestations = (a1, a2)=>{
|
|
@@ -67,26 +81,17 @@ export function describeAttestationPool(getAttestationPool) {
|
|
|
67
81
|
it('should handle duplicate proposals in a slot', async ()=>{
|
|
68
82
|
const slotNumber = 420;
|
|
69
83
|
const archive = Fr.random();
|
|
70
|
-
const txs = [
|
|
71
|
-
0,
|
|
72
|
-
1,
|
|
73
|
-
2,
|
|
74
|
-
3,
|
|
75
|
-
4,
|
|
76
|
-
5
|
|
77
|
-
].map(()=>TxHash.random());
|
|
78
84
|
// Use the same signer for all attestations
|
|
79
85
|
const attestations = [];
|
|
80
86
|
const signer = signers[0];
|
|
81
87
|
for(let i = 0; i < NUMBER_OF_SIGNERS_PER_TEST; i++){
|
|
82
|
-
attestations.push(mockAttestation(signer, slotNumber, archive
|
|
88
|
+
attestations.push(mockAttestation(signer, slotNumber, archive));
|
|
83
89
|
}
|
|
84
90
|
// Add them to store and check we end up with only one
|
|
85
91
|
await ap.addAttestations(attestations);
|
|
86
92
|
const retreivedAttestations = await ap.getAttestationsForSlotAndProposal(BigInt(slotNumber), archive.toString());
|
|
87
93
|
expect(retreivedAttestations.length).toBe(1);
|
|
88
94
|
expect(retreivedAttestations[0].toBuffer()).toEqual(attestations[0].toBuffer());
|
|
89
|
-
expect(retreivedAttestations[0].payload.txHashes).toEqual(txs);
|
|
90
95
|
expect(retreivedAttestations[0].getSender().toString()).toEqual(signer.address.toString());
|
|
91
96
|
// Try adding them on another operation and check they are still not duplicated
|
|
92
97
|
await ap.addAttestations([
|
|
@@ -210,4 +215,106 @@ export function describeAttestationPool(getAttestationPool) {
|
|
|
210
215
|
expect(deleteAttestationsSpy).toHaveBeenCalledWith(BigInt(69));
|
|
211
216
|
expect(deleteAttestationsSpy).toHaveBeenCalledWith(BigInt(72));
|
|
212
217
|
});
|
|
218
|
+
describe('BlockProposal in attestation pool', ()=>{
|
|
219
|
+
it('should add and retrieve block proposal', async ()=>{
|
|
220
|
+
const slotNumber = 420;
|
|
221
|
+
const archive = Fr.random();
|
|
222
|
+
const proposal = mockBlockProposal(signers[0], slotNumber, archive);
|
|
223
|
+
const proposalId = proposal.archive.toString();
|
|
224
|
+
await ap.addBlockProposal(proposal);
|
|
225
|
+
const retrievedProposal = await ap.getBlockProposal(proposalId);
|
|
226
|
+
// This are cached values, so we need to call them to ensure they are not undefined
|
|
227
|
+
retrievedProposal.payload.getSize();
|
|
228
|
+
retrievedProposal.signature.getSize();
|
|
229
|
+
expect(retrievedProposal).toBeDefined();
|
|
230
|
+
expect(retrievedProposal).toEqual(proposal);
|
|
231
|
+
});
|
|
232
|
+
it('should return undefined for non-existent block proposal', async ()=>{
|
|
233
|
+
const nonExistentId = Fr.random().toString();
|
|
234
|
+
const retrievedProposal = await ap.getBlockProposal(nonExistentId);
|
|
235
|
+
expect(retrievedProposal).toBeUndefined();
|
|
236
|
+
});
|
|
237
|
+
it('should update block proposal if added twice with same id', async ()=>{
|
|
238
|
+
const slotNumber = 420;
|
|
239
|
+
const archive = Fr.random();
|
|
240
|
+
const proposal1 = mockBlockProposal(signers[0], slotNumber, archive);
|
|
241
|
+
const proposalId = proposal1.archive.toString();
|
|
242
|
+
await ap.addBlockProposal(proposal1);
|
|
243
|
+
// Create a new proposal with same archive but different signer
|
|
244
|
+
const proposal2 = mockBlockProposal(signers[1], slotNumber, archive);
|
|
245
|
+
await ap.addBlockProposal(proposal2);
|
|
246
|
+
const retrievedProposal = await ap.getBlockProposal(proposalId);
|
|
247
|
+
expect(retrievedProposal).toBeDefined();
|
|
248
|
+
// Should have the second proposal
|
|
249
|
+
expect(retrievedProposal.toBuffer()).toEqual(proposal2.toBuffer());
|
|
250
|
+
expect(retrievedProposal.getSender().toString()).toBe(signers[1].address.toString());
|
|
251
|
+
});
|
|
252
|
+
it('should handle block proposals with different slots and same archive', async ()=>{
|
|
253
|
+
const archive = Fr.random();
|
|
254
|
+
const proposal1 = mockBlockProposal(signers[0], 100, archive);
|
|
255
|
+
const proposal2 = mockBlockProposal(signers[1], 200, archive);
|
|
256
|
+
const proposalId = archive.toString();
|
|
257
|
+
await ap.addBlockProposal(proposal1);
|
|
258
|
+
await ap.addBlockProposal(proposal2);
|
|
259
|
+
// Should get the latest one added
|
|
260
|
+
const retrievedProposal = await ap.getBlockProposal(proposalId);
|
|
261
|
+
expect(retrievedProposal).toBeDefined();
|
|
262
|
+
expect(retrievedProposal.toBuffer()).toEqual(proposal2.toBuffer());
|
|
263
|
+
expect(retrievedProposal.slotNumber.toBigInt()).toBe(BigInt(200));
|
|
264
|
+
});
|
|
265
|
+
it('should delete block proposal when deleting attestations for slot and proposal', async ()=>{
|
|
266
|
+
const slotNumber = 420;
|
|
267
|
+
const archive = Fr.random();
|
|
268
|
+
const proposal = mockBlockProposal(signers[0], slotNumber, archive);
|
|
269
|
+
const proposalId = proposal.archive.toString();
|
|
270
|
+
// Add proposal and some attestations
|
|
271
|
+
await ap.addBlockProposal(proposal);
|
|
272
|
+
const attestations = signers.map((signer)=>mockAttestation(signer, slotNumber, archive));
|
|
273
|
+
await ap.addAttestations(attestations);
|
|
274
|
+
// Verify proposal exists
|
|
275
|
+
let retrievedProposal = await ap.getBlockProposal(proposalId);
|
|
276
|
+
expect(retrievedProposal).toBeDefined();
|
|
277
|
+
// Delete attestations for slot and proposal
|
|
278
|
+
await ap.deleteAttestationsForSlotAndProposal(BigInt(slotNumber), proposalId);
|
|
279
|
+
// Proposal should be deleted
|
|
280
|
+
retrievedProposal = await ap.getBlockProposal(proposalId);
|
|
281
|
+
expect(retrievedProposal).toBeUndefined();
|
|
282
|
+
});
|
|
283
|
+
it('should delete block proposal when deleting attestations for slot', async ()=>{
|
|
284
|
+
const slotNumber = 420;
|
|
285
|
+
const archive = Fr.random();
|
|
286
|
+
const proposal = mockBlockProposal(signers[0], slotNumber, archive);
|
|
287
|
+
const proposalId = proposal.archive.toString();
|
|
288
|
+
// Add proposal
|
|
289
|
+
await ap.addBlockProposal(proposal);
|
|
290
|
+
// Verify proposal exists
|
|
291
|
+
let retrievedProposal = await ap.getBlockProposal(proposalId);
|
|
292
|
+
expect(retrievedProposal).toBeDefined();
|
|
293
|
+
// Delete attestations for slot
|
|
294
|
+
await ap.deleteAttestationsForSlot(BigInt(slotNumber));
|
|
295
|
+
// Proposal should be deleted
|
|
296
|
+
retrievedProposal = await ap.getBlockProposal(proposalId);
|
|
297
|
+
expect(retrievedProposal).toBeUndefined();
|
|
298
|
+
});
|
|
299
|
+
it('should be able to fetch both block proposal and attestations', async ()=>{
|
|
300
|
+
const slotNumber = 420;
|
|
301
|
+
const archive = Fr.random();
|
|
302
|
+
const proposal = mockBlockProposal(signers[0], slotNumber, archive);
|
|
303
|
+
const proposalId = proposal.archive.toString();
|
|
304
|
+
// Add proposal first
|
|
305
|
+
await ap.addBlockProposal(proposal);
|
|
306
|
+
// Add attestations for the same proposal
|
|
307
|
+
const attestations = signers.slice(1).map((signer)=>mockAttestation(signer, slotNumber, archive));
|
|
308
|
+
await ap.addAttestations(attestations);
|
|
309
|
+
// Retrieve both proposal and attestations
|
|
310
|
+
const retrievedProposal = await ap.getBlockProposal(proposalId);
|
|
311
|
+
const retrievedAttestations = await ap.getAttestationsForSlotAndProposal(BigInt(slotNumber), proposalId);
|
|
312
|
+
expect(retrievedProposal).toBeDefined();
|
|
313
|
+
// This are cached values, so we need to call them to ensure they are not undefined
|
|
314
|
+
retrievedProposal.payload.getSize();
|
|
315
|
+
retrievedProposal.signature.getSize();
|
|
316
|
+
expect(retrievedProposal).toEqual(proposal);
|
|
317
|
+
compareAttestations(retrievedAttestations, attestations);
|
|
318
|
+
});
|
|
319
|
+
});
|
|
213
320
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { AztecAsyncKVStore } from '@aztec/kv-store';
|
|
2
|
-
import { BlockAttestation } from '@aztec/stdlib/p2p';
|
|
2
|
+
import { BlockAttestation, BlockProposal } from '@aztec/stdlib/p2p';
|
|
3
3
|
import { type TelemetryClient } from '@aztec/telemetry-client';
|
|
4
4
|
import type { AttestationPool } from './attestation_pool.js';
|
|
5
5
|
export declare class KvAttestationPool implements AttestationPool {
|
|
@@ -7,6 +7,7 @@ export declare class KvAttestationPool implements AttestationPool {
|
|
|
7
7
|
private log;
|
|
8
8
|
private metrics;
|
|
9
9
|
private attestations;
|
|
10
|
+
private proposals;
|
|
10
11
|
private proposalsForSlot;
|
|
11
12
|
private attestationsForProposal;
|
|
12
13
|
constructor(store: AztecAsyncKVStore, telemetry?: TelemetryClient, log?: import("@aztec/foundation/log").Logger);
|
|
@@ -21,5 +22,7 @@ export declare class KvAttestationPool implements AttestationPool {
|
|
|
21
22
|
deleteAttestationsForSlot(slot: bigint): Promise<void>;
|
|
22
23
|
deleteAttestationsForSlotAndProposal(slot: bigint, proposalId: string): Promise<void>;
|
|
23
24
|
deleteAttestations(attestations: BlockAttestation[]): Promise<void>;
|
|
25
|
+
getBlockProposal(id: string): Promise<BlockProposal | undefined>;
|
|
26
|
+
addBlockProposal(blockProposal: BlockProposal): Promise<void>;
|
|
24
27
|
}
|
|
25
28
|
//# sourceMappingURL=kv_attestation_pool.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"kv_attestation_pool.d.ts","sourceRoot":"","sources":["../../../src/mem_pools/attestation_pool/kv_attestation_pool.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,iBAAiB,EAAqC,MAAM,iBAAiB,CAAC;AAC5F,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"kv_attestation_pool.d.ts","sourceRoot":"","sources":["../../../src/mem_pools/attestation_pool/kv_attestation_pool.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,iBAAiB,EAAqC,MAAM,iBAAiB,CAAC;AAC5F,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACpE,OAAO,EAAE,KAAK,eAAe,EAAsB,MAAM,yBAAyB,CAAC;AAGnF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAE7D,qBAAa,iBAAkB,YAAW,eAAe;IAYrD,OAAO,CAAC,KAAK;IAEb,OAAO,CAAC,GAAG;IAbb,OAAO,CAAC,OAAO,CAAwC;IAEvD,OAAO,CAAC,YAAY,CAAgC;IACpD,OAAO,CAAC,SAAS,CAGf;IACF,OAAO,CAAC,gBAAgB,CAAqC;IAC7D,OAAO,CAAC,uBAAuB,CAAqC;gBAG1D,KAAK,EAAE,iBAAiB,EAChC,SAAS,GAAE,eAAsC,EACzC,GAAG,yCAAyC;IAUtD,OAAO,CAAC,SAAS,CAIf;IAEW,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC;IAOxC,OAAO,CAAC,cAAc;IAYtB,OAAO,CAAC,iBAAiB;IAIZ,eAAe,CAAC,YAAY,EAAE,gBAAgB,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAyBhE,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAYjE,iCAAiC,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAsBhG,2BAA2B,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAO9D,yBAAyB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAuBtD,oCAAoC,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAqBrF,kBAAkB,CAAC,YAAY,EAAE,gBAAgB,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAsBnE,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,SAAS,CAAC;IAahE,gBAAgB,CAAC,aAAa,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;CAM3E"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Fr } from '@aztec/foundation/fields';
|
|
2
2
|
import { toArray } from '@aztec/foundation/iterable';
|
|
3
3
|
import { createLogger } from '@aztec/foundation/log';
|
|
4
|
-
import { BlockAttestation } from '@aztec/stdlib/p2p';
|
|
4
|
+
import { BlockAttestation, BlockProposal } from '@aztec/stdlib/p2p';
|
|
5
5
|
import { getTelemetryClient } from '@aztec/telemetry-client';
|
|
6
6
|
import { PoolInstrumentation, PoolName } from '../instrumentation.js';
|
|
7
7
|
export class KvAttestationPool {
|
|
@@ -9,6 +9,7 @@ export class KvAttestationPool {
|
|
|
9
9
|
log;
|
|
10
10
|
metrics;
|
|
11
11
|
attestations;
|
|
12
|
+
proposals;
|
|
12
13
|
proposalsForSlot;
|
|
13
14
|
attestationsForProposal;
|
|
14
15
|
constructor(store, telemetry = getTelemetryClient(), log = createLogger('aztec:attestation_pool')){
|
|
@@ -20,6 +21,7 @@ export class KvAttestationPool {
|
|
|
20
21
|
};
|
|
21
22
|
};
|
|
22
23
|
this.attestations = store.openMap('attestations');
|
|
24
|
+
this.proposals = store.openMap('proposals');
|
|
23
25
|
this.proposalsForSlot = store.openMultiMap('proposals_for_slot');
|
|
24
26
|
this.attestationsForProposal = store.openMultiMap('attestations_for_proposal');
|
|
25
27
|
this.metrics = new PoolInstrumentation(telemetry, PoolName.ATTESTATION_POOL, this.poolStats);
|
|
@@ -100,6 +102,7 @@ export class KvAttestationPool {
|
|
|
100
102
|
for (const attestation of attestations){
|
|
101
103
|
await this.attestations.delete(attestation);
|
|
102
104
|
}
|
|
105
|
+
await this.proposals.delete(proposalId);
|
|
103
106
|
await this.attestationsForProposal.delete(this.getProposalKey(slotFr, proposalId));
|
|
104
107
|
}
|
|
105
108
|
this.log.verbose(`Removed ${numberOfAttestations} attestations for slot ${slot}`);
|
|
@@ -114,6 +117,7 @@ export class KvAttestationPool {
|
|
|
114
117
|
for (const attestation of attestations){
|
|
115
118
|
await this.attestations.delete(attestation);
|
|
116
119
|
}
|
|
120
|
+
await this.proposals.delete(proposalId);
|
|
117
121
|
await this.proposalsForSlot.deleteValue(slotString, proposalId);
|
|
118
122
|
await this.attestationsForProposal.delete(this.getProposalKey(slotString, proposalId));
|
|
119
123
|
this.log.verbose(`Removed ${numberOfAttestations} attestations for slot ${slot} and proposal ${proposalId}`);
|
|
@@ -134,4 +138,21 @@ export class KvAttestationPool {
|
|
|
134
138
|
}
|
|
135
139
|
});
|
|
136
140
|
}
|
|
141
|
+
async getBlockProposal(id) {
|
|
142
|
+
const buffer = await this.proposals.getAsync(id);
|
|
143
|
+
try {
|
|
144
|
+
if (buffer && buffer.length > 0) {
|
|
145
|
+
return BlockProposal.fromBuffer(buffer);
|
|
146
|
+
}
|
|
147
|
+
} catch {
|
|
148
|
+
return Promise.resolve(undefined);
|
|
149
|
+
}
|
|
150
|
+
return Promise.resolve(undefined);
|
|
151
|
+
}
|
|
152
|
+
async addBlockProposal(blockProposal) {
|
|
153
|
+
await this.store.transactionAsync(async ()=>{
|
|
154
|
+
await this.proposalsForSlot.set(blockProposal.slotNumber.toString(), blockProposal.archive.toString());
|
|
155
|
+
await this.proposals.set(blockProposal.payload.archive.toString(), blockProposal.toBuffer());
|
|
156
|
+
});
|
|
157
|
+
}
|
|
137
158
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { BlockAttestation } from '@aztec/stdlib/p2p';
|
|
1
|
+
import type { BlockAttestation, BlockProposal } from '@aztec/stdlib/p2p';
|
|
2
2
|
import { type TelemetryClient } from '@aztec/telemetry-client';
|
|
3
3
|
import type { AttestationPool } from './attestation_pool.js';
|
|
4
4
|
export declare class InMemoryAttestationPool implements AttestationPool {
|
|
@@ -6,6 +6,7 @@ export declare class InMemoryAttestationPool implements AttestationPool {
|
|
|
6
6
|
private log;
|
|
7
7
|
private metrics;
|
|
8
8
|
private attestations;
|
|
9
|
+
private proposals;
|
|
9
10
|
constructor(telemetry?: TelemetryClient, log?: import("@aztec/foundation/log").Logger);
|
|
10
11
|
private poolStats;
|
|
11
12
|
isEmpty(): Promise<boolean>;
|
|
@@ -16,5 +17,7 @@ export declare class InMemoryAttestationPool implements AttestationPool {
|
|
|
16
17
|
deleteAttestationsForSlot(slot: bigint): Promise<void>;
|
|
17
18
|
deleteAttestationsForSlotAndProposal(slot: bigint, proposalId: string): Promise<void>;
|
|
18
19
|
deleteAttestations(attestations: BlockAttestation[]): Promise<void>;
|
|
20
|
+
addBlockProposal(blockProposal: BlockProposal): Promise<void>;
|
|
21
|
+
getBlockProposal(id: string): Promise<BlockProposal | undefined>;
|
|
19
22
|
}
|
|
20
23
|
//# sourceMappingURL=memory_attestation_pool.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"memory_attestation_pool.d.ts","sourceRoot":"","sources":["../../../src/mem_pools/attestation_pool/memory_attestation_pool.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"memory_attestation_pool.d.ts","sourceRoot":"","sources":["../../../src/mem_pools/attestation_pool/memory_attestation_pool.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACzE,OAAO,EAAE,KAAK,eAAe,EAAsB,MAAM,yBAAyB,CAAC;AAGnF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAE7D,qBAAa,uBAAwB,YAAW,eAAe;;IAQ3D,OAAO,CAAC,GAAG;IAPb,OAAO,CAAC,OAAO,CAAwC;IAEvD,OAAO,CAAC,YAAY,CAAgG;IACpH,OAAO,CAAC,SAAS,CAA6B;gBAG5C,SAAS,GAAE,eAAsC,EACzC,GAAG,yCAAuC;IAOpD,OAAO,CAAC,SAAS,CAIf;IAEK,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC;IAI3B,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAQjE,iCAAiC,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAWhG,eAAe,CAAC,YAAY,EAAE,gBAAgB,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAmC1D,2BAA2B,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAqBpE,yBAAyB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAkBtD,oCAAoC,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAgBrF,kBAAkB,CAAC,YAAY,EAAE,gBAAgB,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAiBnE,gBAAgB,CAAC,aAAa,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAU7D,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,SAAS,CAAC;CAGxE"}
|
|
@@ -5,6 +5,7 @@ export class InMemoryAttestationPool {
|
|
|
5
5
|
log;
|
|
6
6
|
metrics;
|
|
7
7
|
attestations;
|
|
8
|
+
proposals;
|
|
8
9
|
constructor(telemetry = getTelemetryClient(), log = createLogger('p2p:attestation_pool')){
|
|
9
10
|
this.log = log;
|
|
10
11
|
this.poolStats = ()=>{
|
|
@@ -13,6 +14,7 @@ export class InMemoryAttestationPool {
|
|
|
13
14
|
});
|
|
14
15
|
};
|
|
15
16
|
this.attestations = new Map();
|
|
17
|
+
this.proposals = new Map();
|
|
16
18
|
this.metrics = new PoolInstrumentation(telemetry, PoolName.ATTESTATION_POOL, this.poolStats);
|
|
17
19
|
}
|
|
18
20
|
poolStats;
|
|
@@ -81,8 +83,14 @@ export class InMemoryAttestationPool {
|
|
|
81
83
|
deleteAttestationsForSlot(slot) {
|
|
82
84
|
// We count the number of attestations we are removing
|
|
83
85
|
const numberOfAttestations = this.#getNumberOfAttestationsInSlot(slot);
|
|
86
|
+
const proposalIdsToDelete = this.attestations.get(slot)?.keys();
|
|
87
|
+
let proposalIdsToDeleteCount = 0;
|
|
88
|
+
proposalIdsToDelete?.forEach((proposalId)=>{
|
|
89
|
+
this.proposals.delete(proposalId);
|
|
90
|
+
proposalIdsToDeleteCount++;
|
|
91
|
+
});
|
|
84
92
|
this.attestations.delete(slot);
|
|
85
|
-
this.log.verbose(`Removed ${numberOfAttestations} attestations for slot ${slot}`);
|
|
93
|
+
this.log.verbose(`Removed ${numberOfAttestations} attestations and ${proposalIdsToDeleteCount} proposals for slot ${slot}`);
|
|
86
94
|
return Promise.resolve();
|
|
87
95
|
}
|
|
88
96
|
deleteAttestationsForSlotAndProposal(slot, proposalId) {
|
|
@@ -94,6 +102,7 @@ export class InMemoryAttestationPool {
|
|
|
94
102
|
this.log.verbose(`Removed ${numberOfAttestations} attestations for slot ${slot} and proposal ${proposalId}`);
|
|
95
103
|
}
|
|
96
104
|
}
|
|
105
|
+
this.proposals.delete(proposalId);
|
|
97
106
|
return Promise.resolve();
|
|
98
107
|
}
|
|
99
108
|
deleteAttestations(attestations) {
|
|
@@ -112,6 +121,17 @@ export class InMemoryAttestationPool {
|
|
|
112
121
|
}
|
|
113
122
|
return Promise.resolve();
|
|
114
123
|
}
|
|
124
|
+
addBlockProposal(blockProposal) {
|
|
125
|
+
// We initialize slot-proposal mapping if it does not exist
|
|
126
|
+
// This is important to ensure we can delete this proposal if there were not attestations for it
|
|
127
|
+
const slotProposalMapping = getSlotOrDefault(this.attestations, blockProposal.slotNumber.toBigInt());
|
|
128
|
+
slotProposalMapping.set(blockProposal.payload.archive.toString(), new Map());
|
|
129
|
+
this.proposals.set(blockProposal.payload.archive.toString(), blockProposal);
|
|
130
|
+
return Promise.resolve();
|
|
131
|
+
}
|
|
132
|
+
getBlockProposal(id) {
|
|
133
|
+
return Promise.resolve(this.proposals.get(id));
|
|
134
|
+
}
|
|
115
135
|
}
|
|
116
136
|
/**
|
|
117
137
|
* Get Slot or Default
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import type { Secp256k1Signer } from '@aztec/foundation/crypto';
|
|
2
2
|
import { Fr } from '@aztec/foundation/fields';
|
|
3
3
|
import { BlockAttestation } from '@aztec/stdlib/p2p';
|
|
4
|
-
import { TxHash } from '@aztec/stdlib/tx';
|
|
5
4
|
import { type LocalAccount } from 'viem/accounts';
|
|
6
5
|
/** Generate Account
|
|
7
6
|
*
|
|
@@ -15,5 +14,5 @@ export declare const generateAccount: () => LocalAccount;
|
|
|
15
14
|
* @param slot The slot number the attestation is for
|
|
16
15
|
* @returns A Block Attestation
|
|
17
16
|
*/
|
|
18
|
-
export declare const mockAttestation: (signer: Secp256k1Signer, slot?: number, archive?: Fr
|
|
17
|
+
export declare const mockAttestation: (signer: Secp256k1Signer, slot?: number, archive?: Fr) => BlockAttestation;
|
|
19
18
|
//# sourceMappingURL=mocks.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mocks.d.ts","sourceRoot":"","sources":["../../../src/mem_pools/attestation_pool/mocks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,EAAE,EAAE,EAAE,MAAM,0BAA0B,CAAC;AAC9C,OAAO,EACL,gBAAgB,EAIjB,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"mocks.d.ts","sourceRoot":"","sources":["../../../src/mem_pools/attestation_pool/mocks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,EAAE,EAAE,EAAE,MAAM,0BAA0B,CAAC;AAC9C,OAAO,EACL,gBAAgB,EAIjB,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EAAE,KAAK,YAAY,EAA2C,MAAM,eAAe,CAAC;AAE3F;;;;GAIG;AACH,eAAO,MAAM,eAAe,QAAO,YAGlC,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,eAAe,GAC1B,QAAQ,eAAe,EACvB,OAAM,MAAU,EAChB,UAAS,EAAgB,KACxB,gBASF,CAAC"}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { Fr } from '@aztec/foundation/fields';
|
|
2
2
|
import { BlockAttestation, ConsensusPayload, SignatureDomainSeparator, getHashedSignaturePayloadEthSignedMessage } from '@aztec/stdlib/p2p';
|
|
3
3
|
import { makeHeader } from '@aztec/stdlib/testing';
|
|
4
|
-
import { TxHash } from '@aztec/stdlib/tx';
|
|
5
4
|
import { generatePrivateKey, privateKeyToAccount } from 'viem/accounts';
|
|
6
5
|
/** Generate Account
|
|
7
6
|
*
|
|
@@ -16,17 +15,10 @@ import { generatePrivateKey, privateKeyToAccount } from 'viem/accounts';
|
|
|
16
15
|
* @param signer A viem signer to create a signature
|
|
17
16
|
* @param slot The slot number the attestation is for
|
|
18
17
|
* @returns A Block Attestation
|
|
19
|
-
*/ export const mockAttestation = (signer, slot = 0, archive = Fr.random()
|
|
20
|
-
0,
|
|
21
|
-
1,
|
|
22
|
-
2,
|
|
23
|
-
3,
|
|
24
|
-
4,
|
|
25
|
-
5
|
|
26
|
-
].map(()=>TxHash.random()))=>{
|
|
18
|
+
*/ export const mockAttestation = (signer, slot = 0, archive = Fr.random())=>{
|
|
27
19
|
// Use arbitrary numbers for all other than slot
|
|
28
20
|
const header = makeHeader(1, 2, slot);
|
|
29
|
-
const payload = new ConsensusPayload(header.toPropose(), archive, header.state
|
|
21
|
+
const payload = new ConsensusPayload(header.toPropose(), archive, header.state);
|
|
30
22
|
const hash = getHashedSignaturePayloadEthSignedMessage(payload, SignatureDomainSeparator.blockAttestation);
|
|
31
23
|
const signature = signer.sign(hash);
|
|
32
24
|
return new BlockAttestation(header.globalVariables.blockNumber, payload, signature);
|
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
import { type Logger } from '@aztec/foundation/log';
|
|
2
|
+
import type { TypedEventEmitter } from '@aztec/foundation/types';
|
|
2
3
|
import type { AztecAsyncKVStore } from '@aztec/kv-store';
|
|
3
4
|
import type { MerkleTreeReadOperations, WorldStateSynchronizer } from '@aztec/stdlib/interfaces/server';
|
|
4
5
|
import { BlockHeader, Tx, TxHash } from '@aztec/stdlib/tx';
|
|
5
6
|
import { type TelemetryClient } from '@aztec/telemetry-client';
|
|
6
7
|
import { ArchiveCache } from '../../msg_validators/tx_validator/archive_cache.js';
|
|
7
8
|
import { GasTxValidator } from '../../msg_validators/tx_validator/gas_validator.js';
|
|
8
|
-
import type { TxPool, TxPoolOptions } from './tx_pool.js';
|
|
9
|
+
import type { TxPool, TxPoolEvents, TxPoolOptions } from './tx_pool.js';
|
|
10
|
+
declare const AztecKVTxPool_base: new () => TypedEventEmitter<TxPoolEvents>;
|
|
9
11
|
/**
|
|
10
12
|
* KV implementation of the Transaction Pool.
|
|
11
13
|
*/
|
|
12
|
-
export declare class AztecKVTxPool implements TxPool {
|
|
14
|
+
export declare class AztecKVTxPool extends AztecKVTxPool_base implements TxPool {
|
|
13
15
|
#private;
|
|
14
16
|
/** The tx evicion logic will kick after pool size is greater than maxTxPoolSize * txPoolOverflowFactor */
|
|
15
17
|
txPoolOverflowFactor: number;
|
|
@@ -57,7 +59,9 @@ export declare class AztecKVTxPool implements TxPool {
|
|
|
57
59
|
* @param txs - An array of txs to be added to the pool.
|
|
58
60
|
* @returns Empty promise.
|
|
59
61
|
*/
|
|
60
|
-
addTxs(txs: Tx[]
|
|
62
|
+
addTxs(txs: Tx[], opts?: {
|
|
63
|
+
source?: string;
|
|
64
|
+
}): Promise<number>;
|
|
61
65
|
/**
|
|
62
66
|
* Deletes transactions from the pool. Tx hashes that are not present are ignored.
|
|
63
67
|
* @param txHashes - An array of tx hashes to be removed from the tx pool.
|
|
@@ -131,4 +135,5 @@ export declare class AztecKVTxPool implements TxPool {
|
|
|
131
135
|
private addPendingTxIndices;
|
|
132
136
|
private removePendingTxIndices;
|
|
133
137
|
}
|
|
138
|
+
export {};
|
|
134
139
|
//# sourceMappingURL=aztec_kv_tx_pool.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"aztec_kv_tx_pool.d.ts","sourceRoot":"","sources":["../../../src/mem_pools/tx_pool/aztec_kv_tx_pool.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,MAAM,EAAgB,MAAM,uBAAuB,CAAC;AAClE,OAAO,KAAK,EAAE,iBAAiB,EAA0D,MAAM,iBAAiB,CAAC;AAGjH,OAAO,KAAK,EAAE,wBAAwB,EAAE,sBAAsB,EAAE,MAAM,iCAAiC,CAAC;AAIxG,OAAO,EAAE,WAAW,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,EAAE,KAAK,eAAe,EAAsB,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"aztec_kv_tx_pool.d.ts","sourceRoot":"","sources":["../../../src/mem_pools/tx_pool/aztec_kv_tx_pool.ts"],"names":[],"mappings":"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"}
|
|
@@ -8,13 +8,14 @@ import { DatabasePublicStateSource } from '@aztec/stdlib/trees';
|
|
|
8
8
|
import { Tx, TxHash } from '@aztec/stdlib/tx';
|
|
9
9
|
import { getTelemetryClient } from '@aztec/telemetry-client';
|
|
10
10
|
import assert from 'assert';
|
|
11
|
+
import EventEmitter from 'node:events';
|
|
11
12
|
import { ArchiveCache } from '../../msg_validators/tx_validator/archive_cache.js';
|
|
12
13
|
import { GasTxValidator } from '../../msg_validators/tx_validator/gas_validator.js';
|
|
13
14
|
import { PoolInstrumentation, PoolName } from '../instrumentation.js';
|
|
14
15
|
import { getPendingTxPriority } from './priority.js';
|
|
15
16
|
/**
|
|
16
17
|
* KV implementation of the Transaction Pool.
|
|
17
|
-
*/ export class AztecKVTxPool {
|
|
18
|
+
*/ export class AztecKVTxPool extends EventEmitter {
|
|
18
19
|
#store;
|
|
19
20
|
/** Our tx pool, stored as a Map, with K: tx hash and V: the transaction. */ #txs;
|
|
20
21
|
/** The maximum cumulative tx size that the pending txs in the pool take up. */ #maxTxPoolSize = 0;
|
|
@@ -41,6 +42,7 @@ import { getPendingTxPriority } from './priority.js';
|
|
|
41
42
|
* @param archivedTxLimit - The number of txs to archive.
|
|
42
43
|
* @param log - A logger.
|
|
43
44
|
*/ constructor(store, archive, worldStateSynchronizer, telemetry = getTelemetryClient(), config = {}, log = createLogger('p2p:tx_pool')){
|
|
45
|
+
super();
|
|
44
46
|
this.#log = log;
|
|
45
47
|
this.updateConfig(config);
|
|
46
48
|
this.#txs = store.openMap('txs');
|
|
@@ -208,12 +210,12 @@ import { getPendingTxPriority } from './priority.js';
|
|
|
208
210
|
* Adds a list of transactions to the pool. Duplicates are ignored.
|
|
209
211
|
* @param txs - An array of txs to be added to the pool.
|
|
210
212
|
* @returns Empty promise.
|
|
211
|
-
*/ async addTxs(txs) {
|
|
212
|
-
|
|
213
|
-
const hashesAndStats =
|
|
214
|
-
txHash:
|
|
215
|
-
txStats:
|
|
216
|
-
}))
|
|
213
|
+
*/ async addTxs(txs, opts = {}) {
|
|
214
|
+
const addedTxs = [];
|
|
215
|
+
const hashesAndStats = txs.map((tx)=>({
|
|
216
|
+
txHash: tx.getTxHash(),
|
|
217
|
+
txStats: tx.getStats()
|
|
218
|
+
}));
|
|
217
219
|
await this.#store.transactionAsync(async ()=>{
|
|
218
220
|
let pendingTxSize = await this.#pendingTxSize.getAsync() ?? 0;
|
|
219
221
|
await Promise.all(txs.map(async (tx, i)=>{
|
|
@@ -228,8 +230,8 @@ import { getPendingTxPriority } from './priority.js';
|
|
|
228
230
|
...txStats
|
|
229
231
|
});
|
|
230
232
|
await this.#txs.set(key, tx.toBuffer());
|
|
233
|
+
addedTxs.push(tx);
|
|
231
234
|
if (!await this.#minedTxHashToBlock.hasAsync(key)) {
|
|
232
|
-
addedCount++;
|
|
233
235
|
pendingTxSize += tx.getSize();
|
|
234
236
|
await this.addPendingTxIndices(tx, key);
|
|
235
237
|
this.#metrics.recordSize(tx);
|
|
@@ -238,13 +240,22 @@ import { getPendingTxPriority } from './priority.js';
|
|
|
238
240
|
await this.#pendingTxSize.set(pendingTxSize);
|
|
239
241
|
await this.evictLowPriorityTxs(hashesAndStats.map(({ txHash })=>txHash));
|
|
240
242
|
});
|
|
241
|
-
|
|
243
|
+
if (addedTxs.length > 0) {
|
|
244
|
+
this.emit('txs-added', {
|
|
245
|
+
...opts,
|
|
246
|
+
txs: addedTxs
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
return addedTxs.length;
|
|
242
250
|
}
|
|
243
251
|
/**
|
|
244
252
|
* Deletes transactions from the pool. Tx hashes that are not present are ignored.
|
|
245
253
|
* @param txHashes - An array of tx hashes to be removed from the tx pool.
|
|
246
254
|
* @returns Empty promise.
|
|
247
255
|
*/ deleteTxs(txHashes, eviction = false) {
|
|
256
|
+
if (txHashes.length === 0) {
|
|
257
|
+
return Promise.resolve();
|
|
258
|
+
}
|
|
248
259
|
const deletedTxs = [];
|
|
249
260
|
const poolDbTx = this.#store.transactionAsync(async ()=>{
|
|
250
261
|
let pendingTxSize = await this.#pendingTxSize.getAsync() ?? 0;
|
|
@@ -266,6 +277,9 @@ import { getPendingTxPriority } from './priority.js';
|
|
|
266
277
|
}
|
|
267
278
|
await this.#pendingTxSize.set(pendingTxSize);
|
|
268
279
|
});
|
|
280
|
+
this.#log.debug(`Deleted ${txHashes.length} txs from pool`, {
|
|
281
|
+
txHashes
|
|
282
|
+
});
|
|
269
283
|
return this.#archivedTxLimit ? poolDbTx.then(()=>this.archiveTxs(deletedTxs)) : poolDbTx;
|
|
270
284
|
}
|
|
271
285
|
/**
|
|
@@ -357,33 +371,46 @@ import { getPendingTxPriority } from './priority.js';
|
|
|
357
371
|
* @param txs - The list of transactions to archive.
|
|
358
372
|
* @returns Empty promise.
|
|
359
373
|
*/ async archiveTxs(txs) {
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
374
|
+
if (txs.length === 0) {
|
|
375
|
+
return;
|
|
376
|
+
}
|
|
377
|
+
try {
|
|
378
|
+
const txHashes = await Promise.all(txs.map((tx)=>tx.getTxHash()));
|
|
379
|
+
await this.#archive.transactionAsync(async ()=>{
|
|
380
|
+
// calculate the head and tail indices of the archived txs by insertion order.
|
|
381
|
+
let headIdx = ((await this.#archivedTxIndices.entriesAsync({
|
|
382
|
+
limit: 1,
|
|
383
|
+
reverse: true
|
|
384
|
+
}).next()).value?.[0] ?? -1) + 1;
|
|
385
|
+
let tailIdx = (await this.#archivedTxIndices.entriesAsync({
|
|
386
|
+
limit: 1
|
|
387
|
+
}).next()).value?.[0] ?? 0;
|
|
388
|
+
for(let i = 0; i < txs.length; i++){
|
|
389
|
+
const tx = txs[i];
|
|
390
|
+
while(headIdx - tailIdx >= this.#archivedTxLimit){
|
|
391
|
+
const txHash = await this.#archivedTxIndices.getAsync(tailIdx);
|
|
392
|
+
if (txHash) {
|
|
393
|
+
await this.#archivedTxs.delete(txHash);
|
|
394
|
+
await this.#archivedTxIndices.delete(tailIdx);
|
|
395
|
+
}
|
|
396
|
+
tailIdx++;
|
|
377
397
|
}
|
|
378
|
-
|
|
398
|
+
const archivedTx = new Tx(tx.txHash, tx.data, ClientIvcProof.empty(), tx.contractClassLogFields, tx.publicFunctionCalldata);
|
|
399
|
+
const txHash = txHashes[i].toString();
|
|
400
|
+
await this.#archivedTxs.set(txHash, archivedTx.toBuffer());
|
|
401
|
+
await this.#archivedTxIndices.set(headIdx, txHash);
|
|
402
|
+
headIdx++;
|
|
379
403
|
}
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
404
|
+
this.#log.debug(`Archived ${txs.length} txs`, {
|
|
405
|
+
txHashes
|
|
406
|
+
});
|
|
407
|
+
this.#log.debug(`Total archived txs: ${headIdx - tailIdx}`);
|
|
408
|
+
});
|
|
409
|
+
} catch (error) {
|
|
410
|
+
this.#log.error(`Error archiving txs`, {
|
|
411
|
+
error
|
|
412
|
+
});
|
|
413
|
+
}
|
|
387
414
|
}
|
|
388
415
|
/**
|
|
389
416
|
* Evicts pending txs with the lowest priority fees from the pool to accomodate the max tx count and cumulative max tx size
|
|
@@ -468,9 +495,9 @@ import { getPendingTxPriority } from './priority.js';
|
|
|
468
495
|
continue;
|
|
469
496
|
}
|
|
470
497
|
// Evict pending txs with an expiration timestamp less than or equal to the mined block timestamp
|
|
471
|
-
const includeByTimestamp = tx.data.
|
|
472
|
-
if (includeByTimestamp
|
|
473
|
-
this.#log.verbose(`Evicting tx ${txHash} from pool due to the tx being expired (includeByTimestamp: ${includeByTimestamp
|
|
498
|
+
const includeByTimestamp = tx.data.includeByTimestamp;
|
|
499
|
+
if (includeByTimestamp <= timestamp) {
|
|
500
|
+
this.#log.verbose(`Evicting tx ${txHash} from pool due to the tx being expired (includeByTimestamp: ${includeByTimestamp}, mined block timestamp: ${timestamp})`);
|
|
474
501
|
txsToEvict.push(TxHash.fromString(txHash));
|
|
475
502
|
continue;
|
|
476
503
|
}
|
|
@@ -1,10 +1,12 @@
|
|
|
1
|
+
import type { TypedEventEmitter } from '@aztec/foundation/types';
|
|
1
2
|
import { BlockHeader, Tx, TxHash } from '@aztec/stdlib/tx';
|
|
2
3
|
import { type TelemetryClient } from '@aztec/telemetry-client';
|
|
3
|
-
import type { TxPool, TxPoolOptions } from './tx_pool.js';
|
|
4
|
+
import type { TxPool, TxPoolEvents, TxPoolOptions } from './tx_pool.js';
|
|
5
|
+
declare const InMemoryTxPool_base: new () => TypedEventEmitter<TxPoolEvents>;
|
|
4
6
|
/**
|
|
5
7
|
* In-memory implementation of the Transaction Pool.
|
|
6
8
|
*/
|
|
7
|
-
export declare class InMemoryTxPool implements TxPool {
|
|
9
|
+
export declare class InMemoryTxPool extends InMemoryTxPool_base implements TxPool {
|
|
8
10
|
private log;
|
|
9
11
|
/**
|
|
10
12
|
* Our tx pool, stored as a Map in-memory, with K: tx hash and V: the transaction.
|
|
@@ -40,7 +42,9 @@ export declare class InMemoryTxPool implements TxPool {
|
|
|
40
42
|
* @param txs - An array of txs to be added to the pool.
|
|
41
43
|
* @returns Empty promise.
|
|
42
44
|
*/
|
|
43
|
-
addTxs(txs: Tx[]
|
|
45
|
+
addTxs(txs: Tx[], opts?: {
|
|
46
|
+
source?: string;
|
|
47
|
+
}): Promise<number>;
|
|
44
48
|
/**
|
|
45
49
|
* Deletes transactions from the pool. Tx hashes that are not present are ignored.
|
|
46
50
|
* @param txHashes - An array of tx hashes to be removed from the tx pool.
|
|
@@ -60,4 +64,5 @@ export declare class InMemoryTxPool implements TxPool {
|
|
|
60
64
|
updateConfig(_config: TxPoolOptions): void;
|
|
61
65
|
markTxsAsNonEvictable(_: TxHash[]): Promise<void>;
|
|
62
66
|
}
|
|
67
|
+
export {};
|
|
63
68
|
//# sourceMappingURL=memory_tx_pool.d.ts.map
|