@aztec/p2p 0.67.1 → 0.68.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dest/bootstrap/bootstrap.js +2 -2
- package/dest/client/factory.d.ts +19 -0
- package/dest/client/factory.d.ts.map +1 -0
- package/dest/client/factory.js +40 -0
- package/dest/client/index.d.ts +1 -15
- package/dest/client/index.d.ts.map +1 -1
- package/dest/client/index.js +2 -37
- package/dest/client/p2p_client.d.ts +6 -6
- package/dest/client/p2p_client.d.ts.map +1 -1
- package/dest/client/p2p_client.js +12 -11
- package/dest/config.d.ts +1 -1
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +3 -3
- package/dest/errors/reqresp.error.d.ts +12 -1
- package/dest/errors/reqresp.error.d.ts.map +1 -1
- package/dest/errors/reqresp.error.js +15 -2
- package/dest/index.d.ts +2 -2
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +3 -3
- package/dest/mem_pools/attestation_pool/attestation_pool.d.ts +9 -0
- package/dest/mem_pools/attestation_pool/attestation_pool.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.d.ts +3 -0
- package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.d.ts.map +1 -0
- package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.js +171 -0
- package/dest/mem_pools/attestation_pool/kv_attestation_pool.d.ts +29 -0
- package/dest/mem_pools/attestation_pool/kv_attestation_pool.d.ts.map +1 -0
- package/dest/mem_pools/attestation_pool/kv_attestation_pool.js +114 -0
- package/dest/mem_pools/interface.d.ts +4 -3
- package/dest/mem_pools/interface.d.ts.map +1 -1
- package/dest/mocks/index.d.ts +7 -6
- package/dest/mocks/index.d.ts.map +1 -1
- package/dest/mocks/index.js +8 -8
- package/dest/msg_validators/attestation_validator/attestation_validator.d.ts +8 -0
- package/dest/msg_validators/attestation_validator/attestation_validator.d.ts.map +1 -0
- package/dest/msg_validators/attestation_validator/attestation_validator.js +19 -0
- package/dest/msg_validators/attestation_validator/index.d.ts +2 -0
- package/dest/msg_validators/attestation_validator/index.d.ts.map +1 -0
- package/dest/msg_validators/attestation_validator/index.js +2 -0
- package/dest/msg_validators/block_proposal_validator/block_proposal_validator.d.ts +8 -0
- package/dest/msg_validators/block_proposal_validator/block_proposal_validator.d.ts.map +1 -0
- package/dest/msg_validators/block_proposal_validator/block_proposal_validator.js +21 -0
- package/dest/msg_validators/block_proposal_validator/index.d.ts +2 -0
- package/dest/msg_validators/block_proposal_validator/index.d.ts.map +1 -0
- package/dest/msg_validators/block_proposal_validator/index.js +2 -0
- package/dest/msg_validators/epoch_proof_quote_validator/epoch_proof_quote_validator.d.ts +8 -0
- package/dest/msg_validators/epoch_proof_quote_validator/epoch_proof_quote_validator.d.ts.map +1 -0
- package/dest/msg_validators/epoch_proof_quote_validator/epoch_proof_quote_validator.js +16 -0
- package/dest/msg_validators/epoch_proof_quote_validator/index.d.ts +2 -0
- package/dest/msg_validators/epoch_proof_quote_validator/index.d.ts.map +1 -0
- package/dest/msg_validators/epoch_proof_quote_validator/index.js +2 -0
- package/dest/msg_validators/index.d.ts +4 -0
- package/dest/msg_validators/index.d.ts.map +1 -0
- package/dest/msg_validators/index.js +4 -0
- package/dest/{tx_validator → msg_validators/tx_validator}/aggregate_tx_validator.d.ts +1 -1
- package/dest/msg_validators/tx_validator/aggregate_tx_validator.d.ts.map +1 -0
- package/dest/msg_validators/tx_validator/aggregate_tx_validator.js +34 -0
- package/dest/msg_validators/tx_validator/data_validator.d.ts.map +1 -0
- package/dest/{tx_validator → msg_validators/tx_validator}/data_validator.js +1 -1
- package/dest/{tx_validator → msg_validators/tx_validator}/double_spend_validator.d.ts +3 -2
- package/dest/msg_validators/tx_validator/double_spend_validator.d.ts.map +1 -0
- package/dest/msg_validators/tx_validator/double_spend_validator.js +56 -0
- package/dest/msg_validators/tx_validator/index.d.ts.map +1 -0
- package/dest/{tx_validator → msg_validators/tx_validator}/index.js +1 -1
- package/dest/msg_validators/tx_validator/metadata_validator.d.ts.map +1 -0
- package/dest/{tx_validator → msg_validators/tx_validator}/metadata_validator.js +1 -1
- package/dest/msg_validators/tx_validator/tx_proof_validator.d.ts.map +1 -0
- package/dest/msg_validators/tx_validator/tx_proof_validator.js +29 -0
- package/dest/services/data_store.d.ts.map +1 -0
- package/dest/services/data_store.js +188 -0
- package/dest/{service → services/discv5}/discV5_service.d.ts +2 -2
- package/dest/services/discv5/discV5_service.d.ts.map +1 -0
- package/dest/services/discv5/discV5_service.js +144 -0
- package/dest/services/dummy_service.d.ts.map +1 -0
- package/dest/{service → services}/dummy_service.js +1 -1
- package/dest/{service → services}/encoding.d.ts +5 -0
- package/dest/services/encoding.d.ts.map +1 -0
- package/dest/services/encoding.js +65 -0
- package/dest/services/index.d.ts +3 -0
- package/dest/services/index.d.ts.map +1 -0
- package/dest/services/index.js +3 -0
- package/dest/services/libp2p/libp2p_service.d.ts +221 -0
- package/dest/services/libp2p/libp2p_service.d.ts.map +1 -0
- package/dest/services/libp2p/libp2p_service.js +690 -0
- package/dest/services/peer-scoring/peer_scoring.d.ts +19 -0
- package/dest/services/peer-scoring/peer_scoring.d.ts.map +1 -0
- package/dest/services/peer-scoring/peer_scoring.js +55 -0
- package/dest/{service → services}/peer_manager.d.ts +5 -4
- package/dest/services/peer_manager.d.ts.map +1 -0
- package/dest/services/peer_manager.js +270 -0
- package/dest/services/reqresp/config.d.ts.map +1 -0
- package/dest/{service → services}/reqresp/config.js +1 -1
- package/dest/services/reqresp/handlers.d.ts.map +1 -0
- package/dest/{service → services}/reqresp/handlers.js +1 -1
- package/dest/services/reqresp/index.d.ts.map +1 -0
- package/dest/{service → services}/reqresp/index.js +1 -1
- package/dest/services/reqresp/interface.d.ts.map +1 -0
- package/dest/{service → services}/reqresp/interface.js +1 -1
- package/dest/services/reqresp/rate_limiter/index.d.ts.map +1 -0
- package/dest/{service → services}/reqresp/rate_limiter/index.js +1 -1
- package/dest/{service → services}/reqresp/rate_limiter/rate_limiter.d.ts +0 -5
- package/dest/services/reqresp/rate_limiter/rate_limiter.d.ts.map +1 -0
- package/dest/{service → services}/reqresp/rate_limiter/rate_limiter.js +7 -2
- package/dest/services/reqresp/rate_limiter/rate_limits.d.ts.map +1 -0
- package/dest/{service → services}/reqresp/rate_limiter/rate_limits.js +1 -1
- package/dest/{service → services}/reqresp/reqresp.d.ts +16 -0
- package/dest/services/reqresp/reqresp.d.ts.map +1 -0
- package/dest/services/reqresp/reqresp.js +279 -0
- package/dest/services/service.d.ts.map +1 -0
- package/dest/{service → services}/service.js +1 -1
- package/package.json +13 -10
- package/src/bootstrap/bootstrap.ts +1 -1
- package/src/client/factory.ts +97 -0
- package/src/client/index.ts +1 -73
- package/src/client/p2p_client.ts +28 -15
- package/src/config.ts +2 -2
- package/src/errors/reqresp.error.ts +15 -1
- package/src/index.ts +2 -2
- package/src/mem_pools/attestation_pool/attestation_pool.ts +10 -0
- package/src/mem_pools/attestation_pool/attestation_pool_test_suite.ts +237 -0
- package/src/mem_pools/attestation_pool/kv_attestation_pool.ts +153 -0
- package/src/mem_pools/interface.ts +5 -3
- package/src/mocks/index.ts +16 -10
- package/src/msg_validators/attestation_validator/attestation_validator.ts +26 -0
- package/src/msg_validators/attestation_validator/index.ts +1 -0
- package/src/msg_validators/block_proposal_validator/block_proposal_validator.ts +29 -0
- package/src/msg_validators/block_proposal_validator/index.ts +1 -0
- package/src/msg_validators/epoch_proof_quote_validator/epoch_proof_quote_validator.ts +22 -0
- package/src/msg_validators/epoch_proof_quote_validator/index.ts +1 -0
- package/src/msg_validators/index.ts +3 -0
- package/src/{tx_validator → msg_validators/tx_validator}/aggregate_tx_validator.ts +5 -3
- package/src/{tx_validator → msg_validators/tx_validator}/double_spend_validator.ts +6 -8
- package/src/{service → services/discv5}/discV5_service.ts +3 -3
- package/src/{service → services}/encoding.ts +21 -3
- package/src/services/index.ts +2 -0
- package/src/{service → services/libp2p}/libp2p_service.ts +330 -85
- package/src/{service → services/peer-scoring}/peer_scoring.ts +6 -23
- package/src/{service → services}/peer_manager.ts +50 -3
- package/src/{service → services}/reqresp/rate_limiter/rate_limiter.ts +2 -1
- package/src/{service → services}/reqresp/reqresp.ts +83 -17
- package/dest/service/data_store.d.ts.map +0 -1
- package/dest/service/data_store.js +0 -188
- package/dest/service/discV5_service.d.ts.map +0 -1
- package/dest/service/discV5_service.js +0 -144
- package/dest/service/dummy_service.d.ts.map +0 -1
- package/dest/service/encoding.d.ts.map +0 -1
- package/dest/service/encoding.js +0 -49
- package/dest/service/index.d.ts +0 -3
- package/dest/service/index.d.ts.map +0 -1
- package/dest/service/index.js +0 -3
- package/dest/service/libp2p_service.d.ts +0 -136
- package/dest/service/libp2p_service.d.ts.map +0 -1
- package/dest/service/libp2p_service.js +0 -500
- package/dest/service/peer_manager.d.ts.map +0 -1
- package/dest/service/peer_manager.js +0 -214
- package/dest/service/peer_scoring.d.ts +0 -35
- package/dest/service/peer_scoring.d.ts.map +0 -1
- package/dest/service/peer_scoring.js +0 -72
- package/dest/service/reqresp/config.d.ts.map +0 -1
- package/dest/service/reqresp/handlers.d.ts.map +0 -1
- package/dest/service/reqresp/index.d.ts.map +0 -1
- package/dest/service/reqresp/interface.d.ts.map +0 -1
- package/dest/service/reqresp/rate_limiter/index.d.ts.map +0 -1
- package/dest/service/reqresp/rate_limiter/rate_limiter.d.ts.map +0 -1
- package/dest/service/reqresp/rate_limiter/rate_limits.d.ts.map +0 -1
- package/dest/service/reqresp/reqresp.d.ts.map +0 -1
- package/dest/service/reqresp/reqresp.js +0 -230
- package/dest/service/service.d.ts.map +0 -1
- package/dest/tx_validator/aggregate_tx_validator.d.ts.map +0 -1
- package/dest/tx_validator/aggregate_tx_validator.js +0 -32
- package/dest/tx_validator/data_validator.d.ts.map +0 -1
- package/dest/tx_validator/double_spend_validator.d.ts.map +0 -1
- package/dest/tx_validator/double_spend_validator.js +0 -56
- package/dest/tx_validator/index.d.ts.map +0 -1
- package/dest/tx_validator/metadata_validator.d.ts.map +0 -1
- package/dest/tx_validator/tx_proof_validator.d.ts.map +0 -1
- package/dest/tx_validator/tx_proof_validator.js +0 -29
- package/src/service/index.ts +0 -2
- /package/dest/{tx_validator → msg_validators/tx_validator}/data_validator.d.ts +0 -0
- /package/dest/{tx_validator → msg_validators/tx_validator}/index.d.ts +0 -0
- /package/dest/{tx_validator → msg_validators/tx_validator}/metadata_validator.d.ts +0 -0
- /package/dest/{tx_validator → msg_validators/tx_validator}/tx_proof_validator.d.ts +0 -0
- /package/dest/{service → services}/data_store.d.ts +0 -0
- /package/dest/{service → services}/dummy_service.d.ts +0 -0
- /package/dest/{service → services}/reqresp/config.d.ts +0 -0
- /package/dest/{service → services}/reqresp/handlers.d.ts +0 -0
- /package/dest/{service → services}/reqresp/index.d.ts +0 -0
- /package/dest/{service → services}/reqresp/interface.d.ts +0 -0
- /package/dest/{service → services}/reqresp/rate_limiter/index.d.ts +0 -0
- /package/dest/{service → services}/reqresp/rate_limiter/rate_limits.d.ts +0 -0
- /package/dest/{service → services}/service.d.ts +0 -0
- /package/src/{tx_validator → msg_validators/tx_validator}/data_validator.ts +0 -0
- /package/src/{tx_validator → msg_validators/tx_validator}/index.ts +0 -0
- /package/src/{tx_validator → msg_validators/tx_validator}/metadata_validator.ts +0 -0
- /package/src/{tx_validator → msg_validators/tx_validator}/tx_proof_validator.ts +0 -0
- /package/src/{service → services}/data_store.ts +0 -0
- /package/src/{service → services}/dummy_service.ts +0 -0
- /package/src/{service → services}/reqresp/config.ts +0 -0
- /package/src/{service → services}/reqresp/handlers.ts +0 -0
- /package/src/{service → services}/reqresp/index.ts +0 -0
- /package/src/{service → services}/reqresp/interface.ts +0 -0
- /package/src/{service → services}/reqresp/rate_limiter/index.ts +0 -0
- /package/src/{service → services}/reqresp/rate_limiter/rate_limits.ts +0 -0
- /package/src/{service → services}/service.ts +0 -0
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { type PeerInfo } from '@aztec/circuit-types';
|
|
1
|
+
import { type PeerErrorSeverity, type PeerInfo } from '@aztec/circuit-types';
|
|
2
2
|
import { createLogger } from '@aztec/foundation/log';
|
|
3
|
+
import { type Traceable, type Tracer, trackSpan } from '@aztec/telemetry-client';
|
|
3
4
|
|
|
4
5
|
import { type ENR } from '@chainsafe/enr';
|
|
5
6
|
import { type PeerId } from '@libp2p/interface';
|
|
@@ -8,7 +9,7 @@ import { inspect } from 'util';
|
|
|
8
9
|
|
|
9
10
|
import { type P2PConfig } from '../config.js';
|
|
10
11
|
import { type PubSubLibp2p } from '../util.js';
|
|
11
|
-
import {
|
|
12
|
+
import { PeerScoring } from './peer-scoring/peer_scoring.js';
|
|
12
13
|
import { type PeerDiscoveryService } from './service.js';
|
|
13
14
|
|
|
14
15
|
const MAX_DIAL_ATTEMPTS = 3;
|
|
@@ -21,7 +22,7 @@ type CachedPeer = {
|
|
|
21
22
|
dialAttempts: number;
|
|
22
23
|
};
|
|
23
24
|
|
|
24
|
-
export class PeerManager {
|
|
25
|
+
export class PeerManager implements Traceable {
|
|
25
26
|
private cachedPeers: Map<string, CachedPeer> = new Map();
|
|
26
27
|
private peerScoring: PeerScoring;
|
|
27
28
|
private heartbeatCounter: number = 0;
|
|
@@ -30,6 +31,7 @@ export class PeerManager {
|
|
|
30
31
|
private libP2PNode: PubSubLibp2p,
|
|
31
32
|
private peerDiscoveryService: PeerDiscoveryService,
|
|
32
33
|
private config: P2PConfig,
|
|
34
|
+
public readonly tracer: Tracer,
|
|
33
35
|
private logger = createLogger('p2p:peer-manager'),
|
|
34
36
|
) {
|
|
35
37
|
this.peerScoring = new PeerScoring(config);
|
|
@@ -59,6 +61,7 @@ export class PeerManager {
|
|
|
59
61
|
});
|
|
60
62
|
}
|
|
61
63
|
|
|
64
|
+
@trackSpan('PeerManager.heartbeat')
|
|
62
65
|
public heartbeat() {
|
|
63
66
|
this.heartbeatCounter++;
|
|
64
67
|
this.discover();
|
|
@@ -230,6 +233,7 @@ export class PeerManager {
|
|
|
230
233
|
this.logger.trace(`Failed to dial peer ${id} (attempt ${peer.dialAttempts})`, { error: inspect(error) });
|
|
231
234
|
this.cachedPeers.set(id, peer);
|
|
232
235
|
} else {
|
|
236
|
+
formatLibp2pDialError(error as Error);
|
|
233
237
|
this.logger.debug(`Failed to dial peer ${id} (dropping)`, { error: inspect(error) });
|
|
234
238
|
this.cachedPeers.delete(id);
|
|
235
239
|
}
|
|
@@ -264,3 +268,46 @@ export class PeerManager {
|
|
|
264
268
|
}
|
|
265
269
|
}
|
|
266
270
|
}
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* copied from github.com/ChainSafe/lodestar
|
|
274
|
+
* libp2p errors with extremely noisy errors here, which are deeply nested taking 30-50 lines.
|
|
275
|
+
* Some known errors:
|
|
276
|
+
* ```
|
|
277
|
+
* Error: The operation was aborted
|
|
278
|
+
* Error: stream ended before 1 bytes became available
|
|
279
|
+
* Error: Error occurred during XX handshake: Error occurred while verifying signed payload: Peer ID doesn't match libp2p public key
|
|
280
|
+
* ```
|
|
281
|
+
*
|
|
282
|
+
* Also the error's message is not properly formatted, where the error message is indented and includes the full stack
|
|
283
|
+
* ```
|
|
284
|
+
* {
|
|
285
|
+
* emessage: '\n' +
|
|
286
|
+
* ' Error: stream ended before 1 bytes became available\n' +
|
|
287
|
+
* ' at /home/lion/Code/eth2.0/lodestar/node_modules/it-reader/index.js:37:9\n' +
|
|
288
|
+
* ' at runMicrotasks (<anonymous>)\n' +
|
|
289
|
+
* ' at decoder (/home/lion/Code/eth2.0/lodestar/node_modules/it-length-prefixed/src/decode.js:113:22)\n' +
|
|
290
|
+
* ' at first (/home/lion/Code/eth2.0/lodestar/node_modules/it-first/index.js:11:20)\n' +
|
|
291
|
+
* ' at Object.exports.read (/home/lion/Code/eth2.0/lodestar/node_modules/multistream-select/src/multistream.js:31:15)\n' +
|
|
292
|
+
* ' at module.exports (/home/lion/Code/eth2.0/lodestar/node_modules/multistream-select/src/select.js:21:19)\n' +
|
|
293
|
+
* ' at Upgrader._encryptOutbound (/home/lion/Code/eth2.0/lodestar/node_modules/libp2p/src/upgrader.js:397:36)\n' +
|
|
294
|
+
* ' at Upgrader.upgradeOutbound (/home/lion/Code/eth2.0/lodestar/node_modules/libp2p/src/upgrader.js:176:11)\n' +
|
|
295
|
+
* ' at ClassIsWrapper.dial (/home/lion/Code/eth2.0/lodestar/node_modules/libp2p-tcp/src/index.js:49:18)'
|
|
296
|
+
* }
|
|
297
|
+
* ```
|
|
298
|
+
*
|
|
299
|
+
* Tracking issue https://github.com/libp2p/js-libp2p/issues/996
|
|
300
|
+
*/
|
|
301
|
+
function formatLibp2pDialError(e: Error): void {
|
|
302
|
+
const errorMessage = e.message.trim();
|
|
303
|
+
const newlineIndex = errorMessage.indexOf('\n');
|
|
304
|
+
e.message = newlineIndex !== -1 ? errorMessage.slice(0, newlineIndex) : errorMessage;
|
|
305
|
+
|
|
306
|
+
if (
|
|
307
|
+
e.message.includes('The operation was aborted') ||
|
|
308
|
+
e.message.includes('stream ended before 1 bytes became available') ||
|
|
309
|
+
e.message.includes('The operation was aborted')
|
|
310
|
+
) {
|
|
311
|
+
e.stack = undefined;
|
|
312
|
+
}
|
|
313
|
+
}
|
|
@@ -3,10 +3,11 @@
|
|
|
3
3
|
* Rationale is that if it was good enough for them, then it should be good enough for us.
|
|
4
4
|
* https://github.com/ChainSafe/lodestar
|
|
5
5
|
*/
|
|
6
|
+
import { PeerErrorSeverity } from '@aztec/circuit-types';
|
|
7
|
+
|
|
6
8
|
import { type PeerId } from '@libp2p/interface';
|
|
7
9
|
|
|
8
10
|
import { type PeerManager } from '../../peer_manager.js';
|
|
9
|
-
import { PeerErrorSeverity } from '../../peer_scoring.js';
|
|
10
11
|
import { type ReqRespSubProtocol, type ReqRespSubProtocolRateLimits } from '../interface.js';
|
|
11
12
|
import { DEFAULT_RATE_LIMITS } from './rate_limits.js';
|
|
12
13
|
|
|
@@ -1,16 +1,20 @@
|
|
|
1
1
|
// @attribution: lodestar impl for inspiration
|
|
2
|
+
import { PeerErrorSeverity } from '@aztec/circuit-types';
|
|
2
3
|
import { type Logger, createLogger } from '@aztec/foundation/log';
|
|
3
4
|
import { executeTimeoutWithCustomError } from '@aztec/foundation/timer';
|
|
4
5
|
|
|
5
6
|
import { type IncomingStreamData, type PeerId, type Stream } from '@libp2p/interface';
|
|
6
7
|
import { pipe } from 'it-pipe';
|
|
7
8
|
import { type Libp2p } from 'libp2p';
|
|
8
|
-
import { compressSync, uncompressSync } from 'snappy';
|
|
9
9
|
import { type Uint8ArrayList } from 'uint8arraylist';
|
|
10
10
|
|
|
11
|
-
import {
|
|
11
|
+
import {
|
|
12
|
+
CollectiveReqRespTimeoutError,
|
|
13
|
+
IndividualReqRespTimeoutError,
|
|
14
|
+
InvalidResponseError,
|
|
15
|
+
} from '../../errors/reqresp.error.js';
|
|
16
|
+
import { SnappyTransform } from '../encoding.js';
|
|
12
17
|
import { type PeerManager } from '../peer_manager.js';
|
|
13
|
-
import { PeerErrorSeverity } from '../peer_scoring.js';
|
|
14
18
|
import { type P2PReqRespConfig } from './config.js';
|
|
15
19
|
import {
|
|
16
20
|
DEFAULT_SUB_PROTOCOL_HANDLERS,
|
|
@@ -49,6 +53,8 @@ export class ReqResp {
|
|
|
49
53
|
|
|
50
54
|
private rateLimiter: RequestResponseRateLimiter;
|
|
51
55
|
|
|
56
|
+
private snappyTransform: SnappyTransform;
|
|
57
|
+
|
|
52
58
|
constructor(config: P2PReqRespConfig, protected readonly libp2p: Libp2p, private peerManager: PeerManager) {
|
|
53
59
|
this.logger = createLogger('p2p:reqresp');
|
|
54
60
|
|
|
@@ -56,6 +62,7 @@ export class ReqResp {
|
|
|
56
62
|
this.individualRequestTimeoutMs = config.individualRequestTimeoutMs;
|
|
57
63
|
|
|
58
64
|
this.rateLimiter = new RequestResponseRateLimiter(peerManager);
|
|
65
|
+
this.snappyTransform = new SnappyTransform();
|
|
59
66
|
}
|
|
60
67
|
|
|
61
68
|
/**
|
|
@@ -143,8 +150,7 @@ export class ReqResp {
|
|
|
143
150
|
// The response validator handles peer punishment within
|
|
144
151
|
const isValid = await responseValidator(request, object, peer);
|
|
145
152
|
if (!isValid) {
|
|
146
|
-
|
|
147
|
-
return undefined;
|
|
153
|
+
throw new InvalidResponseError();
|
|
148
154
|
}
|
|
149
155
|
return object;
|
|
150
156
|
}
|
|
@@ -159,7 +165,7 @@ export class ReqResp {
|
|
|
159
165
|
() => new CollectiveReqRespTimeoutError(),
|
|
160
166
|
);
|
|
161
167
|
} catch (e: any) {
|
|
162
|
-
this.logger.
|
|
168
|
+
this.logger.debug(`${e.message} | subProtocol: ${subProtocol}`);
|
|
163
169
|
return undefined;
|
|
164
170
|
}
|
|
165
171
|
}
|
|
@@ -200,18 +206,14 @@ export class ReqResp {
|
|
|
200
206
|
|
|
201
207
|
// Open the stream with a timeout
|
|
202
208
|
const result = await executeTimeoutWithCustomError<Buffer>(
|
|
203
|
-
(): Promise<Buffer> => pipe([payload], stream!, this.readMessage),
|
|
209
|
+
(): Promise<Buffer> => pipe([payload], stream!, this.readMessage.bind(this)),
|
|
204
210
|
this.individualRequestTimeoutMs,
|
|
205
|
-
() => new
|
|
211
|
+
() => new IndividualReqRespTimeoutError(),
|
|
206
212
|
);
|
|
207
213
|
|
|
208
|
-
await stream.close();
|
|
209
|
-
this.logger.trace(`Stream closed with ${peerId.toString()} for ${subProtocol}`);
|
|
210
|
-
|
|
211
214
|
return result;
|
|
212
215
|
} catch (e: any) {
|
|
213
|
-
this.
|
|
214
|
-
this.peerManager.penalizePeer(peerId, PeerErrorSeverity.HighToleranceError);
|
|
216
|
+
this.handleResponseError(e, peerId, subProtocol);
|
|
215
217
|
} finally {
|
|
216
218
|
if (stream) {
|
|
217
219
|
try {
|
|
@@ -224,7 +226,70 @@ export class ReqResp {
|
|
|
224
226
|
}
|
|
225
227
|
}
|
|
226
228
|
}
|
|
227
|
-
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* Handle a response error
|
|
233
|
+
*
|
|
234
|
+
* ReqResp errors are punished differently depending on the severity of the offense
|
|
235
|
+
*
|
|
236
|
+
* @param e - The error
|
|
237
|
+
* @param peerId - The peer id
|
|
238
|
+
* @param subProtocol - The sub protocol
|
|
239
|
+
* @returns If the error is non pubishable, then undefined is returned, otherwise the peer is penalized
|
|
240
|
+
*/
|
|
241
|
+
private handleResponseError(e: any, peerId: PeerId, subProtocol: ReqRespSubProtocol): void {
|
|
242
|
+
const severity = this.categorizeError(e, peerId, subProtocol);
|
|
243
|
+
if (severity) {
|
|
244
|
+
this.peerManager.penalizePeer(peerId, severity);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* Categorize the error and log it.
|
|
250
|
+
*/
|
|
251
|
+
private categorizeError(e: any, peerId: PeerId, subProtocol: ReqRespSubProtocol): PeerErrorSeverity | undefined {
|
|
252
|
+
// Non pubishable errors
|
|
253
|
+
// We do not punish a collective timeout, as the node triggers this interupt, independent of the peer's behaviour
|
|
254
|
+
const logTags = {
|
|
255
|
+
peerId: peerId.toString(),
|
|
256
|
+
subProtocol,
|
|
257
|
+
};
|
|
258
|
+
if (e instanceof CollectiveReqRespTimeoutError || e instanceof InvalidResponseError) {
|
|
259
|
+
this.logger.debug(
|
|
260
|
+
`Non-punishable error: ${e.message} | peerId: ${peerId.toString()} | subProtocol: ${subProtocol}`,
|
|
261
|
+
logTags,
|
|
262
|
+
);
|
|
263
|
+
return undefined;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
// Pubishable errors
|
|
267
|
+
// Connection reset errors in the networking stack are punished with high severity
|
|
268
|
+
// it just signals an unreliable peer
|
|
269
|
+
// We assume that the requesting node has a functioning networking stack.
|
|
270
|
+
if (e?.code === 'ECONNRESET' || e?.code === 'EPIPE') {
|
|
271
|
+
this.logger.debug(`Connection reset: ${peerId.toString()}`, logTags);
|
|
272
|
+
return PeerErrorSeverity.HighToleranceError;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
if (e?.code === 'ECONNREFUSED') {
|
|
276
|
+
this.logger.debug(`Connection refused: ${peerId.toString()}`, logTags);
|
|
277
|
+
return PeerErrorSeverity.HighToleranceError;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
// Timeout errors are punished with high tolerance, they can be due to a geogrpahically far away peer or an
|
|
281
|
+
// overloaded peer
|
|
282
|
+
if (e instanceof IndividualReqRespTimeoutError) {
|
|
283
|
+
this.logger.debug(
|
|
284
|
+
`Timeout error: ${e.message} | peerId: ${peerId.toString()} | subProtocol: ${subProtocol}`,
|
|
285
|
+
logTags,
|
|
286
|
+
);
|
|
287
|
+
return PeerErrorSeverity.HighToleranceError;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
// Catch all error
|
|
291
|
+
this.logger.error(`Unexpected error sending request to peer`, e, logTags);
|
|
292
|
+
return PeerErrorSeverity.HighToleranceError;
|
|
228
293
|
}
|
|
229
294
|
|
|
230
295
|
/**
|
|
@@ -235,8 +300,8 @@ export class ReqResp {
|
|
|
235
300
|
for await (const chunk of source) {
|
|
236
301
|
chunks.push(chunk.subarray());
|
|
237
302
|
}
|
|
238
|
-
const messageData =
|
|
239
|
-
return
|
|
303
|
+
const messageData = Buffer.concat(chunks);
|
|
304
|
+
return this.snappyTransform.inboundTransformNoTopic(messageData);
|
|
240
305
|
}
|
|
241
306
|
|
|
242
307
|
/**
|
|
@@ -266,6 +331,7 @@ export class ReqResp {
|
|
|
266
331
|
}
|
|
267
332
|
|
|
268
333
|
const handler = this.subProtocolHandlers[protocol];
|
|
334
|
+
const transform = this.snappyTransform;
|
|
269
335
|
|
|
270
336
|
try {
|
|
271
337
|
await pipe(
|
|
@@ -274,7 +340,7 @@ export class ReqResp {
|
|
|
274
340
|
for await (const chunkList of source) {
|
|
275
341
|
const msg = Buffer.from(chunkList.subarray());
|
|
276
342
|
const response = await handler(msg);
|
|
277
|
-
yield new Uint8Array(
|
|
343
|
+
yield new Uint8Array(transform.outboundTransformNoTopic(response));
|
|
278
344
|
}
|
|
279
345
|
},
|
|
280
346
|
stream,
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"data_store.d.ts","sourceRoot":"","sources":["../../src/service/data_store.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAY,MAAM,iBAAiB,CAAC;AAE9D,OAAO,EAAE,KAAK,KAAK,EAAE,KAAK,SAAS,EAAE,GAAG,EAAE,KAAK,QAAQ,EAAE,KAAK,IAAI,EAAE,KAAK,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAC5G,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAqBrD,qBAAa,cAAe,YAAW,SAAS;;IAM9C,OAAO,CAAC,cAAc,CAAS;gBAEnB,EAAE,EAAE,YAAY,EAAE,EAAE,cAAc,EAAE;;KAAyB;IAOzE,GAAG,CAAC,GAAG,EAAE,GAAG,GAAG,OAAO;IAItB,GAAG,CAAC,GAAG,EAAE,GAAG,GAAG,UAAU;IAgBzB,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC;IAIrC,OAAO,CAAC,MAAM,EAAE,aAAa,CAAC,IAAI,CAAC,GAAG,aAAa,CAAC,GAAG,CAAC;IAOxD,OAAO,CAAC,MAAM,EAAE,aAAa,CAAC,GAAG,CAAC,GAAG,aAAa,CAAC,IAAI,CAAC;IASxD,UAAU,CAAC,MAAM,EAAE,aAAa,CAAC,GAAG,CAAC,GAAG,aAAa,CAAC,GAAG,CAAC;IAO3D,MAAM,CAAC,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC;IAKrC,KAAK,IAAI,KAAK;IA4Bd,KAAK,CAAC,CAAC,EAAE,KAAK,GAAG,aAAa,CAAC,IAAI,CAAC;IA4BpC,SAAS,CAAC,CAAC,EAAE,QAAQ,GAAG,aAAa,CAAC,GAAG,CAAC;YA2B5B,IAAI;YAqBH,GAAG;IAkBlB;;OAEG;IACH,OAAO,CAAC,oBAAoB;CAiB7B"}
|
|
@@ -1,188 +0,0 @@
|
|
|
1
|
-
var _AztecDatastore_memoryDatastore, _AztecDatastore_dbDatastore, _AztecDatastore_batchOps;
|
|
2
|
-
import { __classPrivateFieldGet, __classPrivateFieldSet } from "tslib";
|
|
3
|
-
import { filter, map, sort, take } from '@aztec/foundation/iterable';
|
|
4
|
-
import { Key } from 'interface-datastore';
|
|
5
|
-
class KeyNotFoundError extends Error {
|
|
6
|
-
constructor(message) {
|
|
7
|
-
super(message);
|
|
8
|
-
this.code = 'ERR_NOT_FOUND';
|
|
9
|
-
}
|
|
10
|
-
}
|
|
11
|
-
export class AztecDatastore {
|
|
12
|
-
constructor(db, { maxMemoryItems } = { maxMemoryItems: 50 }) {
|
|
13
|
-
_AztecDatastore_memoryDatastore.set(this, void 0);
|
|
14
|
-
_AztecDatastore_dbDatastore.set(this, void 0);
|
|
15
|
-
_AztecDatastore_batchOps.set(this, []);
|
|
16
|
-
__classPrivateFieldSet(this, _AztecDatastore_memoryDatastore, new Map(), "f");
|
|
17
|
-
__classPrivateFieldSet(this, _AztecDatastore_dbDatastore, db.openMap('p2p_datastore'), "f");
|
|
18
|
-
this.maxMemoryItems = maxMemoryItems;
|
|
19
|
-
}
|
|
20
|
-
has(key) {
|
|
21
|
-
return __classPrivateFieldGet(this, _AztecDatastore_memoryDatastore, "f").has(key.toString()) || __classPrivateFieldGet(this, _AztecDatastore_dbDatastore, "f").has(key.toString());
|
|
22
|
-
}
|
|
23
|
-
get(key) {
|
|
24
|
-
const keyStr = key.toString();
|
|
25
|
-
const memoryItem = __classPrivateFieldGet(this, _AztecDatastore_memoryDatastore, "f").get(keyStr);
|
|
26
|
-
if (memoryItem) {
|
|
27
|
-
memoryItem.lastAccessedMs = Date.now();
|
|
28
|
-
return memoryItem.data;
|
|
29
|
-
}
|
|
30
|
-
const dbItem = __classPrivateFieldGet(this, _AztecDatastore_dbDatastore, "f").get(keyStr);
|
|
31
|
-
if (!dbItem) {
|
|
32
|
-
throw new KeyNotFoundError(`Key not found`);
|
|
33
|
-
}
|
|
34
|
-
return Uint8Array.from(dbItem);
|
|
35
|
-
}
|
|
36
|
-
put(key, val) {
|
|
37
|
-
return this._put(key, val);
|
|
38
|
-
}
|
|
39
|
-
async *putMany(source) {
|
|
40
|
-
for await (const { key, value } of source) {
|
|
41
|
-
await this.put(key, value);
|
|
42
|
-
yield key;
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
async *getMany(source) {
|
|
46
|
-
for await (const key of source) {
|
|
47
|
-
yield {
|
|
48
|
-
key,
|
|
49
|
-
value: this.get(key),
|
|
50
|
-
};
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
async *deleteMany(source) {
|
|
54
|
-
for await (const key of source) {
|
|
55
|
-
await this.delete(key);
|
|
56
|
-
yield key;
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
async delete(key) {
|
|
60
|
-
__classPrivateFieldGet(this, _AztecDatastore_memoryDatastore, "f").delete(key.toString());
|
|
61
|
-
await __classPrivateFieldGet(this, _AztecDatastore_dbDatastore, "f").delete(key.toString());
|
|
62
|
-
}
|
|
63
|
-
batch() {
|
|
64
|
-
return {
|
|
65
|
-
put: (key, value) => {
|
|
66
|
-
__classPrivateFieldGet(this, _AztecDatastore_batchOps, "f").push({
|
|
67
|
-
type: 'put',
|
|
68
|
-
key,
|
|
69
|
-
value,
|
|
70
|
-
});
|
|
71
|
-
},
|
|
72
|
-
delete: key => {
|
|
73
|
-
__classPrivateFieldGet(this, _AztecDatastore_batchOps, "f").push({
|
|
74
|
-
type: 'del',
|
|
75
|
-
key,
|
|
76
|
-
});
|
|
77
|
-
},
|
|
78
|
-
commit: async () => {
|
|
79
|
-
for (const op of __classPrivateFieldGet(this, _AztecDatastore_batchOps, "f")) {
|
|
80
|
-
if (op.type === 'put' && op.value) {
|
|
81
|
-
await this.put(op.key, op.value);
|
|
82
|
-
}
|
|
83
|
-
else if (op.type === 'del') {
|
|
84
|
-
await this.delete(op.key);
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
__classPrivateFieldSet(this, _AztecDatastore_batchOps, [], "f"); // Clear operations after commit
|
|
88
|
-
},
|
|
89
|
-
};
|
|
90
|
-
}
|
|
91
|
-
query(q) {
|
|
92
|
-
let it = this.all(); //
|
|
93
|
-
const { prefix, filters, orders, offset, limit } = q;
|
|
94
|
-
if (prefix != null) {
|
|
95
|
-
it = filter(it, e => e.key.toString().startsWith(`${prefix}`));
|
|
96
|
-
}
|
|
97
|
-
if (Array.isArray(filters)) {
|
|
98
|
-
it = filters.reduce((it, f) => filter(it, f), it);
|
|
99
|
-
}
|
|
100
|
-
if (Array.isArray(orders)) {
|
|
101
|
-
it = orders.reduce((it, f) => sort(it, f), it);
|
|
102
|
-
}
|
|
103
|
-
if (offset != null) {
|
|
104
|
-
let i = 0;
|
|
105
|
-
it = filter(it, () => i++ >= offset);
|
|
106
|
-
}
|
|
107
|
-
if (limit != null) {
|
|
108
|
-
it = take(it, limit);
|
|
109
|
-
}
|
|
110
|
-
return it;
|
|
111
|
-
}
|
|
112
|
-
queryKeys(q) {
|
|
113
|
-
let it = map(this.all(), ({ key }) => key);
|
|
114
|
-
const { prefix, filters, orders, offset, limit } = q;
|
|
115
|
-
if (prefix != null) {
|
|
116
|
-
it = filter(it, e => e.toString().startsWith(`${prefix}`));
|
|
117
|
-
}
|
|
118
|
-
if (Array.isArray(filters)) {
|
|
119
|
-
it = filters.reduce((it, f) => filter(it, f), it);
|
|
120
|
-
}
|
|
121
|
-
if (Array.isArray(orders)) {
|
|
122
|
-
it = orders.reduce((it, f) => sort(it, f), it);
|
|
123
|
-
}
|
|
124
|
-
if (offset != null) {
|
|
125
|
-
let i = 0;
|
|
126
|
-
it = filter(it, () => i++ >= offset);
|
|
127
|
-
}
|
|
128
|
-
if (limit != null) {
|
|
129
|
-
it = take(it, limit);
|
|
130
|
-
}
|
|
131
|
-
return it;
|
|
132
|
-
}
|
|
133
|
-
async _put(key, val) {
|
|
134
|
-
const keyStr = key.toString();
|
|
135
|
-
while (__classPrivateFieldGet(this, _AztecDatastore_memoryDatastore, "f").size >= this.maxMemoryItems) {
|
|
136
|
-
this.pruneMemoryDatastore();
|
|
137
|
-
}
|
|
138
|
-
const memoryItem = __classPrivateFieldGet(this, _AztecDatastore_memoryDatastore, "f").get(keyStr);
|
|
139
|
-
if (memoryItem) {
|
|
140
|
-
// update existing
|
|
141
|
-
memoryItem.lastAccessedMs = Date.now();
|
|
142
|
-
memoryItem.data = val;
|
|
143
|
-
}
|
|
144
|
-
else {
|
|
145
|
-
// new entry
|
|
146
|
-
__classPrivateFieldGet(this, _AztecDatastore_memoryDatastore, "f").set(keyStr, { data: val, lastAccessedMs: Date.now() });
|
|
147
|
-
}
|
|
148
|
-
// Always add to DB
|
|
149
|
-
await __classPrivateFieldGet(this, _AztecDatastore_dbDatastore, "f").set(keyStr, val);
|
|
150
|
-
return key;
|
|
151
|
-
}
|
|
152
|
-
async *all() {
|
|
153
|
-
for (const [key, value] of __classPrivateFieldGet(this, _AztecDatastore_memoryDatastore, "f").entries()) {
|
|
154
|
-
yield {
|
|
155
|
-
key: new Key(key),
|
|
156
|
-
value: value.data,
|
|
157
|
-
};
|
|
158
|
-
}
|
|
159
|
-
for (const [key, value] of __classPrivateFieldGet(this, _AztecDatastore_dbDatastore, "f").entries()) {
|
|
160
|
-
if (!__classPrivateFieldGet(this, _AztecDatastore_memoryDatastore, "f").has(key)) {
|
|
161
|
-
yield {
|
|
162
|
-
key: new Key(key),
|
|
163
|
-
value,
|
|
164
|
-
};
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
/**
|
|
169
|
-
* Prune memory store
|
|
170
|
-
*/
|
|
171
|
-
pruneMemoryDatastore() {
|
|
172
|
-
let oldestAccessedMs = Date.now() + 1000;
|
|
173
|
-
let oldestKey = undefined;
|
|
174
|
-
let oldestValue = undefined;
|
|
175
|
-
for (const [key, value] of __classPrivateFieldGet(this, _AztecDatastore_memoryDatastore, "f")) {
|
|
176
|
-
if (value.lastAccessedMs < oldestAccessedMs) {
|
|
177
|
-
oldestAccessedMs = value.lastAccessedMs;
|
|
178
|
-
oldestKey = key;
|
|
179
|
-
oldestValue = value.data;
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
if (oldestKey && oldestValue) {
|
|
183
|
-
__classPrivateFieldGet(this, _AztecDatastore_memoryDatastore, "f").delete(oldestKey);
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
_AztecDatastore_memoryDatastore = new WeakMap(), _AztecDatastore_dbDatastore = new WeakMap(), _AztecDatastore_batchOps = new WeakMap();
|
|
188
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0YV9zdG9yZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zZXJ2aWNlL2RhdGFfc3RvcmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSxPQUFPLEVBQUUsTUFBTSxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFHckUsT0FBTyxFQUE4QixHQUFHLEVBQXdDLE1BQU0scUJBQXFCLENBQUM7QUFjNUcsTUFBTSxnQkFBaUIsU0FBUSxLQUFLO0lBRWxDLFlBQVksT0FBZTtRQUN6QixLQUFLLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDZixJQUFJLENBQUMsSUFBSSxHQUFHLGVBQWUsQ0FBQztJQUM5QixDQUFDO0NBQ0Y7QUFFRCxNQUFNLE9BQU8sY0FBYztJQVF6QixZQUFZLEVBQWdCLEVBQUUsRUFBRSxjQUFjLEVBQUUsR0FBRyxFQUFFLGNBQWMsRUFBRSxFQUFFLEVBQUU7UUFQekUsa0RBQTBDO1FBQzFDLDhDQUEyQztRQUUzQyxtQ0FBdUIsRUFBRSxFQUFDO1FBS3hCLHVCQUFBLElBQUksbUNBQW9CLElBQUksR0FBRyxFQUFFLE1BQUEsQ0FBQztRQUNsQyx1QkFBQSxJQUFJLCtCQUFnQixFQUFFLENBQUMsT0FBTyxDQUFDLGVBQWUsQ0FBQyxNQUFBLENBQUM7UUFFaEQsSUFBSSxDQUFDLGNBQWMsR0FBRyxjQUFjLENBQUM7SUFDdkMsQ0FBQztJQUVELEdBQUcsQ0FBQyxHQUFRO1FBQ1YsT0FBTyx1QkFBQSxJQUFJLHVDQUFpQixDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsUUFBUSxFQUFFLENBQUMsSUFBSSx1QkFBQSxJQUFJLG1DQUFhLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDO0lBQzVGLENBQUM7SUFFRCxHQUFHLENBQUMsR0FBUTtRQUNWLE1BQU0sTUFBTSxHQUFHLEdBQUcsQ0FBQyxRQUFRLEVBQUUsQ0FBQztRQUM5QixN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
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"discV5_service.d.ts","sourceRoot":"","sources":["../../src/service/discV5_service.ts"],"names":[],"mappings":";AAEA,OAAO,EAAsB,KAAK,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAGnF,OAAO,EAAE,GAAG,EAAe,MAAM,gBAAgB,CAAC;AAClD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAEhD,OAAO,YAAY,MAAM,QAAQ,CAAC;AAElC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAE9C,OAAO,EAAE,KAAK,oBAAoB,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAE7E,eAAO,MAAM,aAAa,kBAAkB,CAAC;AAI7C,oBAAY,QAAQ;IAClB,MAAM,IAAO;IACb,OAAO,IAAO;IACd,OAAO,IAAO;CACf;AAGD,eAAO,MAAM,SAAS,kBAAkB,CAAC;AAEzC;;GAEG;AACH,qBAAa,aAAc,SAAQ,YAAa,YAAW,oBAAoB;IAkB3E,OAAO,CAAC,MAAM;IAGd,OAAO,CAAC,MAAM;IApBhB,0BAA0B;IAC1B,OAAO,CAAC,MAAM,CAAS;IAEvB,0BAA0B;IAC1B,OAAO,CAAC,GAAG,CAAc;IAEzB,sBAAsB;IACtB,OAAO,CAAC,kBAAkB,CAAY;IAEtC,OAAO,CAAC,YAAY,CAA8B;IAElD,OAAO,CAAC,cAAc,CAAW;IACjC,OAAO,CAAC,oBAAoB,CAAgB;IAE5C,OAAO,CAAC,SAAS,CAAK;gBAGZ,MAAM,EAAE,MAAM,EACtB,MAAM,EAAE,SAAS,EACjB,SAAS,EAAE,eAAe,EAClB,MAAM,yCAAqC;IAgDxC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IA+BtB,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC;IAmB1C,WAAW,IAAI,GAAG,EAAE;IAIpB,MAAM,IAAI,GAAG;IAIb,SAAS,IAAI,MAAM;IAInB,SAAS,IAAI,kBAAkB;IAI/B,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO;IAIlC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAKlC,OAAO,CAAC,YAAY;CAWrB"}
|
|
@@ -1,144 +0,0 @@
|
|
|
1
|
-
import { createLogger } from '@aztec/foundation/log';
|
|
2
|
-
import { sleep } from '@aztec/foundation/sleep';
|
|
3
|
-
import { OtelMetricsAdapter } from '@aztec/telemetry-client';
|
|
4
|
-
import { Discv5 } from '@chainsafe/discv5';
|
|
5
|
-
import { ENR, SignableENR } from '@chainsafe/enr';
|
|
6
|
-
import { multiaddr } from '@multiformats/multiaddr';
|
|
7
|
-
import EventEmitter from 'events';
|
|
8
|
-
import { convertToMultiaddr } from '../util.js';
|
|
9
|
-
import { PeerDiscoveryState } from './service.js';
|
|
10
|
-
export const AZTEC_ENR_KEY = 'aztec_network';
|
|
11
|
-
const delayBeforeStart = 2000; // 2sec
|
|
12
|
-
export var AztecENR;
|
|
13
|
-
(function (AztecENR) {
|
|
14
|
-
AztecENR[AztecENR["devnet"] = 1] = "devnet";
|
|
15
|
-
AztecENR[AztecENR["testnet"] = 2] = "testnet";
|
|
16
|
-
AztecENR[AztecENR["mainnet"] = 3] = "mainnet";
|
|
17
|
-
})(AztecENR || (AztecENR = {}));
|
|
18
|
-
// TODO: Make this an env var
|
|
19
|
-
export const AZTEC_NET = AztecENR.devnet;
|
|
20
|
-
/**
|
|
21
|
-
* Peer discovery service using Discv5.
|
|
22
|
-
*/
|
|
23
|
-
export class DiscV5Service extends EventEmitter {
|
|
24
|
-
constructor(peerId, config, telemetry, logger = createLogger('p2p:discv5_service')) {
|
|
25
|
-
super();
|
|
26
|
-
this.peerId = peerId;
|
|
27
|
-
this.logger = logger;
|
|
28
|
-
this.currentState = PeerDiscoveryState.STOPPED;
|
|
29
|
-
this.bootstrapNodePeerIds = [];
|
|
30
|
-
this.startTime = 0;
|
|
31
|
-
const { tcpAnnounceAddress, udpAnnounceAddress, udpListenAddress, bootstrapNodes } = config;
|
|
32
|
-
this.bootstrapNodes = bootstrapNodes;
|
|
33
|
-
// create ENR from PeerId
|
|
34
|
-
this.enr = SignableENR.createFromPeerId(peerId);
|
|
35
|
-
// Add aztec identification to ENR
|
|
36
|
-
this.enr.set(AZTEC_ENR_KEY, Uint8Array.from([AZTEC_NET]));
|
|
37
|
-
if (!tcpAnnounceAddress) {
|
|
38
|
-
throw new Error('You need to provide at least a TCP announce address.');
|
|
39
|
-
}
|
|
40
|
-
const multiAddrTcp = multiaddr(`${convertToMultiaddr(tcpAnnounceAddress, 'tcp')}/p2p/${peerId.toString()}`);
|
|
41
|
-
// if no udp announce address is provided, use the tcp announce address
|
|
42
|
-
const multiAddrUdp = multiaddr(`${convertToMultiaddr(udpAnnounceAddress || tcpAnnounceAddress, 'udp')}/p2p/${peerId.toString()}`);
|
|
43
|
-
this.listenMultiAddrUdp = multiaddr(convertToMultiaddr(udpListenAddress, 'udp'));
|
|
44
|
-
// set location multiaddr in ENR record
|
|
45
|
-
this.enr.setLocationMultiaddr(multiAddrUdp);
|
|
46
|
-
this.enr.setLocationMultiaddr(multiAddrTcp);
|
|
47
|
-
const metricsRegistry = new OtelMetricsAdapter(telemetry);
|
|
48
|
-
this.discv5 = Discv5.create({
|
|
49
|
-
enr: this.enr,
|
|
50
|
-
peerId,
|
|
51
|
-
bindAddrs: { ip4: this.listenMultiAddrUdp },
|
|
52
|
-
config: {
|
|
53
|
-
lookupTimeout: 2000,
|
|
54
|
-
requestTimeout: 2000,
|
|
55
|
-
allowUnverifiedSessions: true,
|
|
56
|
-
},
|
|
57
|
-
metricsRegistry,
|
|
58
|
-
});
|
|
59
|
-
this.discv5.on('discovered', (enr) => this.onDiscovered(enr));
|
|
60
|
-
this.discv5.on('enrAdded', async (enr) => {
|
|
61
|
-
const multiAddrTcp = await enr.getFullMultiaddr('tcp');
|
|
62
|
-
const multiAddrUdp = await enr.getFullMultiaddr('udp');
|
|
63
|
-
this.logger.debug(`Added ENR ${enr.encodeTxt()}`, { multiAddrTcp, multiAddrUdp, nodeId: enr.nodeId });
|
|
64
|
-
this.onDiscovered(enr);
|
|
65
|
-
});
|
|
66
|
-
}
|
|
67
|
-
async start() {
|
|
68
|
-
if (this.currentState === PeerDiscoveryState.RUNNING) {
|
|
69
|
-
throw new Error('DiscV5Service already started');
|
|
70
|
-
}
|
|
71
|
-
this.logger.debug('Starting DiscV5');
|
|
72
|
-
await this.discv5.start();
|
|
73
|
-
this.startTime = Date.now();
|
|
74
|
-
this.logger.info(`DiscV5 service started`, {
|
|
75
|
-
nodeId: this.enr.nodeId,
|
|
76
|
-
peerId: this.peerId,
|
|
77
|
-
enrUdp: await this.enr.getFullMultiaddr('udp'),
|
|
78
|
-
enrTcp: await this.enr.getFullMultiaddr('tcp'),
|
|
79
|
-
});
|
|
80
|
-
this.currentState = PeerDiscoveryState.RUNNING;
|
|
81
|
-
// Add bootnode ENR if provided
|
|
82
|
-
if (this.bootstrapNodes?.length) {
|
|
83
|
-
// Do this conversion once since it involves an async function call
|
|
84
|
-
this.bootstrapNodePeerIds = await Promise.all(this.bootstrapNodes.map(enr => ENR.decodeTxt(enr).peerId()));
|
|
85
|
-
this.logger.info(`Adding bootstrap nodes ENRs: ${this.bootstrapNodes.join(', ')}`);
|
|
86
|
-
try {
|
|
87
|
-
this.bootstrapNodes.forEach(enr => {
|
|
88
|
-
this.discv5.addEnr(enr);
|
|
89
|
-
});
|
|
90
|
-
}
|
|
91
|
-
catch (e) {
|
|
92
|
-
this.logger.error(`Error adding bootnode ENRs: ${e}`);
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
async runRandomNodesQuery() {
|
|
97
|
-
if (this.currentState !== PeerDiscoveryState.RUNNING) {
|
|
98
|
-
throw new Error('DiscV5Service not running');
|
|
99
|
-
}
|
|
100
|
-
// First, wait some time before starting the peer discovery
|
|
101
|
-
// reference: https://github.com/ChainSafe/lodestar/issues/3423
|
|
102
|
-
const msSinceStart = Date.now() - this.startTime;
|
|
103
|
-
if (Date.now() - this.startTime <= delayBeforeStart) {
|
|
104
|
-
await sleep(delayBeforeStart - msSinceStart);
|
|
105
|
-
}
|
|
106
|
-
try {
|
|
107
|
-
await this.discv5.findRandomNode();
|
|
108
|
-
}
|
|
109
|
-
catch (err) {
|
|
110
|
-
this.logger.error(`Error running discV5 random node query: ${err}`);
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
getAllPeers() {
|
|
114
|
-
return this.discv5.kadValues();
|
|
115
|
-
}
|
|
116
|
-
getEnr() {
|
|
117
|
-
return this.enr.toENR();
|
|
118
|
-
}
|
|
119
|
-
getPeerId() {
|
|
120
|
-
return this.peerId;
|
|
121
|
-
}
|
|
122
|
-
getStatus() {
|
|
123
|
-
return this.currentState;
|
|
124
|
-
}
|
|
125
|
-
isBootstrapPeer(peerId) {
|
|
126
|
-
return this.bootstrapNodePeerIds.some(node => node.equals(peerId));
|
|
127
|
-
}
|
|
128
|
-
async stop() {
|
|
129
|
-
await this.discv5.stop();
|
|
130
|
-
this.currentState = PeerDiscoveryState.STOPPED;
|
|
131
|
-
}
|
|
132
|
-
onDiscovered(enr) {
|
|
133
|
-
// check the peer is an aztec peer
|
|
134
|
-
const value = enr.kvs.get(AZTEC_ENR_KEY);
|
|
135
|
-
if (value) {
|
|
136
|
-
const network = value[0];
|
|
137
|
-
// check if the peer is on the same network
|
|
138
|
-
if (network === AZTEC_NET) {
|
|
139
|
-
this.emit('peer:discovered', enr);
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGlzY1Y1X3NlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc2VydmljZS9kaXNjVjVfc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDckQsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQ2hELE9BQU8sRUFBRSxrQkFBa0IsRUFBd0IsTUFBTSx5QkFBeUIsQ0FBQztBQUVuRixPQUFPLEVBQUUsTUFBTSxFQUEyQixNQUFNLG1CQUFtQixDQUFDO0FBQ3BFLE9BQU8sRUFBRSxHQUFHLEVBQUUsV0FBVyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFbEQsT0FBTyxFQUFrQixTQUFTLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUNwRSxPQUFPLFlBQVksTUFBTSxRQUFRLENBQUM7QUFHbEMsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sWUFBWSxDQUFDO0FBQ2hELE9BQU8sRUFBNkIsa0JBQWtCLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFFN0UsTUFBTSxDQUFDLE1BQU0sYUFBYSxHQUFHLGVBQWUsQ0FBQztBQUU3QyxNQUFNLGdCQUFnQixHQUFHLElBQUksQ0FBQyxDQUFDLE9BQU87QUFFdEMsTUFBTSxDQUFOLElBQVksUUFJWDtBQUpELFdBQVksUUFBUTtJQUNsQiwyQ0FBYSxDQUFBO0lBQ2IsNkNBQWMsQ0FBQTtJQUNkLDZDQUFjLENBQUE7QUFDaEIsQ0FBQyxFQUpXLFFBQVEsS0FBUixRQUFRLFFBSW5CO0FBRUQsNkJBQTZCO0FBQzdCLE1BQU0sQ0FBQyxNQUFNLFNBQVMsR0FBRyxRQUFRLENBQUMsTUFBTSxDQUFDO0FBRXpDOztHQUVHO0FBQ0gsTUFBTSxPQUFPLGFBQWMsU0FBUSxZQUFZO0lBaUI3QyxZQUNVLE1BQWMsRUFDdEIsTUFBaUIsRUFDakIsU0FBMEIsRUFDbEIsU0FBUyxZQUFZLENBQUMsb0JB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
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"dummy_service.d.ts","sourceRoot":"","sources":["../../src/service/dummy_service.ts"],"names":[],"mappings":";AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,aAAa,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAE1G,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,YAAY,MAAM,QAAQ,CAAC;AAElC,OAAO,EAAE,KAAK,kBAAkB,EAAE,KAAK,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACtF,OAAO,EAAE,KAAK,UAAU,EAAE,KAAK,oBAAoB,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAE9F;;GAEG;AACH,qBAAa,eAAgB,YAAW,UAAU;IAChD,wCAAwC;IACxC,QAAQ,IAAI,QAAQ,EAAE;IAItB;;;OAGG;IACI,KAAK;IAIZ;;;OAGG;IACI,IAAI;IAIX;;;OAGG;IACI,SAAS,CAAC,CAAC,SAAS,UAAU,EAAE,CAAC,EAAE,CAAC;IAE3C;;;OAGG;IACI,UAAU,CAAC,CAAC,EAAE,MAAM,EAAE;IAE7B;;OAEG;IACI,6BAA6B,CAAC,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,OAAO,CAAC,gBAAgB,CAAC;IAE3F;;;;;OAKG;IACI,WAAW,CAAC,QAAQ,SAAS,kBAAkB,EACpD,SAAS,EAAE,QAAQ,EACnB,QAAQ,EAAE,YAAY,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC,SAAS,CAAC,CAAC,GAC1D,OAAO,CAAC,YAAY,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC,UAAU,CAAC,CAAC,GAAG,SAAS,CAAC;IAI1E;;;OAGG;IACI,MAAM,IAAI,SAAS;CAG3B;AAED;;GAEG;AACH,qBAAa,yBAA0B,SAAQ,YAAa,YAAW,oBAAoB;IACzF,OAAO,CAAC,YAAY,CAA8B;IAClD;;;OAGG;IACI,KAAK;IAIZ;;;OAGG;IACI,IAAI;IAIX;;;OAGG;IACI,WAAW;IAIX,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC;IAIpC,eAAe,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO;IAInC,SAAS,IAAI,kBAAkB;IAI/B,MAAM,IAAI,SAAS;CAG3B"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"encoding.d.ts","sourceRoot":"","sources":["../../src/service/encoding.ts"],"names":[],"mappings":";;AAGA,OAAO,EAAE,KAAK,GAAG,EAAE,MAAM,qCAAqC,CAAC;AAC/D,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,mCAAmC,CAAC;AACvE,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAajD;;;GAGG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,GAAG,CAAC,OAAO,GAAG,MAAM,CAKvD;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAItD;AAED;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,OAAO,UAK1C;AAED,qBAAa,eAAgB,YAAW,aAAa;IACnD,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,UAAU;IAKjE,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,UAAU;CAGnE"}
|