@aztec/p2p 0.82.3 → 0.83.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/client/p2p_client.js +2 -2
- package/dest/config.d.ts +1 -1
- package/dest/msg_validators/tx_validator/double_spend_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/double_spend_validator.js +21 -27
- package/dest/msg_validators/tx_validator/metadata_validator.d.ts +2 -1
- package/dest/msg_validators/tx_validator/metadata_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/metadata_validator.js +14 -1
- package/dest/services/libp2p/libp2p_service.d.ts +1 -0
- package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
- package/dest/services/libp2p/libp2p_service.js +5 -3
- package/dest/test-helpers/reqresp-nodes.js +3 -3
- package/dest/testbench/worker_client_manager.js +1 -1
- package/package.json +10 -10
- package/src/client/p2p_client.ts +2 -2
- package/src/msg_validators/tx_validator/double_spend_validator.ts +12 -17
- package/src/msg_validators/tx_validator/metadata_validator.ts +17 -1
- package/src/services/libp2p/libp2p_service.ts +11 -3
- package/src/test-helpers/reqresp-nodes.ts +3 -3
- package/src/testbench/worker_client_manager.ts +1 -1
|
@@ -123,12 +123,12 @@ import { ReqRespSubProtocol } from '../services/reqresp/interface.js';
|
|
|
123
123
|
case 'chain-proven':
|
|
124
124
|
{
|
|
125
125
|
const from = await this.getSyncedProvenBlockNum() + 1;
|
|
126
|
-
const limit = event.
|
|
126
|
+
const limit = event.block.number - from + 1;
|
|
127
127
|
await this.handleProvenL2Blocks(await this.l2BlockSource.getBlocks(from, limit));
|
|
128
128
|
break;
|
|
129
129
|
}
|
|
130
130
|
case 'chain-pruned':
|
|
131
|
-
await this.handlePruneL2Blocks(event.
|
|
131
|
+
await this.handlePruneL2Blocks(event.block.number);
|
|
132
132
|
break;
|
|
133
133
|
default:
|
|
134
134
|
{
|
package/dest/config.d.ts
CHANGED
|
@@ -142,7 +142,7 @@ export declare function getP2PDefaultConfig(): P2PConfig;
|
|
|
142
142
|
export type BootnodeConfig = Pick<P2PConfig, 'p2pIp' | 'p2pPort' | 'peerIdPrivateKey' | 'bootstrapNodes' | 'listenAddress'> & Required<Pick<P2PConfig, 'p2pIp' | 'p2pPort'>> & Pick<DataStoreConfig, 'dataDirectory' | 'dataStoreMapSizeKB'> & Pick<ChainConfig, 'l1ChainId'>;
|
|
143
143
|
export declare const bootnodeConfigMappings: ConfigMappingsType<Pick<{
|
|
144
144
|
l1ChainId: unknown;
|
|
145
|
-
|
|
145
|
+
rollupVersion: unknown;
|
|
146
146
|
l1Contracts: unknown;
|
|
147
147
|
dataDirectory: unknown;
|
|
148
148
|
dataStoreMapSizeKB: unknown;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"double_spend_validator.d.ts","sourceRoot":"","sources":["../../../src/msg_validators/tx_validator/double_spend_validator.ts"],"names":[],"mappings":";;AACA,OAAO,EAAE,KAAK,KAAK,EAAM,KAAK,kBAAkB,EAAE,KAAK,WAAW,
|
|
1
|
+
{"version":3,"file":"double_spend_validator.d.ts","sourceRoot":"","sources":["../../../src/msg_validators/tx_validator/double_spend_validator.ts"],"names":[],"mappings":";;AACA,OAAO,EAAE,KAAK,KAAK,EAAM,KAAK,kBAAkB,EAAE,KAAK,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE7F,MAAM,WAAW,eAAe;IAC9B,eAAe,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;CAC/D;AAED,qBAAa,sBAAsB,CAAC,CAAC,SAAS,KAAK,CAAE,YAAW,WAAW,CAAC,CAAC,CAAC;;gBAIhE,eAAe,EAAE,eAAe;IAItC,UAAU,CAAC,EAAE,EAAE,CAAC,GAAG,OAAO,CAAC,kBAAkB,CAAC;CAiBrD"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createLogger } from '@aztec/foundation/log';
|
|
2
|
-
import { Tx
|
|
2
|
+
import { Tx } from '@aztec/stdlib/tx';
|
|
3
3
|
export class DoubleSpendTxValidator {
|
|
4
4
|
#log = createLogger('p2p:tx_validator:tx_double_spend');
|
|
5
5
|
#nullifierSource;
|
|
@@ -7,32 +7,26 @@ export class DoubleSpendTxValidator {
|
|
|
7
7
|
this.#nullifierSource = nullifierSource;
|
|
8
8
|
}
|
|
9
9
|
async validateTx(tx) {
|
|
10
|
-
|
|
11
|
-
//
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
result: 'invalid',
|
|
31
|
-
reason: [
|
|
32
|
-
'Existing nullifier'
|
|
33
|
-
]
|
|
34
|
-
};
|
|
35
|
-
}
|
|
10
|
+
const nullifiers = tx instanceof Tx ? tx.data.getNonEmptyNullifiers() : tx.txEffect.nullifiers;
|
|
11
|
+
// Ditch this tx if it has repeated nullifiers
|
|
12
|
+
const uniqueNullifiers = new Set(nullifiers);
|
|
13
|
+
if (uniqueNullifiers.size !== nullifiers.length) {
|
|
14
|
+
this.#log.warn(`Rejecting tx ${await Tx.getHash(tx)} for emitting duplicate nullifiers`);
|
|
15
|
+
return {
|
|
16
|
+
result: 'invalid',
|
|
17
|
+
reason: [
|
|
18
|
+
'Duplicate nullifier in tx'
|
|
19
|
+
]
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
if ((await this.#nullifierSource.nullifiersExist(nullifiers.map((n)=>n.toBuffer()))).some(Boolean)) {
|
|
23
|
+
this.#log.warn(`Rejecting tx ${await Tx.getHash(tx)} for repeating a nullifier`);
|
|
24
|
+
return {
|
|
25
|
+
result: 'invalid',
|
|
26
|
+
reason: [
|
|
27
|
+
'Existing nullifier'
|
|
28
|
+
]
|
|
29
|
+
};
|
|
36
30
|
}
|
|
37
31
|
return {
|
|
38
32
|
result: 'valid'
|
|
@@ -3,8 +3,9 @@ import { type AnyTx, type TxValidationResult, type TxValidator } from '@aztec/st
|
|
|
3
3
|
export declare class MetadataTxValidator<T extends AnyTx> implements TxValidator<T> {
|
|
4
4
|
#private;
|
|
5
5
|
private chainId;
|
|
6
|
+
private rollupVersion;
|
|
6
7
|
private blockNumber;
|
|
7
|
-
constructor(chainId: Fr, blockNumber: Fr);
|
|
8
|
+
constructor(chainId: Fr, rollupVersion: Fr, blockNumber: Fr);
|
|
8
9
|
validateTx(tx: T): Promise<TxValidationResult>;
|
|
9
10
|
}
|
|
10
11
|
//# sourceMappingURL=metadata_validator.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"metadata_validator.d.ts","sourceRoot":"","sources":["../../../src/msg_validators/tx_validator/metadata_validator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,0BAA0B,CAAC;AAEnD,OAAO,EAAE,KAAK,KAAK,EAAM,KAAK,kBAAkB,EAAE,KAAK,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE7F,qBAAa,mBAAmB,CAAC,CAAC,SAAS,KAAK,CAAE,YAAW,WAAW,CAAC,CAAC,CAAC;;IAG7D,OAAO,CAAC,OAAO;IAAM,OAAO,CAAC,WAAW;
|
|
1
|
+
{"version":3,"file":"metadata_validator.d.ts","sourceRoot":"","sources":["../../../src/msg_validators/tx_validator/metadata_validator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,0BAA0B,CAAC;AAEnD,OAAO,EAAE,KAAK,KAAK,EAAM,KAAK,kBAAkB,EAAE,KAAK,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE7F,qBAAa,mBAAmB,CAAC,CAAC,SAAS,KAAK,CAAE,YAAW,WAAW,CAAC,CAAC,CAAC;;IAG7D,OAAO,CAAC,OAAO;IAAM,OAAO,CAAC,aAAa;IAAM,OAAO,CAAC,WAAW;gBAA3D,OAAO,EAAE,EAAE,EAAU,aAAa,EAAE,EAAE,EAAU,WAAW,EAAE,EAAE;IAE7E,UAAU,CAAC,EAAE,EAAE,CAAC,GAAG,OAAO,CAAC,kBAAkB,CAAC;CAsDrD"}
|
|
@@ -2,10 +2,12 @@ import { createLogger } from '@aztec/foundation/log';
|
|
|
2
2
|
import { Tx } from '@aztec/stdlib/tx';
|
|
3
3
|
export class MetadataTxValidator {
|
|
4
4
|
chainId;
|
|
5
|
+
rollupVersion;
|
|
5
6
|
blockNumber;
|
|
6
7
|
#log;
|
|
7
|
-
constructor(chainId, blockNumber){
|
|
8
|
+
constructor(chainId, rollupVersion, blockNumber){
|
|
8
9
|
this.chainId = chainId;
|
|
10
|
+
this.rollupVersion = rollupVersion;
|
|
9
11
|
this.blockNumber = blockNumber;
|
|
10
12
|
this.#log = createLogger('p2p:tx_validator:tx_metadata');
|
|
11
13
|
}
|
|
@@ -14,6 +16,9 @@ export class MetadataTxValidator {
|
|
|
14
16
|
if (!await this.#hasCorrectChainId(tx)) {
|
|
15
17
|
errors.push('Incorrect chain id');
|
|
16
18
|
}
|
|
19
|
+
if (!await this.#hasCorrectRollupVersion(tx)) {
|
|
20
|
+
errors.push('Incorrect rollup version');
|
|
21
|
+
}
|
|
17
22
|
if (!await this.#isValidForBlockNumber(tx)) {
|
|
18
23
|
errors.push('Invalid block number');
|
|
19
24
|
}
|
|
@@ -41,4 +46,12 @@ export class MetadataTxValidator {
|
|
|
41
46
|
return true;
|
|
42
47
|
}
|
|
43
48
|
}
|
|
49
|
+
async #hasCorrectRollupVersion(tx) {
|
|
50
|
+
if (!tx.data.constants.txContext.version.equals(this.rollupVersion)) {
|
|
51
|
+
this.#log.warn(`Rejecting tx ${await Tx.getHash(tx)} because of incorrect rollup version ${tx.data.constants.txContext.version.toNumber()} != ${this.rollupVersion.toNumber()}`);
|
|
52
|
+
return false;
|
|
53
|
+
} else {
|
|
54
|
+
return true;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
44
57
|
}
|
|
@@ -39,6 +39,7 @@ export declare class LibP2PService<T extends P2PClientType> extends WithTracer i
|
|
|
39
39
|
* @returns The attestation for the block, if any.
|
|
40
40
|
*/
|
|
41
41
|
private blockReceivedCallback;
|
|
42
|
+
private gossipSubEventHandler;
|
|
42
43
|
constructor(clientType: T, config: P2PConfig, node: PubSubLibp2p, peerDiscoveryService: PeerDiscoveryService, mempools: MemPools<T>, l2BlockSource: L2BlockSource, epochCache: EpochCacheInterface, proofVerifier: ClientProtocolCircuitVerifier, worldStateSynchronizer: WorldStateSynchronizer, telemetry: TelemetryClient, logger?: import("@aztec/foundation/log").Logger);
|
|
43
44
|
/**
|
|
44
45
|
* Creates an instance of the LibP2P service.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"libp2p_service.d.ts","sourceRoot":"","sources":["../../../src/services/libp2p/libp2p_service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAK9D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACzD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,KAAK,EAAE,6BAA6B,EAAE,QAAQ,EAAE,sBAAsB,EAAE,MAAM,iCAAiC,CAAC;AACvH,OAAO,EACL,gBAAgB,EAChB,aAAa,EACb,KAAK,UAAU,EACf,aAAa,EAKd,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EAAkC,KAAK,eAAe,EAAE,UAAU,EAAa,MAAM,yBAAyB,CAAC;AAEtH,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAC;AAa1C,OAAO,EAAgB,KAAK,MAAM,EAAwB,MAAM,mBAAmB,CAAC;AAEpF,OAAO,iBAAiB,CAAC;AAKzB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AAS7D,OAAO,EAAE,KAAK,YAAY,EAAsB,MAAM,eAAe,CAAC;AAMtE,OAAO,EAAmC,kBAAkB,EAAE,KAAK,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAGnH,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAChD,OAAO,KAAK,EAAE,UAAU,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAiBtE;;GAEG;AACH,qBAAa,aAAa,CAAC,CAAC,SAAS,aAAa,CAAE,SAAQ,UAAW,YAAW,UAAU;
|
|
1
|
+
{"version":3,"file":"libp2p_service.d.ts","sourceRoot":"","sources":["../../../src/services/libp2p/libp2p_service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAK9D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACzD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,KAAK,EAAE,6BAA6B,EAAE,QAAQ,EAAE,sBAAsB,EAAE,MAAM,iCAAiC,CAAC;AACvH,OAAO,EACL,gBAAgB,EAChB,aAAa,EACb,KAAK,UAAU,EACf,aAAa,EAKd,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EAAkC,KAAK,eAAe,EAAE,UAAU,EAAa,MAAM,yBAAyB,CAAC;AAEtH,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAC;AAa1C,OAAO,EAAgB,KAAK,MAAM,EAAwB,MAAM,mBAAmB,CAAC;AAEpF,OAAO,iBAAiB,CAAC;AAKzB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AAS7D,OAAO,EAAE,KAAK,YAAY,EAAsB,MAAM,eAAe,CAAC;AAMtE,OAAO,EAAmC,kBAAkB,EAAE,KAAK,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAGnH,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAChD,OAAO,KAAK,EAAE,UAAU,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAiBtE;;GAEG;AACH,qBAAa,aAAa,CAAC,CAAC,SAAS,aAAa,CAAE,SAAQ,UAAW,YAAW,UAAU;IAyBxF,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,IAAI;IACZ,OAAO,CAAC,oBAAoB;IAC5B,OAAO,CAAC,QAAQ;IAChB,OAAO,CAAC,aAAa;IAErB,OAAO,CAAC,aAAa;IACrB,OAAO,CAAC,sBAAsB;IAE9B,OAAO,CAAC,MAAM;IAlChB,OAAO,CAAC,QAAQ,CAAkC;IAClD,OAAO,CAAC,WAAW,CAAc;IACjC,OAAO,CAAC,uBAAuB,CAAC,CAAiB;IAGjD,OAAO,CAAC,oBAAoB,CAAuB;IACnD,OAAO,CAAC,sBAAsB,CAAyB;IAGhD,OAAO,EAAE,OAAO,CAAC;IAGxB,OAAO,CAAC,eAAe,CAAgB;IAEvC;;;;OAIG;IACH,OAAO,CAAC,qBAAqB,CAAkE;IAE/F,OAAO,CAAC,qBAAqB,CAA6C;gBAGhE,UAAU,EAAE,CAAC,EACb,MAAM,EAAE,SAAS,EACjB,IAAI,EAAE,YAAY,EAClB,oBAAoB,EAAE,oBAAoB,EAC1C,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,EACrB,aAAa,EAAE,aAAa,EACpC,UAAU,EAAE,mBAAmB,EACvB,aAAa,EAAE,6BAA6B,EAC5C,sBAAsB,EAAE,sBAAsB,EACtD,SAAS,EAAE,eAAe,EAClB,MAAM,yCAAqC;IAqCrD;;;;;OAKG;WACiB,GAAG,CAAC,CAAC,SAAS,aAAa,EAC7C,UAAU,EAAE,CAAC,EACb,MAAM,EAAE,SAAS,EACjB,oBAAoB,EAAE,oBAAoB,EAC1C,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,EACrB,aAAa,EAAE,aAAa,EAC5B,UAAU,EAAE,mBAAmB,EAC/B,aAAa,EAAE,6BAA6B,EAC5C,sBAAsB,EAAE,sBAAsB,EAC9C,KAAK,EAAE,iBAAiB,EACxB,SAAS,EAAE,eAAe,EAC1B,MAAM,yCAAqC;IAwH7C;;;OAGG;IACU,KAAK;IAgElB;;;OAGG;IACU,IAAI;IAqBV,QAAQ,CAAC,cAAc,CAAC,EAAE,OAAO,GAAG,QAAQ,EAAE;IAIrD,OAAO,CAAC,oBAAoB;IAa5B;;;;;;;;;OASG;IACH,WAAW,CAAC,WAAW,SAAS,kBAAkB,EAChD,QAAQ,EAAE,WAAW,EACrB,OAAO,EAAE,YAAY,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC,SAAS,CAAC,CAAC,GAC5D,OAAO,CAAC,YAAY,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC,UAAU,CAAC,CAAC,GAAG,SAAS,CAAC;IAI7E;;;;;OAKG;IACH,gBAAgB,CAAC,WAAW,SAAS,kBAAkB,EACrD,QAAQ,EAAE,WAAW,EACrB,QAAQ,EAAE,YAAY,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,GAC/D,OAAO,CAAC,YAAY,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC,UAAU,CAAC,CAAC,EAAE,GAAG,SAAS,CAAC;IAI/E;;;OAGG;IACI,MAAM,IAAI,GAAG,GAAG,SAAS;IAIzB,6BAA6B,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,OAAO,CAAC,gBAAgB,GAAG,SAAS,CAAC;IAK9G;;;OAGG;IACH,OAAO,CAAC,gBAAgB;IAOxB;;;;;OAKG;YACW,cAAc;IAS5B;;;;OAIG;YACW,sBAAsB;YActB,uBAAuB;YAoBvB,gBAAgB;IAiB9B;;;;;OAKG;YACW,0BAA0B;YA+B1B,oBAAoB;YAyBpB,yBAAyB;IA4BvC;;;OAGG;YAOW,oBAAoB;IAIlC;;;OAGG;IACU,SAAS,CAAC,CAAC,SAAS,UAAU,EAAE,OAAO,EAAE,CAAC;IAYvD;;;;;;;;;;;;;OAaG;YAIW,mBAAmB;YAuBnB,oBAAoB;IAoBlC;;;;;;;;OAQG;IACH,OAAO,CAAC,uBAAuB;IA+B/B;;;;;OAKG;YACW,cAAc;IA8B5B;;;;;;;;;;OAUG;YACW,wBAAwB;IAuBtC;;;;;OAKG;IAOU,mBAAmB,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,gBAAgB,GAAG,OAAO,CAAC,OAAO,CAAC;IAUjG;;;;;OAKG;IAIU,qBAAqB,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,OAAO,CAAC;IAUnF,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;YAI7B,WAAW;YAcX,UAAU;CAYzB"}
|
|
@@ -64,6 +64,7 @@ import { ReqResp } from '../reqresp/reqresp.js';
|
|
|
64
64
|
* @param block - The block received from the peer.
|
|
65
65
|
* @returns The attestation for the block, if any.
|
|
66
66
|
*/ blockReceivedCallback;
|
|
67
|
+
gossipSubEventHandler;
|
|
67
68
|
constructor(clientType, config, node, peerDiscoveryService, mempools, l2BlockSource, epochCache, proofVerifier, worldStateSynchronizer, telemetry, logger = createLogger('p2p:libp2p_service')){
|
|
68
69
|
super(telemetry, 'LibP2PService'), this.clientType = clientType, this.config = config, this.node = node, this.peerDiscoveryService = peerDiscoveryService, this.mempools = mempools, this.l2BlockSource = l2BlockSource, this.proofVerifier = proofVerifier, this.worldStateSynchronizer = worldStateSynchronizer, this.logger = logger, this.jobQueue = new SerialQueue(), this.trustedPeersIds = [];
|
|
69
70
|
const peerScoring = new PeerScoring(config);
|
|
@@ -76,6 +77,7 @@ import { ReqResp } from '../reqresp/reqresp.js';
|
|
|
76
77
|
this.node.services.pubsub.score.params.appSpecificWeight = 10;
|
|
77
78
|
this.attestationValidator = new AttestationValidator(epochCache);
|
|
78
79
|
this.blockProposalValidator = new BlockProposalValidator(epochCache);
|
|
80
|
+
this.gossipSubEventHandler = this.handleGossipSubEvent.bind(this);
|
|
79
81
|
this.blockReceivedCallback = async (block)=>{
|
|
80
82
|
this.logger.debug(`Handler not yet registered: Block received callback not set. Received block for slot ${block.slotNumber.toNumber()} from peer.`, {
|
|
81
83
|
p2pMessageIdentifier: await block.p2pMessageIdentifier()
|
|
@@ -230,7 +232,7 @@ import { ReqResp } from '../reqresp/reqresp.js';
|
|
|
230
232
|
[ReqRespSubProtocol.BLOCK]: blockHandler.bind(this)
|
|
231
233
|
};
|
|
232
234
|
// add GossipSub listener
|
|
233
|
-
this.node.services.pubsub.addEventListener(GossipSubEvent.MESSAGE, this.
|
|
235
|
+
this.node.services.pubsub.addEventListener(GossipSubEvent.MESSAGE, this.gossipSubEventHandler);
|
|
234
236
|
// Start running promise for peer discovery
|
|
235
237
|
this.discoveryRunningPromise = new RunningPromise(()=>this.peerManager.heartbeat(), this.logger, this.config.peerCheckIntervalMS);
|
|
236
238
|
this.discoveryRunningPromise.start();
|
|
@@ -253,7 +255,7 @@ import { ReqResp } from '../reqresp/reqresp.js';
|
|
|
253
255
|
* @returns An empty promise.
|
|
254
256
|
*/ async stop() {
|
|
255
257
|
// Remove gossip sub listener
|
|
256
|
-
this.node.services.pubsub.removeEventListener(GossipSubEvent.MESSAGE, this.
|
|
258
|
+
this.node.services.pubsub.removeEventListener(GossipSubEvent.MESSAGE, this.gossipSubEventHandler);
|
|
257
259
|
// Stop peer manager
|
|
258
260
|
this.logger.debug('Stopping peer manager...');
|
|
259
261
|
await this.peerManager.stop();
|
|
@@ -537,7 +539,7 @@ import { ReqResp } from '../reqresp/reqresp.js';
|
|
|
537
539
|
severity: PeerErrorSeverity.HighToleranceError
|
|
538
540
|
},
|
|
539
541
|
metadataValidator: {
|
|
540
|
-
validator: new MetadataTxValidator(new Fr(this.config.l1ChainId), new Fr(blockNumber)),
|
|
542
|
+
validator: new MetadataTxValidator(new Fr(this.config.l1ChainId), new Fr(this.config.rollupVersion), new Fr(blockNumber)),
|
|
541
543
|
severity: PeerErrorSeverity.HighToleranceError
|
|
542
544
|
},
|
|
543
545
|
proofValidator: {
|
|
@@ -30,10 +30,10 @@ import { convertToMultiaddr, createLibP2PPeerIdFromPrivateKey } from '../util.js
|
|
|
30
30
|
start,
|
|
31
31
|
addresses: {
|
|
32
32
|
listen: [
|
|
33
|
-
`/ip4/
|
|
33
|
+
`/ip4/127.0.0.1/tcp/${port}`
|
|
34
34
|
],
|
|
35
35
|
announce: [
|
|
36
|
-
`/ip4/
|
|
36
|
+
`/ip4/127.0.0.1/tcp/${port}`
|
|
37
37
|
]
|
|
38
38
|
},
|
|
39
39
|
connectionEncryption: [
|
|
@@ -173,7 +173,7 @@ export function createBootstrapNodeConfig(privateKey, port, chainConfig) {
|
|
|
173
173
|
dataDirectory: undefined,
|
|
174
174
|
dataStoreMapSizeKB: 0,
|
|
175
175
|
bootstrapNodes: [],
|
|
176
|
-
listenAddress: '
|
|
176
|
+
listenAddress: '127.0.0.1'
|
|
177
177
|
};
|
|
178
178
|
}
|
|
179
179
|
export function createBootstrapNodeFromPrivateKey(privateKey, port, telemetry = getTelemetryClient(), chainConfig = emptyChainConfig) {
|
|
@@ -11,7 +11,7 @@ const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
|
11
11
|
const workerPath = path.join(__dirname, '../../dest/testbench/p2p_client_testbench_worker.js');
|
|
12
12
|
const testChainConfig = {
|
|
13
13
|
l1ChainId: 31337,
|
|
14
|
-
|
|
14
|
+
rollupVersion: 1,
|
|
15
15
|
l1Contracts: {
|
|
16
16
|
rollupAddress: EthAddress.random()
|
|
17
17
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aztec/p2p",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.83.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": "./dest/index.js",
|
|
@@ -65,14 +65,14 @@
|
|
|
65
65
|
]
|
|
66
66
|
},
|
|
67
67
|
"dependencies": {
|
|
68
|
-
"@aztec/constants": "0.
|
|
69
|
-
"@aztec/epoch-cache": "0.
|
|
70
|
-
"@aztec/foundation": "0.
|
|
71
|
-
"@aztec/kv-store": "0.
|
|
72
|
-
"@aztec/noir-protocol-circuits-types": "0.
|
|
73
|
-
"@aztec/protocol-contracts": "0.
|
|
74
|
-
"@aztec/stdlib": "0.
|
|
75
|
-
"@aztec/telemetry-client": "0.
|
|
68
|
+
"@aztec/constants": "0.83.0",
|
|
69
|
+
"@aztec/epoch-cache": "0.83.0",
|
|
70
|
+
"@aztec/foundation": "0.83.0",
|
|
71
|
+
"@aztec/kv-store": "0.83.0",
|
|
72
|
+
"@aztec/noir-protocol-circuits-types": "0.83.0",
|
|
73
|
+
"@aztec/protocol-contracts": "0.83.0",
|
|
74
|
+
"@aztec/stdlib": "0.83.0",
|
|
75
|
+
"@aztec/telemetry-client": "0.83.0",
|
|
76
76
|
"@chainsafe/discv5": "9.0.0",
|
|
77
77
|
"@chainsafe/enr": "3.0.0",
|
|
78
78
|
"@chainsafe/libp2p-gossipsub": "13.0.0",
|
|
@@ -101,7 +101,7 @@
|
|
|
101
101
|
"xxhash-wasm": "^1.1.0"
|
|
102
102
|
},
|
|
103
103
|
"devDependencies": {
|
|
104
|
-
"@aztec/archiver": "0.
|
|
104
|
+
"@aztec/archiver": "0.83.0",
|
|
105
105
|
"@jest/globals": "^29.5.0",
|
|
106
106
|
"@types/jest": "^29.5.0",
|
|
107
107
|
"@types/node": "^18.14.6",
|
package/src/client/p2p_client.ts
CHANGED
|
@@ -295,12 +295,12 @@ export class P2PClient<T extends P2PClientType = P2PClientType.Full>
|
|
|
295
295
|
break;
|
|
296
296
|
case 'chain-proven': {
|
|
297
297
|
const from = (await this.getSyncedProvenBlockNum()) + 1;
|
|
298
|
-
const limit = event.
|
|
298
|
+
const limit = event.block.number - from + 1;
|
|
299
299
|
await this.handleProvenL2Blocks(await this.l2BlockSource.getBlocks(from, limit));
|
|
300
300
|
break;
|
|
301
301
|
}
|
|
302
302
|
case 'chain-pruned':
|
|
303
|
-
await this.handlePruneL2Blocks(event.
|
|
303
|
+
await this.handlePruneL2Blocks(event.block.number);
|
|
304
304
|
break;
|
|
305
305
|
default: {
|
|
306
306
|
const _: never = event;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createLogger } from '@aztec/foundation/log';
|
|
2
|
-
import { type AnyTx, Tx, type TxValidationResult, type TxValidator
|
|
2
|
+
import { type AnyTx, Tx, type TxValidationResult, type TxValidator } from '@aztec/stdlib/tx';
|
|
3
3
|
|
|
4
4
|
export interface NullifierSource {
|
|
5
5
|
nullifiersExist: (nullifiers: Buffer[]) => Promise<boolean[]>;
|
|
@@ -14,25 +14,20 @@ export class DoubleSpendTxValidator<T extends AnyTx> implements TxValidator<T> {
|
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
async validateTx(tx: T): Promise<TxValidationResult> {
|
|
17
|
-
|
|
18
|
-
// because the AVM will perform merkle insertions as it goes and will fail on
|
|
19
|
-
// duplicate nullifier. In fact we CANNOT check here because the nullifiers
|
|
20
|
-
// have already been inserted, and so they will exist in nullifierSource.
|
|
21
|
-
if (!hasPublicCalls(tx)) {
|
|
22
|
-
const nullifiers = tx instanceof Tx ? tx.data.getNonEmptyNullifiers() : tx.txEffect.nullifiers;
|
|
17
|
+
const nullifiers = tx instanceof Tx ? tx.data.getNonEmptyNullifiers() : tx.txEffect.nullifiers;
|
|
23
18
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
19
|
+
// Ditch this tx if it has repeated nullifiers
|
|
20
|
+
const uniqueNullifiers = new Set(nullifiers);
|
|
21
|
+
if (uniqueNullifiers.size !== nullifiers.length) {
|
|
22
|
+
this.#log.warn(`Rejecting tx ${await Tx.getHash(tx)} for emitting duplicate nullifiers`);
|
|
23
|
+
return { result: 'invalid', reason: ['Duplicate nullifier in tx'] };
|
|
24
|
+
}
|
|
30
25
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
}
|
|
26
|
+
if ((await this.#nullifierSource.nullifiersExist(nullifiers.map(n => n.toBuffer()))).some(Boolean)) {
|
|
27
|
+
this.#log.warn(`Rejecting tx ${await Tx.getHash(tx)} for repeating a nullifier`);
|
|
28
|
+
return { result: 'invalid', reason: ['Existing nullifier'] };
|
|
35
29
|
}
|
|
30
|
+
|
|
36
31
|
return { result: 'valid' };
|
|
37
32
|
}
|
|
38
33
|
}
|
|
@@ -5,13 +5,16 @@ import { type AnyTx, Tx, type TxValidationResult, type TxValidator } from '@azte
|
|
|
5
5
|
export class MetadataTxValidator<T extends AnyTx> implements TxValidator<T> {
|
|
6
6
|
#log = createLogger('p2p:tx_validator:tx_metadata');
|
|
7
7
|
|
|
8
|
-
constructor(private chainId: Fr, private blockNumber: Fr) {}
|
|
8
|
+
constructor(private chainId: Fr, private rollupVersion: Fr, private blockNumber: Fr) {}
|
|
9
9
|
|
|
10
10
|
async validateTx(tx: T): Promise<TxValidationResult> {
|
|
11
11
|
const errors = [];
|
|
12
12
|
if (!(await this.#hasCorrectChainId(tx))) {
|
|
13
13
|
errors.push('Incorrect chain id');
|
|
14
14
|
}
|
|
15
|
+
if (!(await this.#hasCorrectRollupVersion(tx))) {
|
|
16
|
+
errors.push('Incorrect rollup version');
|
|
17
|
+
}
|
|
15
18
|
if (!(await this.#isValidForBlockNumber(tx))) {
|
|
16
19
|
errors.push('Invalid block number');
|
|
17
20
|
}
|
|
@@ -45,4 +48,17 @@ export class MetadataTxValidator<T extends AnyTx> implements TxValidator<T> {
|
|
|
45
48
|
return true;
|
|
46
49
|
}
|
|
47
50
|
}
|
|
51
|
+
|
|
52
|
+
async #hasCorrectRollupVersion(tx: T): Promise<boolean> {
|
|
53
|
+
if (!tx.data.constants.txContext.version.equals(this.rollupVersion)) {
|
|
54
|
+
this.#log.warn(
|
|
55
|
+
`Rejecting tx ${await Tx.getHash(
|
|
56
|
+
tx,
|
|
57
|
+
)} because of incorrect rollup version ${tx.data.constants.txContext.version.toNumber()} != ${this.rollupVersion.toNumber()}`,
|
|
58
|
+
);
|
|
59
|
+
return false;
|
|
60
|
+
} else {
|
|
61
|
+
return true;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
48
64
|
}
|
|
@@ -102,6 +102,8 @@ export class LibP2PService<T extends P2PClientType> extends WithTracer implement
|
|
|
102
102
|
*/
|
|
103
103
|
private blockReceivedCallback: (block: BlockProposal) => Promise<BlockAttestation | undefined>;
|
|
104
104
|
|
|
105
|
+
private gossipSubEventHandler: (e: CustomEvent<GossipsubMessage>) => void;
|
|
106
|
+
|
|
105
107
|
constructor(
|
|
106
108
|
private clientType: T,
|
|
107
109
|
private config: P2PConfig,
|
|
@@ -139,6 +141,8 @@ export class LibP2PService<T extends P2PClientType> extends WithTracer implement
|
|
|
139
141
|
this.attestationValidator = new AttestationValidator(epochCache);
|
|
140
142
|
this.blockProposalValidator = new BlockProposalValidator(epochCache);
|
|
141
143
|
|
|
144
|
+
this.gossipSubEventHandler = this.handleGossipSubEvent.bind(this);
|
|
145
|
+
|
|
142
146
|
this.blockReceivedCallback = async (block: BlockProposal): Promise<BlockAttestation | undefined> => {
|
|
143
147
|
this.logger.debug(
|
|
144
148
|
`Handler not yet registered: Block received callback not set. Received block for slot ${block.slotNumber.toNumber()} from peer.`,
|
|
@@ -329,7 +333,7 @@ export class LibP2PService<T extends P2PClientType> extends WithTracer implement
|
|
|
329
333
|
};
|
|
330
334
|
|
|
331
335
|
// add GossipSub listener
|
|
332
|
-
this.node.services.pubsub.addEventListener(GossipSubEvent.MESSAGE, this.
|
|
336
|
+
this.node.services.pubsub.addEventListener(GossipSubEvent.MESSAGE, this.gossipSubEventHandler);
|
|
333
337
|
|
|
334
338
|
// Start running promise for peer discovery
|
|
335
339
|
this.discoveryRunningPromise = new RunningPromise(
|
|
@@ -360,7 +364,7 @@ export class LibP2PService<T extends P2PClientType> extends WithTracer implement
|
|
|
360
364
|
*/
|
|
361
365
|
public async stop() {
|
|
362
366
|
// Remove gossip sub listener
|
|
363
|
-
this.node.services.pubsub.removeEventListener(GossipSubEvent.MESSAGE, this.
|
|
367
|
+
this.node.services.pubsub.removeEventListener(GossipSubEvent.MESSAGE, this.gossipSubEventHandler);
|
|
364
368
|
|
|
365
369
|
// Stop peer manager
|
|
366
370
|
this.logger.debug('Stopping peer manager...');
|
|
@@ -717,7 +721,11 @@ export class LibP2PService<T extends P2PClientType> extends WithTracer implement
|
|
|
717
721
|
severity: PeerErrorSeverity.HighToleranceError,
|
|
718
722
|
},
|
|
719
723
|
metadataValidator: {
|
|
720
|
-
validator: new MetadataTxValidator(
|
|
724
|
+
validator: new MetadataTxValidator(
|
|
725
|
+
new Fr(this.config.l1ChainId),
|
|
726
|
+
new Fr(this.config.rollupVersion),
|
|
727
|
+
new Fr(blockNumber),
|
|
728
|
+
),
|
|
721
729
|
severity: PeerErrorSeverity.HighToleranceError,
|
|
722
730
|
},
|
|
723
731
|
proofValidator: {
|
|
@@ -55,8 +55,8 @@ export async function createLibp2pNode(
|
|
|
55
55
|
const options: Libp2pOptions = {
|
|
56
56
|
start,
|
|
57
57
|
addresses: {
|
|
58
|
-
listen: [`/ip4/
|
|
59
|
-
announce: [`/ip4/
|
|
58
|
+
listen: [`/ip4/127.0.0.1/tcp/${port}`],
|
|
59
|
+
announce: [`/ip4/127.0.0.1/tcp/${port}`],
|
|
60
60
|
},
|
|
61
61
|
connectionEncryption: [noise()],
|
|
62
62
|
streamMuxers: [yamux()],
|
|
@@ -239,7 +239,7 @@ export function createBootstrapNodeConfig(privateKey: string, port: number, chai
|
|
|
239
239
|
dataDirectory: undefined,
|
|
240
240
|
dataStoreMapSizeKB: 0,
|
|
241
241
|
bootstrapNodes: [],
|
|
242
|
-
listenAddress: '
|
|
242
|
+
listenAddress: '127.0.0.1',
|
|
243
243
|
};
|
|
244
244
|
}
|
|
245
245
|
|