@aztec/p2p 0.85.0-alpha-testnet.7 → 0.85.0-alpha-testnet.9
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/msg_validators/tx_validator/block_header_validator.js +1 -1
- package/dest/msg_validators/tx_validator/double_spend_validator.js +2 -2
- package/dest/msg_validators/tx_validator/gas_validator.js +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/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 +40 -20
- package/dest/services/reqresp/reqresp.d.ts +1 -1
- package/dest/services/reqresp/reqresp.d.ts.map +1 -1
- package/dest/services/reqresp/reqresp.js +2 -2
- package/package.json +12 -12
- package/src/msg_validators/tx_validator/block_header_validator.ts +1 -1
- package/src/msg_validators/tx_validator/double_spend_validator.ts +2 -2
- package/src/msg_validators/tx_validator/gas_validator.ts +1 -1
- package/src/services/peer-manager/peer_manager.ts +18 -1
- package/src/services/reqresp/connection-sampler/connection_sampler.ts +41 -18
- package/src/services/reqresp/reqresp.ts +2 -1
|
@@ -11,7 +11,7 @@ export class BlockHeaderTxValidator {
|
|
|
11
11
|
await tx.data.constants.historicalHeader.hash()
|
|
12
12
|
]);
|
|
13
13
|
if (index === undefined) {
|
|
14
|
-
this.#log.
|
|
14
|
+
this.#log.debug(`Rejecting tx ${await Tx.getHash(tx)} for referencing an unknown block header`);
|
|
15
15
|
return {
|
|
16
16
|
result: 'invalid',
|
|
17
17
|
reason: [
|
|
@@ -11,7 +11,7 @@ export class DoubleSpendTxValidator {
|
|
|
11
11
|
// Ditch this tx if it has repeated nullifiers
|
|
12
12
|
const uniqueNullifiers = new Set(nullifiers);
|
|
13
13
|
if (uniqueNullifiers.size !== nullifiers.length) {
|
|
14
|
-
this.#log.
|
|
14
|
+
this.#log.debug(`Rejecting tx ${await Tx.getHash(tx)} for emitting duplicate nullifiers`);
|
|
15
15
|
return {
|
|
16
16
|
result: 'invalid',
|
|
17
17
|
reason: [
|
|
@@ -20,7 +20,7 @@ export class DoubleSpendTxValidator {
|
|
|
20
20
|
};
|
|
21
21
|
}
|
|
22
22
|
if ((await this.#nullifierSource.nullifiersExist(nullifiers.map((n)=>n.toBuffer()))).some(Boolean)) {
|
|
23
|
-
this.#log.
|
|
23
|
+
this.#log.debug(`Rejecting tx ${await Tx.getHash(tx)} for repeating a nullifier`);
|
|
24
24
|
return {
|
|
25
25
|
result: 'invalid',
|
|
26
26
|
reason: [
|
|
@@ -41,7 +41,7 @@ export class GasTxValidator {
|
|
|
41
41
|
const maxFeesPerGas = gasSettings.maxFeesPerGas;
|
|
42
42
|
const notEnoughMaxFees = maxFeesPerGas.feePerDaGas.lt(this.#gasFees.feePerDaGas) || maxFeesPerGas.feePerL2Gas.lt(this.#gasFees.feePerL2Gas);
|
|
43
43
|
if (notEnoughMaxFees) {
|
|
44
|
-
this.#log.
|
|
44
|
+
this.#log.debug(`Skipping transaction ${await tx.getTxHash()} due to insufficient fee per gas`, {
|
|
45
45
|
txMaxFeesPerGas: maxFeesPerGas.toInspect(),
|
|
46
46
|
currentGasFees: this.#gasFees.toInspect()
|
|
47
47
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"peer_manager.d.ts","sourceRoot":"","sources":["../../../src/services/peer-manager/peer_manager.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iCAAiC,CAAC;AAChE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAC3D,OAAO,EAAE,KAAK,eAAe,EAAa,MAAM,yBAAyB,CAAC;AAG1E,OAAO,KAAK,EAAc,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAI5D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAEjD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAElD,OAAO,EAAE,aAAa,EAAuB,MAAM,iCAAiC,CAAC;AACrF,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"peer_manager.d.ts","sourceRoot":"","sources":["../../../src/services/peer-manager/peer_manager.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iCAAiC,CAAC;AAChE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAC3D,OAAO,EAAE,KAAK,eAAe,EAAa,MAAM,yBAAyB,CAAC;AAG1E,OAAO,KAAK,EAAc,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAI5D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAEjD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAElD,OAAO,EAAE,aAAa,EAAuB,MAAM,iCAAiC,CAAC;AACrF,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAErD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAE1D,OAAO,EAAkB,KAAK,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAqBrE,qBAAa,WAAW;IAgBpB,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,oBAAoB;IAC5B,OAAO,CAAC,MAAM;IAEd,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,WAAW;IACnB,OAAO,CAAC,OAAO;IArBjB,OAAO,CAAC,WAAW,CAAsC;IACzD,OAAO,CAAC,gBAAgB,CAAa;IACrC,OAAO,CAAC,8BAA8B,CAAa;IACnD,OAAO,CAAC,aAAa,CAAwC;IAC7D,OAAO,CAAC,YAAY,CAA0B;IAC9C,OAAO,CAAC,uBAAuB,CAAkB;IAEjD,OAAO,CAAC,OAAO,CAAqB;IACpC,OAAO,CAAC,QAAQ,CAId;gBAGQ,UAAU,EAAE,YAAY,EACxB,oBAAoB,EAAE,oBAAoB,EAC1C,MAAM,EAAE,SAAS,EACzB,eAAe,EAAE,eAAe,EACxB,MAAM,wCAAmC,EACzC,WAAW,EAAE,WAAW,EACxB,OAAO,EAAE,OAAO;IAwB1B;;;;OAIG;IACG,sBAAsB;IAU5B,IAAI,MAAM,6CAET;IAGM,SAAS;IAShB;;;;;;OAMG;IACH,OAAO,CAAC,sBAAsB;IAU9B;;;OAGG;IACH,OAAO,CAAC,wBAAwB;IAShC;;;OAGG;IACH,OAAO,CAAC,2BAA2B;IASnC;;;;;OAKG;IACH,OAAO,CAAC,aAAa;IAQrB;;;OAGG;IACI,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAM3C;;;;;;OAMG;IACI,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa;IAQrD,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,iBAAiB;IAIvD,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;IAIpC,QAAQ,CAAC,cAAc,UAAQ,GAAG,QAAQ,EAAE;IAiCnD;;OAEG;IACH,OAAO,CAAC,QAAQ;IAiEhB,OAAO,CAAC,mBAAmB;IAI3B,OAAO,CAAC,mBAAmB;IAwB3B;;;;;OAKG;IACH,OAAO,CAAC,eAAe;IAwBvB;;;;;;;;OAQG;IACH,OAAO,CAAC,mBAAmB;YAuBb,wBAAwB;YA6BxB,cAAc;IAQ5B;;;OAGG;YACW,oBAAoB;YA8DpB,QAAQ;IA2BtB,OAAO,CAAC,cAAc;IAWtB,OAAO,CAAC,gBAAgB;IAsBxB;;;OAGG;IACU,IAAI;CAYlB"}
|
|
@@ -11,12 +11,14 @@ import { inspect } from 'util';
|
|
|
11
11
|
import { PeerEvent } from '../../types/index.js';
|
|
12
12
|
import { ReqRespSubProtocol } from '../reqresp/interface.js';
|
|
13
13
|
import { GoodByeReason, prettyGoodbyeReason } from '../reqresp/protocols/goodbye.js';
|
|
14
|
+
import { ReqRespStatus } from '../reqresp/status.js';
|
|
14
15
|
import { PeerManagerMetrics } from './metrics.js';
|
|
15
16
|
import { PeerScoreState } from './peer_scoring.js';
|
|
16
17
|
const MAX_DIAL_ATTEMPTS = 3;
|
|
17
18
|
const MAX_CACHED_PEERS = 100;
|
|
18
19
|
const MAX_CACHED_PEER_AGE_MS = 5 * 60 * 1000; // 5 minutes
|
|
19
20
|
const FAILED_PEER_BAN_TIME_MS = 5 * 60 * 1000; // 5 minutes timeout after failing MAX_DIAL_ATTEMPTS
|
|
21
|
+
const GOODBYE_DIAL_TIMEOUT_MS = 1000;
|
|
20
22
|
export class PeerManager {
|
|
21
23
|
libP2PNode;
|
|
22
24
|
peerDiscoveryService;
|
|
@@ -311,9 +313,16 @@ export class PeerManager {
|
|
|
311
313
|
this.logger.debug(`Disconnecting peer ${peer.toString()} with reason ${prettyGoodbyeReason(reason)}`);
|
|
312
314
|
this.metrics.recordGoodbyeSent(reason);
|
|
313
315
|
try {
|
|
314
|
-
await this.reqresp.sendRequestToPeer(peer, ReqRespSubProtocol.GOODBYE, Buffer.from([
|
|
316
|
+
const resp = await this.reqresp.sendRequestToPeer(peer, ReqRespSubProtocol.GOODBYE, Buffer.from([
|
|
315
317
|
reason
|
|
316
|
-
]));
|
|
318
|
+
]), GOODBYE_DIAL_TIMEOUT_MS);
|
|
319
|
+
if (resp.status === ReqRespStatus.FAILURE) {
|
|
320
|
+
this.logger.debug(`Failed to send goodbye to peer ${peer.toString()}`);
|
|
321
|
+
} else if (resp.status === ReqRespStatus.SUCCESS) {
|
|
322
|
+
this.logger.verbose(`Sent goodbye to peer ${peer.toString()}`);
|
|
323
|
+
} else {
|
|
324
|
+
this.logger.debug(`Unexpected status sending goodbye to peer ${peer.toString()}: ${ReqRespStatus[resp.status]}`);
|
|
325
|
+
}
|
|
317
326
|
} catch (error) {
|
|
318
327
|
this.logger.debug(`Failed to send goodbye to peer ${peer.toString()}: ${error}`);
|
|
319
328
|
} finally{
|
|
@@ -15,7 +15,7 @@ export declare class ConnectionSampler {
|
|
|
15
15
|
private readonly sampler;
|
|
16
16
|
private readonly logger;
|
|
17
17
|
private cleanupInterval;
|
|
18
|
-
private
|
|
18
|
+
private dialAttempts;
|
|
19
19
|
private readonly activeConnectionsCount;
|
|
20
20
|
private readonly streams;
|
|
21
21
|
private dialQueue;
|
|
@@ -62,7 +62,7 @@ export declare class ConnectionSampler {
|
|
|
62
62
|
* @param protocol - The protocol
|
|
63
63
|
* @returns The stream
|
|
64
64
|
*/
|
|
65
|
-
dialProtocol(peerId: PeerId, protocol: string): Promise<Stream>;
|
|
65
|
+
dialProtocol(peerId: PeerId, protocol: string, timeout?: number): Promise<Stream>;
|
|
66
66
|
/**
|
|
67
67
|
* Closes a stream and updates the active connections count
|
|
68
68
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"connection_sampler.d.ts","sourceRoot":"","sources":["../../../../src/services/reqresp/connection-sampler/connection_sampler.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAShE,qBAAa,aAAa;IACxB,MAAM,CAAC,GAAG,EAAE,MAAM;CAGnB;AAED;;;;;;GAMG;AACH,qBAAa,iBAAiB;IAY1B,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAClC,OAAO,CAAC,QAAQ,CAAC,OAAO;IAb1B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAkD;IACzE,OAAO,CAAC,eAAe,CAAiB;IACxC,OAAO,CAAC,
|
|
1
|
+
{"version":3,"file":"connection_sampler.d.ts","sourceRoot":"","sources":["../../../../src/services/reqresp/connection-sampler/connection_sampler.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAShE,qBAAa,aAAa;IACxB,MAAM,CAAC,GAAG,EAAE,MAAM;CAGnB;AAED;;;;;;GAMG;AACH,qBAAa,iBAAiB;IAY1B,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAClC,OAAO,CAAC,QAAQ,CAAC,OAAO;IAb1B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAkD;IACzE,OAAO,CAAC,eAAe,CAAiB;IACxC,OAAO,CAAC,YAAY,CAAyB;IAE7C,OAAO,CAAC,QAAQ,CAAC,sBAAsB,CAAkC;IACzE,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA2C;IAGnE,OAAO,CAAC,SAAS,CAAkC;gBAGhC,MAAM,EAAE,MAAM,EACd,iBAAiB,GAAE,MAAc,EAAE,sBAAsB;IACzD,OAAO,GAAE,aAAmC;IAO/D;;OAEG;IACG,IAAI;IAgBV;;;;;OAKG;IACH,OAAO,CAAC,SAAS,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,GAAG,SAAS;IAO7D;;;;;;;;;;;OAWG;IACH,eAAe,CACb,KAAK,EAAE,MAAM,EAAE,EACf,SAAS,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,GAC/B;QACD,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;QACzB,YAAY,EAAE,MAAM,EAAE,CAAC;KACxB;IAuCD;;;;;OAKG;IACH,gBAAgB,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM,EAAE;IAyClD;;;;;;OAMG;IACG,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAwCvF;;;;OAIG;IACG,KAAK,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA4B5C;;OAEG;YACW,uBAAuB;CAetC"}
|
|
@@ -18,7 +18,7 @@ export class RandomSampler {
|
|
|
18
18
|
sampler;
|
|
19
19
|
logger;
|
|
20
20
|
cleanupInterval;
|
|
21
|
-
|
|
21
|
+
dialAttempts;
|
|
22
22
|
activeConnectionsCount;
|
|
23
23
|
streams;
|
|
24
24
|
// Serial queue to ensure that we only dial one peer at a time
|
|
@@ -28,7 +28,7 @@ export class RandomSampler {
|
|
|
28
28
|
this.cleanupIntervalMs = cleanupIntervalMs;
|
|
29
29
|
this.sampler = sampler;
|
|
30
30
|
this.logger = createLogger('p2p:reqresp:connection-sampler');
|
|
31
|
-
this.
|
|
31
|
+
this.dialAttempts = [];
|
|
32
32
|
this.activeConnectionsCount = new Map();
|
|
33
33
|
this.streams = new Map();
|
|
34
34
|
this.dialQueue = new SerialQueue();
|
|
@@ -40,7 +40,10 @@ export class RandomSampler {
|
|
|
40
40
|
*/ async stop() {
|
|
41
41
|
this.logger.info('Stopping connection sampler');
|
|
42
42
|
clearInterval(this.cleanupInterval);
|
|
43
|
-
this.
|
|
43
|
+
for (const attempt of this.dialAttempts){
|
|
44
|
+
attempt.abort();
|
|
45
|
+
}
|
|
46
|
+
this.dialAttempts = [];
|
|
44
47
|
await this.dialQueue.end();
|
|
45
48
|
// Close all active streams
|
|
46
49
|
const closePromises = Array.from(this.streams.keys()).map((streamId)=>this.close(streamId));
|
|
@@ -157,25 +160,42 @@ export class RandomSampler {
|
|
|
157
160
|
* @param peerId - The peer id
|
|
158
161
|
* @param protocol - The protocol
|
|
159
162
|
* @returns The stream
|
|
160
|
-
*/ async dialProtocol(peerId, protocol) {
|
|
163
|
+
*/ async dialProtocol(peerId, protocol, timeout) {
|
|
161
164
|
// Dialling at the same time can cause race conditions where two different streams
|
|
162
165
|
// end up with the same id, hence a serial queue
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
166
|
+
this.logger.debug(`Dial queue length: ${this.dialQueue.length()}`);
|
|
167
|
+
const abortController = new AbortController();
|
|
168
|
+
this.dialAttempts.push(abortController);
|
|
169
|
+
let timeoutHandle;
|
|
170
|
+
if (timeout) {
|
|
171
|
+
timeoutHandle = setTimeout(()=>abortController.abort(), timeout);
|
|
172
|
+
}
|
|
173
|
+
try {
|
|
174
|
+
const stream = await this.dialQueue.put(()=>this.libp2p.dialProtocol(peerId, protocol, {
|
|
175
|
+
signal: abortController.signal
|
|
176
|
+
}));
|
|
177
|
+
this.streams.set(stream.id, {
|
|
178
|
+
stream,
|
|
179
|
+
peerId
|
|
180
|
+
});
|
|
181
|
+
const updatedActiveConnectionsCount = (this.activeConnectionsCount.get(peerId) ?? 0) + 1;
|
|
182
|
+
this.activeConnectionsCount.set(peerId, updatedActiveConnectionsCount);
|
|
183
|
+
this.logger.trace('Dialed protocol', {
|
|
184
|
+
streamId: stream.id,
|
|
185
|
+
protocol,
|
|
186
|
+
peerId: peerId.toString(),
|
|
187
|
+
activeConnectionsCount: updatedActiveConnectionsCount
|
|
188
|
+
});
|
|
189
|
+
return stream;
|
|
190
|
+
} finally{
|
|
191
|
+
if (timeoutHandle) {
|
|
192
|
+
clearTimeout(timeoutHandle);
|
|
193
|
+
}
|
|
194
|
+
const idx = this.dialAttempts.indexOf(abortController);
|
|
195
|
+
if (idx > -1) {
|
|
196
|
+
this.dialAttempts.splice(idx, 1);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
179
199
|
}
|
|
180
200
|
/**
|
|
181
201
|
* Closes a stream and updates the active connections count
|
|
@@ -120,7 +120,7 @@ export declare class ReqResp {
|
|
|
120
120
|
* If the stream is not closed by the dialled peer, and a timeout occurs, then
|
|
121
121
|
* the stream is closed on the requester's end and sender (us) updates its peer score
|
|
122
122
|
*/
|
|
123
|
-
sendRequestToPeer(peerId: PeerId, subProtocol: ReqRespSubProtocol, payload: Buffer): Promise<ReqRespResponse>;
|
|
123
|
+
sendRequestToPeer(peerId: PeerId, subProtocol: ReqRespSubProtocol, payload: Buffer, dialTimeout?: number): Promise<ReqRespResponse>;
|
|
124
124
|
/**
|
|
125
125
|
* Handle a response error
|
|
126
126
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reqresp.d.ts","sourceRoot":"","sources":["../../../src/services/reqresp/reqresp.ts"],"names":[],"mappings":";;AACA,OAAO,EAAE,KAAK,MAAM,EAAgB,MAAM,uBAAuB,CAAC;AAGlE,OAAO,EAAc,KAAK,eAAe,EAAiC,MAAM,yBAAyB,CAAC;AAE1G,OAAO,KAAK,EAAsB,MAAM,EAAU,MAAM,mBAAmB,CAAC;AAE5E,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AASrC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAGpD,OAAO,EAGL,KAAK,eAAe,EACpB,kBAAkB,EAClB,KAAK,0BAA0B,EAC/B,KAAK,4BAA4B,EACjC,KAAK,cAAc,EAEpB,MAAM,gBAAgB,CAAC;AASxB;;;;;;;;;;;;;GAaG;AACH,qBAAa,OAAO;IAmBhB,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,WAAW;IAnBrB,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAElC,OAAO,CAAC,uBAAuB,CAAS;IACxC,OAAO,CAAC,0BAA0B,CAAS;IAG3C,OAAO,CAAC,mBAAmB,CAA6D;IACxF,OAAO,CAAC,qBAAqB,CAAiE;IAE9F,OAAO,CAAC,iBAAiB,CAAoB;IAC7C,OAAO,CAAC,WAAW,CAA6B;IAEhD,OAAO,CAAC,eAAe,CAAkB;IAEzC,OAAO,CAAC,OAAO,CAAiB;gBAG9B,MAAM,EAAE,gBAAgB,EAChB,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,WAAW,EAChC,eAAe,GAAE,eAAsC;IAgBzD,IAAI,MAAM,6CAET;IAED;;OAEG;IACG,KAAK,CAAC,mBAAmB,EAAE,0BAA0B,EAAE,qBAAqB,EAAE,4BAA4B;IAiBhH;;OAEG;IACG,IAAI;IAoBV;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA4BG;IACG,WAAW,CAAC,WAAW,SAAS,kBAAkB,EACtD,WAAW,EAAE,WAAW,EACxB,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;IA8D7E;;;;;;;;;;;;;;;;;;;;;OAqBG;IAQG,gBAAgB,CAAC,WAAW,SAAS,kBAAkB,EAC3D,WAAW,EAAE,WAAW,EACxB,QAAQ,EAAE,YAAY,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,EAChE,SAAS,SAAQ,EACjB,QAAQ,SAA+C,EACvD,gBAAgB,SAAI,GACnB,OAAO,CAAC,CAAC,YAAY,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC,UAAU,CAAC,CAAC,GAAG,SAAS,CAAC,EAAE,CAAC;IA6HjF;;;;;;;;;;;;;;;;;;;;;;;OAuBG;IAKU,iBAAiB,CAC5B,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,kBAAkB,EAC/B,OAAO,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"reqresp.d.ts","sourceRoot":"","sources":["../../../src/services/reqresp/reqresp.ts"],"names":[],"mappings":";;AACA,OAAO,EAAE,KAAK,MAAM,EAAgB,MAAM,uBAAuB,CAAC;AAGlE,OAAO,EAAc,KAAK,eAAe,EAAiC,MAAM,yBAAyB,CAAC;AAE1G,OAAO,KAAK,EAAsB,MAAM,EAAU,MAAM,mBAAmB,CAAC;AAE5E,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AASrC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAGpD,OAAO,EAGL,KAAK,eAAe,EACpB,kBAAkB,EAClB,KAAK,0BAA0B,EAC/B,KAAK,4BAA4B,EACjC,KAAK,cAAc,EAEpB,MAAM,gBAAgB,CAAC;AASxB;;;;;;;;;;;;;GAaG;AACH,qBAAa,OAAO;IAmBhB,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,WAAW;IAnBrB,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAElC,OAAO,CAAC,uBAAuB,CAAS;IACxC,OAAO,CAAC,0BAA0B,CAAS;IAG3C,OAAO,CAAC,mBAAmB,CAA6D;IACxF,OAAO,CAAC,qBAAqB,CAAiE;IAE9F,OAAO,CAAC,iBAAiB,CAAoB;IAC7C,OAAO,CAAC,WAAW,CAA6B;IAEhD,OAAO,CAAC,eAAe,CAAkB;IAEzC,OAAO,CAAC,OAAO,CAAiB;gBAG9B,MAAM,EAAE,gBAAgB,EAChB,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,WAAW,EAChC,eAAe,GAAE,eAAsC;IAgBzD,IAAI,MAAM,6CAET;IAED;;OAEG;IACG,KAAK,CAAC,mBAAmB,EAAE,0BAA0B,EAAE,qBAAqB,EAAE,4BAA4B;IAiBhH;;OAEG;IACG,IAAI;IAoBV;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA4BG;IACG,WAAW,CAAC,WAAW,SAAS,kBAAkB,EACtD,WAAW,EAAE,WAAW,EACxB,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;IA8D7E;;;;;;;;;;;;;;;;;;;;;OAqBG;IAQG,gBAAgB,CAAC,WAAW,SAAS,kBAAkB,EAC3D,WAAW,EAAE,WAAW,EACxB,QAAQ,EAAE,YAAY,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,EAChE,SAAS,SAAQ,EACjB,QAAQ,SAA+C,EACvD,gBAAgB,SAAI,GACnB,OAAO,CAAC,CAAC,YAAY,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC,UAAU,CAAC,CAAC,GAAG,SAAS,CAAC,EAAE,CAAC;IA6HjF;;;;;;;;;;;;;;;;;;;;;;;OAuBG;IAKU,iBAAiB,CAC5B,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,kBAAkB,EAC/B,OAAO,EAAE,MAAM,EACf,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,eAAe,CAAC;IAsC3B;;;;;;;;;OASG;IACH,OAAO,CAAC,mBAAmB;IAO3B;;OAEG;IACH,OAAO,CAAC,eAAe;IAoDvB;;;;;;OAMG;YACW,WAAW;IAoCzB;;;;;;;;;;;;;;;OAeG;YAKW,aAAa;YAkEZ,cAAc;CAI9B"}
|
|
@@ -312,11 +312,11 @@ import { ReqRespStatus, ReqRespStatusError, parseStatusChunk, prettyPrintReqResp
|
|
|
312
312
|
*
|
|
313
313
|
* If the stream is not closed by the dialled peer, and a timeout occurs, then
|
|
314
314
|
* the stream is closed on the requester's end and sender (us) updates its peer score
|
|
315
|
-
*/ async sendRequestToPeer(peerId, subProtocol, payload) {
|
|
315
|
+
*/ async sendRequestToPeer(peerId, subProtocol, payload, dialTimeout) {
|
|
316
316
|
let stream;
|
|
317
317
|
try {
|
|
318
318
|
this.metrics.recordRequestSent(subProtocol);
|
|
319
|
-
stream = await this.connectionSampler.dialProtocol(peerId, subProtocol);
|
|
319
|
+
stream = await this.connectionSampler.dialProtocol(peerId, subProtocol, dialTimeout);
|
|
320
320
|
// Open the stream with a timeout
|
|
321
321
|
const result = await executeTimeout(()=>pipe([
|
|
322
322
|
payload
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aztec/p2p",
|
|
3
|
-
"version": "0.85.0-alpha-testnet.
|
|
3
|
+
"version": "0.85.0-alpha-testnet.9",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": "./dest/index.js",
|
|
@@ -65,16 +65,16 @@
|
|
|
65
65
|
]
|
|
66
66
|
},
|
|
67
67
|
"dependencies": {
|
|
68
|
-
"@aztec/constants": "0.85.0-alpha-testnet.
|
|
69
|
-
"@aztec/epoch-cache": "0.85.0-alpha-testnet.
|
|
70
|
-
"@aztec/foundation": "0.85.0-alpha-testnet.
|
|
71
|
-
"@aztec/kv-store": "0.85.0-alpha-testnet.
|
|
72
|
-
"@aztec/noir-contracts.js": "0.85.0-alpha-testnet.
|
|
73
|
-
"@aztec/noir-protocol-circuits-types": "0.85.0-alpha-testnet.
|
|
74
|
-
"@aztec/protocol-contracts": "0.85.0-alpha-testnet.
|
|
75
|
-
"@aztec/simulator": "0.85.0-alpha-testnet.
|
|
76
|
-
"@aztec/stdlib": "0.85.0-alpha-testnet.
|
|
77
|
-
"@aztec/telemetry-client": "0.85.0-alpha-testnet.
|
|
68
|
+
"@aztec/constants": "0.85.0-alpha-testnet.9",
|
|
69
|
+
"@aztec/epoch-cache": "0.85.0-alpha-testnet.9",
|
|
70
|
+
"@aztec/foundation": "0.85.0-alpha-testnet.9",
|
|
71
|
+
"@aztec/kv-store": "0.85.0-alpha-testnet.9",
|
|
72
|
+
"@aztec/noir-contracts.js": "0.85.0-alpha-testnet.9",
|
|
73
|
+
"@aztec/noir-protocol-circuits-types": "0.85.0-alpha-testnet.9",
|
|
74
|
+
"@aztec/protocol-contracts": "0.85.0-alpha-testnet.9",
|
|
75
|
+
"@aztec/simulator": "0.85.0-alpha-testnet.9",
|
|
76
|
+
"@aztec/stdlib": "0.85.0-alpha-testnet.9",
|
|
77
|
+
"@aztec/telemetry-client": "0.85.0-alpha-testnet.9",
|
|
78
78
|
"@chainsafe/discv5": "9.0.0",
|
|
79
79
|
"@chainsafe/enr": "3.0.0",
|
|
80
80
|
"@chainsafe/libp2p-gossipsub": "13.0.0",
|
|
@@ -103,7 +103,7 @@
|
|
|
103
103
|
"xxhash-wasm": "^1.1.0"
|
|
104
104
|
},
|
|
105
105
|
"devDependencies": {
|
|
106
|
-
"@aztec/archiver": "0.85.0-alpha-testnet.
|
|
106
|
+
"@aztec/archiver": "0.85.0-alpha-testnet.9",
|
|
107
107
|
"@jest/globals": "^29.5.0",
|
|
108
108
|
"@types/jest": "^29.5.0",
|
|
109
109
|
"@types/node": "^18.14.6",
|
|
@@ -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.debug(`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' };
|
|
@@ -26,12 +26,12 @@ export class DoubleSpendTxValidator<T extends AnyTx> implements TxValidator<T> {
|
|
|
26
26
|
// Ditch this tx if it has repeated nullifiers
|
|
27
27
|
const uniqueNullifiers = new Set(nullifiers);
|
|
28
28
|
if (uniqueNullifiers.size !== nullifiers.length) {
|
|
29
|
-
this.#log.
|
|
29
|
+
this.#log.debug(`Rejecting tx ${await Tx.getHash(tx)} for emitting duplicate nullifiers`);
|
|
30
30
|
return { result: 'invalid', reason: [TX_ERROR_DUPLICATE_NULLIFIER_IN_TX] };
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
if ((await this.#nullifierSource.nullifiersExist(nullifiers.map(n => n.toBuffer()))).some(Boolean)) {
|
|
34
|
-
this.#log.
|
|
34
|
+
this.#log.debug(`Rejecting tx ${await Tx.getHash(tx)} for repeating a nullifier`);
|
|
35
35
|
return { result: 'invalid', reason: [TX_ERROR_EXISTING_NULLIFIER] };
|
|
36
36
|
}
|
|
37
37
|
|
|
@@ -55,7 +55,7 @@ export class GasTxValidator implements TxValidator<Tx> {
|
|
|
55
55
|
maxFeesPerGas.feePerL2Gas.lt(this.#gasFees.feePerL2Gas);
|
|
56
56
|
|
|
57
57
|
if (notEnoughMaxFees) {
|
|
58
|
-
this.#log.
|
|
58
|
+
this.#log.debug(`Skipping transaction ${await tx.getTxHash()} due to insufficient fee per gas`, {
|
|
59
59
|
txMaxFeesPerGas: maxFeesPerGas.toInspect(),
|
|
60
60
|
currentGasFees: this.#gasFees.toInspect(),
|
|
61
61
|
});
|
|
@@ -14,6 +14,7 @@ import type { PubSubLibp2p } from '../../util.js';
|
|
|
14
14
|
import { ReqRespSubProtocol } from '../reqresp/interface.js';
|
|
15
15
|
import { GoodByeReason, prettyGoodbyeReason } from '../reqresp/protocols/goodbye.js';
|
|
16
16
|
import type { ReqResp } from '../reqresp/reqresp.js';
|
|
17
|
+
import { ReqRespStatus } from '../reqresp/status.js';
|
|
17
18
|
import type { PeerDiscoveryService } from '../service.js';
|
|
18
19
|
import { PeerManagerMetrics } from './metrics.js';
|
|
19
20
|
import { PeerScoreState, type PeerScoring } from './peer_scoring.js';
|
|
@@ -22,6 +23,7 @@ const MAX_DIAL_ATTEMPTS = 3;
|
|
|
22
23
|
const MAX_CACHED_PEERS = 100;
|
|
23
24
|
const MAX_CACHED_PEER_AGE_MS = 5 * 60 * 1000; // 5 minutes
|
|
24
25
|
const FAILED_PEER_BAN_TIME_MS = 5 * 60 * 1000; // 5 minutes timeout after failing MAX_DIAL_ATTEMPTS
|
|
26
|
+
const GOODBYE_DIAL_TIMEOUT_MS = 1000;
|
|
25
27
|
|
|
26
28
|
type CachedPeer = {
|
|
27
29
|
peerId: PeerId;
|
|
@@ -398,7 +400,22 @@ export class PeerManager {
|
|
|
398
400
|
this.metrics.recordGoodbyeSent(reason);
|
|
399
401
|
|
|
400
402
|
try {
|
|
401
|
-
await this.reqresp.sendRequestToPeer(
|
|
403
|
+
const resp = await this.reqresp.sendRequestToPeer(
|
|
404
|
+
peer,
|
|
405
|
+
ReqRespSubProtocol.GOODBYE,
|
|
406
|
+
Buffer.from([reason]),
|
|
407
|
+
GOODBYE_DIAL_TIMEOUT_MS,
|
|
408
|
+
);
|
|
409
|
+
|
|
410
|
+
if (resp.status === ReqRespStatus.FAILURE) {
|
|
411
|
+
this.logger.debug(`Failed to send goodbye to peer ${peer.toString()}`);
|
|
412
|
+
} else if (resp.status === ReqRespStatus.SUCCESS) {
|
|
413
|
+
this.logger.verbose(`Sent goodbye to peer ${peer.toString()}`);
|
|
414
|
+
} else {
|
|
415
|
+
this.logger.debug(
|
|
416
|
+
`Unexpected status sending goodbye to peer ${peer.toString()}: ${ReqRespStatus[resp.status]}`,
|
|
417
|
+
);
|
|
418
|
+
}
|
|
402
419
|
} catch (error) {
|
|
403
420
|
this.logger.debug(`Failed to send goodbye to peer ${peer.toString()}: ${error}`);
|
|
404
421
|
} finally {
|
|
@@ -26,7 +26,7 @@ export class RandomSampler {
|
|
|
26
26
|
export class ConnectionSampler {
|
|
27
27
|
private readonly logger = createLogger('p2p:reqresp:connection-sampler');
|
|
28
28
|
private cleanupInterval: NodeJS.Timeout;
|
|
29
|
-
private
|
|
29
|
+
private dialAttempts: AbortController[] = [];
|
|
30
30
|
|
|
31
31
|
private readonly activeConnectionsCount: Map<PeerId, number> = new Map();
|
|
32
32
|
private readonly streams: Map<string, StreamAndPeerId> = new Map();
|
|
@@ -51,7 +51,10 @@ export class ConnectionSampler {
|
|
|
51
51
|
this.logger.info('Stopping connection sampler');
|
|
52
52
|
clearInterval(this.cleanupInterval);
|
|
53
53
|
|
|
54
|
-
this.
|
|
54
|
+
for (const attempt of this.dialAttempts) {
|
|
55
|
+
attempt.abort();
|
|
56
|
+
}
|
|
57
|
+
this.dialAttempts = [];
|
|
55
58
|
await this.dialQueue.end();
|
|
56
59
|
|
|
57
60
|
// Close all active streams
|
|
@@ -184,24 +187,44 @@ export class ConnectionSampler {
|
|
|
184
187
|
* @param protocol - The protocol
|
|
185
188
|
* @returns The stream
|
|
186
189
|
*/
|
|
187
|
-
async dialProtocol(peerId: PeerId, protocol: string): Promise<Stream> {
|
|
190
|
+
async dialProtocol(peerId: PeerId, protocol: string, timeout?: number): Promise<Stream> {
|
|
188
191
|
// Dialling at the same time can cause race conditions where two different streams
|
|
189
192
|
// end up with the same id, hence a serial queue
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
);
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
193
|
+
this.logger.debug(`Dial queue length: ${this.dialQueue.length()}`);
|
|
194
|
+
|
|
195
|
+
const abortController = new AbortController();
|
|
196
|
+
this.dialAttempts.push(abortController);
|
|
197
|
+
let timeoutHandle: NodeJS.Timeout | undefined;
|
|
198
|
+
if (timeout) {
|
|
199
|
+
timeoutHandle = setTimeout(() => abortController.abort(), timeout);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
try {
|
|
203
|
+
const stream = await this.dialQueue.put(() =>
|
|
204
|
+
this.libp2p.dialProtocol(peerId, protocol, { signal: abortController.signal }),
|
|
205
|
+
);
|
|
206
|
+
|
|
207
|
+
this.streams.set(stream.id, { stream, peerId });
|
|
208
|
+
const updatedActiveConnectionsCount = (this.activeConnectionsCount.get(peerId) ?? 0) + 1;
|
|
209
|
+
this.activeConnectionsCount.set(peerId, updatedActiveConnectionsCount);
|
|
210
|
+
|
|
211
|
+
this.logger.trace('Dialed protocol', {
|
|
212
|
+
streamId: stream.id,
|
|
213
|
+
protocol,
|
|
214
|
+
peerId: peerId.toString(),
|
|
215
|
+
activeConnectionsCount: updatedActiveConnectionsCount,
|
|
216
|
+
});
|
|
217
|
+
return stream;
|
|
218
|
+
} finally {
|
|
219
|
+
if (timeoutHandle) {
|
|
220
|
+
clearTimeout(timeoutHandle);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
const idx = this.dialAttempts.indexOf(abortController);
|
|
224
|
+
if (idx > -1) {
|
|
225
|
+
this.dialAttempts.splice(idx, 1);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
205
228
|
}
|
|
206
229
|
|
|
207
230
|
/**
|
|
@@ -421,12 +421,13 @@ export class ReqResp {
|
|
|
421
421
|
peerId: PeerId,
|
|
422
422
|
subProtocol: ReqRespSubProtocol,
|
|
423
423
|
payload: Buffer,
|
|
424
|
+
dialTimeout?: number,
|
|
424
425
|
): Promise<ReqRespResponse> {
|
|
425
426
|
let stream: Stream | undefined;
|
|
426
427
|
try {
|
|
427
428
|
this.metrics.recordRequestSent(subProtocol);
|
|
428
429
|
|
|
429
|
-
stream = await this.connectionSampler.dialProtocol(peerId, subProtocol);
|
|
430
|
+
stream = await this.connectionSampler.dialProtocol(peerId, subProtocol, dialTimeout);
|
|
430
431
|
|
|
431
432
|
// Open the stream with a timeout
|
|
432
433
|
const result = await executeTimeout<ReqRespResponse>(
|