@aztec/p2p 2.1.0-rc.9 → 3.0.0-devnet.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dest/bootstrap/bootstrap.d.ts.map +1 -1
- package/dest/bootstrap/bootstrap.js +14 -4
- package/dest/client/factory.d.ts +1 -0
- package/dest/client/factory.d.ts.map +1 -1
- package/dest/client/factory.js +5 -3
- package/dest/client/interface.d.ts +1 -1
- package/dest/client/interface.d.ts.map +1 -1
- package/dest/client/p2p_client.d.ts +2 -1
- package/dest/client/p2p_client.d.ts.map +1 -1
- package/dest/client/p2p_client.js +14 -4
- package/dest/config.d.ts +4 -4
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +4 -3
- package/dest/enr/generate-enr.d.ts +1 -1
- package/dest/enr/generate-enr.d.ts.map +1 -1
- package/dest/enr/generate-enr.js +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 +6 -7
- package/dest/mem_pools/attestation_pool/kv_attestation_pool.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/kv_attestation_pool.js +18 -2
- 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 -7
- package/dest/mem_pools/attestation_pool/mocks.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/mocks.js +8 -6
- package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.js +1 -1
- package/dest/msg_validators/attestation_validator/attestation_validator.d.ts +1 -0
- package/dest/msg_validators/attestation_validator/attestation_validator.d.ts.map +1 -1
- package/dest/msg_validators/attestation_validator/attestation_validator.js +29 -2
- package/dest/msg_validators/block_proposal_validator/block_proposal_validator.d.ts +4 -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 +24 -4
- package/dest/msg_validators/tx_validator/block_header_validator.js +1 -1
- package/dest/msg_validators/tx_validator/factory.d.ts +1 -1
- package/dest/msg_validators/tx_validator/factory.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/factory.js +10 -4
- package/dest/msg_validators/tx_validator/index.d.ts +1 -0
- package/dest/msg_validators/tx_validator/index.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/index.js +1 -0
- package/dest/msg_validators/tx_validator/metadata_validator.d.ts +1 -4
- package/dest/msg_validators/tx_validator/metadata_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/metadata_validator.js +6 -24
- package/dest/msg_validators/tx_validator/timestamp_validator.d.ts +12 -0
- package/dest/msg_validators/tx_validator/timestamp_validator.d.ts.map +1 -0
- package/dest/msg_validators/tx_validator/timestamp_validator.js +32 -0
- 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 +2 -2
- package/dest/services/dummy_service.d.ts +1 -1
- package/dest/services/dummy_service.d.ts.map +1 -1
- package/dest/services/libp2p/libp2p_service.d.ts +11 -1
- package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
- package/dest/services/libp2p/libp2p_service.js +72 -34
- package/dest/services/peer-manager/peer_manager.d.ts.map +1 -1
- package/dest/services/peer-manager/peer_manager.js +9 -3
- package/dest/services/service.d.ts +1 -1
- package/dest/services/service.d.ts.map +1 -1
- package/dest/services/tx_collection/fast_tx_collection.d.ts.map +1 -1
- package/dest/services/tx_collection/fast_tx_collection.js +6 -1
- package/dest/services/tx_collection/tx_collection.d.ts +2 -1
- package/dest/services/tx_collection/tx_collection.d.ts.map +1 -1
- package/dest/services/tx_collection/tx_collection.js +3 -2
- package/dest/services/tx_collection/tx_collection_sink.d.ts.map +1 -1
- package/dest/services/tx_collection/tx_collection_sink.js +34 -4
- package/dest/services/tx_collection/tx_source.js +2 -2
- package/dest/services/tx_provider.d.ts +1 -1
- package/dest/services/tx_provider.d.ts.map +1 -1
- package/dest/services/tx_provider.js +7 -3
- package/dest/test-helpers/make-enrs.js +1 -1
- package/dest/test-helpers/mock-tx-helpers.d.ts +12 -0
- package/dest/test-helpers/mock-tx-helpers.d.ts.map +1 -0
- package/dest/test-helpers/mock-tx-helpers.js +19 -0
- package/dest/test-helpers/reqresp-nodes.d.ts +1 -1
- package/dest/test-helpers/reqresp-nodes.d.ts.map +1 -1
- package/dest/test-helpers/reqresp-nodes.js +4 -3
- package/dest/versioning.d.ts +1 -1
- package/dest/versioning.d.ts.map +1 -1
- package/dest/versioning.js +2 -2
- package/package.json +17 -17
- package/src/bootstrap/bootstrap.ts +15 -4
- package/src/client/factory.ts +10 -3
- package/src/client/interface.ts +1 -1
- package/src/client/p2p_client.ts +14 -5
- package/src/config.ts +6 -4
- package/src/enr/generate-enr.ts +1 -1
- package/src/mem_pools/attestation_pool/attestation_pool_test_suite.ts +6 -7
- package/src/mem_pools/attestation_pool/kv_attestation_pool.ts +22 -2
- package/src/mem_pools/attestation_pool/memory_attestation_pool.ts +24 -7
- package/src/mem_pools/attestation_pool/mocks.ts +9 -6
- package/src/mem_pools/tx_pool/aztec_kv_tx_pool.ts +1 -1
- package/src/msg_validators/attestation_validator/attestation_validator.ts +39 -2
- package/src/msg_validators/block_proposal_validator/block_proposal_validator.ts +29 -4
- package/src/msg_validators/tx_validator/block_header_validator.ts +1 -1
- package/src/msg_validators/tx_validator/factory.ts +10 -4
- package/src/msg_validators/tx_validator/index.ts +1 -0
- package/src/msg_validators/tx_validator/metadata_validator.ts +7 -41
- package/src/msg_validators/tx_validator/timestamp_validator.ts +46 -0
- package/src/services/discv5/discV5_service.ts +2 -2
- package/src/services/dummy_service.ts +1 -1
- package/src/services/libp2p/libp2p_service.ts +100 -52
- package/src/services/peer-manager/peer_manager.ts +10 -3
- package/src/services/service.ts +1 -1
- package/src/services/tx_collection/fast_tx_collection.ts +3 -1
- package/src/services/tx_collection/tx_collection.ts +3 -2
- package/src/services/tx_collection/tx_collection_sink.ts +34 -3
- package/src/services/tx_collection/tx_source.ts +2 -2
- package/src/services/tx_provider.ts +3 -2
- package/src/test-helpers/make-enrs.ts +1 -1
- package/src/test-helpers/mock-tx-helpers.ts +24 -0
- package/src/test-helpers/reqresp-nodes.ts +3 -2
- package/src/versioning.ts +3 -3
|
@@ -20,6 +20,7 @@ import { DoubleSpendTxValidator } from './double_spend_validator.js';
|
|
|
20
20
|
import { GasTxValidator } from './gas_validator.js';
|
|
21
21
|
import { MetadataTxValidator } from './metadata_validator.js';
|
|
22
22
|
import { PhasesTxValidator } from './phases_validator.js';
|
|
23
|
+
import { TimestampTxValidator } from './timestamp_validator.js';
|
|
23
24
|
import { TxPermittedValidator } from './tx_permitted_validator.js';
|
|
24
25
|
import { TxProofValidator } from './tx_proof_validator.js';
|
|
25
26
|
|
|
@@ -37,7 +38,7 @@ export function createTxMessageValidators(
|
|
|
37
38
|
gasFees: GasFees,
|
|
38
39
|
l1ChainId: number,
|
|
39
40
|
rollupVersion: number,
|
|
40
|
-
|
|
41
|
+
protocolContractsHash: Fr,
|
|
41
42
|
contractDataSource: ContractDataSource,
|
|
42
43
|
proofVerifier: ClientProtocolCircuitVerifier,
|
|
43
44
|
txsPermitted: boolean,
|
|
@@ -59,13 +60,18 @@ export function createTxMessageValidators(
|
|
|
59
60
|
validator: new MetadataTxValidator({
|
|
60
61
|
l1ChainId: new Fr(l1ChainId),
|
|
61
62
|
rollupVersion: new Fr(rollupVersion),
|
|
62
|
-
|
|
63
|
-
blockNumber,
|
|
64
|
-
protocolContractTreeRoot,
|
|
63
|
+
protocolContractsHash,
|
|
65
64
|
vkTreeRoot: getVKTreeRoot(),
|
|
66
65
|
}),
|
|
67
66
|
severity: PeerErrorSeverity.HighToleranceError,
|
|
68
67
|
},
|
|
68
|
+
timestampValidator: {
|
|
69
|
+
validator: new TimestampTxValidator<Tx>({
|
|
70
|
+
timestamp,
|
|
71
|
+
blockNumber,
|
|
72
|
+
}),
|
|
73
|
+
severity: PeerErrorSeverity.MidToleranceError,
|
|
74
|
+
},
|
|
69
75
|
doubleSpendValidator: {
|
|
70
76
|
validator: new DoubleSpendTxValidator({
|
|
71
77
|
nullifiersExist: async (nullifiers: Buffer[]) => {
|
|
@@ -3,15 +3,12 @@ import { createLogger } from '@aztec/foundation/log';
|
|
|
3
3
|
import {
|
|
4
4
|
type AnyTx,
|
|
5
5
|
TX_ERROR_INCORRECT_L1_CHAIN_ID,
|
|
6
|
-
|
|
6
|
+
TX_ERROR_INCORRECT_PROTOCOL_CONTRACTS_HASH,
|
|
7
7
|
TX_ERROR_INCORRECT_ROLLUP_VERSION,
|
|
8
8
|
TX_ERROR_INCORRECT_VK_TREE_ROOT,
|
|
9
|
-
TX_ERROR_INVALID_INCLUDE_BY_TIMESTAMP,
|
|
10
9
|
type TxValidationResult,
|
|
11
10
|
type TxValidator,
|
|
12
|
-
getTxHash,
|
|
13
11
|
} from '@aztec/stdlib/tx';
|
|
14
|
-
import type { UInt64 } from '@aztec/stdlib/types';
|
|
15
12
|
|
|
16
13
|
export class MetadataTxValidator<T extends AnyTx> implements TxValidator<T> {
|
|
17
14
|
#log = createLogger('p2p:tx_validator:tx_metadata');
|
|
@@ -20,13 +17,8 @@ export class MetadataTxValidator<T extends AnyTx> implements TxValidator<T> {
|
|
|
20
17
|
private values: {
|
|
21
18
|
l1ChainId: Fr;
|
|
22
19
|
rollupVersion: Fr;
|
|
23
|
-
// Timestamp at which we will validate that the tx is not expired. This is typically the timestamp of the block
|
|
24
|
-
// being built.
|
|
25
|
-
timestamp: UInt64;
|
|
26
|
-
// Block number in which the tx is considered to be included.
|
|
27
|
-
blockNumber: number;
|
|
28
20
|
vkTreeRoot: Fr;
|
|
29
|
-
|
|
21
|
+
protocolContractsHash: Fr;
|
|
30
22
|
},
|
|
31
23
|
) {}
|
|
32
24
|
|
|
@@ -38,14 +30,11 @@ export class MetadataTxValidator<T extends AnyTx> implements TxValidator<T> {
|
|
|
38
30
|
if (!this.#hasCorrectRollupVersion(tx)) {
|
|
39
31
|
errors.push(TX_ERROR_INCORRECT_ROLLUP_VERSION);
|
|
40
32
|
}
|
|
41
|
-
if (!this.#isValidForTimestamp(tx)) {
|
|
42
|
-
errors.push(TX_ERROR_INVALID_INCLUDE_BY_TIMESTAMP);
|
|
43
|
-
}
|
|
44
33
|
if (!this.#hasCorrectVkTreeRoot(tx)) {
|
|
45
34
|
errors.push(TX_ERROR_INCORRECT_VK_TREE_ROOT);
|
|
46
35
|
}
|
|
47
|
-
if (!this.#
|
|
48
|
-
errors.push(
|
|
36
|
+
if (!this.#hasCorrectprotocolContractsHash(tx)) {
|
|
37
|
+
errors.push(TX_ERROR_INCORRECT_PROTOCOL_CONTRACTS_HASH);
|
|
49
38
|
}
|
|
50
39
|
return Promise.resolve(errors.length > 0 ? { result: 'invalid', reason: errors } : { result: 'valid' });
|
|
51
40
|
}
|
|
@@ -62,10 +51,10 @@ export class MetadataTxValidator<T extends AnyTx> implements TxValidator<T> {
|
|
|
62
51
|
}
|
|
63
52
|
}
|
|
64
53
|
|
|
65
|
-
#
|
|
66
|
-
if (!tx.data.constants.
|
|
54
|
+
#hasCorrectprotocolContractsHash(tx: T): boolean {
|
|
55
|
+
if (!tx.data.constants.protocolContractsHash.equals(this.values.protocolContractsHash)) {
|
|
67
56
|
this.#log.verbose(
|
|
68
|
-
`Rejecting tx ${'txHash' in tx ? tx.txHash : tx.hash} because of incorrect protocol
|
|
57
|
+
`Rejecting tx ${'txHash' in tx ? tx.txHash : tx.hash} because of incorrect protocol contracts hash ${tx.data.constants.protocolContractsHash.toString()} != ${this.values.protocolContractsHash.toString()}`,
|
|
69
58
|
);
|
|
70
59
|
return false;
|
|
71
60
|
}
|
|
@@ -83,29 +72,6 @@ export class MetadataTxValidator<T extends AnyTx> implements TxValidator<T> {
|
|
|
83
72
|
}
|
|
84
73
|
}
|
|
85
74
|
|
|
86
|
-
#isValidForTimestamp(tx: T): boolean {
|
|
87
|
-
const includeByTimestamp = tx.data.includeByTimestamp;
|
|
88
|
-
// If building block 1, we skip the expiration check. For details on why see the `validate_include_by_timestamp`
|
|
89
|
-
// function in `noir-projects/noir-protocol-circuits/crates/rollup-lib/src/base/components/validation_requests.nr`.
|
|
90
|
-
const buildingBlock1 = this.values.blockNumber === 1;
|
|
91
|
-
|
|
92
|
-
if (!buildingBlock1 && includeByTimestamp < this.values.timestamp) {
|
|
93
|
-
if (tx.data.constants.historicalHeader.globalVariables.blockNumber === 0) {
|
|
94
|
-
this.#log.warn(
|
|
95
|
-
`A tx built against a genesis block failed to be included in block 1 which is the only block in which txs built against a genesis block are allowed to be included.`,
|
|
96
|
-
);
|
|
97
|
-
}
|
|
98
|
-
this.#log.verbose(
|
|
99
|
-
`Rejecting tx ${getTxHash(tx)} for low expiration timestamp. Tx expiration timestamp: ${includeByTimestamp}, timestamp: ${
|
|
100
|
-
this.values.timestamp
|
|
101
|
-
}.`,
|
|
102
|
-
);
|
|
103
|
-
return false;
|
|
104
|
-
} else {
|
|
105
|
-
return true;
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
|
|
109
75
|
#hasCorrectRollupVersion(tx: T): boolean {
|
|
110
76
|
if (!tx.data.constants.txContext.version.equals(this.values.rollupVersion)) {
|
|
111
77
|
this.#log.verbose(
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { createLogger } from '@aztec/foundation/log';
|
|
2
|
+
import {
|
|
3
|
+
type AnyTx,
|
|
4
|
+
TX_ERROR_INVALID_INCLUDE_BY_TIMESTAMP,
|
|
5
|
+
type TxValidationResult,
|
|
6
|
+
type TxValidator,
|
|
7
|
+
getTxHash,
|
|
8
|
+
} from '@aztec/stdlib/tx';
|
|
9
|
+
import type { UInt64 } from '@aztec/stdlib/types';
|
|
10
|
+
|
|
11
|
+
export class TimestampTxValidator<T extends AnyTx> implements TxValidator<T> {
|
|
12
|
+
#log = createLogger('p2p:tx_validator:timestamp');
|
|
13
|
+
|
|
14
|
+
constructor(
|
|
15
|
+
private values: {
|
|
16
|
+
// Timestamp at which we will validate that the tx is not expired. This is typically the timestamp of the block
|
|
17
|
+
// being built.
|
|
18
|
+
timestamp: UInt64;
|
|
19
|
+
// Block number in which the tx is considered to be included.
|
|
20
|
+
blockNumber: number;
|
|
21
|
+
},
|
|
22
|
+
) {}
|
|
23
|
+
|
|
24
|
+
validateTx(tx: T): Promise<TxValidationResult> {
|
|
25
|
+
const includeByTimestamp = tx.data.includeByTimestamp;
|
|
26
|
+
// If building block 1, we skip the expiration check. For details on why see the `validate_include_by_timestamp`
|
|
27
|
+
// function in `noir-projects/noir-protocol-circuits/crates/rollup-lib/src/base/components/validation_requests.nr`.
|
|
28
|
+
const buildingBlock1 = this.values.blockNumber === 1;
|
|
29
|
+
|
|
30
|
+
if (!buildingBlock1 && includeByTimestamp < this.values.timestamp) {
|
|
31
|
+
if (tx.data.constants.anchorBlockHeader.globalVariables.blockNumber === 0) {
|
|
32
|
+
this.#log.warn(
|
|
33
|
+
`A tx built against a genesis block failed to be included in block 1 which is the only block in which txs built against a genesis block are allowed to be included.`,
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
this.#log.verbose(
|
|
37
|
+
`Rejecting tx ${getTxHash(tx)} for low expiration timestamp. Tx expiration timestamp: ${includeByTimestamp}, timestamp: ${
|
|
38
|
+
this.values.timestamp
|
|
39
|
+
}.`,
|
|
40
|
+
);
|
|
41
|
+
return Promise.resolve({ result: 'invalid', reason: [TX_ERROR_INVALID_INCLUDE_BY_TIMESTAMP] });
|
|
42
|
+
} else {
|
|
43
|
+
return Promise.resolve({ result: 'valid' });
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -3,10 +3,10 @@ import { sleep } from '@aztec/foundation/sleep';
|
|
|
3
3
|
import { type ComponentsVersions, checkCompressedComponentVersion } from '@aztec/stdlib/versioning';
|
|
4
4
|
import { OtelMetricsAdapter, type TelemetryClient, getTelemetryClient } from '@aztec/telemetry-client';
|
|
5
5
|
|
|
6
|
-
import { Discv5, type Discv5EventEmitter, type IDiscv5CreateOptions } from '@chainsafe/discv5';
|
|
7
|
-
import { ENR, SignableENR } from '@chainsafe/enr';
|
|
8
6
|
import type { PeerId } from '@libp2p/interface';
|
|
9
7
|
import { type Multiaddr, multiaddr } from '@multiformats/multiaddr';
|
|
8
|
+
import { Discv5, type Discv5EventEmitter, type IDiscv5CreateOptions } from '@nethermindeth/discv5';
|
|
9
|
+
import { ENR, SignableENR } from '@nethermindeth/enr';
|
|
10
10
|
import EventEmitter from 'events';
|
|
11
11
|
|
|
12
12
|
import type { P2PConfig } from '../../config.js';
|
|
@@ -3,8 +3,8 @@ import type { PeerInfo } from '@aztec/stdlib/interfaces/server';
|
|
|
3
3
|
import type { Gossipable, PeerErrorSeverity } from '@aztec/stdlib/p2p';
|
|
4
4
|
import { Tx, TxHash } from '@aztec/stdlib/tx';
|
|
5
5
|
|
|
6
|
-
import type { ENR } from '@chainsafe/enr';
|
|
7
6
|
import type { PeerId } from '@libp2p/interface';
|
|
7
|
+
import type { ENR } from '@nethermindeth/enr';
|
|
8
8
|
import EventEmitter from 'events';
|
|
9
9
|
|
|
10
10
|
import type { PeerManagerInterface } from './peer-manager/interface.js';
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import type { EpochCacheInterface } from '@aztec/epoch-cache';
|
|
2
2
|
import { randomInt } from '@aztec/foundation/crypto';
|
|
3
|
+
import { Fr } from '@aztec/foundation/fields';
|
|
3
4
|
import { type Logger, createLibp2pComponentLogger, createLogger } from '@aztec/foundation/log';
|
|
4
5
|
import { SerialQueue } from '@aztec/foundation/queue';
|
|
5
6
|
import { RunningPromise } from '@aztec/foundation/running-promise';
|
|
6
7
|
import { Timer } from '@aztec/foundation/timer';
|
|
7
8
|
import type { AztecAsyncKVStore } from '@aztec/kv-store';
|
|
8
|
-
import {
|
|
9
|
+
import { getVKTreeRoot } from '@aztec/noir-protocol-circuits-types/vk-tree';
|
|
10
|
+
import { protocolContractsHash } from '@aztec/protocol-contracts';
|
|
9
11
|
import type { EthAddress, L2BlockSource } from '@aztec/stdlib/block';
|
|
10
12
|
import type { ContractDataSource } from '@aztec/stdlib/contract';
|
|
11
13
|
import { GasFees } from '@aztec/stdlib/gas';
|
|
@@ -23,12 +25,11 @@ import {
|
|
|
23
25
|
metricsTopicStrToLabels,
|
|
24
26
|
} from '@aztec/stdlib/p2p';
|
|
25
27
|
import { MerkleTreeId } from '@aztec/stdlib/trees';
|
|
26
|
-
import { Tx, type TxHash, type TxValidationResult } from '@aztec/stdlib/tx';
|
|
28
|
+
import { Tx, type TxHash, type TxValidationResult, type TxValidator } from '@aztec/stdlib/tx';
|
|
27
29
|
import type { UInt64 } from '@aztec/stdlib/types';
|
|
28
30
|
import { compressComponentVersions } from '@aztec/stdlib/versioning';
|
|
29
31
|
import { Attributes, OtelMetricsAdapter, type TelemetryClient, WithTracer, trackSpan } from '@aztec/telemetry-client';
|
|
30
32
|
|
|
31
|
-
import { ENR } from '@chainsafe/enr';
|
|
32
33
|
import {
|
|
33
34
|
type GossipSub,
|
|
34
35
|
type GossipSubComponents,
|
|
@@ -45,6 +46,7 @@ import { type Message, type MultiaddrConnection, type PeerId, TopicValidatorResu
|
|
|
45
46
|
import type { ConnectionManager } from '@libp2p/interface-internal';
|
|
46
47
|
import { mplex } from '@libp2p/mplex';
|
|
47
48
|
import { tcp } from '@libp2p/tcp';
|
|
49
|
+
import { ENR } from '@nethermindeth/enr';
|
|
48
50
|
import { createLibp2p } from 'libp2p';
|
|
49
51
|
|
|
50
52
|
import type { P2PConfig } from '../../config.js';
|
|
@@ -53,7 +55,13 @@ import { AttestationValidator, BlockProposalValidator } from '../../msg_validato
|
|
|
53
55
|
import { MessageSeenValidator } from '../../msg_validators/msg_seen_validator/msg_seen_validator.js';
|
|
54
56
|
import { getDefaultAllowedSetupFunctions } from '../../msg_validators/tx_validator/allowed_public_setup.js';
|
|
55
57
|
import { type MessageValidator, createTxMessageValidators } from '../../msg_validators/tx_validator/factory.js';
|
|
56
|
-
import {
|
|
58
|
+
import {
|
|
59
|
+
AggregateTxValidator,
|
|
60
|
+
DataTxValidator,
|
|
61
|
+
DoubleSpendTxValidator,
|
|
62
|
+
MetadataTxValidator,
|
|
63
|
+
TxProofValidator,
|
|
64
|
+
} from '../../msg_validators/tx_validator/index.js';
|
|
57
65
|
import { GossipSubEvent } from '../../types/index.js';
|
|
58
66
|
import { type PubSubLibp2p, convertToMultiaddr } from '../../util.js';
|
|
59
67
|
import { getVersions } from '../../versioning.js';
|
|
@@ -79,6 +87,8 @@ import { reqRespBlockTxsHandler } from '../reqresp/protocols/block_txs/block_txs
|
|
|
79
87
|
import { reqGoodbyeHandler } from '../reqresp/protocols/goodbye.js';
|
|
80
88
|
import {
|
|
81
89
|
AuthRequest,
|
|
90
|
+
BlockTxsRequest,
|
|
91
|
+
BlockTxsResponse,
|
|
82
92
|
StatusMessage,
|
|
83
93
|
pingHandler,
|
|
84
94
|
reqRespBlockHandler,
|
|
@@ -160,7 +170,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
160
170
|
);
|
|
161
171
|
|
|
162
172
|
this.attestationValidator = new AttestationValidator(epochCache);
|
|
163
|
-
this.blockProposalValidator = new BlockProposalValidator(epochCache);
|
|
173
|
+
this.blockProposalValidator = new BlockProposalValidator(epochCache, { txsPermitted: !config.disableTransactions });
|
|
164
174
|
|
|
165
175
|
this.gossipSubEventHandler = this.handleGossipSubEvent.bind(this);
|
|
166
176
|
|
|
@@ -487,7 +497,8 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
487
497
|
const reqrespSubProtocolValidators = {
|
|
488
498
|
...DEFAULT_SUB_PROTOCOL_VALIDATORS,
|
|
489
499
|
// TODO(#11336): A request validator for blocks
|
|
490
|
-
[ReqRespSubProtocol.TX]: this.
|
|
500
|
+
[ReqRespSubProtocol.TX]: this.validateRequestedTxs.bind(this),
|
|
501
|
+
[ReqRespSubProtocol.BLOCK_TXS]: this.validateRequestedBlockTxs.bind(this),
|
|
491
502
|
};
|
|
492
503
|
await this.reqresp.start(requestResponseHandlers, reqrespSubProtocolValidators);
|
|
493
504
|
this.logger.info(`Started P2P service`, {
|
|
@@ -745,12 +756,11 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
745
756
|
return;
|
|
746
757
|
}
|
|
747
758
|
this.logger.debug(
|
|
748
|
-
`Received attestation for
|
|
759
|
+
`Received attestation for slot ${attestation.slotNumber.toNumber()} from external peer ${source.toString()}`,
|
|
749
760
|
{
|
|
750
761
|
p2pMessageIdentifier: await attestation.p2pMessageIdentifier(),
|
|
751
762
|
slot: attestation.slotNumber.toNumber(),
|
|
752
763
|
archive: attestation.archive.toString(),
|
|
753
|
-
block: attestation.blockNumber,
|
|
754
764
|
source: source.toString(),
|
|
755
765
|
},
|
|
756
766
|
);
|
|
@@ -783,7 +793,6 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
783
793
|
|
|
784
794
|
// REVIEW: callback pattern https://github.com/AztecProtocol/aztec-packages/issues/7963
|
|
785
795
|
@trackSpan('Libp2pService.processValidBlockProposal', async block => ({
|
|
786
|
-
[Attributes.BLOCK_NUMBER]: block.blockNumber,
|
|
787
796
|
[Attributes.SLOT_NUMBER]: block.slotNumber.toNumber(),
|
|
788
797
|
[Attributes.BLOCK_ARCHIVE]: block.archive.toString(),
|
|
789
798
|
[Attributes.P2P_ID]: await block.p2pMessageIdentifier().then(i => i.toString()),
|
|
@@ -791,16 +800,12 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
791
800
|
private async processValidBlockProposal(block: BlockProposal, sender: PeerId) {
|
|
792
801
|
const slot = block.slotNumber.toBigInt();
|
|
793
802
|
const previousSlot = slot - 1n;
|
|
794
|
-
this.logger.verbose(
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
block: block.blockNumber,
|
|
801
|
-
source: sender.toString(),
|
|
802
|
-
},
|
|
803
|
-
);
|
|
803
|
+
this.logger.verbose(`Received block proposal for slot ${slot} from external peer ${sender.toString()}.`, {
|
|
804
|
+
p2pMessageIdentifier: await block.p2pMessageIdentifier(),
|
|
805
|
+
slot: block.slotNumber.toNumber(),
|
|
806
|
+
archive: block.archive.toString(),
|
|
807
|
+
source: sender.toString(),
|
|
808
|
+
});
|
|
804
809
|
const attestationsForPreviousSlot = await this.mempools.attestationPool?.getAttestationsForSlot(previousSlot);
|
|
805
810
|
if (attestationsForPreviousSlot !== undefined) {
|
|
806
811
|
this.logger.verbose(`Received ${attestationsForPreviousSlot.length} attestations for slot ${previousSlot}`);
|
|
@@ -815,15 +820,11 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
815
820
|
// The attestation can be undefined if no handler is registered / the validator deems the block invalid
|
|
816
821
|
if (attestations?.length) {
|
|
817
822
|
for (const attestation of attestations) {
|
|
818
|
-
this.logger.verbose(
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
archive: attestation.archive.toString(),
|
|
824
|
-
block: attestation.blockNumber,
|
|
825
|
-
},
|
|
826
|
-
);
|
|
823
|
+
this.logger.verbose(`Broadcasting attestation for slot ${attestation.slotNumber.toNumber()}`, {
|
|
824
|
+
p2pMessageIdentifier: await attestation.p2pMessageIdentifier(),
|
|
825
|
+
slot: attestation.slotNumber.toNumber(),
|
|
826
|
+
archive: attestation.archive.toString(),
|
|
827
|
+
});
|
|
827
828
|
await this.broadcastAttestation(attestation);
|
|
828
829
|
}
|
|
829
830
|
}
|
|
@@ -834,7 +835,6 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
834
835
|
* @param attestation - The attestation to broadcast.
|
|
835
836
|
*/
|
|
836
837
|
@trackSpan('Libp2pService.broadcastAttestation', async attestation => ({
|
|
837
|
-
[Attributes.BLOCK_NUMBER]: attestation.blockNumber,
|
|
838
838
|
[Attributes.SLOT_NUMBER]: attestation.payload.header.slotNumber.toNumber(),
|
|
839
839
|
[Attributes.BLOCK_ARCHIVE]: attestation.archive.toString(),
|
|
840
840
|
[Attributes.P2P_ID]: await attestation.p2pMessageIdentifier().then(i => i.toString()),
|
|
@@ -859,6 +859,38 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
859
859
|
});
|
|
860
860
|
}
|
|
861
861
|
|
|
862
|
+
/**
|
|
863
|
+
* Validate the requested block transactions.
|
|
864
|
+
* @param request - The block transactions request.
|
|
865
|
+
* @param response - The block transactions response.
|
|
866
|
+
* @param peerId - The ID of the peer that made the request.
|
|
867
|
+
* @returns True if the requested block transactions are valid, false otherwise.
|
|
868
|
+
*/
|
|
869
|
+
@trackSpan('Libp2pService.validateRequestedBlockTxs', request => ({
|
|
870
|
+
[Attributes.BLOCK_HASH]: request.blockHash.toString(),
|
|
871
|
+
}))
|
|
872
|
+
private async validateRequestedBlockTxs(
|
|
873
|
+
_request: BlockTxsRequest,
|
|
874
|
+
response: BlockTxsResponse,
|
|
875
|
+
peerId: PeerId,
|
|
876
|
+
): Promise<boolean> {
|
|
877
|
+
const requestedTxValidator = this.createRequestedTxValidator();
|
|
878
|
+
|
|
879
|
+
try {
|
|
880
|
+
// TODO(palla/txs): Validate that this tx belongs to the block hash being requested
|
|
881
|
+
await Promise.all(response.txs.map(tx => this.validateRequestedTx(tx, peerId, requestedTxValidator)));
|
|
882
|
+
return true;
|
|
883
|
+
} catch (e: any) {
|
|
884
|
+
if (e instanceof ValidationError) {
|
|
885
|
+
this.logger.warn(`Failed validation for requested block txs from peer ${peerId.toString()}`);
|
|
886
|
+
} else {
|
|
887
|
+
this.logger.error(`Error during validation of requested block txs`, e);
|
|
888
|
+
}
|
|
889
|
+
|
|
890
|
+
return false;
|
|
891
|
+
}
|
|
892
|
+
}
|
|
893
|
+
|
|
862
894
|
/**
|
|
863
895
|
* Validate a collection of txs that has been requested from a peer.
|
|
864
896
|
*
|
|
@@ -873,43 +905,60 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
873
905
|
* @param peerId - The peer ID of the peer that sent the tx.
|
|
874
906
|
* @returns True if the whole collection of txs is valid, false otherwise.
|
|
875
907
|
*/
|
|
876
|
-
//TODO: (mralj) - this is somewhat naive implementation, if single tx is invlid we consider the whole response invalid.
|
|
877
|
-
// I think we should still extract the valid txs and return them, so that we can still use the response.
|
|
878
908
|
@trackSpan('Libp2pService.validateRequestedTx', (requestedTxHash, _responseTx) => ({
|
|
879
909
|
[Attributes.TX_HASH]: requestedTxHash.toString(),
|
|
880
910
|
}))
|
|
881
|
-
private async
|
|
911
|
+
private async validateRequestedTxs(requestedTxHash: TxHash[], responseTx: Tx[], peerId: PeerId): Promise<boolean> {
|
|
882
912
|
const requested = new Set(requestedTxHash.map(h => h.toString()));
|
|
913
|
+
const requestedTxValidator = this.createRequestedTxValidator();
|
|
883
914
|
|
|
884
|
-
|
|
885
|
-
|
|
915
|
+
//TODO: (mralj) - this is somewhat naive implementation, if single tx is invlid we consider the whole response invalid.
|
|
916
|
+
// I think we should still extract the valid txs and return them, so that we can still use the response.
|
|
886
917
|
try {
|
|
887
|
-
await Promise.all(
|
|
888
|
-
responseTx.map(async tx => {
|
|
889
|
-
if (!requested.has(tx.getTxHash().toString())) {
|
|
890
|
-
this.peerManager.penalizePeer(peerId, PeerErrorSeverity.MidToleranceError);
|
|
891
|
-
throw new ValidationError(`Received tx with hash ${tx.getTxHash().toString()} that was not requested.`);
|
|
892
|
-
}
|
|
893
|
-
|
|
894
|
-
const { result } = await proofValidator.validateTx(tx);
|
|
895
|
-
if (result === 'invalid') {
|
|
896
|
-
this.peerManager.penalizePeer(peerId, PeerErrorSeverity.LowToleranceError);
|
|
897
|
-
throw new ValidationError(`Received tx with hash ${tx.getTxHash().toString()} that is invalid.`);
|
|
898
|
-
}
|
|
899
|
-
}),
|
|
900
|
-
);
|
|
918
|
+
await Promise.all(responseTx.map(tx => this.validateRequestedTx(tx, peerId, requestedTxValidator, requested)));
|
|
901
919
|
return true;
|
|
902
920
|
} catch (e: any) {
|
|
903
921
|
if (e instanceof ValidationError) {
|
|
904
|
-
this.logger.
|
|
922
|
+
this.logger.warn(`Failed to validate requested txs from peer ${peerId.toString()}, reason ${e.message}`);
|
|
905
923
|
} else {
|
|
906
|
-
this.logger.
|
|
924
|
+
this.logger.error(`Error during validation of requested txs`, e);
|
|
907
925
|
}
|
|
908
926
|
|
|
909
927
|
return false;
|
|
910
928
|
}
|
|
911
929
|
}
|
|
912
930
|
|
|
931
|
+
private createRequestedTxValidator(): TxValidator {
|
|
932
|
+
return new AggregateTxValidator(
|
|
933
|
+
new DataTxValidator(),
|
|
934
|
+
new MetadataTxValidator({
|
|
935
|
+
l1ChainId: new Fr(this.config.l1ChainId),
|
|
936
|
+
rollupVersion: new Fr(this.config.rollupVersion),
|
|
937
|
+
protocolContractsHash,
|
|
938
|
+
vkTreeRoot: getVKTreeRoot(),
|
|
939
|
+
}),
|
|
940
|
+
new TxProofValidator(this.proofVerifier),
|
|
941
|
+
);
|
|
942
|
+
}
|
|
943
|
+
|
|
944
|
+
private async validateRequestedTx(tx: Tx, peerId: PeerId, txValidator: TxValidator, requested?: Set<`0x${string}`>) {
|
|
945
|
+
if (!(await tx.validateTxHash())) {
|
|
946
|
+
this.peerManager.penalizePeer(peerId, PeerErrorSeverity.MidToleranceError);
|
|
947
|
+
throw new ValidationError(`Received tx with invalid hash ${tx.getTxHash().toString()}.`);
|
|
948
|
+
}
|
|
949
|
+
|
|
950
|
+
if (requested && !requested.has(tx.getTxHash().toString())) {
|
|
951
|
+
this.peerManager.penalizePeer(peerId, PeerErrorSeverity.MidToleranceError);
|
|
952
|
+
throw new ValidationError(`Received tx with hash ${tx.getTxHash().toString()} that was not requested.`);
|
|
953
|
+
}
|
|
954
|
+
|
|
955
|
+
const { result } = await txValidator.validateTx(tx);
|
|
956
|
+
if (result === 'invalid') {
|
|
957
|
+
this.peerManager.penalizePeer(peerId, PeerErrorSeverity.LowToleranceError);
|
|
958
|
+
throw new ValidationError(`Received tx with hash ${tx.getTxHash().toString()} that is invalid.`);
|
|
959
|
+
}
|
|
960
|
+
}
|
|
961
|
+
|
|
913
962
|
@trackSpan('Libp2pService.validatePropagatedTx', tx => ({
|
|
914
963
|
[Attributes.TX_HASH]: tx.getTxHash().toString(),
|
|
915
964
|
}))
|
|
@@ -997,7 +1046,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
997
1046
|
gasFees,
|
|
998
1047
|
this.config.l1ChainId,
|
|
999
1048
|
this.config.rollupVersion,
|
|
1000
|
-
|
|
1049
|
+
protocolContractsHash,
|
|
1001
1050
|
this.archiver,
|
|
1002
1051
|
this.proofVerifier,
|
|
1003
1052
|
!this.config.disableTransactions,
|
|
@@ -1080,7 +1129,6 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
1080
1129
|
* @returns True if the attestation is valid, false otherwise.
|
|
1081
1130
|
*/
|
|
1082
1131
|
@trackSpan('Libp2pService.validateAttestation', async (_, attestation) => ({
|
|
1083
|
-
[Attributes.BLOCK_NUMBER]: attestation.blockNumber,
|
|
1084
1132
|
[Attributes.SLOT_NUMBER]: attestation.payload.header.slotNumber.toNumber(),
|
|
1085
1133
|
[Attributes.BLOCK_ARCHIVE]: attestation.archive.toString(),
|
|
1086
1134
|
[Attributes.P2P_ID]: await attestation.p2pMessageIdentifier().then(i => i.toString()),
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { EpochCacheInterface } from '@aztec/epoch-cache';
|
|
2
|
-
import { makeEthSignDigest,
|
|
2
|
+
import { makeEthSignDigest, tryRecoverAddress } from '@aztec/foundation/crypto';
|
|
3
3
|
import type { EthAddress } from '@aztec/foundation/eth-address';
|
|
4
4
|
import { Fr } from '@aztec/foundation/fields';
|
|
5
5
|
import { createLogger } from '@aztec/foundation/log';
|
|
@@ -9,10 +9,10 @@ import type { PeerInfo, WorldStateSynchronizer } from '@aztec/stdlib/interfaces/
|
|
|
9
9
|
import type { PeerErrorSeverity } from '@aztec/stdlib/p2p';
|
|
10
10
|
import { type TelemetryClient, trackSpan } from '@aztec/telemetry-client';
|
|
11
11
|
|
|
12
|
-
import { ENR } from '@chainsafe/enr';
|
|
13
12
|
import type { Connection, PeerId } from '@libp2p/interface';
|
|
14
13
|
import { peerIdFromString } from '@libp2p/peer-id';
|
|
15
14
|
import type { Multiaddr } from '@multiformats/multiaddr';
|
|
15
|
+
import { ENR } from '@nethermindeth/enr';
|
|
16
16
|
import { inspect } from 'util';
|
|
17
17
|
|
|
18
18
|
import type { P2PConfig } from '../../config.js';
|
|
@@ -907,7 +907,14 @@ export class PeerManager implements PeerManagerInterface {
|
|
|
907
907
|
|
|
908
908
|
const hashToRecover = authRequest.getPayloadToSign();
|
|
909
909
|
const ethSignedHash = makeEthSignDigest(hashToRecover);
|
|
910
|
-
const sender =
|
|
910
|
+
const sender = tryRecoverAddress(ethSignedHash, peerAuthResponse.signature);
|
|
911
|
+
if (!sender) {
|
|
912
|
+
this.logger.verbose(`Disconnecting peer ${peerId} due to failed auth handshake, invalid signature.`, logData);
|
|
913
|
+
this.markAuthHandshakeFailed(peerId);
|
|
914
|
+
this.markPeerForDisconnect(peerId);
|
|
915
|
+
return;
|
|
916
|
+
}
|
|
917
|
+
|
|
911
918
|
const registeredValidators = await this.epochCache.getRegisteredValidators();
|
|
912
919
|
const found = registeredValidators.find(v => v.toString() === sender.toString()) !== undefined;
|
|
913
920
|
if (!found) {
|
package/src/services/service.ts
CHANGED
|
@@ -3,8 +3,8 @@ import type { PeerInfo } from '@aztec/stdlib/interfaces/server';
|
|
|
3
3
|
import type { BlockAttestation, BlockProposal, Gossipable } from '@aztec/stdlib/p2p';
|
|
4
4
|
import type { Tx } from '@aztec/stdlib/tx';
|
|
5
5
|
|
|
6
|
-
import type { ENR } from '@chainsafe/enr';
|
|
7
6
|
import type { PeerId } from '@libp2p/interface';
|
|
7
|
+
import type { ENR } from '@nethermindeth/enr';
|
|
8
8
|
import type EventEmitter from 'events';
|
|
9
9
|
|
|
10
10
|
import type { P2PReqRespConfig } from './reqresp/config.js';
|
|
@@ -55,7 +55,9 @@ export class FastTxCollection {
|
|
|
55
55
|
}
|
|
56
56
|
|
|
57
57
|
const blockInfo: L2BlockInfo =
|
|
58
|
-
input.type === 'proposal'
|
|
58
|
+
input.type === 'proposal'
|
|
59
|
+
? { ...input.blockProposal.toBlockInfo(), blockNumber: input.blockNumber }
|
|
60
|
+
: { ...input.block.toBlockInfo() };
|
|
59
61
|
|
|
60
62
|
// This promise is used to await for the collection to finish during the main collectFast method.
|
|
61
63
|
// It gets resolved in `foundTxs` when all txs have been collected, or rejected if the request is aborted or hits the deadline.
|
|
@@ -25,7 +25,7 @@ export type MissingTxInfo = { blockNumber: number; deadline: Date; readyForReqRe
|
|
|
25
25
|
|
|
26
26
|
export type FastCollectionRequestInput =
|
|
27
27
|
| { type: 'block'; block: L2Block }
|
|
28
|
-
| { type: 'proposal'; blockProposal: BlockProposal };
|
|
28
|
+
| { type: 'proposal'; blockProposal: BlockProposal; blockNumber: number };
|
|
29
29
|
|
|
30
30
|
export type FastCollectionRequest = FastCollectionRequestInput & {
|
|
31
31
|
missingTxHashes: Set<string>;
|
|
@@ -152,10 +152,11 @@ export class TxCollection {
|
|
|
152
152
|
/** Collects the set of txs for the given block proposal as fast as possible */
|
|
153
153
|
public collectFastForProposal(
|
|
154
154
|
blockProposal: BlockProposal,
|
|
155
|
+
blockNumber: number,
|
|
155
156
|
txHashes: TxHash[] | string[],
|
|
156
157
|
opts: { deadline: Date; pinnedPeer?: PeerId },
|
|
157
158
|
) {
|
|
158
|
-
return this.collectFastFor({ type: 'proposal', blockProposal }, txHashes, opts);
|
|
159
|
+
return this.collectFastFor({ type: 'proposal', blockProposal, blockNumber }, txHashes, opts);
|
|
159
160
|
}
|
|
160
161
|
|
|
161
162
|
/** Collects the set of txs for the given mined block as fast as possible */
|
|
@@ -58,17 +58,48 @@ export class TxCollectionSink extends (EventEmitter as new () => TypedEventEmitt
|
|
|
58
58
|
return { txs, requested, duration };
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
+
// Validate tx hashes for all collected txs from external sources
|
|
62
|
+
const validTxs: Tx[] = [];
|
|
63
|
+
const invalidTxHashes: string[] = [];
|
|
64
|
+
await Promise.all(
|
|
65
|
+
txs.map(async tx => {
|
|
66
|
+
const isValid = await tx.validateTxHash();
|
|
67
|
+
if (isValid) {
|
|
68
|
+
validTxs.push(tx);
|
|
69
|
+
} else {
|
|
70
|
+
invalidTxHashes.push(tx.getTxHash().toString());
|
|
71
|
+
}
|
|
72
|
+
}),
|
|
73
|
+
);
|
|
74
|
+
|
|
75
|
+
if (invalidTxHashes.length > 0) {
|
|
76
|
+
this.log.warn(`Rejecting ${invalidTxHashes.length} txs with invalid hashes from ${info.description}`, {
|
|
77
|
+
...info,
|
|
78
|
+
invalidTxHashes,
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (validTxs.length === 0) {
|
|
83
|
+
this.log.trace(`No valid txs found via ${info.description} after validation`, {
|
|
84
|
+
...info,
|
|
85
|
+
requestedTxs: requested.map(t => t.toString()),
|
|
86
|
+
invalidTxHashes,
|
|
87
|
+
});
|
|
88
|
+
return { txs: [], requested, duration };
|
|
89
|
+
}
|
|
90
|
+
|
|
61
91
|
this.log.verbose(
|
|
62
|
-
`Collected ${
|
|
92
|
+
`Collected ${validTxs.length} txs out of ${requested.length} requested via ${info.description} in ${duration}ms`,
|
|
63
93
|
{
|
|
64
94
|
...info,
|
|
65
95
|
duration,
|
|
66
|
-
txs:
|
|
96
|
+
txs: validTxs.map(t => t.getTxHash().toString()),
|
|
67
97
|
requestedTxs: requested.map(t => t.toString()),
|
|
98
|
+
rejectedCount: invalidTxHashes.length,
|
|
68
99
|
},
|
|
69
100
|
);
|
|
70
101
|
|
|
71
|
-
return await this.foundTxs(
|
|
102
|
+
return await this.foundTxs(validTxs, { ...info, duration });
|
|
72
103
|
}
|
|
73
104
|
|
|
74
105
|
private async foundTxs(
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { getVKTreeRoot } from '@aztec/noir-protocol-circuits-types/vk-tree';
|
|
2
|
-
import {
|
|
2
|
+
import { protocolContractsHash } from '@aztec/protocol-contracts';
|
|
3
3
|
import type { ChainConfig } from '@aztec/stdlib/config';
|
|
4
4
|
import { type AztecNode, createAztecNodeClient } from '@aztec/stdlib/interfaces/client';
|
|
5
5
|
import type { Tx, TxHash } from '@aztec/stdlib/tx';
|
|
@@ -32,6 +32,6 @@ export class NodeRpcTxSource implements TxSource {
|
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
export function createNodeRpcTxSources(urls: string[], chainConfig: ChainConfig) {
|
|
35
|
-
const versions = getComponentsVersionsFromConfig(chainConfig,
|
|
35
|
+
const versions = getComponentsVersionsFromConfig(chainConfig, protocolContractsHash, getVKTreeRoot());
|
|
36
36
|
return urls.map(url => NodeRpcTxSource.fromUrl(url, versions));
|
|
37
37
|
}
|
|
@@ -55,11 +55,12 @@ export class TxProvider implements ITxProvider {
|
|
|
55
55
|
/** Gathers txs from the tx pool, proposal body, remote rpc nodes, and reqresp. */
|
|
56
56
|
public getTxsForBlockProposal(
|
|
57
57
|
blockProposal: BlockProposal,
|
|
58
|
+
blockNumber: number,
|
|
58
59
|
opts: { pinnedPeer: PeerId | undefined; deadline: Date },
|
|
59
60
|
): Promise<{ txs: Tx[]; missingTxs: TxHash[] }> {
|
|
60
61
|
return this.getOrderedTxsFromAllSources(
|
|
61
|
-
{ type: 'proposal', blockProposal },
|
|
62
|
-
blockProposal.toBlockInfo(),
|
|
62
|
+
{ type: 'proposal', blockProposal, blockNumber },
|
|
63
|
+
{ ...blockProposal.toBlockInfo(), blockNumber },
|
|
63
64
|
blockProposal.txHashes,
|
|
64
65
|
{ ...opts, pinnedPeer: opts.pinnedPeer },
|
|
65
66
|
);
|