@aztec/p2p 0.86.0 → 0.87.0
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.map +1 -1
- package/dest/client/factory.d.ts +4 -1
- package/dest/client/factory.d.ts.map +1 -1
- package/dest/client/factory.js +16 -14
- package/dest/client/index.d.ts +1 -0
- package/dest/client/index.d.ts.map +1 -1
- package/dest/client/index.js +1 -0
- package/dest/client/interface.d.ts +155 -0
- package/dest/client/interface.d.ts.map +1 -0
- package/dest/client/interface.js +9 -0
- package/dest/client/p2p_client.d.ts +26 -164
- package/dest/client/p2p_client.d.ts.map +1 -1
- package/dest/client/p2p_client.js +185 -114
- package/dest/config.d.ts +5 -6
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +6 -11
- package/dest/enr/generate-enr.d.ts +9 -1
- package/dest/enr/generate-enr.d.ts.map +1 -1
- package/dest/enr/generate-enr.js +24 -2
- 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 +2 -0
- package/dest/mem_pools/attestation_pool/attestation_pool.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.js +4 -4
- package/dest/mem_pools/attestation_pool/kv_attestation_pool.d.ts +1 -0
- package/dest/mem_pools/attestation_pool/kv_attestation_pool.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/kv_attestation_pool.js +8 -2
- package/dest/mem_pools/attestation_pool/memory_attestation_pool.d.ts +1 -0
- package/dest/mem_pools/attestation_pool/memory_attestation_pool.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/memory_attestation_pool.js +5 -2
- 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/tx_pool/aztec_kv_tx_pool.d.ts +4 -0
- 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 +50 -14
- package/dest/mem_pools/tx_pool/memory_tx_pool.d.ts +3 -0
- package/dest/mem_pools/tx_pool/memory_tx_pool.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool/memory_tx_pool.js +9 -0
- package/dest/mem_pools/tx_pool/tx_pool.d.ts +9 -0
- 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 +13 -5
- package/dest/msg_validators/attestation_validator/attestation_validator.js +1 -1
- package/dest/msg_validators/block_proposal_validator/block_proposal_validator.js +1 -1
- package/dest/msg_validators/tx_validator/block_header_validator.js +1 -1
- package/dest/msg_validators/tx_validator/data_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/data_validator.js +15 -14
- package/dest/msg_validators/tx_validator/double_spend_validator.d.ts +0 -2
- package/dest/msg_validators/tx_validator/double_spend_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/double_spend_validator.js +2 -2
- package/dest/msg_validators/tx_validator/factory.d.ts +14 -0
- package/dest/msg_validators/tx_validator/factory.d.ts.map +1 -0
- package/dest/msg_validators/tx_validator/factory.js +62 -0
- package/dest/msg_validators/tx_validator/gas_validator.js +3 -3
- package/dest/msg_validators/tx_validator/metadata_validator.d.ts +8 -4
- package/dest/msg_validators/tx_validator/metadata_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/metadata_validator.js +35 -17
- package/dest/msg_validators/tx_validator/phases_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/phases_validator.js +1 -1
- package/dest/msg_validators/tx_validator/tx_proof_validator.js +1 -1
- package/dest/services/discv5/discV5_service.d.ts +2 -2
- package/dest/services/discv5/discV5_service.d.ts.map +1 -1
- package/dest/services/discv5/discV5_service.js +9 -13
- package/dest/services/dummy_service.d.ts +3 -3
- package/dest/services/dummy_service.d.ts.map +1 -1
- package/dest/services/dummy_service.js +6 -1
- package/dest/services/encoding.d.ts +1 -3
- package/dest/services/encoding.d.ts.map +1 -1
- package/dest/services/libp2p/libp2p_service.d.ts +4 -2
- package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
- package/dest/services/libp2p/libp2p_service.js +94 -88
- package/dest/services/peer-manager/metrics.d.ts.map +1 -1
- package/dest/services/peer-manager/peer_manager.d.ts +1 -1
- package/dest/services/peer-manager/peer_manager.d.ts.map +1 -1
- package/dest/services/peer-manager/peer_manager.js +11 -2
- package/dest/services/reqresp/connection-sampler/batch_connection_sampler.d.ts.map +1 -1
- package/dest/services/reqresp/connection-sampler/connection_sampler.d.ts +2 -2
- package/dest/services/reqresp/connection-sampler/connection_sampler.d.ts.map +1 -1
- package/dest/services/reqresp/connection-sampler/connection_sampler.js +41 -21
- package/dest/services/reqresp/interface.d.ts +1 -3
- package/dest/services/reqresp/interface.d.ts.map +1 -1
- package/dest/services/reqresp/metrics.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/goodbye.d.ts +0 -2
- package/dest/services/reqresp/protocols/goodbye.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/goodbye.js +1 -1
- package/dest/services/reqresp/protocols/ping.d.ts +0 -2
- package/dest/services/reqresp/protocols/ping.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/status.d.ts +0 -2
- package/dest/services/reqresp/protocols/status.d.ts.map +1 -1
- package/dest/services/reqresp/rate-limiter/rate_limiter.d.ts.map +1 -1
- package/dest/services/reqresp/reqresp.d.ts +1 -3
- package/dest/services/reqresp/reqresp.d.ts.map +1 -1
- package/dest/services/reqresp/reqresp.js +13 -10
- package/dest/services/service.d.ts +4 -3
- package/dest/services/service.d.ts.map +1 -1
- package/dest/test-helpers/get-ports.d.ts.map +1 -1
- package/dest/test-helpers/make-test-p2p-clients.d.ts.map +1 -1
- package/dest/test-helpers/make-test-p2p-clients.js +2 -2
- package/dest/test-helpers/reqresp-nodes.d.ts.map +1 -1
- package/dest/test-helpers/reqresp-nodes.js +1 -1
- package/dest/testbench/p2p_client_testbench_worker.js +11 -6
- package/dest/testbench/testbench.js +1 -1
- package/dest/testbench/worker_client_manager.d.ts +0 -1
- package/dest/testbench/worker_client_manager.d.ts.map +1 -1
- package/dest/testbench/worker_client_manager.js +2 -2
- package/dest/types/index.d.ts +1 -0
- package/dest/types/index.d.ts.map +1 -1
- package/dest/types/index.js +1 -0
- package/dest/versioning.d.ts +2 -2
- package/dest/versioning.d.ts.map +1 -1
- package/dest/versioning.js +6 -1
- package/package.json +15 -15
- package/src/bootstrap/bootstrap.ts +1 -1
- package/src/client/factory.ts +38 -33
- package/src/client/index.ts +1 -0
- package/src/client/interface.ts +186 -0
- package/src/client/p2p_client.ts +226 -287
- package/src/config.ts +11 -18
- package/src/enr/generate-enr.ts +35 -3
- package/src/index.ts +1 -0
- package/src/mem_pools/attestation_pool/attestation_pool.ts +3 -0
- package/src/mem_pools/attestation_pool/attestation_pool_test_suite.ts +4 -4
- package/src/mem_pools/attestation_pool/kv_attestation_pool.ts +11 -4
- package/src/mem_pools/attestation_pool/memory_attestation_pool.ts +10 -3
- package/src/mem_pools/attestation_pool/mocks.ts +2 -2
- package/src/mem_pools/tx_pool/aztec_kv_tx_pool.ts +79 -34
- package/src/mem_pools/tx_pool/memory_tx_pool.ts +16 -1
- package/src/mem_pools/tx_pool/tx_pool.ts +12 -0
- package/src/mem_pools/tx_pool/tx_pool_test_suite.ts +9 -3
- package/src/msg_validators/attestation_validator/attestation_validator.ts +1 -1
- package/src/msg_validators/block_proposal_validator/block_proposal_validator.ts +1 -1
- package/src/msg_validators/tx_validator/block_header_validator.ts +1 -1
- package/src/msg_validators/tx_validator/data_validator.ts +24 -18
- package/src/msg_validators/tx_validator/double_spend_validator.ts +2 -2
- package/src/msg_validators/tx_validator/factory.ts +94 -0
- package/src/msg_validators/tx_validator/gas_validator.ts +3 -3
- package/src/msg_validators/tx_validator/metadata_validator.ts +50 -14
- package/src/msg_validators/tx_validator/phases_validator.ts +6 -2
- package/src/msg_validators/tx_validator/tx_proof_validator.ts +1 -1
- package/src/services/discv5/discV5_service.ts +14 -12
- package/src/services/dummy_service.ts +8 -2
- package/src/services/libp2p/libp2p_service.ts +102 -111
- package/src/services/peer-manager/metrics.ts +4 -1
- package/src/services/peer-manager/peer_manager.ts +18 -1
- package/src/services/reqresp/connection-sampler/batch_connection_sampler.ts +5 -1
- package/src/services/reqresp/connection-sampler/connection_sampler.ts +42 -19
- package/src/services/reqresp/metrics.ts +4 -1
- package/src/services/reqresp/protocols/goodbye.ts +1 -1
- package/src/services/reqresp/rate-limiter/rate_limiter.ts +4 -1
- package/src/services/reqresp/reqresp.ts +12 -12
- package/src/services/service.ts +7 -1
- package/src/test-helpers/make-test-p2p-clients.ts +2 -1
- package/src/test-helpers/reqresp-nodes.ts +1 -1
- package/src/testbench/p2p_client_testbench_worker.ts +10 -4
- package/src/testbench/testbench.ts +1 -1
- package/src/testbench/worker_client_manager.ts +2 -2
- package/src/types/index.ts +1 -0
- package/src/versioning.ts +8 -1
package/src/config.ts
CHANGED
|
@@ -99,12 +99,6 @@ export interface P2PConfig extends P2PReqRespConfig, ChainConfig {
|
|
|
99
99
|
*/
|
|
100
100
|
queryForIp: boolean;
|
|
101
101
|
|
|
102
|
-
/** How many blocks have to pass after a block is proven before its txs are deleted (zero to delete immediately once proven) */
|
|
103
|
-
keepProvenTxsInPoolFor: number;
|
|
104
|
-
|
|
105
|
-
/** How many slots to keep attestations for. */
|
|
106
|
-
keepAttestationsInPoolFor: number;
|
|
107
|
-
|
|
108
102
|
/**
|
|
109
103
|
* The interval of the gossipsub heartbeat to perform maintenance tasks.
|
|
110
104
|
*/
|
|
@@ -145,6 +139,11 @@ export interface P2PConfig extends P2PReqRespConfig, ChainConfig {
|
|
|
145
139
|
*/
|
|
146
140
|
gossipsubMcacheGossip: number;
|
|
147
141
|
|
|
142
|
+
/**
|
|
143
|
+
* How long to keep message IDs in the seen cache (ms).
|
|
144
|
+
*/
|
|
145
|
+
gossipsubSeenTTL: number;
|
|
146
|
+
|
|
148
147
|
/**
|
|
149
148
|
* The 'age' (in # of L2 blocks) of a processed tx after which we heavily penalize a peer for re-sending it.
|
|
150
149
|
*/
|
|
@@ -281,17 +280,6 @@ export const p2pConfigMappings: ConfigMappingsType<P2PConfig> = {
|
|
|
281
280
|
'If announceUdpAddress or announceTcpAddress are not provided, query for the IP address of the machine. Default is false.',
|
|
282
281
|
...booleanConfigHelper(),
|
|
283
282
|
},
|
|
284
|
-
keepProvenTxsInPoolFor: {
|
|
285
|
-
env: 'P2P_TX_POOL_KEEP_PROVEN_FOR',
|
|
286
|
-
description:
|
|
287
|
-
'How many blocks have to pass after a block is proven before its txs are deleted (zero to delete immediately once proven)',
|
|
288
|
-
...numberConfigHelper(0),
|
|
289
|
-
},
|
|
290
|
-
keepAttestationsInPoolFor: {
|
|
291
|
-
env: 'P2P_ATTESTATION_POOL_KEEP_FOR',
|
|
292
|
-
description: 'How many slots to keep attestations for.',
|
|
293
|
-
...numberConfigHelper(96),
|
|
294
|
-
},
|
|
295
283
|
gossipsubInterval: {
|
|
296
284
|
env: 'P2P_GOSSIPSUB_INTERVAL_MS',
|
|
297
285
|
description: 'The interval of the gossipsub heartbeat to perform maintenance tasks.',
|
|
@@ -329,9 +317,14 @@ export const p2pConfigMappings: ConfigMappingsType<P2PConfig> = {
|
|
|
329
317
|
},
|
|
330
318
|
gossipsubMcacheGossip: {
|
|
331
319
|
env: 'P2P_GOSSIPSUB_MCACHE_GOSSIP',
|
|
332
|
-
description: 'How many message cache windows to include when gossiping with other
|
|
320
|
+
description: 'How many message cache windows to include when gossiping with other peers.',
|
|
333
321
|
...numberConfigHelper(3),
|
|
334
322
|
},
|
|
323
|
+
gossipsubSeenTTL: {
|
|
324
|
+
env: 'P2P_GOSSIPSUB_SEEN_TTL',
|
|
325
|
+
description: 'How long to keep message IDs in the seen cache.',
|
|
326
|
+
...numberConfigHelper(20 * 60 * 1000),
|
|
327
|
+
},
|
|
335
328
|
gossipsubTxTopicWeight: {
|
|
336
329
|
env: 'P2P_GOSSIPSUB_TX_TOPIC_WEIGHT',
|
|
337
330
|
description: 'The weight of the tx topic for the gossipsub protocol.',
|
package/src/enr/generate-enr.ts
CHANGED
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
import type { LogFn } from '@aztec/foundation/log';
|
|
2
2
|
import { type ChainConfig, emptyChainConfig } from '@aztec/stdlib/config';
|
|
3
|
+
import type { ComponentsVersions } from '@aztec/stdlib/versioning';
|
|
3
4
|
|
|
4
5
|
import { ENR, SignableENR } from '@chainsafe/enr';
|
|
5
6
|
import type { PeerId } from '@libp2p/interface';
|
|
6
|
-
import { multiaddr } from '@multiformats/multiaddr';
|
|
7
|
+
import { type Multiaddr, multiaddr } from '@multiformats/multiaddr';
|
|
7
8
|
|
|
8
|
-
import { AZTEC_ENR_KEY } from '../types/index.js';
|
|
9
|
+
import { AZTEC_ENR_CLIENT_VERSION_KEY, AZTEC_ENR_KEY } from '../types/index.js';
|
|
9
10
|
import { convertToMultiaddr, createLibP2PPeerIdFromPrivateKey } from '../util.js';
|
|
10
|
-
import { setAztecEnrKey } from '../versioning.js';
|
|
11
|
+
import { setAztecClientVersionEnrKey, setAztecEnrKey } from '../versioning.js';
|
|
12
|
+
|
|
13
|
+
export { ENR };
|
|
11
14
|
|
|
12
15
|
export async function createBootnodeENRandPeerId(
|
|
13
16
|
privateKey: string,
|
|
@@ -29,12 +32,41 @@ export async function createBootnodeENRandPeerId(
|
|
|
29
32
|
return { enr, peerId };
|
|
30
33
|
}
|
|
31
34
|
|
|
35
|
+
export function createNodeENR(
|
|
36
|
+
peerId: PeerId,
|
|
37
|
+
multiAddrUdp: Multiaddr | undefined,
|
|
38
|
+
multiAddrTcp: Multiaddr | undefined,
|
|
39
|
+
chainConfig: ChainConfig,
|
|
40
|
+
packageVersion: string,
|
|
41
|
+
): { enr: SignableENR; versions: ComponentsVersions } {
|
|
42
|
+
// create ENR from PeerId
|
|
43
|
+
const enr = SignableENR.createFromPeerId(peerId);
|
|
44
|
+
// Add aztec identification to ENR
|
|
45
|
+
const versions = setAztecEnrKey(enr, chainConfig);
|
|
46
|
+
// Add aztec client version to ENR
|
|
47
|
+
setAztecClientVersionEnrKey(enr, packageVersion);
|
|
48
|
+
|
|
49
|
+
// set location multiaddr in ENR record
|
|
50
|
+
if (multiAddrUdp) {
|
|
51
|
+
enr.setLocationMultiaddr(multiAddrUdp);
|
|
52
|
+
}
|
|
53
|
+
if (multiAddrTcp) {
|
|
54
|
+
enr.setLocationMultiaddr(multiAddrTcp);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return { enr, versions };
|
|
58
|
+
}
|
|
59
|
+
|
|
32
60
|
export async function printENR(enr: string, log: LogFn) {
|
|
33
61
|
const decoded = ENR.decodeTxt(enr);
|
|
34
62
|
log(`PeerID: ${await decoded.peerId()}`);
|
|
35
63
|
log(`IP: ${decoded.ip}`);
|
|
36
64
|
log(`UDP: ${decoded.udp}`);
|
|
37
65
|
log(`TCP: ${decoded.tcp}`);
|
|
66
|
+
|
|
38
67
|
const aztec = decoded.kvs.get(AZTEC_ENR_KEY);
|
|
39
68
|
log(`Aztec version: ${aztec?.toString()}`);
|
|
69
|
+
|
|
70
|
+
const aztecClientVersion = decoded.kvs.get(AZTEC_ENR_CLIENT_VERSION_KEY);
|
|
71
|
+
log(`Aztec client version ${aztecClientVersion ? aztecClientVersion!.toString() : 'N/A'}`);
|
|
40
72
|
}
|
package/src/index.ts
CHANGED
|
@@ -118,13 +118,13 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
|
|
|
118
118
|
await ap.addAttestations(attestations);
|
|
119
119
|
|
|
120
120
|
for (const attestation of attestations) {
|
|
121
|
-
const slot = attestation.payload.header.
|
|
121
|
+
const slot = attestation.payload.header.slotNumber;
|
|
122
122
|
const archive = attestation.archive.toString();
|
|
123
123
|
|
|
124
124
|
const retreivedAttestations = await ap.getAttestationsForSlotAndProposal(slot.toBigInt(), archive);
|
|
125
125
|
expect(retreivedAttestations.length).toBe(1);
|
|
126
126
|
expect(retreivedAttestations[0].toBuffer()).toEqual(attestation.toBuffer());
|
|
127
|
-
expect(retreivedAttestations[0].payload.header.
|
|
127
|
+
expect(retreivedAttestations[0].payload.header.slotNumber).toEqual(slot);
|
|
128
128
|
}
|
|
129
129
|
});
|
|
130
130
|
|
|
@@ -136,13 +136,13 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
|
|
|
136
136
|
await ap.addAttestations(attestations);
|
|
137
137
|
|
|
138
138
|
for (const attestation of attestations) {
|
|
139
|
-
const slot = attestation.payload.header.
|
|
139
|
+
const slot = attestation.payload.header.slotNumber;
|
|
140
140
|
const proposalId = attestation.archive.toString();
|
|
141
141
|
|
|
142
142
|
const retreivedAttestations = await ap.getAttestationsForSlotAndProposal(slot.toBigInt(), proposalId);
|
|
143
143
|
expect(retreivedAttestations.length).toBe(1);
|
|
144
144
|
expect(retreivedAttestations[0].toBuffer()).toEqual(attestation.toBuffer());
|
|
145
|
-
expect(retreivedAttestations[0].payload.header.
|
|
145
|
+
expect(retreivedAttestations[0].payload.header.slotNumber).toEqual(slot);
|
|
146
146
|
}
|
|
147
147
|
});
|
|
148
148
|
|
|
@@ -27,14 +27,21 @@ export class KvAttestationPool implements AttestationPool {
|
|
|
27
27
|
this.metrics = new PoolInstrumentation(telemetry, PoolName.ATTESTATION_POOL);
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
+
public async isEmpty(): Promise<boolean> {
|
|
31
|
+
for await (const _ of this.attestations.entriesAsync()) {
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
return true;
|
|
35
|
+
}
|
|
36
|
+
|
|
30
37
|
private getProposalKey(slot: number | bigint | Fr | string, proposalId: Fr | string | Buffer): string {
|
|
31
38
|
const slotStr = typeof slot === 'string' ? slot : new Fr(slot).toString();
|
|
32
39
|
const proposalIdStr =
|
|
33
40
|
typeof proposalId === 'string'
|
|
34
41
|
? proposalId
|
|
35
42
|
: Buffer.isBuffer(proposalId)
|
|
36
|
-
|
|
37
|
-
|
|
43
|
+
? Fr.fromBuffer(proposalId).toString()
|
|
44
|
+
: proposalId.toString();
|
|
38
45
|
|
|
39
46
|
return `${slotStr}-${proposalIdStr}`;
|
|
40
47
|
}
|
|
@@ -46,7 +53,7 @@ export class KvAttestationPool implements AttestationPool {
|
|
|
46
53
|
public async addAttestations(attestations: BlockAttestation[]): Promise<void> {
|
|
47
54
|
await this.store.transactionAsync(async () => {
|
|
48
55
|
for (const attestation of attestations) {
|
|
49
|
-
const slotNumber = attestation.payload.header.
|
|
56
|
+
const slotNumber = attestation.payload.header.slotNumber;
|
|
50
57
|
const proposalId = attestation.archive;
|
|
51
58
|
const address = attestation.getSender().toString();
|
|
52
59
|
|
|
@@ -158,7 +165,7 @@ export class KvAttestationPool implements AttestationPool {
|
|
|
158
165
|
public async deleteAttestations(attestations: BlockAttestation[]): Promise<void> {
|
|
159
166
|
await this.store.transactionAsync(async () => {
|
|
160
167
|
for (const attestation of attestations) {
|
|
161
|
-
const slotNumber = attestation.payload.header.
|
|
168
|
+
const slotNumber = attestation.payload.header.slotNumber;
|
|
162
169
|
const proposalId = attestation.archive;
|
|
163
170
|
const address = attestation.getSender().toString();
|
|
164
171
|
|
|
@@ -10,11 +10,18 @@ export class InMemoryAttestationPool implements AttestationPool {
|
|
|
10
10
|
|
|
11
11
|
private attestations: Map</*slot=*/ bigint, Map</*proposalId*/ string, Map</*address=*/ string, BlockAttestation>>>;
|
|
12
12
|
|
|
13
|
-
constructor(
|
|
13
|
+
constructor(
|
|
14
|
+
telemetry: TelemetryClient = getTelemetryClient(),
|
|
15
|
+
private log = createLogger('p2p:attestation_pool'),
|
|
16
|
+
) {
|
|
14
17
|
this.attestations = new Map();
|
|
15
18
|
this.metrics = new PoolInstrumentation(telemetry, PoolName.ATTESTATION_POOL);
|
|
16
19
|
}
|
|
17
20
|
|
|
21
|
+
public isEmpty(): Promise<boolean> {
|
|
22
|
+
return Promise.resolve(this.attestations.size === 0);
|
|
23
|
+
}
|
|
24
|
+
|
|
18
25
|
public getAttestationsForSlot(slot: bigint): Promise<BlockAttestation[]> {
|
|
19
26
|
return Promise.resolve(
|
|
20
27
|
Array.from(this.attestations.get(slot)?.values() ?? []).flatMap(proposalAttestationMap =>
|
|
@@ -37,7 +44,7 @@ export class InMemoryAttestationPool implements AttestationPool {
|
|
|
37
44
|
public addAttestations(attestations: BlockAttestation[]): Promise<void> {
|
|
38
45
|
for (const attestation of attestations) {
|
|
39
46
|
// Perf: order and group by slot before insertion
|
|
40
|
-
const slotNumber = attestation.payload.header.
|
|
47
|
+
const slotNumber = attestation.payload.header.slotNumber;
|
|
41
48
|
|
|
42
49
|
const proposalId = attestation.archive.toString();
|
|
43
50
|
const address = attestation.getSender();
|
|
@@ -120,7 +127,7 @@ export class InMemoryAttestationPool implements AttestationPool {
|
|
|
120
127
|
|
|
121
128
|
public deleteAttestations(attestations: BlockAttestation[]): Promise<void> {
|
|
122
129
|
for (const attestation of attestations) {
|
|
123
|
-
const slotNumber = attestation.payload.header.
|
|
130
|
+
const slotNumber = attestation.payload.header.slotNumber;
|
|
124
131
|
const slotAttestationMap = this.attestations.get(slotNumber.toBigInt());
|
|
125
132
|
if (slotAttestationMap) {
|
|
126
133
|
const proposalId = attestation.archive.toString();
|
|
@@ -35,10 +35,10 @@ export const mockAttestation = (
|
|
|
35
35
|
): BlockAttestation => {
|
|
36
36
|
// Use arbitrary numbers for all other than slot
|
|
37
37
|
const header = makeHeader(1, 2, slot);
|
|
38
|
-
const payload = new ConsensusPayload(header, archive, txs);
|
|
38
|
+
const payload = new ConsensusPayload(header.toPropose(), archive, header.state, txs);
|
|
39
39
|
|
|
40
40
|
const hash = getHashedSignaturePayloadEthSignedMessage(payload, SignatureDomainSeparator.blockAttestation);
|
|
41
41
|
const signature = signer.sign(hash);
|
|
42
42
|
|
|
43
|
-
return new BlockAttestation(payload, signature);
|
|
43
|
+
return new BlockAttestation(header.globalVariables.blockNumber, payload, signature);
|
|
44
44
|
};
|
|
@@ -44,9 +44,15 @@ export class AztecKVTxPool implements TxPool {
|
|
|
44
44
|
/** The cumulative tx size in bytes that the pending txs in the pool take up. */
|
|
45
45
|
#pendingTxSize: AztecAsyncSingleton<number>;
|
|
46
46
|
|
|
47
|
+
/** Count of total pending txs. */
|
|
48
|
+
#pendingTxCount: AztecAsyncSingleton<number>;
|
|
49
|
+
|
|
47
50
|
/** In-memory mapping of pending tx hashes to the hydrated pending tx in the pool. */
|
|
48
51
|
#pendingTxs: Map<string, Tx>;
|
|
49
52
|
|
|
53
|
+
/** In-memory set of txs that should not be evicted from the pool. */
|
|
54
|
+
#nonEvictableTxs: Set<string>;
|
|
55
|
+
|
|
50
56
|
/** KV store for archived txs. */
|
|
51
57
|
#archive: AztecAsyncKVStore;
|
|
52
58
|
|
|
@@ -91,8 +97,10 @@ export class AztecKVTxPool implements TxPool {
|
|
|
91
97
|
this.#pendingTxHashToSize = store.openMap('pendingTxHashToSize');
|
|
92
98
|
this.#pendingTxHashToHeaderHash = store.openMap('pendingTxHashToHeaderHash');
|
|
93
99
|
this.#pendingTxSize = store.openSingleton('pendingTxSize');
|
|
100
|
+
this.#pendingTxCount = store.openSingleton('pendingTxCount');
|
|
94
101
|
this.#maxTxPoolSize = config.maxTxPoolSize;
|
|
95
102
|
this.#pendingTxs = new Map<string, Tx>();
|
|
103
|
+
this.#nonEvictableTxs = new Set<string>();
|
|
96
104
|
|
|
97
105
|
this.#archivedTxs = archive.openMap('archivedTxs');
|
|
98
106
|
this.#archivedTxIndices = archive.openMap('archivedTxIndices');
|
|
@@ -105,7 +113,14 @@ export class AztecKVTxPool implements TxPool {
|
|
|
105
113
|
this.#metrics = new PoolInstrumentation(telemetry, PoolName.TX_POOL, () => store.estimateSize());
|
|
106
114
|
}
|
|
107
115
|
|
|
108
|
-
public
|
|
116
|
+
public async isEmpty(): Promise<boolean> {
|
|
117
|
+
for await (const _ of this.#txs.entriesAsync()) {
|
|
118
|
+
return false;
|
|
119
|
+
}
|
|
120
|
+
return true;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
public async markAsMined(txHashes: TxHash[], blockNumber: number): Promise<void> {
|
|
109
124
|
if (txHashes.length === 0) {
|
|
110
125
|
return Promise.resolve();
|
|
111
126
|
}
|
|
@@ -113,7 +128,8 @@ export class AztecKVTxPool implements TxPool {
|
|
|
113
128
|
let deletedPending = 0;
|
|
114
129
|
const minedNullifiers = new Set<string>();
|
|
115
130
|
const minedFeePayers = new Set<string>();
|
|
116
|
-
|
|
131
|
+
|
|
132
|
+
await this.#store.transactionAsync(async () => {
|
|
117
133
|
let pendingTxSize = (await this.#pendingTxSize.getAsync()) ?? 0;
|
|
118
134
|
for (const hash of txHashes) {
|
|
119
135
|
const key = hash.toString();
|
|
@@ -132,6 +148,7 @@ export class AztecKVTxPool implements TxPool {
|
|
|
132
148
|
}
|
|
133
149
|
this.#metrics.recordAddedObjects(txHashes.length, 'mined');
|
|
134
150
|
await this.#pendingTxSize.set(pendingTxSize);
|
|
151
|
+
await this.increasePendingTxCount(-deletedPending);
|
|
135
152
|
|
|
136
153
|
const numTxsEvicted = await this.evictInvalidTxsAfterMining(
|
|
137
154
|
txHashes,
|
|
@@ -141,43 +158,44 @@ export class AztecKVTxPool implements TxPool {
|
|
|
141
158
|
);
|
|
142
159
|
this.#metrics.recordRemovedObjects(deletedPending + numTxsEvicted, 'pending');
|
|
143
160
|
});
|
|
161
|
+
// We update this after the transaction above. This ensures that the non-evictable transactions are not evicted
|
|
162
|
+
// until any that have been mined are marked as such.
|
|
163
|
+
// The non-evictable set is not considered when evicting transactions that are invalid after a block is mined.
|
|
164
|
+
this.#nonEvictableTxs.clear();
|
|
144
165
|
}
|
|
145
166
|
|
|
146
|
-
public markMinedAsPending(txHashes: TxHash[]): Promise<void> {
|
|
167
|
+
public async markMinedAsPending(txHashes: TxHash[]): Promise<void> {
|
|
147
168
|
if (txHashes.length === 0) {
|
|
148
169
|
return Promise.resolve();
|
|
149
170
|
}
|
|
150
171
|
|
|
151
172
|
let markedAsPending = 0;
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
await this.#minedTxHashToBlock.delete(key);
|
|
173
|
+
await this.#store.transactionAsync(async () => {
|
|
174
|
+
let pendingTxSize = (await this.#pendingTxSize.getAsync()) ?? 0;
|
|
175
|
+
for (const hash of txHashes) {
|
|
176
|
+
const key = hash.toString();
|
|
177
|
+
await this.#minedTxHashToBlock.delete(key);
|
|
158
178
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
}
|
|
179
|
+
// Rehydrate the tx in the in-memory pending txs mapping
|
|
180
|
+
const tx = await this.getPendingTxByHash(hash);
|
|
181
|
+
if (tx) {
|
|
182
|
+
await this.addPendingTxIndices(tx, key);
|
|
183
|
+
pendingTxSize += tx.getSize();
|
|
184
|
+
markedAsPending++;
|
|
166
185
|
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
await this.#pendingTxSize.set(pendingTxSize);
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
const numInvalidTxsEvicted = await this.evictInvalidTxsAfterReorg(txHashes);
|
|
192
|
+
const { numLowPriorityTxsEvicted, numNewTxsEvicted } = await this.evictLowPriorityTxs(txHashes);
|
|
167
193
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
this.#metrics.recordAddedObjects(markedAsPending - numNewTxsEvicted, 'pending');
|
|
175
|
-
this.#metrics.recordRemovedObjects(
|
|
176
|
-
numInvalidTxsEvicted + numLowPriorityTxsEvicted - numNewTxsEvicted,
|
|
177
|
-
'pending',
|
|
178
|
-
);
|
|
179
|
-
this.#metrics.recordRemovedObjects(markedAsPending, 'mined');
|
|
180
|
-
});
|
|
194
|
+
await this.increasePendingTxCount(markedAsPending);
|
|
195
|
+
|
|
196
|
+
this.#metrics.recordAddedObjects(markedAsPending - numNewTxsEvicted, 'pending');
|
|
197
|
+
this.#metrics.recordRemovedObjects(numInvalidTxsEvicted + numLowPriorityTxsEvicted - numNewTxsEvicted, 'pending');
|
|
198
|
+
this.#metrics.recordRemovedObjects(markedAsPending, 'mined');
|
|
181
199
|
}
|
|
182
200
|
|
|
183
201
|
public async getPendingTxHashes(): Promise<TxHash[]> {
|
|
@@ -190,6 +208,10 @@ export class AztecKVTxPool implements TxPool {
|
|
|
190
208
|
return vals.map(([txHash, blockNumber]) => [TxHash.fromString(txHash), blockNumber]);
|
|
191
209
|
}
|
|
192
210
|
|
|
211
|
+
public async getPendingTxCount(): Promise<number> {
|
|
212
|
+
return (await this.#pendingTxCount.getAsync()) ?? 0;
|
|
213
|
+
}
|
|
214
|
+
|
|
193
215
|
public async getTxStatus(txHash: TxHash): Promise<'pending' | 'mined' | undefined> {
|
|
194
216
|
const key = txHash.toString();
|
|
195
217
|
const [isMined, isKnown] = await Promise.all([this.#minedTxHashToBlock.hasAsync(key), this.#txs.hasAsync(key)]);
|
|
@@ -259,21 +281,26 @@ export class AztecKVTxPool implements TxPool {
|
|
|
259
281
|
txs.map(async tx => ({ txHash: await tx.getTxHash(), txStats: await tx.getStats() })),
|
|
260
282
|
);
|
|
261
283
|
await this.#store.transactionAsync(async () => {
|
|
262
|
-
let
|
|
284
|
+
let addedCount = 0;
|
|
263
285
|
let pendingTxSize = (await this.#pendingTxSize.getAsync()) ?? 0;
|
|
264
286
|
await Promise.all(
|
|
265
287
|
txs.map(async (tx, i) => {
|
|
266
288
|
const { txHash, txStats } = hashesAndStats[i];
|
|
289
|
+
const key = txHash.toString();
|
|
290
|
+
if (await this.#txs.hasAsync(key)) {
|
|
291
|
+
this.#log.debug(`Tx ${txHash.toString()} already exists in the pool`);
|
|
292
|
+
return;
|
|
293
|
+
}
|
|
294
|
+
|
|
267
295
|
this.#log.verbose(`Adding tx ${txHash.toString()} to pool`, {
|
|
268
296
|
eventName: 'tx-added-to-pool',
|
|
269
297
|
...txStats,
|
|
270
298
|
} satisfies TxAddedToPoolStats);
|
|
271
299
|
|
|
272
|
-
const key = txHash.toString();
|
|
273
300
|
await this.#txs.set(key, tx.toBuffer());
|
|
274
301
|
|
|
275
302
|
if (!(await this.#minedTxHashToBlock.hasAsync(key))) {
|
|
276
|
-
|
|
303
|
+
addedCount++;
|
|
277
304
|
pendingTxSize += tx.getSize();
|
|
278
305
|
await this.addPendingTxIndices(tx, key);
|
|
279
306
|
this.#metrics.recordSize(tx);
|
|
@@ -281,13 +308,13 @@ export class AztecKVTxPool implements TxPool {
|
|
|
281
308
|
}),
|
|
282
309
|
);
|
|
283
310
|
|
|
311
|
+
await this.increasePendingTxCount(addedCount);
|
|
284
312
|
await this.#pendingTxSize.set(pendingTxSize);
|
|
285
|
-
|
|
286
313
|
const { numLowPriorityTxsEvicted, numNewTxsEvicted } = await this.evictLowPriorityTxs(
|
|
287
314
|
hashesAndStats.map(({ txHash }) => txHash),
|
|
288
315
|
);
|
|
289
316
|
|
|
290
|
-
this.#metrics.recordAddedObjects(
|
|
317
|
+
this.#metrics.recordAddedObjects(addedCount - numNewTxsEvicted, 'pending');
|
|
291
318
|
this.#metrics.recordRemovedObjects(numLowPriorityTxsEvicted - numNewTxsEvicted, 'pending');
|
|
292
319
|
});
|
|
293
320
|
}
|
|
@@ -328,6 +355,8 @@ export class AztecKVTxPool implements TxPool {
|
|
|
328
355
|
}
|
|
329
356
|
|
|
330
357
|
await this.#pendingTxSize.set(pendingTxSize);
|
|
358
|
+
await this.increasePendingTxCount(-pendingDeleted);
|
|
359
|
+
|
|
331
360
|
this.#metrics.recordRemovedObjects(pendingDeleted, 'pending');
|
|
332
361
|
this.#metrics.recordRemovedObjects(minedDeleted, 'mined');
|
|
333
362
|
});
|
|
@@ -362,6 +391,11 @@ export class AztecKVTxPool implements TxPool {
|
|
|
362
391
|
return Promise.resolve();
|
|
363
392
|
}
|
|
364
393
|
|
|
394
|
+
public markTxsAsNonEvictable(txHashes: TxHash[]): Promise<void> {
|
|
395
|
+
txHashes.forEach(txHash => this.#nonEvictableTxs.add(txHash.toString()));
|
|
396
|
+
return Promise.resolve();
|
|
397
|
+
}
|
|
398
|
+
|
|
365
399
|
/**
|
|
366
400
|
* Creates a GasTxValidator instance.
|
|
367
401
|
* @param db - DB for the validator to use
|
|
@@ -459,6 +493,9 @@ export class AztecKVTxPool implements TxPool {
|
|
|
459
493
|
let pendingTxsSize = (await this.#pendingTxSize.getAsync()) ?? 0;
|
|
460
494
|
if (pendingTxsSize > this.#maxTxPoolSize) {
|
|
461
495
|
for await (const txHash of this.#pendingTxPriorityToHash.valuesAsync()) {
|
|
496
|
+
if (this.#nonEvictableTxs.has(txHash.toString())) {
|
|
497
|
+
continue;
|
|
498
|
+
}
|
|
462
499
|
this.#log.verbose(`Evicting tx ${txHash} from pool due to low priority to satisfy max tx size limit`);
|
|
463
500
|
txsToEvict.push(TxHash.fromString(txHash));
|
|
464
501
|
|
|
@@ -606,4 +643,12 @@ export class AztecKVTxPool implements TxPool {
|
|
|
606
643
|
await this.#pendingTxHashToHeaderHash.delete(txHash);
|
|
607
644
|
this.#pendingTxs.delete(txHash);
|
|
608
645
|
}
|
|
646
|
+
|
|
647
|
+
private async increasePendingTxCount(count: number): Promise<void> {
|
|
648
|
+
const pendingTxCount = (await this.#pendingTxCount.getAsync()) ?? 0;
|
|
649
|
+
this.#log.debug(
|
|
650
|
+
`Increasing pending tx count: current ${pendingTxCount} + count ${count} = ${pendingTxCount + count}`,
|
|
651
|
+
);
|
|
652
|
+
await this.#pendingTxCount.set(pendingTxCount + count);
|
|
653
|
+
}
|
|
609
654
|
}
|
|
@@ -24,13 +24,20 @@ export class InMemoryTxPool implements TxPool {
|
|
|
24
24
|
* Class constructor for in-memory TxPool. Initiates our transaction pool as a JS Map.
|
|
25
25
|
* @param log - A logger.
|
|
26
26
|
*/
|
|
27
|
-
constructor(
|
|
27
|
+
constructor(
|
|
28
|
+
telemetry: TelemetryClient = getTelemetryClient(),
|
|
29
|
+
private log = createLogger('p2p:tx_pool'),
|
|
30
|
+
) {
|
|
28
31
|
this.txs = new Map<bigint, Tx>();
|
|
29
32
|
this.minedTxs = new Map();
|
|
30
33
|
this.pendingTxs = new Set();
|
|
31
34
|
this.metrics = new PoolInstrumentation(telemetry, PoolName.TX_POOL);
|
|
32
35
|
}
|
|
33
36
|
|
|
37
|
+
public isEmpty(): Promise<boolean> {
|
|
38
|
+
return Promise.resolve(this.txs.size === 0);
|
|
39
|
+
}
|
|
40
|
+
|
|
34
41
|
public markAsMined(txHashes: TxHash[], blockNumber: number): Promise<void> {
|
|
35
42
|
const keys = txHashes.map(x => x.toBigInt());
|
|
36
43
|
for (const key of keys) {
|
|
@@ -82,6 +89,10 @@ export class InMemoryTxPool implements TxPool {
|
|
|
82
89
|
);
|
|
83
90
|
}
|
|
84
91
|
|
|
92
|
+
public getPendingTxCount(): Promise<number> {
|
|
93
|
+
return Promise.resolve(this.pendingTxs.size);
|
|
94
|
+
}
|
|
95
|
+
|
|
85
96
|
public getTxStatus(txHash: TxHash): Promise<'pending' | 'mined' | undefined> {
|
|
86
97
|
const key = txHash.toBigInt();
|
|
87
98
|
if (this.pendingTxs.has(key)) {
|
|
@@ -182,4 +193,8 @@ export class InMemoryTxPool implements TxPool {
|
|
|
182
193
|
setMaxTxPoolSize(_maxSizeBytes: number | undefined): Promise<void> {
|
|
183
194
|
return Promise.resolve();
|
|
184
195
|
}
|
|
196
|
+
|
|
197
|
+
markTxsAsNonEvictable(_: TxHash[]): Promise<void> {
|
|
198
|
+
return Promise.resolve();
|
|
199
|
+
}
|
|
185
200
|
}
|
|
@@ -75,6 +75,9 @@ export interface TxPool {
|
|
|
75
75
|
*/
|
|
76
76
|
getPendingTxHashes(): Promise<TxHash[]>;
|
|
77
77
|
|
|
78
|
+
/** Returns the number of pending txs in the pool. */
|
|
79
|
+
getPendingTxCount(): Promise<number>;
|
|
80
|
+
|
|
78
81
|
/**
|
|
79
82
|
* Gets the hashes of mined transactions currently in the tx pool.
|
|
80
83
|
* @returns An array of mined transaction hashes found in the tx pool.
|
|
@@ -93,4 +96,13 @@ export interface TxPool {
|
|
|
93
96
|
* @param maxSizeBytes - The maximum size in bytes of the mempool. Set to undefined to disable it
|
|
94
97
|
*/
|
|
95
98
|
setMaxTxPoolSize(maxSizeBytes: number | undefined): Promise<void>;
|
|
99
|
+
|
|
100
|
+
/** Returns whether the pool is empty. */
|
|
101
|
+
isEmpty(): Promise<boolean>;
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Marks transactions as non-evictible in the pool.
|
|
105
|
+
* @param txHashes - Hashes of the transactions to mark as non-evictible.
|
|
106
|
+
*/
|
|
107
|
+
markTxsAsNonEvictable(txHashes: TxHash[]): Promise<void>;
|
|
96
108
|
}
|
|
@@ -24,6 +24,7 @@ export function describeTxPool(getTxPool: () => TxPool) {
|
|
|
24
24
|
expect(await poolTx!.getTxHash()).toEqual(await tx1.getTxHash());
|
|
25
25
|
await expect(pool.getTxStatus(await tx1.getTxHash())).resolves.toEqual('pending');
|
|
26
26
|
await expect(pool.getPendingTxHashes()).resolves.toEqual([await tx1.getTxHash()]);
|
|
27
|
+
await expect(pool.getPendingTxCount()).resolves.toEqual(1);
|
|
27
28
|
});
|
|
28
29
|
|
|
29
30
|
it('Removes txs from the pool', async () => {
|
|
@@ -34,6 +35,7 @@ export function describeTxPool(getTxPool: () => TxPool) {
|
|
|
34
35
|
|
|
35
36
|
await expect(pool.getTxByHash(await tx1.getTxHash())).resolves.toBeFalsy();
|
|
36
37
|
await expect(pool.getTxStatus(await tx1.getTxHash())).resolves.toBeUndefined();
|
|
38
|
+
await expect(pool.getPendingTxCount()).resolves.toEqual(0);
|
|
37
39
|
});
|
|
38
40
|
|
|
39
41
|
it('Marks txs as mined', async () => {
|
|
@@ -47,6 +49,7 @@ export function describeTxPool(getTxPool: () => TxPool) {
|
|
|
47
49
|
await expect(pool.getTxStatus(await tx1.getTxHash())).resolves.toEqual('mined');
|
|
48
50
|
await expect(pool.getMinedTxHashes()).resolves.toEqual([[await tx1.getTxHash(), 1]]);
|
|
49
51
|
await expect(pool.getPendingTxHashes()).resolves.toEqual([await tx2.getTxHash()]);
|
|
52
|
+
await expect(pool.getPendingTxCount()).resolves.toEqual(1);
|
|
50
53
|
});
|
|
51
54
|
|
|
52
55
|
it('Marks txs as pending after being mined', async () => {
|
|
@@ -61,6 +64,7 @@ export function describeTxPool(getTxPool: () => TxPool) {
|
|
|
61
64
|
const pending = await pool.getPendingTxHashes();
|
|
62
65
|
expect(pending).toHaveLength(2);
|
|
63
66
|
expect(pending).toEqual(expect.arrayContaining([await tx1.getTxHash(), await tx2.getTxHash()]));
|
|
67
|
+
await expect(pool.getPendingTxCount()).resolves.toEqual(2);
|
|
64
68
|
});
|
|
65
69
|
|
|
66
70
|
it('Only marks txs as pending if they are known', async () => {
|
|
@@ -82,6 +86,7 @@ export function describeTxPool(getTxPool: () => TxPool) {
|
|
|
82
86
|
await pool.markMinedAsPending([await tx1.getTxHash(), someTxHashThatThisPeerDidNotSee]);
|
|
83
87
|
await expect(pool.getMinedTxHashes()).resolves.toEqual([]);
|
|
84
88
|
await expect(pool.getPendingTxHashes()).resolves.toEqual([await tx1.getTxHash()]); // tx2 is not in the pool
|
|
89
|
+
await expect(pool.getPendingTxCount()).resolves.toEqual(1);
|
|
85
90
|
});
|
|
86
91
|
|
|
87
92
|
it('Returns all transactions in the pool', async () => {
|
|
@@ -94,6 +99,7 @@ export function describeTxPool(getTxPool: () => TxPool) {
|
|
|
94
99
|
const poolTxs = await pool.getAllTxs();
|
|
95
100
|
expect(poolTxs).toHaveLength(3);
|
|
96
101
|
expect(poolTxs).toEqual(expect.arrayContaining([tx1, tx2, tx3]));
|
|
102
|
+
await expect(pool.getPendingTxCount()).resolves.toEqual(3);
|
|
97
103
|
});
|
|
98
104
|
|
|
99
105
|
it('Returns all txHashes in the pool', async () => {
|
|
@@ -104,10 +110,10 @@ export function describeTxPool(getTxPool: () => TxPool) {
|
|
|
104
110
|
await pool.addTxs([tx1, tx2, tx3]);
|
|
105
111
|
|
|
106
112
|
const poolTxHashes = await pool.getAllTxHashes();
|
|
113
|
+
const expectedHashes = await Promise.all([tx1, tx2, tx3].map(tx => tx.getTxHash()));
|
|
107
114
|
expect(poolTxHashes).toHaveLength(3);
|
|
108
|
-
expect(poolTxHashes).toEqual(
|
|
109
|
-
|
|
110
|
-
);
|
|
115
|
+
expect(poolTxHashes).toEqual(expect.arrayContaining(expectedHashes));
|
|
116
|
+
await expect(pool.getPendingTxCount()).resolves.toEqual(3);
|
|
111
117
|
});
|
|
112
118
|
|
|
113
119
|
it('Returns txs by their hash', async () => {
|
|
@@ -11,7 +11,7 @@ export class AttestationValidator implements P2PValidator<BlockAttestation> {
|
|
|
11
11
|
async validate(message: BlockAttestation): Promise<PeerErrorSeverity | undefined> {
|
|
12
12
|
const { currentSlot, nextSlot } = await this.epochCache.getProposerInCurrentOrNextSlot();
|
|
13
13
|
|
|
14
|
-
const slotNumberBigInt = message.payload.header.
|
|
14
|
+
const slotNumberBigInt = message.payload.header.slotNumber.toBigInt();
|
|
15
15
|
if (slotNumberBigInt !== currentSlot && slotNumberBigInt !== nextSlot) {
|
|
16
16
|
return PeerErrorSeverity.HighToleranceError;
|
|
17
17
|
}
|
|
@@ -16,7 +16,7 @@ export class BlockProposalValidator implements P2PValidator<BlockProposal> {
|
|
|
16
16
|
await this.epochCache.getProposerInCurrentOrNextSlot();
|
|
17
17
|
|
|
18
18
|
// Check that the attestation is for the current or next slot
|
|
19
|
-
const slotNumberBigInt = block.payload.header.
|
|
19
|
+
const slotNumberBigInt = block.payload.header.slotNumber.toBigInt();
|
|
20
20
|
if (slotNumberBigInt !== currentSlot && slotNumberBigInt !== nextSlot) {
|
|
21
21
|
this.logger.debug(
|
|
22
22
|
`Penalizing peer for invalid slot number ${slotNumberBigInt}, current slot: ${currentSlot}, next slot: ${nextSlot}`,
|
|
@@ -17,7 +17,7 @@ export class BlockHeaderTxValidator<T extends AnyTx> implements TxValidator<T> {
|
|
|
17
17
|
async validateTx(tx: T): Promise<TxValidationResult> {
|
|
18
18
|
const [index] = await this.#archiveSource.getArchiveIndices([await tx.data.constants.historicalHeader.hash()]);
|
|
19
19
|
if (index === undefined) {
|
|
20
|
-
this.#log.
|
|
20
|
+
this.#log.verbose(`Rejecting tx ${await Tx.getHash(tx)} for referencing an unknown block header`);
|
|
21
21
|
return { result: 'invalid', reason: [TX_ERROR_BLOCK_HEADER] };
|
|
22
22
|
}
|
|
23
23
|
return { result: 'valid' };
|