@aztec/p2p 3.0.0-devnet.2 → 3.0.0-devnet.2-patch.1
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 +4 -2
- package/dest/client/interface.d.ts.map +1 -1
- package/dest/client/p2p_client.d.ts +8 -26
- package/dest/client/p2p_client.d.ts.map +1 -1
- package/dest/client/p2p_client.js +31 -24
- package/dest/config.d.ts +60 -54
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +12 -2
- 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 +7 -0
- package/dest/errors/attestation-pool.error.d.ts.map +1 -0
- package/dest/errors/attestation-pool.error.js +12 -0
- 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 +43 -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 +67 -34
- package/dest/mem_pools/attestation_pool/index.d.ts +1 -1
- package/dest/mem_pools/attestation_pool/kv_attestation_pool.d.ts +15 -6
- package/dest/mem_pools/attestation_pool/kv_attestation_pool.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/kv_attestation_pool.js +57 -18
- package/dest/mem_pools/attestation_pool/memory_attestation_pool.d.ts +13 -6
- package/dest/mem_pools/attestation_pool/memory_attestation_pool.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/memory_attestation_pool.js +51 -7
- package/dest/mem_pools/attestation_pool/mocks.d.ts +226 -5
- package/dest/mem_pools/attestation_pool/mocks.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/mocks.js +2 -2
- package/dest/mem_pools/index.d.ts +1 -1
- package/dest/mem_pools/instrumentation.d.ts +3 -1
- package/dest/mem_pools/instrumentation.d.ts.map +1 -1
- package/dest/mem_pools/instrumentation.js +11 -2
- package/dest/mem_pools/interface.d.ts +1 -1
- package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts +5 -38
- 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 +9 -3
- package/dest/mem_pools/tx_pool/index.d.ts +1 -1
- package/dest/mem_pools/tx_pool/memory_tx_pool.d.ts +5 -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 +7 -0
- package/dest/mem_pools/tx_pool/priority.d.ts +1 -1
- package/dest/mem_pools/tx_pool/tx_pool.d.ts +10 -3
- 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 +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 +5 -4
- package/dest/msg_validators/attestation_validator/attestation_validator.d.ts +4 -3
- package/dest/msg_validators/attestation_validator/attestation_validator.d.ts.map +1 -1
- package/dest/msg_validators/attestation_validator/attestation_validator.js +12 -12
- package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts +20 -0
- package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts.map +1 -0
- package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.js +67 -0
- package/dest/msg_validators/attestation_validator/index.d.ts +2 -1
- package/dest/msg_validators/attestation_validator/index.d.ts.map +1 -1
- package/dest/msg_validators/attestation_validator/index.js +1 -0
- 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 +22 -10
- 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 +2 -2
- package/dest/msg_validators/tx_validator/archive_cache.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/block_header_validator.d.ts +2 -2
- 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 +4 -3
- package/dest/msg_validators/tx_validator/factory.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/factory.js +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 +2 -2
- 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/phases_validator.js +3 -1
- package/dest/msg_validators/tx_validator/test_utils.d.ts +2 -2
- package/dest/msg_validators/tx_validator/test_utils.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/timestamp_validator.d.ts +3 -2
- 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 +25 -4
- package/dest/services/encoding.d.ts.map +1 -1
- package/dest/services/encoding.js +74 -6
- package/dest/services/gossipsub/scoring.d.ts +1 -1
- package/dest/services/index.d.ts +1 -1
- package/dest/services/libp2p/instrumentation.d.ts +3 -1
- package/dest/services/libp2p/instrumentation.d.ts.map +1 -1
- package/dest/services/libp2p/instrumentation.js +9 -2
- package/dest/services/libp2p/libp2p_service.d.ts +25 -74
- package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
- package/dest/services/libp2p/libp2p_service.js +308 -84
- package/dest/services/peer-manager/interface.d.ts +1 -1
- package/dest/services/peer-manager/metrics.d.ts +3 -1
- package/dest/services/peer-manager/metrics.d.ts.map +1 -1
- package/dest/services/peer-manager/metrics.js +11 -0
- 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_manager.js +4 -2
- package/dest/services/peer-manager/peer_scoring.d.ts +7 -2
- package/dest/services/peer-manager/peer_scoring.d.ts.map +1 -1
- package/dest/services/peer-manager/peer_scoring.js +40 -2
- 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 +2 -2
- package/dest/services/reqresp/interface.d.ts.map +1 -1
- package/dest/services/reqresp/interface.js +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 +2 -2
- package/dest/services/reqresp/protocols/auth.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/auth.js +2 -2
- package/dest/services/reqresp/protocols/block.d.ts +1 -1
- package/dest/services/reqresp/protocols/block.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/block.js +3 -2
- 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 +4 -6
- package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.js +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 +6 -5
- package/dest/services/reqresp/protocols/status.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/status.js +4 -3
- 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/reqresp.js +2 -2
- 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 +4 -9
- 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 +6 -7
- 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 +11 -11
- 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 +5 -4
- 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/mock-tx-helpers.js +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 +14 -8
- package/dest/testbench/parse_log_file.d.ts +1 -1
- package/dest/testbench/testbench.d.ts +1 -1
- package/dest/testbench/testbench.js +2 -2
- 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 +2 -1
- package/dest/util.d.ts.map +1 -1
- package/dest/util.js +11 -2
- package/dest/versioning.d.ts +1 -1
- package/package.json +19 -18
- package/src/client/interface.ts +4 -1
- package/src/client/p2p_client.ts +51 -43
- package/src/config.ts +19 -2
- package/src/errors/attestation-pool.error.ts +13 -0
- package/src/mem_pools/attestation_pool/attestation_pool.ts +46 -5
- package/src/mem_pools/attestation_pool/attestation_pool_test_suite.ts +84 -34
- package/src/mem_pools/attestation_pool/kv_attestation_pool.ts +87 -24
- package/src/mem_pools/attestation_pool/memory_attestation_pool.ts +77 -15
- package/src/mem_pools/attestation_pool/mocks.ts +3 -3
- package/src/mem_pools/instrumentation.ts +13 -0
- package/src/mem_pools/tx_pool/aztec_kv_tx_pool.ts +15 -9
- package/src/mem_pools/tx_pool/memory_tx_pool.ts +13 -6
- package/src/mem_pools/tx_pool/tx_pool.ts +10 -2
- package/src/mem_pools/tx_pool/tx_pool_test_suite.ts +5 -4
- package/src/msg_validators/attestation_validator/attestation_validator.ts +14 -16
- package/src/msg_validators/attestation_validator/fisherman_attestation_validator.ts +91 -0
- package/src/msg_validators/attestation_validator/index.ts +1 -0
- package/src/msg_validators/block_proposal_validator/block_proposal_validator.ts +26 -10
- package/src/msg_validators/tx_validator/archive_cache.ts +1 -1
- package/src/msg_validators/tx_validator/block_header_validator.ts +1 -1
- package/src/msg_validators/tx_validator/factory.ts +3 -2
- package/src/msg_validators/tx_validator/metadata_validator.ts +1 -1
- package/src/msg_validators/tx_validator/phases_validator.ts +3 -1
- package/src/msg_validators/tx_validator/test_utils.ts +1 -1
- package/src/msg_validators/tx_validator/timestamp_validator.ts +2 -1
- package/src/services/encoding.ts +81 -6
- package/src/services/libp2p/instrumentation.ts +10 -1
- package/src/services/libp2p/libp2p_service.ts +334 -91
- package/src/services/peer-manager/metrics.ts +10 -0
- package/src/services/peer-manager/peer_manager.ts +4 -2
- package/src/services/peer-manager/peer_scoring.ts +46 -3
- package/src/services/reqresp/interface.ts +1 -1
- package/src/services/reqresp/protocols/auth.ts +2 -2
- package/src/services/reqresp/protocols/block.ts +3 -2
- package/src/services/reqresp/protocols/block_txs/block_txs_reqresp.ts +1 -1
- package/src/services/reqresp/protocols/status.ts +9 -8
- package/src/services/reqresp/reqresp.ts +2 -2
- package/src/services/tx_collection/fast_tx_collection.ts +3 -2
- package/src/services/tx_collection/slow_tx_collection.ts +7 -6
- package/src/services/tx_collection/tx_collection.ts +10 -9
- package/src/services/tx_provider.ts +4 -3
- package/src/test-helpers/mock-tx-helpers.ts +1 -1
- package/src/testbench/p2p_client_testbench_worker.ts +11 -5
- package/src/testbench/testbench.ts +2 -2
- package/src/util.ts +12 -2
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { SlotNumber } from '@aztec/foundation/branded-types';
|
|
2
|
+
import { Secp256k1Signer } from '@aztec/foundation/crypto/secp256k1-signer';
|
|
3
|
+
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
3
4
|
import type { BlockAttestation, BlockProposal } from '@aztec/stdlib/p2p';
|
|
4
5
|
import {
|
|
5
6
|
BlockProposal as BlockProposalClass,
|
|
@@ -42,7 +43,7 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
|
|
|
42
43
|
|
|
43
44
|
const mockBlockProposal = (signer: Secp256k1Signer, slotNumber: number, archive: Fr = Fr.random()): BlockProposal => {
|
|
44
45
|
const header = makeL2BlockHeader(1, 2, slotNumber);
|
|
45
|
-
const payload = new ConsensusPayload(header.toCheckpointHeader(), archive
|
|
46
|
+
const payload = new ConsensusPayload(header.toCheckpointHeader(), archive);
|
|
46
47
|
|
|
47
48
|
const hash = getHashedSignaturePayloadEthSignedMessage(payload, SignatureDomainSeparator.blockProposal);
|
|
48
49
|
const signature = signer.sign(hash);
|
|
@@ -68,11 +69,19 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
|
|
|
68
69
|
|
|
69
70
|
await ap.addAttestations(attestations);
|
|
70
71
|
|
|
71
|
-
const retrievedAttestations = await ap.getAttestationsForSlotAndProposal(
|
|
72
|
+
const retrievedAttestations = await ap.getAttestationsForSlotAndProposal(
|
|
73
|
+
SlotNumber(slotNumber),
|
|
74
|
+
archive.toString(),
|
|
75
|
+
);
|
|
72
76
|
expect(retrievedAttestations.length).toBe(attestations.length);
|
|
73
77
|
compareAttestations(retrievedAttestations, attestations);
|
|
74
78
|
|
|
75
|
-
|
|
79
|
+
// Check hasAttestation for added attestations
|
|
80
|
+
for (const attestation of attestations) {
|
|
81
|
+
expect(await ap.hasAttestation(attestation)).toBe(true);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const retrievedAttestationsForSlot = await ap.getAttestationsForSlot(SlotNumber(slotNumber));
|
|
76
85
|
expect(retrievedAttestationsForSlot.length).toBe(attestations.length);
|
|
77
86
|
compareAttestations(retrievedAttestationsForSlot, attestations);
|
|
78
87
|
|
|
@@ -80,23 +89,29 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
|
|
|
80
89
|
const newAttestation = mockAttestation(signers[NUMBER_OF_SIGNERS_PER_TEST - 1], slotNumber, archive);
|
|
81
90
|
await ap.addAttestations([newAttestation]);
|
|
82
91
|
const retrievedAttestationsAfterAdd = await ap.getAttestationsForSlotAndProposal(
|
|
83
|
-
|
|
92
|
+
SlotNumber(slotNumber),
|
|
84
93
|
archive.toString(),
|
|
85
94
|
);
|
|
86
95
|
expect(retrievedAttestationsAfterAdd.length).toBe(attestations.length + 1);
|
|
87
96
|
compareAttestations(retrievedAttestationsAfterAdd, [...attestations, newAttestation]);
|
|
88
|
-
|
|
97
|
+
expect(await ap.hasAttestation(newAttestation)).toBe(true);
|
|
98
|
+
const retrievedAttestationsForSlotAfterAdd = await ap.getAttestationsForSlot(SlotNumber(slotNumber));
|
|
89
99
|
expect(retrievedAttestationsForSlotAfterAdd.length).toBe(attestations.length + 1);
|
|
90
100
|
compareAttestations(retrievedAttestationsForSlotAfterAdd, [...attestations, newAttestation]);
|
|
91
101
|
|
|
92
102
|
// Delete by slot
|
|
93
|
-
await ap.deleteAttestationsForSlot(
|
|
103
|
+
await ap.deleteAttestationsForSlot(SlotNumber(slotNumber));
|
|
94
104
|
|
|
95
105
|
const retreivedAttestationsAfterDelete = await ap.getAttestationsForSlotAndProposal(
|
|
96
|
-
|
|
106
|
+
SlotNumber(slotNumber),
|
|
97
107
|
archive.toString(),
|
|
98
108
|
);
|
|
99
109
|
expect(retreivedAttestationsAfterDelete.length).toBe(0);
|
|
110
|
+
// Check hasAttestation after deletion
|
|
111
|
+
for (const attestation of attestations) {
|
|
112
|
+
expect(await ap.hasAttestation(attestation)).toBe(false);
|
|
113
|
+
}
|
|
114
|
+
expect(await ap.hasAttestation(newAttestation)).toBe(false);
|
|
100
115
|
});
|
|
101
116
|
|
|
102
117
|
it('should handle duplicate proposals in a slot', async () => {
|
|
@@ -113,14 +128,17 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
|
|
|
113
128
|
// Add them to store and check we end up with only one
|
|
114
129
|
await ap.addAttestations(attestations);
|
|
115
130
|
|
|
116
|
-
const retreivedAttestations = await ap.getAttestationsForSlotAndProposal(
|
|
131
|
+
const retreivedAttestations = await ap.getAttestationsForSlotAndProposal(
|
|
132
|
+
SlotNumber(slotNumber),
|
|
133
|
+
archive.toString(),
|
|
134
|
+
);
|
|
117
135
|
expect(retreivedAttestations.length).toBe(1);
|
|
118
136
|
expect(retreivedAttestations[0].toBuffer()).toEqual(attestations[0].toBuffer());
|
|
119
137
|
expect(retreivedAttestations[0].getSender()?.toString()).toEqual(signer.address.toString());
|
|
120
138
|
|
|
121
139
|
// Try adding them on another operation and check they are still not duplicated
|
|
122
140
|
await ap.addAttestations([attestations[0]]);
|
|
123
|
-
expect(await ap.getAttestationsForSlotAndProposal(
|
|
141
|
+
expect(await ap.getAttestationsForSlotAndProposal(SlotNumber(slotNumber), archive.toString())).toHaveLength(1);
|
|
124
142
|
});
|
|
125
143
|
|
|
126
144
|
it('should store attestations by differing slot', async () => {
|
|
@@ -133,7 +151,7 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
|
|
|
133
151
|
const slot = attestation.payload.header.slotNumber;
|
|
134
152
|
const archive = attestation.archive.toString();
|
|
135
153
|
|
|
136
|
-
const retreivedAttestations = await ap.getAttestationsForSlotAndProposal(slot
|
|
154
|
+
const retreivedAttestations = await ap.getAttestationsForSlotAndProposal(slot, archive);
|
|
137
155
|
expect(retreivedAttestations.length).toBe(1);
|
|
138
156
|
expect(retreivedAttestations[0].toBuffer()).toEqual(attestation.toBuffer());
|
|
139
157
|
expect(retreivedAttestations[0].payload.header.slotNumber).toEqual(slot);
|
|
@@ -151,7 +169,7 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
|
|
|
151
169
|
const slot = attestation.payload.header.slotNumber;
|
|
152
170
|
const proposalId = attestation.archive.toString();
|
|
153
171
|
|
|
154
|
-
const retreivedAttestations = await ap.getAttestationsForSlotAndProposal(slot
|
|
172
|
+
const retreivedAttestations = await ap.getAttestationsForSlotAndProposal(slot, proposalId);
|
|
155
173
|
expect(retreivedAttestations.length).toBe(1);
|
|
156
174
|
expect(retreivedAttestations[0].toBuffer()).toEqual(attestation.toBuffer());
|
|
157
175
|
expect(retreivedAttestations[0].payload.header.slotNumber).toEqual(slot);
|
|
@@ -166,14 +184,24 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
|
|
|
166
184
|
|
|
167
185
|
await ap.addAttestations(attestations);
|
|
168
186
|
|
|
169
|
-
const retreivedAttestations = await ap.getAttestationsForSlotAndProposal(
|
|
187
|
+
const retreivedAttestations = await ap.getAttestationsForSlotAndProposal(SlotNumber(slotNumber), proposalId);
|
|
170
188
|
expect(retreivedAttestations.length).toBe(NUMBER_OF_SIGNERS_PER_TEST);
|
|
171
189
|
compareAttestations(retreivedAttestations, attestations);
|
|
172
190
|
|
|
191
|
+
// Check hasAttestation before deletion
|
|
192
|
+
for (const attestation of attestations) {
|
|
193
|
+
expect(await ap.hasAttestation(attestation)).toBe(true);
|
|
194
|
+
}
|
|
195
|
+
|
|
173
196
|
await ap.deleteAttestations(attestations);
|
|
174
197
|
|
|
175
|
-
const gottenAfterDelete = await ap.getAttestationsForSlotAndProposal(
|
|
198
|
+
const gottenAfterDelete = await ap.getAttestationsForSlotAndProposal(SlotNumber(slotNumber), proposalId);
|
|
176
199
|
expect(gottenAfterDelete.length).toBe(0);
|
|
200
|
+
|
|
201
|
+
// Check hasAttestation after deletion
|
|
202
|
+
for (const attestation of attestations) {
|
|
203
|
+
expect(await ap.hasAttestation(attestation)).toBe(false);
|
|
204
|
+
}
|
|
177
205
|
});
|
|
178
206
|
|
|
179
207
|
it('should blanket delete attestations per slot', async () => {
|
|
@@ -184,13 +212,16 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
|
|
|
184
212
|
|
|
185
213
|
await ap.addAttestations(attestations);
|
|
186
214
|
|
|
187
|
-
const retreivedAttestations = await ap.getAttestationsForSlotAndProposal(
|
|
215
|
+
const retreivedAttestations = await ap.getAttestationsForSlotAndProposal(SlotNumber(slotNumber), proposalId);
|
|
188
216
|
expect(retreivedAttestations.length).toBe(NUMBER_OF_SIGNERS_PER_TEST);
|
|
189
217
|
compareAttestations(retreivedAttestations, attestations);
|
|
190
218
|
|
|
191
|
-
await ap.deleteAttestationsForSlot(
|
|
219
|
+
await ap.deleteAttestationsForSlot(SlotNumber(slotNumber));
|
|
192
220
|
|
|
193
|
-
const retreivedAttestationsAfterDelete = await ap.getAttestationsForSlotAndProposal(
|
|
221
|
+
const retreivedAttestationsAfterDelete = await ap.getAttestationsForSlotAndProposal(
|
|
222
|
+
SlotNumber(slotNumber),
|
|
223
|
+
proposalId,
|
|
224
|
+
);
|
|
194
225
|
expect(retreivedAttestationsAfterDelete.length).toBe(0);
|
|
195
226
|
});
|
|
196
227
|
|
|
@@ -208,17 +239,20 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
|
|
|
208
239
|
await ap.addAttestations(attestations);
|
|
209
240
|
await ap.addAttestations(attestations2);
|
|
210
241
|
|
|
211
|
-
const retreivedAttestations = await ap.getAttestationsForSlotAndProposal(
|
|
242
|
+
const retreivedAttestations = await ap.getAttestationsForSlotAndProposal(SlotNumber(slotNumber), proposalId);
|
|
212
243
|
expect(retreivedAttestations.length).toBe(NUMBER_OF_SIGNERS_PER_TEST);
|
|
213
244
|
compareAttestations(retreivedAttestations, attestations);
|
|
214
245
|
|
|
215
|
-
await ap.deleteAttestationsForSlotAndProposal(
|
|
246
|
+
await ap.deleteAttestationsForSlotAndProposal(SlotNumber(slotNumber), proposalId);
|
|
216
247
|
|
|
217
|
-
const retreivedAttestationsAfterDelete = await ap.getAttestationsForSlotAndProposal(
|
|
248
|
+
const retreivedAttestationsAfterDelete = await ap.getAttestationsForSlotAndProposal(
|
|
249
|
+
SlotNumber(slotNumber),
|
|
250
|
+
proposalId,
|
|
251
|
+
);
|
|
218
252
|
expect(retreivedAttestationsAfterDelete.length).toBe(0);
|
|
219
253
|
|
|
220
254
|
const retreivedAttestationsAfterDeleteForOtherProposal = await ap.getAttestationsForSlotAndProposal(
|
|
221
|
-
|
|
255
|
+
SlotNumber(slotNumber),
|
|
222
256
|
proposalId2,
|
|
223
257
|
);
|
|
224
258
|
expect(retreivedAttestationsAfterDeleteForOtherProposal.length).toBe(NUMBER_OF_SIGNERS_PER_TEST);
|
|
@@ -234,22 +268,22 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
|
|
|
234
268
|
|
|
235
269
|
await ap.addAttestations(attestations);
|
|
236
270
|
|
|
237
|
-
const attestationsForSlot1 = await ap.getAttestationsForSlotAndProposal(
|
|
271
|
+
const attestationsForSlot1 = await ap.getAttestationsForSlotAndProposal(SlotNumber(1), proposalId);
|
|
238
272
|
expect(attestationsForSlot1.length).toBe(signers.length);
|
|
239
273
|
|
|
240
274
|
const deleteAttestationsSpy = jest.spyOn(ap, 'deleteAttestationsForSlot');
|
|
241
275
|
|
|
242
|
-
await ap.deleteAttestationsOlderThan(
|
|
276
|
+
await ap.deleteAttestationsOlderThan(SlotNumber(73));
|
|
243
277
|
|
|
244
|
-
const attestationsForSlot1AfterDelete = await ap.getAttestationsForSlotAndProposal(
|
|
278
|
+
const attestationsForSlot1AfterDelete = await ap.getAttestationsForSlotAndProposal(SlotNumber(1), proposalId);
|
|
245
279
|
expect(attestationsForSlot1AfterDelete.length).toBe(0);
|
|
246
280
|
|
|
247
281
|
expect(deleteAttestationsSpy).toHaveBeenCalledTimes(5);
|
|
248
|
-
expect(deleteAttestationsSpy).toHaveBeenCalledWith(
|
|
249
|
-
expect(deleteAttestationsSpy).toHaveBeenCalledWith(
|
|
250
|
-
expect(deleteAttestationsSpy).toHaveBeenCalledWith(
|
|
251
|
-
expect(deleteAttestationsSpy).toHaveBeenCalledWith(
|
|
252
|
-
expect(deleteAttestationsSpy).toHaveBeenCalledWith(
|
|
282
|
+
expect(deleteAttestationsSpy).toHaveBeenCalledWith(SlotNumber(1));
|
|
283
|
+
expect(deleteAttestationsSpy).toHaveBeenCalledWith(SlotNumber(2));
|
|
284
|
+
expect(deleteAttestationsSpy).toHaveBeenCalledWith(SlotNumber(3));
|
|
285
|
+
expect(deleteAttestationsSpy).toHaveBeenCalledWith(SlotNumber(69));
|
|
286
|
+
expect(deleteAttestationsSpy).toHaveBeenCalledWith(SlotNumber(72));
|
|
253
287
|
});
|
|
254
288
|
|
|
255
289
|
describe('BlockProposal in attestation pool', () => {
|
|
@@ -265,12 +299,19 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
|
|
|
265
299
|
|
|
266
300
|
expect(retrievedProposal).toBeDefined();
|
|
267
301
|
expect(retrievedProposal!).toEqual(proposal);
|
|
302
|
+
|
|
303
|
+
// Check hasBlockProposal with both id and object
|
|
304
|
+
expect(await ap.hasBlockProposal(proposalId)).toBe(true);
|
|
305
|
+
expect(await ap.hasBlockProposal(proposal)).toBe(true);
|
|
268
306
|
});
|
|
269
307
|
|
|
270
308
|
it('should return undefined for non-existent block proposal', async () => {
|
|
271
309
|
const nonExistentId = Fr.random().toString();
|
|
272
310
|
const retrievedProposal = await ap.getBlockProposal(nonExistentId);
|
|
273
311
|
expect(retrievedProposal).toBeUndefined();
|
|
312
|
+
|
|
313
|
+
// Check hasBlockProposal returns false for non-existent proposal
|
|
314
|
+
expect(await ap.hasBlockProposal(nonExistentId)).toBe(false);
|
|
274
315
|
});
|
|
275
316
|
|
|
276
317
|
it('should update block proposal if added twice with same id', async () => {
|
|
@@ -306,7 +347,7 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
|
|
|
306
347
|
const retrievedProposal = await ap.getBlockProposal(proposalId);
|
|
307
348
|
expect(retrievedProposal).toBeDefined();
|
|
308
349
|
expect(retrievedProposal!.toBuffer()).toEqual(proposal2.toBuffer());
|
|
309
|
-
expect(retrievedProposal!.slotNumber
|
|
350
|
+
expect(retrievedProposal!.slotNumber).toBe(SlotNumber(200));
|
|
310
351
|
});
|
|
311
352
|
|
|
312
353
|
it('should delete block proposal when deleting attestations for slot and proposal', async () => {
|
|
@@ -323,13 +364,15 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
|
|
|
323
364
|
// Verify proposal exists
|
|
324
365
|
let retrievedProposal = await ap.getBlockProposal(proposalId);
|
|
325
366
|
expect(retrievedProposal).toBeDefined();
|
|
367
|
+
expect(await ap.hasBlockProposal(proposalId)).toBe(true);
|
|
326
368
|
|
|
327
369
|
// Delete attestations for slot and proposal
|
|
328
|
-
await ap.deleteAttestationsForSlotAndProposal(
|
|
370
|
+
await ap.deleteAttestationsForSlotAndProposal(SlotNumber(slotNumber), proposalId);
|
|
329
371
|
|
|
330
372
|
// Proposal should be deleted
|
|
331
373
|
retrievedProposal = await ap.getBlockProposal(proposalId);
|
|
332
374
|
expect(retrievedProposal).toBeUndefined();
|
|
375
|
+
expect(await ap.hasBlockProposal(proposalId)).toBe(false);
|
|
333
376
|
});
|
|
334
377
|
|
|
335
378
|
it('should delete block proposal when deleting attestations for slot', async () => {
|
|
@@ -344,13 +387,15 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
|
|
|
344
387
|
// Verify proposal exists
|
|
345
388
|
let retrievedProposal = await ap.getBlockProposal(proposalId);
|
|
346
389
|
expect(retrievedProposal).toBeDefined();
|
|
390
|
+
expect(await ap.hasBlockProposal(proposal)).toBe(true);
|
|
347
391
|
|
|
348
392
|
// Delete attestations for slot
|
|
349
|
-
await ap.deleteAttestationsForSlot(
|
|
393
|
+
await ap.deleteAttestationsForSlot(SlotNumber(slotNumber));
|
|
350
394
|
|
|
351
395
|
// Proposal should be deleted
|
|
352
396
|
retrievedProposal = await ap.getBlockProposal(proposalId);
|
|
353
397
|
expect(retrievedProposal).toBeUndefined();
|
|
398
|
+
expect(await ap.hasBlockProposal(proposal)).toBe(false);
|
|
354
399
|
});
|
|
355
400
|
|
|
356
401
|
it('should be able to fetch both block proposal and attestations', async () => {
|
|
@@ -368,12 +413,17 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
|
|
|
368
413
|
|
|
369
414
|
// Retrieve both proposal and attestations
|
|
370
415
|
const retrievedProposal = await ap.getBlockProposal(proposalId);
|
|
371
|
-
const retrievedAttestations = await ap.getAttestationsForSlotAndProposal(
|
|
416
|
+
const retrievedAttestations = await ap.getAttestationsForSlotAndProposal(SlotNumber(slotNumber), proposalId);
|
|
372
417
|
|
|
373
418
|
expect(retrievedProposal).toBeDefined();
|
|
374
419
|
expect(retrievedProposal).toEqual(proposal);
|
|
420
|
+
expect(await ap.hasBlockProposal(proposalId)).toBe(true);
|
|
375
421
|
|
|
376
422
|
compareAttestations(retrievedAttestations, attestations);
|
|
423
|
+
// Check hasAttestation for all attestations
|
|
424
|
+
for (const attestation of attestations) {
|
|
425
|
+
expect(await ap.hasAttestation(attestation)).toBe(true);
|
|
426
|
+
}
|
|
377
427
|
});
|
|
378
428
|
});
|
|
379
429
|
}
|
|
@@ -1,13 +1,18 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { SlotNumber } from '@aztec/foundation/branded-types';
|
|
2
|
+
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
2
3
|
import { toArray } from '@aztec/foundation/iterable';
|
|
3
4
|
import { createLogger } from '@aztec/foundation/log';
|
|
4
5
|
import type { AztecAsyncKVStore, AztecAsyncMap, AztecAsyncMultiMap } from '@aztec/kv-store';
|
|
5
6
|
import { BlockAttestation, BlockProposal } from '@aztec/stdlib/p2p';
|
|
6
7
|
import { type TelemetryClient, getTelemetryClient } from '@aztec/telemetry-client';
|
|
7
8
|
|
|
9
|
+
import { ProposalSlotCapExceededError } from '../../errors/attestation-pool.error.js';
|
|
8
10
|
import { PoolInstrumentation, PoolName, type PoolStatsCallback } from '../instrumentation.js';
|
|
9
11
|
import type { AttestationPool } from './attestation_pool.js';
|
|
10
12
|
|
|
13
|
+
export const MAX_PROPOSALS_PER_SLOT = 5;
|
|
14
|
+
export const ATTESTATION_CAP_BUFFER = 10;
|
|
15
|
+
|
|
11
16
|
export class KvAttestationPool implements AttestationPool {
|
|
12
17
|
private metrics: PoolInstrumentation<BlockAttestation>;
|
|
13
18
|
|
|
@@ -16,7 +21,7 @@ export class KvAttestationPool implements AttestationPool {
|
|
|
16
21
|
/* proposal.payload.archive */ string,
|
|
17
22
|
/* buffer representation of proposal */ Buffer
|
|
18
23
|
>;
|
|
19
|
-
private proposalsForSlot: AztecAsyncMultiMap<
|
|
24
|
+
private proposalsForSlot: AztecAsyncMultiMap<number, string>;
|
|
20
25
|
private attestationsForProposal: AztecAsyncMultiMap<string, string>;
|
|
21
26
|
|
|
22
27
|
constructor(
|
|
@@ -70,7 +75,7 @@ export class KvAttestationPool implements AttestationPool {
|
|
|
70
75
|
|
|
71
76
|
// Skip attestations with invalid signatures
|
|
72
77
|
if (!sender) {
|
|
73
|
-
this.log.warn(`Skipping attestation with invalid signature for slot ${slotNumber
|
|
78
|
+
this.log.warn(`Skipping attestation with invalid signature for slot ${slotNumber}`, {
|
|
74
79
|
signature: attestation.signature.toString(),
|
|
75
80
|
slotNumber,
|
|
76
81
|
proposalId,
|
|
@@ -82,13 +87,13 @@ export class KvAttestationPool implements AttestationPool {
|
|
|
82
87
|
|
|
83
88
|
await this.attestations.set(this.getAttestationKey(slotNumber, proposalId, address), attestation.toBuffer());
|
|
84
89
|
|
|
85
|
-
await this.proposalsForSlot.set(slotNumber
|
|
90
|
+
await this.proposalsForSlot.set(slotNumber, proposalId.toString());
|
|
86
91
|
await this.attestationsForProposal.set(
|
|
87
92
|
this.getProposalKey(slotNumber, proposalId),
|
|
88
93
|
this.getAttestationKey(slotNumber, proposalId, address),
|
|
89
94
|
);
|
|
90
95
|
|
|
91
|
-
this.log.verbose(`Added attestation for slot ${slotNumber
|
|
96
|
+
this.log.verbose(`Added attestation for slot ${slotNumber} from ${address}`, {
|
|
92
97
|
signature: attestation.signature.toString(),
|
|
93
98
|
slotNumber,
|
|
94
99
|
address,
|
|
@@ -98,9 +103,8 @@ export class KvAttestationPool implements AttestationPool {
|
|
|
98
103
|
});
|
|
99
104
|
}
|
|
100
105
|
|
|
101
|
-
public async getAttestationsForSlot(slot:
|
|
102
|
-
const
|
|
103
|
-
const proposalIds = await toArray(this.proposalsForSlot.getValuesAsync(slotFr.toString()));
|
|
106
|
+
public async getAttestationsForSlot(slot: SlotNumber): Promise<BlockAttestation[]> {
|
|
107
|
+
const proposalIds = await toArray(this.proposalsForSlot.getValuesAsync(slot));
|
|
104
108
|
const attestations: BlockAttestation[] = [];
|
|
105
109
|
|
|
106
110
|
for (const proposalId of proposalIds) {
|
|
@@ -110,7 +114,7 @@ export class KvAttestationPool implements AttestationPool {
|
|
|
110
114
|
return attestations;
|
|
111
115
|
}
|
|
112
116
|
|
|
113
|
-
public async getAttestationsForSlotAndProposal(slot:
|
|
117
|
+
public async getAttestationsForSlotAndProposal(slot: SlotNumber, proposalId: string): Promise<BlockAttestation[]> {
|
|
114
118
|
const attestationIds = await toArray(
|
|
115
119
|
this.attestationsForProposal.getValuesAsync(this.getProposalKey(slot, proposalId)),
|
|
116
120
|
);
|
|
@@ -132,21 +136,20 @@ export class KvAttestationPool implements AttestationPool {
|
|
|
132
136
|
return attestations;
|
|
133
137
|
}
|
|
134
138
|
|
|
135
|
-
public async deleteAttestationsOlderThan(oldestSlot:
|
|
136
|
-
const olderThan = await toArray(this.proposalsForSlot.keysAsync({ end:
|
|
139
|
+
public async deleteAttestationsOlderThan(oldestSlot: SlotNumber): Promise<void> {
|
|
140
|
+
const olderThan = await toArray(this.proposalsForSlot.keysAsync({ end: oldestSlot }));
|
|
137
141
|
for (const oldSlot of olderThan) {
|
|
138
|
-
await this.deleteAttestationsForSlot(
|
|
142
|
+
await this.deleteAttestationsForSlot(SlotNumber(oldSlot));
|
|
139
143
|
}
|
|
140
144
|
}
|
|
141
145
|
|
|
142
|
-
public async deleteAttestationsForSlot(slot:
|
|
143
|
-
const slotFr = new Fr(slot);
|
|
146
|
+
public async deleteAttestationsForSlot(slot: SlotNumber): Promise<void> {
|
|
144
147
|
let numberOfAttestations = 0;
|
|
145
148
|
await this.store.transactionAsync(async () => {
|
|
146
|
-
const proposalIds = await toArray(this.proposalsForSlot.getValuesAsync(
|
|
149
|
+
const proposalIds = await toArray(this.proposalsForSlot.getValuesAsync(slot));
|
|
147
150
|
for (const proposalId of proposalIds) {
|
|
148
151
|
const attestations = await toArray(
|
|
149
|
-
this.attestationsForProposal.getValuesAsync(this.getProposalKey(
|
|
152
|
+
this.attestationsForProposal.getValuesAsync(this.getProposalKey(slot, proposalId)),
|
|
150
153
|
);
|
|
151
154
|
|
|
152
155
|
numberOfAttestations += attestations.length;
|
|
@@ -155,17 +158,19 @@ export class KvAttestationPool implements AttestationPool {
|
|
|
155
158
|
}
|
|
156
159
|
|
|
157
160
|
await this.proposals.delete(proposalId);
|
|
158
|
-
await this.attestationsForProposal.delete(this.getProposalKey(
|
|
161
|
+
await this.attestationsForProposal.delete(this.getProposalKey(slot, proposalId));
|
|
159
162
|
}
|
|
160
163
|
|
|
164
|
+
// Delete from proposalsForSlot
|
|
165
|
+
await this.proposalsForSlot.delete(slot);
|
|
166
|
+
|
|
161
167
|
this.log.verbose(`Removed ${numberOfAttestations} attestations for slot ${slot}`);
|
|
162
168
|
});
|
|
163
169
|
}
|
|
164
170
|
|
|
165
|
-
public async deleteAttestationsForSlotAndProposal(slot:
|
|
171
|
+
public async deleteAttestationsForSlotAndProposal(slot: SlotNumber, proposalId: string): Promise<void> {
|
|
166
172
|
let numberOfAttestations = 0;
|
|
167
173
|
await this.store.transactionAsync(async () => {
|
|
168
|
-
const slotString = new Fr(slot).toString();
|
|
169
174
|
const attestations = await toArray(
|
|
170
175
|
this.attestationsForProposal.getValuesAsync(this.getProposalKey(slot, proposalId)),
|
|
171
176
|
);
|
|
@@ -176,8 +181,8 @@ export class KvAttestationPool implements AttestationPool {
|
|
|
176
181
|
}
|
|
177
182
|
|
|
178
183
|
await this.proposals.delete(proposalId);
|
|
179
|
-
await this.proposalsForSlot.deleteValue(
|
|
180
|
-
await this.attestationsForProposal.delete(this.getProposalKey(
|
|
184
|
+
await this.proposalsForSlot.deleteValue(slot, proposalId);
|
|
185
|
+
await this.attestationsForProposal.delete(this.getProposalKey(slot, proposalId));
|
|
181
186
|
|
|
182
187
|
this.log.verbose(`Removed ${numberOfAttestations} attestations for slot ${slot} and proposal ${proposalId}`);
|
|
183
188
|
});
|
|
@@ -192,7 +197,7 @@ export class KvAttestationPool implements AttestationPool {
|
|
|
192
197
|
|
|
193
198
|
// Skip attestations with invalid signatures
|
|
194
199
|
if (!sender) {
|
|
195
|
-
this.log.warn(`Skipping deletion of attestation with invalid signature for slot ${slotNumber
|
|
200
|
+
this.log.warn(`Skipping deletion of attestation with invalid signature for slot ${slotNumber}`);
|
|
196
201
|
continue;
|
|
197
202
|
}
|
|
198
203
|
|
|
@@ -213,6 +218,22 @@ export class KvAttestationPool implements AttestationPool {
|
|
|
213
218
|
});
|
|
214
219
|
}
|
|
215
220
|
|
|
221
|
+
public async hasAttestation(attestation: BlockAttestation): Promise<boolean> {
|
|
222
|
+
const slotNumber = attestation.payload.header.slotNumber;
|
|
223
|
+
const proposalId = attestation.archive;
|
|
224
|
+
const sender = attestation.getSender();
|
|
225
|
+
|
|
226
|
+
// Attestations with invalid signatures are never in the pool
|
|
227
|
+
if (!sender) {
|
|
228
|
+
return false;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
const address = sender.toString();
|
|
232
|
+
const key = this.getAttestationKey(slotNumber, proposalId, address);
|
|
233
|
+
|
|
234
|
+
return await this.attestations.hasAsync(key);
|
|
235
|
+
}
|
|
236
|
+
|
|
216
237
|
public async getBlockProposal(id: string): Promise<BlockProposal | undefined> {
|
|
217
238
|
const buffer = await this.proposals.getAsync(id);
|
|
218
239
|
try {
|
|
@@ -226,10 +247,52 @@ export class KvAttestationPool implements AttestationPool {
|
|
|
226
247
|
return Promise.resolve(undefined);
|
|
227
248
|
}
|
|
228
249
|
|
|
250
|
+
public async hasBlockProposal(idOrProposal: string | BlockProposal): Promise<boolean> {
|
|
251
|
+
const id = typeof idOrProposal === 'string' ? idOrProposal : idOrProposal.payload.archive.toString();
|
|
252
|
+
return await this.proposals.hasAsync(id);
|
|
253
|
+
}
|
|
254
|
+
|
|
229
255
|
public async addBlockProposal(blockProposal: BlockProposal): Promise<void> {
|
|
230
256
|
await this.store.transactionAsync(async () => {
|
|
231
|
-
|
|
232
|
-
|
|
257
|
+
const slotKey = blockProposal.slotNumber;
|
|
258
|
+
const proposalId = blockProposal.archive.toString();
|
|
259
|
+
|
|
260
|
+
if (!(await this.canAddProposal(blockProposal))) {
|
|
261
|
+
throw new ProposalSlotCapExceededError(
|
|
262
|
+
`Maximum proposals per slot reached: slot=${slotKey} cap=${MAX_PROPOSALS_PER_SLOT} proposal=${proposalId}`,
|
|
263
|
+
);
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
await this.proposalsForSlot.set(slotKey, proposalId);
|
|
267
|
+
// Always update the stored proposal buffer so re-adds overwrite with latest data
|
|
268
|
+
await this.proposals.set(proposalId, blockProposal.toBuffer());
|
|
233
269
|
});
|
|
234
270
|
}
|
|
271
|
+
|
|
272
|
+
public async hasReachedProposalCap(slot: SlotNumber): Promise<boolean> {
|
|
273
|
+
const uniqueProposalCount = await this.proposalsForSlot.getValueCountAsync(slot);
|
|
274
|
+
return uniqueProposalCount >= MAX_PROPOSALS_PER_SLOT;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
public async hasReachedAttestationCap(slot: SlotNumber, proposalId: string, committeeSize: number): Promise<boolean> {
|
|
278
|
+
const limit = committeeSize + ATTESTATION_CAP_BUFFER;
|
|
279
|
+
return (await this.attestationsForProposal.getValueCountAsync(this.getProposalKey(slot, proposalId))) >= limit;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
public async canAddProposal(block: BlockProposal): Promise<boolean> {
|
|
283
|
+
return (
|
|
284
|
+
(await this.proposals.hasAsync(block.archive.toString())) || !(await this.hasReachedProposalCap(block.slotNumber))
|
|
285
|
+
);
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
public async canAddAttestation(attestation: BlockAttestation, committeeSize: number): Promise<boolean> {
|
|
289
|
+
return (
|
|
290
|
+
(await this.hasAttestation(attestation)) ||
|
|
291
|
+
!(await this.hasReachedAttestationCap(
|
|
292
|
+
attestation.payload.header.slotNumber,
|
|
293
|
+
attestation.archive.toString(),
|
|
294
|
+
committeeSize,
|
|
295
|
+
))
|
|
296
|
+
);
|
|
297
|
+
}
|
|
235
298
|
}
|