@aztec/p2p 0.55.0 → 0.56.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.
Files changed (78) hide show
  1. package/dest/attestation_pool/memory_attestation_pool.d.ts.map +1 -1
  2. package/dest/attestation_pool/memory_attestation_pool.js +8 -7
  3. package/dest/attestation_pool/mocks.d.ts.map +1 -1
  4. package/dest/attestation_pool/mocks.js +6 -5
  5. package/dest/client/index.d.ts +2 -2
  6. package/dest/client/index.d.ts.map +1 -1
  7. package/dest/client/index.js +43 -38
  8. package/dest/client/p2p_client.d.ts.map +1 -1
  9. package/dest/client/p2p_client.js +1 -3
  10. package/dest/config.d.ts +49 -0
  11. package/dest/config.d.ts.map +1 -1
  12. package/dest/config.js +66 -2
  13. package/dest/index.d.ts +1 -0
  14. package/dest/index.d.ts.map +1 -1
  15. package/dest/index.js +2 -1
  16. package/dest/mocks/index.d.ts +13 -4
  17. package/dest/mocks/index.d.ts.map +1 -1
  18. package/dest/mocks/index.js +26 -9
  19. package/dest/service/libp2p_service.d.ts +25 -11
  20. package/dest/service/libp2p_service.d.ts.map +1 -1
  21. package/dest/service/libp2p_service.js +143 -28
  22. package/dest/service/peer_manager.d.ts +9 -13
  23. package/dest/service/peer_manager.d.ts.map +1 -1
  24. package/dest/service/peer_manager.js +15 -1
  25. package/dest/service/peer_scoring.d.ts +32 -0
  26. package/dest/service/peer_scoring.d.ts.map +1 -0
  27. package/dest/service/peer_scoring.js +67 -0
  28. package/dest/service/reqresp/interface.d.ts +7 -0
  29. package/dest/service/reqresp/interface.d.ts.map +1 -1
  30. package/dest/service/reqresp/interface.js +7 -1
  31. package/dest/service/reqresp/rate_limiter/rate_limiter.d.ts +13 -3
  32. package/dest/service/reqresp/rate_limiter/rate_limiter.d.ts.map +1 -1
  33. package/dest/service/reqresp/rate_limiter/rate_limiter.js +29 -7
  34. package/dest/service/reqresp/reqresp.d.ts +56 -5
  35. package/dest/service/reqresp/reqresp.d.ts.map +1 -1
  36. package/dest/service/reqresp/reqresp.js +73 -9
  37. package/dest/tx_validator/aggregate_tx_validator.d.ts +8 -0
  38. package/dest/tx_validator/aggregate_tx_validator.d.ts.map +1 -0
  39. package/dest/tx_validator/aggregate_tx_validator.js +32 -0
  40. package/dest/tx_validator/data_validator.d.ts +7 -0
  41. package/dest/tx_validator/data_validator.d.ts.map +1 -0
  42. package/dest/tx_validator/data_validator.js +50 -0
  43. package/dest/tx_validator/double_spend_validator.d.ts +13 -0
  44. package/dest/tx_validator/double_spend_validator.d.ts.map +1 -0
  45. package/dest/tx_validator/double_spend_validator.js +56 -0
  46. package/dest/tx_validator/index.d.ts +6 -0
  47. package/dest/tx_validator/index.d.ts.map +1 -0
  48. package/dest/tx_validator/index.js +6 -0
  49. package/dest/tx_validator/metadata_validator.d.ts +11 -0
  50. package/dest/tx_validator/metadata_validator.d.ts.map +1 -0
  51. package/dest/tx_validator/metadata_validator.js +53 -0
  52. package/dest/tx_validator/tx_proof_validator.d.ts +9 -0
  53. package/dest/tx_validator/tx_proof_validator.d.ts.map +1 -0
  54. package/dest/tx_validator/tx_proof_validator.js +29 -0
  55. package/dest/util.d.ts +7 -0
  56. package/dest/util.d.ts.map +1 -1
  57. package/dest/util.js +1 -1
  58. package/package.json +6 -6
  59. package/src/attestation_pool/memory_attestation_pool.ts +7 -6
  60. package/src/attestation_pool/mocks.ts +6 -4
  61. package/src/client/index.ts +65 -47
  62. package/src/client/p2p_client.ts +0 -2
  63. package/src/config.ts +127 -0
  64. package/src/index.ts +1 -0
  65. package/src/mocks/index.ts +35 -7
  66. package/src/service/libp2p_service.ts +182 -36
  67. package/src/service/peer_manager.ts +23 -4
  68. package/src/service/peer_scoring.ts +81 -0
  69. package/src/service/reqresp/interface.ts +20 -0
  70. package/src/service/reqresp/rate_limiter/rate_limiter.ts +30 -7
  71. package/src/service/reqresp/reqresp.ts +82 -8
  72. package/src/tx_validator/aggregate_tx_validator.ts +34 -0
  73. package/src/tx_validator/data_validator.ts +65 -0
  74. package/src/tx_validator/double_spend_validator.ts +69 -0
  75. package/src/tx_validator/index.ts +5 -0
  76. package/src/tx_validator/metadata_validator.ts +65 -0
  77. package/src/tx_validator/tx_proof_validator.ts +28 -0
  78. package/src/util.ts +8 -0
@@ -4,7 +4,7 @@ import { bootstrap } from '@libp2p/bootstrap';
4
4
  import { tcp } from '@libp2p/tcp';
5
5
  import { createLibp2p } from 'libp2p';
6
6
  import { pingHandler, statusHandler } from '../service/reqresp/handlers.js';
7
- import { PING_PROTOCOL, STATUS_PROTOCOL, TX_REQ_PROTOCOL, } from '../service/reqresp/interface.js';
7
+ import { PING_PROTOCOL, STATUS_PROTOCOL, TX_REQ_PROTOCOL, noopValidator, } from '../service/reqresp/interface.js';
8
8
  import { ReqResp } from '../service/reqresp/reqresp.js';
9
9
  /**
10
10
  * Creates a libp2p node, pre configured.
@@ -35,17 +35,23 @@ export const MOCK_SUB_PROTOCOL_HANDLERS = {
35
35
  [STATUS_PROTOCOL]: statusHandler,
36
36
  [TX_REQ_PROTOCOL]: (_msg) => Promise.resolve(Uint8Array.from(Buffer.from('tx'))),
37
37
  };
38
+ // By default, all requests are valid
39
+ // If you want to test an invalid response, you can override the validator
40
+ export const MOCK_SUB_PROTOCOL_VALIDATORS = {
41
+ [PING_PROTOCOL]: noopValidator,
42
+ [STATUS_PROTOCOL]: noopValidator,
43
+ [TX_REQ_PROTOCOL]: noopValidator,
44
+ };
38
45
  /**
39
46
  * @param numberOfNodes - the number of nodes to create
40
47
  * @returns An array of the created nodes
41
48
  */
42
- export const createNodes = async (numberOfNodes) => {
43
- return await Promise.all(Array.from({ length: numberOfNodes }, () => createReqResp()));
49
+ export const createNodes = async (peerManager, numberOfNodes) => {
50
+ return await Promise.all(Array.from({ length: numberOfNodes }, () => createReqResp(peerManager)));
44
51
  };
45
- // TODO: think about where else this can go
46
- export const startNodes = async (nodes, subProtocolHandlers = MOCK_SUB_PROTOCOL_HANDLERS) => {
52
+ export const startNodes = async (nodes, subProtocolHandlers = MOCK_SUB_PROTOCOL_HANDLERS, subProtocolValidators = MOCK_SUB_PROTOCOL_VALIDATORS) => {
47
53
  for (const node of nodes) {
48
- await node.req.start(subProtocolHandlers);
54
+ await node.req.start(subProtocolHandlers, subProtocolValidators);
49
55
  }
50
56
  };
51
57
  export const stopNodes = async (nodes) => {
@@ -55,13 +61,13 @@ export const stopNodes = async (nodes) => {
55
61
  }
56
62
  };
57
63
  // Create a req resp node, exposing the underlying p2p node
58
- export const createReqResp = async () => {
64
+ export const createReqResp = async (peerManager) => {
59
65
  const p2p = await createLibp2pNode();
60
66
  const config = {
61
67
  overallRequestTimeoutMs: 4000,
62
68
  individualRequestTimeoutMs: 2000,
63
69
  };
64
- const req = new ReqResp(config, p2p);
70
+ const req = new ReqResp(config, p2p, peerManager);
65
71
  return {
66
72
  p2p,
67
73
  req,
@@ -79,4 +85,15 @@ export const connectToPeers = async (nodes) => {
79
85
  }
80
86
  }
81
87
  };
82
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvbW9ja3MvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQ2hELE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUNoRCxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFDOUMsT0FBTyxFQUFFLEdBQUcsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUNsQyxPQUFPLEVBQW1DLFlBQVksRUFBRSxNQUFNLFFBQVEsQ0FBQztBQUd2RSxPQUFPLEVBQUUsV0FBVyxFQUFFLGFBQWEsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBQzVFLE9BQU8sRUFDTCxhQUFhLEVBRWIsZUFBZSxFQUNmLGVBQWUsR0FDaEIsTUFBTSxpQ0FBaUMsQ0FBQztBQUN6QyxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFFeEQ7Ozs7R0FJRztBQUNILE1BQU0sQ0FBQyxLQUFLLFVBQVUsZ0JBQWdCLENBQUMsZ0JBQTBCLEVBQUU7SUFDakUsTUFBTSxPQUFPLEdBQWtCO1FBQzdCLFNBQVMsRUFBRTtZQUNULE1BQU0sRUFBRSxDQUFDLG9CQUFvQixDQUFDO1NBQy9CO1FBQ0Qsb0JBQW9CLEVBQUUsQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUMvQixZQUFZLEVBQUUsQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUN2QixVQUFVLEVBQUUsQ0FBQyxHQUFHLEVBQUUsQ0FBQztLQUNwQixDQUFDO0lBRUYsSUFBSSxhQUFhLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDO1FBQzdCLE9BQU8sQ0FBQyxhQUFhLEdBQUc7WUFDdEIsU0FBUyxDQUFDO2dCQUNSLElBQUksRUFBRSxhQUFhO2FBQ3BCLENBQUM7U0FDSCxDQUFDO0lBQ0osQ0FBQztJQUVELE9BQU8sTUFBTSxZQUFZLENB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
88
+ // Mock circuit verifier for testing - reimplementation from bb to avoid dependency
89
+ export class AlwaysTrueCircuitVerifier {
90
+ verifyProof(_tx) {
91
+ return Promise.resolve(true);
92
+ }
93
+ }
94
+ export class AlwaysFalseCircuitVerifier {
95
+ verifyProof(_tx) {
96
+ return Promise.resolve(false);
97
+ }
98
+ }
99
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvbW9ja3MvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBRUEsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQ2hELE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUNoRCxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFDOUMsT0FBTyxFQUFFLEdBQUcsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUNsQyxPQUFPLEVBQW1DLFlBQVksRUFBRSxNQUFNLFFBQVEsQ0FBQztBQUl2RSxPQUFPLEVBQUUsV0FBVyxFQUFFLGFBQWEsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBQzVFLE9BQU8sRUFDTCxhQUFhLEVBR2IsZUFBZSxFQUNmLGVBQWUsRUFDZixhQUFhLEdBQ2QsTUFBTSxpQ0FBaUMsQ0FBQztBQUN6QyxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFFeEQ7Ozs7R0FJRztBQUNILE1BQU0sQ0FBQyxLQUFLLFVBQVUsZ0JBQWdCLENBQUMsZ0JBQTBCLEVBQUU7SUFDakUsTUFBTSxPQUFPLEdBQWtCO1FBQzdCLFNBQVMsRUFBRTtZQUNULE1BQU0sRUFBRSxDQUFDLG9CQUFvQixDQUFDO1NBQy9CO1FBQ0Qsb0JBQW9CLEVBQUUsQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUMvQixZQUFZLEVBQUUsQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUN2QixVQUFVLEVBQUUsQ0FBQyxHQUFHLEVBQUUsQ0FBQztLQUNwQixDQUFDO0lBRUYsSUFBSSxhQUFhLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDO1FBQzdCLE9BQU8sQ0FBQyxhQUFhLEdBQUc7WUFDdEIsU0FBUyxDQUFDO2dCQUNSLElBQUksRUFBRSxhQUFhO2FBQ3BCLENBQUM7U0FDSCxDQUFDO0lBQ0osQ0FBQztJQUVELE9BQU8sTUFB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
@@ -1,20 +1,14 @@
1
- import { BlockAttestation, BlockProposal, type Gossipable } from '@aztec/circuit-types';
1
+ import { BlockAttestation, BlockProposal, type ClientProtocolCircuitVerifier, type Gossipable, type L2BlockSource, type WorldStateSynchronizer } from '@aztec/circuit-types';
2
2
  import type { AztecKVStore } from '@aztec/kv-store';
3
3
  import { type ENR } from '@chainsafe/enr';
4
- import { type GossipsubEvents } from '@chainsafe/libp2p-gossipsub';
5
- import type { PeerId, PubSub } from '@libp2p/interface';
4
+ import type { PeerId } from '@libp2p/interface';
6
5
  import '@libp2p/kad-dht';
7
- import { type Libp2p } from 'libp2p';
8
6
  import { type AttestationPool } from '../attestation_pool/attestation_pool.js';
9
7
  import { type P2PConfig } from '../config.js';
10
8
  import { type TxPool } from '../tx_pool/index.js';
9
+ import { type PubSubLibp2p } from '../util.js';
11
10
  import { type ReqRespSubProtocol, type ReqRespSubProtocolHandlers, type SubProtocolMap } from './reqresp/interface.js';
12
11
  import type { P2PService, PeerDiscoveryService } from './service.js';
13
- export interface PubSubLibp2p extends Libp2p {
14
- services: {
15
- pubsub: PubSub<GossipsubEvents>;
16
- };
17
- }
18
12
  /**
19
13
  * Create a libp2p peer ID from the private key if provided, otherwise creates a new random ID.
20
14
  * @param privateKey - Optional peer ID private key as hex string
@@ -30,6 +24,9 @@ export declare class LibP2PService implements P2PService {
30
24
  private peerDiscoveryService;
31
25
  private txPool;
32
26
  private attestationPool;
27
+ private l2BlockSource;
28
+ private proofVerifier;
29
+ private worldStateSynchronizer;
33
30
  private requestResponseHandlers;
34
31
  private logger;
35
32
  private jobQueue;
@@ -42,7 +39,7 @@ export declare class LibP2PService implements P2PService {
42
39
  * @returns The attestation for the block, if any.
43
40
  */
44
41
  private blockReceivedCallback;
45
- constructor(config: P2PConfig, node: PubSubLibp2p, peerDiscoveryService: PeerDiscoveryService, txPool: TxPool, attestationPool: AttestationPool, requestResponseHandlers?: ReqRespSubProtocolHandlers, logger?: import("@aztec/foundation/log").Logger);
42
+ constructor(config: P2PConfig, node: PubSubLibp2p, peerDiscoveryService: PeerDiscoveryService, txPool: TxPool, attestationPool: AttestationPool, l2BlockSource: L2BlockSource, proofVerifier: ClientProtocolCircuitVerifier, worldStateSynchronizer: WorldStateSynchronizer, requestResponseHandlers?: ReqRespSubProtocolHandlers, logger?: import("@aztec/foundation/log").Logger);
46
43
  /**
47
44
  * Starts the LibP2P service.
48
45
  * @returns An empty promise.
@@ -59,7 +56,7 @@ export declare class LibP2PService implements P2PService {
59
56
  * @param txPool - The transaction pool to be accessed by the service.
60
57
  * @returns The new service.
61
58
  */
62
- static new(config: P2PConfig, peerDiscoveryService: PeerDiscoveryService, peerId: PeerId, txPool: TxPool, attestationPool: AttestationPool, store: AztecKVStore): Promise<LibP2PService>;
59
+ static new(config: P2PConfig, peerDiscoveryService: PeerDiscoveryService, peerId: PeerId, txPool: TxPool, attestationPool: AttestationPool, l2BlockSource: L2BlockSource, proofVerifier: ClientProtocolCircuitVerifier, worldStateSynchronizer: WorldStateSynchronizer, store: AztecKVStore): Promise<LibP2PService>;
63
60
  /**
64
61
  * Send Request via the ReqResp service
65
62
  * The subprotocol defined will determine the request and response types
@@ -114,6 +111,23 @@ export declare class LibP2PService implements P2PService {
114
111
  */
115
112
  propagate<T extends Gossipable>(message: T): void;
116
113
  private processTxFromPeer;
114
+ /**
115
+ * Validate a tx that has been requested from a peer.
116
+ *
117
+ * The core component of this validator is that the tx hash MUST match the requested tx hash,
118
+ * In order to perform this check, the tx proof must be verified.
119
+ *
120
+ * Note: This function is called from within `ReqResp.sendRequest` as part of the
121
+ * TX_REQ_PROTOCOL subprotocol validation.
122
+ *
123
+ * @param requestedTxHash - The hash of the tx that was requested.
124
+ * @param responseTx - The tx that was received as a response to the request.
125
+ * @param peerId - The peer ID of the peer that sent the tx.
126
+ * @returns True if the tx is valid, false otherwise.
127
+ */
128
+ private validateRequestedTx;
129
+ private validatePropagatedTx;
130
+ getPeerScore(peerId: PeerId): number;
117
131
  private sendToPeers;
118
132
  private stopLibP2P;
119
133
  }
@@ -1 +1 @@
1
- {"version":3,"file":"libp2p_service.d.ts","sourceRoot":"","sources":["../../src/service/libp2p_service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"libp2p_service.d.ts","sourceRoot":"","sources":["../../src/service/libp2p_service.ts"],"names":[],"mappings":"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"}
@@ -1,8 +1,10 @@
1
- import { BlockAttestation, BlockProposal, TopicType, TopicTypeMap, Tx, TxHash, } from '@aztec/circuit-types';
1
+ import { BlockAttestation, BlockProposal, MerkleTreeId, TopicType, TopicTypeMap, Tx, TxHash, } from '@aztec/circuit-types';
2
+ import { Fr } from '@aztec/circuits.js';
2
3
  import { createDebugLogger } from '@aztec/foundation/log';
3
4
  import { SerialQueue } from '@aztec/foundation/queue';
4
5
  import { RunningPromise } from '@aztec/foundation/running-promise';
5
6
  import { gossipsub } from '@chainsafe/libp2p-gossipsub';
7
+ import { createPeerScoreParams, createTopicScoreParams } from '@chainsafe/libp2p-gossipsub/score';
6
8
  import { noise } from '@chainsafe/libp2p-noise';
7
9
  import { yamux } from '@chainsafe/libp2p-yamux';
8
10
  import { identify } from '@libp2p/identify';
@@ -11,11 +13,13 @@ import { mplex } from '@libp2p/mplex';
11
13
  import { createFromJSON, createSecp256k1PeerId } from '@libp2p/peer-id-factory';
12
14
  import { tcp } from '@libp2p/tcp';
13
15
  import { createLibp2p } from 'libp2p';
16
+ import { DataTxValidator, DoubleSpendTxValidator, MetadataTxValidator, TxProofValidator, } from '../tx_validator/index.js';
14
17
  import { convertToMultiaddr } from '../util.js';
15
18
  import { AztecDatastore } from './data_store.js';
16
19
  import { PeerManager } from './peer_manager.js';
20
+ import { PeerErrorSeverity } from './peer_scoring.js';
17
21
  import { pingHandler, statusHandler } from './reqresp/handlers.js';
18
- import { DEFAULT_SUB_PROTOCOL_HANDLERS, PING_PROTOCOL, STATUS_PROTOCOL, TX_REQ_PROTOCOL, subProtocolMap, } from './reqresp/interface.js';
22
+ import { DEFAULT_SUB_PROTOCOL_HANDLERS, DEFAULT_SUB_PROTOCOL_VALIDATORS, PING_PROTOCOL, STATUS_PROTOCOL, TX_REQ_PROTOCOL, } from './reqresp/interface.js';
19
23
  import { ReqResp } from './reqresp/reqresp.js';
20
24
  /**
21
25
  * Create a libp2p peer ID from the private key if provided, otherwise creates a new random ID.
@@ -36,17 +40,24 @@ export async function createLibP2PPeerId(privateKey) {
36
40
  * Lib P2P implementation of the P2PService interface.
37
41
  */
38
42
  export class LibP2PService {
39
- constructor(config, node, peerDiscoveryService, txPool, attestationPool, requestResponseHandlers = DEFAULT_SUB_PROTOCOL_HANDLERS, logger = createDebugLogger('aztec:libp2p_service')) {
43
+ constructor(config, node, peerDiscoveryService, txPool, attestationPool, l2BlockSource, proofVerifier, worldStateSynchronizer, requestResponseHandlers = DEFAULT_SUB_PROTOCOL_HANDLERS, logger = createDebugLogger('aztec:libp2p_service')) {
40
44
  this.config = config;
41
45
  this.node = node;
42
46
  this.peerDiscoveryService = peerDiscoveryService;
43
47
  this.txPool = txPool;
44
48
  this.attestationPool = attestationPool;
49
+ this.l2BlockSource = l2BlockSource;
50
+ this.proofVerifier = proofVerifier;
51
+ this.worldStateSynchronizer = worldStateSynchronizer;
45
52
  this.requestResponseHandlers = requestResponseHandlers;
46
53
  this.logger = logger;
47
54
  this.jobQueue = new SerialQueue();
48
55
  this.peerManager = new PeerManager(node, peerDiscoveryService, config, logger);
49
- this.reqresp = new ReqResp(config, node);
56
+ this.node.services.pubsub.score.params.appSpecificScore = (peerId) => {
57
+ return this.peerManager.getPeerScore(peerId);
58
+ };
59
+ this.node.services.pubsub.score.params.appSpecificWeight = 10;
60
+ this.reqresp = new ReqResp(config, node, this.peerManager);
50
61
  this.blockReceivedCallback = (block) => {
51
62
  this.logger.verbose(`[WARNING] handler not yet registered: Block received callback not set. Received block ${block.p2pMessageIdentifier()} from peer.`);
52
63
  return Promise.resolve(undefined);
@@ -80,16 +91,21 @@ export class LibP2PService {
80
91
  }
81
92
  // add GossipSub listener
82
93
  this.node.services.pubsub.addEventListener('gossipsub:message', async (e) => {
83
- const { msg } = e.detail;
94
+ const { msg, propagationSource: peerId } = e.detail;
84
95
  this.logger.debug(`Received PUBSUB message.`);
85
- await this.jobQueue.put(() => this.handleNewGossipMessage(msg));
96
+ await this.jobQueue.put(() => this.handleNewGossipMessage(msg, peerId));
86
97
  });
87
98
  // Start running promise for peer discovery
88
99
  this.discoveryRunningPromise = new RunningPromise(() => {
89
- this.peerManager.discover();
100
+ this.peerManager.heartbeat();
90
101
  }, this.config.peerCheckIntervalMS);
91
102
  this.discoveryRunningPromise.start();
92
- await this.reqresp.start(this.requestResponseHandlers);
103
+ // Define the sub protocol validators - This is done within this start() method to gain a callback to the existing validateTx function
104
+ const reqrespSubProtocolValidators = {
105
+ ...DEFAULT_SUB_PROTOCOL_VALIDATORS,
106
+ [TX_REQ_PROTOCOL]: this.validateRequestedTx.bind(this),
107
+ };
108
+ await this.reqresp.start(this.requestResponseHandlers, reqrespSubProtocolValidators);
93
109
  }
94
110
  /**
95
111
  * Stops the LibP2P service.
@@ -115,7 +131,7 @@ export class LibP2PService {
115
131
  * @param txPool - The transaction pool to be accessed by the service.
116
132
  * @returns The new service.
117
133
  */
118
- static async new(config, peerDiscoveryService, peerId, txPool, attestationPool, store) {
134
+ static async new(config, peerDiscoveryService, peerId, txPool, attestationPool, l2BlockSource, proofVerifier, worldStateSynchronizer, store) {
119
135
  const { tcpListenAddress, tcpAnnounceAddress, minPeerCount, maxPeerCount } = config;
120
136
  const bindAddrTcp = convertToMultiaddr(tcpListenAddress, 'tcp');
121
137
  // We know tcpAnnounceAddress cannot be null here because we set it or throw when setting up the service.
@@ -154,12 +170,21 @@ export class LibP2PService {
154
170
  }),
155
171
  pubsub: gossipsub({
156
172
  allowPublishToZeroTopicPeers: true,
157
- D: 6,
158
- Dlo: 4,
159
- Dhi: 12,
160
- heartbeatInterval: 1000,
161
- mcacheLength: 5,
162
- mcacheGossip: 3,
173
+ D: config.gossipsubD,
174
+ Dlo: config.gossipsubDlo,
175
+ Dhi: config.gossipsubDhi,
176
+ heartbeatInterval: config.gossipsubInterval,
177
+ mcacheLength: config.gossipsubMcacheLength,
178
+ mcacheGossip: config.gossipsubMcacheGossip,
179
+ scoreParams: createPeerScoreParams({
180
+ topics: {
181
+ [Tx.p2pTopic]: createTopicScoreParams({
182
+ topicWeight: 1,
183
+ invalidMessageDeliveriesWeight: -20,
184
+ invalidMessageDeliveriesDecay: 0.5,
185
+ }),
186
+ },
187
+ }),
163
188
  }),
164
189
  },
165
190
  });
@@ -180,7 +205,7 @@ export class LibP2PService {
180
205
  [STATUS_PROTOCOL]: statusHandler,
181
206
  [TX_REQ_PROTOCOL]: txHandler,
182
207
  };
183
- return new LibP2PService(config, node, peerDiscoveryService, txPool, attestationPool, requestResponseHandlers);
208
+ return new LibP2PService(config, node, peerDiscoveryService, txPool, attestationPool, l2BlockSource, proofVerifier, worldStateSynchronizer, requestResponseHandlers);
184
209
  }
185
210
  /**
186
211
  * Send Request via the ReqResp service
@@ -192,13 +217,8 @@ export class LibP2PService {
192
217
  * @param request The request type to send
193
218
  * @returns
194
219
  */
195
- async sendRequest(protocol, request) {
196
- const pair = subProtocolMap[protocol];
197
- const res = await this.reqresp.sendRequest(protocol, request.toBuffer());
198
- if (!res) {
199
- return undefined;
200
- }
201
- return pair.response.fromBuffer(res);
220
+ sendRequest(protocol, request) {
221
+ return this.reqresp.sendRequest(protocol, request);
202
222
  }
203
223
  /**
204
224
  * Get the ENR of the node
@@ -239,10 +259,10 @@ export class LibP2PService {
239
259
  * @param topic - The message's topic.
240
260
  * @param data - The message data
241
261
  */
242
- async handleNewGossipMessage(message) {
262
+ async handleNewGossipMessage(message, peerId) {
243
263
  if (message.topic === Tx.p2pTopic) {
244
264
  const tx = Tx.fromBuffer(Buffer.from(message.data));
245
- await this.processTxFromPeer(tx);
265
+ await this.processTxFromPeer(tx, peerId);
246
266
  }
247
267
  if (message.topic === BlockAttestation.p2pTopic) {
248
268
  const attestation = BlockAttestation.fromBuffer(Buffer.from(message.data));
@@ -286,11 +306,106 @@ export class LibP2PService {
286
306
  propagate(message) {
287
307
  void this.jobQueue.put(() => Promise.resolve(this.sendToPeers(message)));
288
308
  }
289
- async processTxFromPeer(tx) {
309
+ async processTxFromPeer(tx, peerId) {
290
310
  const txHash = tx.getTxHash();
291
311
  const txHashString = txHash.toString();
292
312
  this.logger.verbose(`Received tx ${txHashString} from external peer.`);
293
- await this.txPool.addTxs([tx]);
313
+ const isValidTx = await this.validatePropagatedTx(tx, peerId);
314
+ if (isValidTx) {
315
+ await this.txPool.addTxs([tx]);
316
+ }
317
+ }
318
+ /**
319
+ * Validate a tx that has been requested from a peer.
320
+ *
321
+ * The core component of this validator is that the tx hash MUST match the requested tx hash,
322
+ * In order to perform this check, the tx proof must be verified.
323
+ *
324
+ * Note: This function is called from within `ReqResp.sendRequest` as part of the
325
+ * TX_REQ_PROTOCOL subprotocol validation.
326
+ *
327
+ * @param requestedTxHash - The hash of the tx that was requested.
328
+ * @param responseTx - The tx that was received as a response to the request.
329
+ * @param peerId - The peer ID of the peer that sent the tx.
330
+ * @returns True if the tx is valid, false otherwise.
331
+ */
332
+ async validateRequestedTx(requestedTxHash, responseTx, peerId) {
333
+ const proofValidator = new TxProofValidator(this.proofVerifier);
334
+ const validProof = await proofValidator.validateTx(responseTx);
335
+ // If the node returns the wrong data, we penalize it
336
+ if (!requestedTxHash.equals(responseTx.getTxHash())) {
337
+ // Returning the wrong data is a low tolerance error
338
+ this.peerManager.penalizePeer(peerId, PeerErrorSeverity.MidToleranceError);
339
+ return false;
340
+ }
341
+ if (!validProof) {
342
+ // If the proof is invalid, but the txHash is correct, then this is an active attack and we severly punish
343
+ this.peerManager.penalizePeer(peerId, PeerErrorSeverity.LowToleranceError);
344
+ return false;
345
+ }
346
+ return true;
347
+ }
348
+ async validatePropagatedTx(tx, peerId) {
349
+ const blockNumber = (await this.l2BlockSource.getBlockNumber()) + 1;
350
+ // basic data validation
351
+ const dataValidator = new DataTxValidator();
352
+ const validData = await dataValidator.validateTx(tx);
353
+ if (!validData) {
354
+ // penalize
355
+ this.node.services.pubsub.score.markInvalidMessageDelivery(peerId.toString(), Tx.p2pTopic);
356
+ return false;
357
+ }
358
+ // metadata validation
359
+ const metadataValidator = new MetadataTxValidator(new Fr(this.config.l1ChainId), new Fr(blockNumber));
360
+ const validMetadata = await metadataValidator.validateTx(tx);
361
+ if (!validMetadata) {
362
+ // penalize
363
+ this.node.services.pubsub.score.markInvalidMessageDelivery(peerId.toString(), Tx.p2pTopic);
364
+ return false;
365
+ }
366
+ // double spend validation
367
+ const doubleSpendValidator = new DoubleSpendTxValidator({
368
+ getNullifierIndex: async (nullifier) => {
369
+ const merkleTree = this.worldStateSynchronizer.getLatest();
370
+ const index = await merkleTree.findLeafIndex(MerkleTreeId.NULLIFIER_TREE, nullifier.toBuffer());
371
+ return index;
372
+ },
373
+ });
374
+ const validDoubleSpend = await doubleSpendValidator.validateTx(tx);
375
+ if (!validDoubleSpend) {
376
+ // check if nullifier is older than 20 blocks
377
+ if (blockNumber - this.config.severePeerPenaltyBlockLength > 0) {
378
+ const snapshotValidator = new DoubleSpendTxValidator({
379
+ getNullifierIndex: async (nullifier) => {
380
+ const merkleTree = this.worldStateSynchronizer.getSnapshot(blockNumber - this.config.severePeerPenaltyBlockLength);
381
+ const index = await merkleTree.findLeafIndex(MerkleTreeId.NULLIFIER_TREE, nullifier.toBuffer());
382
+ return index;
383
+ },
384
+ });
385
+ const validSnapshot = await snapshotValidator.validateTx(tx);
386
+ // High penalty if nullifier is older than 20 blocks
387
+ if (!validSnapshot) {
388
+ // penalize
389
+ this.peerManager.penalizePeer(peerId, PeerErrorSeverity.LowToleranceError);
390
+ return false;
391
+ }
392
+ }
393
+ // penalize
394
+ this.peerManager.penalizePeer(peerId, PeerErrorSeverity.HighToleranceError);
395
+ return false;
396
+ }
397
+ // proof validation
398
+ const proofValidator = new TxProofValidator(this.proofVerifier);
399
+ const validProof = await proofValidator.validateTx(tx);
400
+ if (!validProof) {
401
+ // penalize
402
+ this.peerManager.penalizePeer(peerId, PeerErrorSeverity.MidToleranceError);
403
+ return false;
404
+ }
405
+ return true;
406
+ }
407
+ getPeerScore(peerId) {
408
+ return this.node.services.pubsub.score.score(peerId.toString());
294
409
  }
295
410
  async sendToPeers(message) {
296
411
  const parent = message.constructor;
@@ -314,4 +429,4 @@ export class LibP2PService {
314
429
  }
315
430
  }
316
431
  }
317
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGlicDJwX3NlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc2VydmljZS9saWJwMnBfc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsZ0JBQWdCLEVBQ2hCLGFBQWEsRUFHYixTQUFTLEVBQ1QsWUFBWSxFQUNaLEVBQUUsRUFDRixNQUFNLEdBQ1AsTUFBTSxzQkFBc0IsQ0FBQztBQUM5QixPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUMxRCxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDdEQsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLG1DQUFtQyxDQUFDO0FBSW5FLE9BQU8sRUFBd0IsU0FBUyxFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFDOUUsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQ2hELE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUNoRCxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFFNUMsT0FBTyxpQkFBaUIsQ0FBQztBQUN6QixPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3RDLE9BQU8sRUFBRSxjQUFjLEVBQUUscUJBQXFCLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUNoRixPQUFPLEVBQUUsR0FBRyxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQ2xDLE9BQU8sRUFBZSxZQUFZLEVBQUUsTUFBTSxRQUFRLENBQUM7QUFLbkQsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sWUFBWSxDQUFDO0FBQ2hELE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUNqRCxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFDaEQsT0FBTyxFQUFFLFdBQVcsRUFBRSxhQUFhLEVBQUUsTUFBTSx1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
432
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGlicDJwX3NlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc2VydmljZS9saWJwMnBfc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsZ0JBQWdCLEVBQ2hCLGFBQWEsRUFJYixZQUFZLEVBRVosU0FBUyxFQUNULFlBQVksRUFDWixFQUFFLEVBQ0YsTUFBTSxHQUVQLE1BQU0sc0JBQXNCLENBQUM7QUFDOUIsT0FBTyxFQUFFLEVBQUUsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQ3hDLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBQzFELE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUN0RCxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sbUNBQW1DLENBQUM7QUFJbkUsT0FBTyxFQUE0QyxTQUFTLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUNsRyxPQUFPLEVBQUUscUJBQXFCLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSxtQ0FBbUMsQ0FBQztBQUNsRyxPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDaEQsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQ2hELE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUU1QyxPQUFPLGlCQUFpQixDQUFDO0FBQ3pCLE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDdEMsT0FBTyxFQUFFLGNBQWMsRUFBRSxxQkFBcUIsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQ2hGLE9BQU8sRUFBRSxHQUFHLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFDbEMsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLFFBQVEsQ0FBQztBQUt0QyxPQUFPLEVBQ0wsZUFBZSxFQUNmLHNCQUFzQixFQUN0QixtQkFBbUIsRUFDbkIsZ0JBQWdCLEdB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
@@ -1,34 +1,30 @@
1
- import { type ENR } from '@chainsafe/enr';
2
1
  import { type PeerId } from '@libp2p/interface';
3
- import { type Multiaddr } from '@multiformats/multiaddr';
4
- import { type Libp2p } from 'libp2p';
5
2
  import { type P2PConfig } from '../config.js';
3
+ import { type PubSubLibp2p } from '../util.js';
4
+ import { type PeerErrorSeverity } from './peer_scoring.js';
6
5
  import { type PeerDiscoveryService } from './service.js';
7
- type CachedPeer = {
8
- peerId: PeerId;
9
- enr: ENR;
10
- multiaddrTcp: Multiaddr;
11
- dialAttempts: number;
12
- };
13
6
  export declare class PeerManager {
14
7
  private libP2PNode;
15
8
  private peerDiscoveryService;
16
9
  private config;
17
10
  private logger;
18
11
  private cachedPeers;
19
- constructor(libP2PNode: Libp2p, peerDiscoveryService: PeerDiscoveryService, config: P2PConfig, logger?: import("@aztec/foundation/log").Logger);
12
+ private peerScoring;
13
+ constructor(libP2PNode: PubSubLibp2p, peerDiscoveryService: PeerDiscoveryService, config: P2PConfig, logger?: import("@aztec/foundation/log").Logger);
14
+ heartbeat(): void;
15
+ penalizePeer(peerId: PeerId, penalty: PeerErrorSeverity): void;
16
+ getPeerScore(peerId: string): number;
20
17
  /**
21
18
  * Discovers peers.
22
19
  */
23
- discover(): void;
20
+ private discover;
24
21
  /**
25
22
  * Handles a discovered peer.
26
23
  * @param enr - The discovered peer's ENR.
27
24
  */
28
25
  private handleDiscoveredPeer;
29
- dialPeer(peer: CachedPeer): Promise<void>;
26
+ private dialPeer;
30
27
  private shouldDialPeer;
31
28
  private pruneCachedPeers;
32
29
  }
33
- export {};
34
30
  //# sourceMappingURL=peer_manager.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"peer_manager.d.ts","sourceRoot":"","sources":["../../src/service/peer_manager.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,GAAG,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,KAAK,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,EAAE,KAAK,MAAM,EAAE,MAAM,QAAQ,CAAC;AAErC,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,KAAK,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAKzD,KAAK,UAAU,GAAG;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,GAAG,CAAC;IACT,YAAY,EAAE,SAAS,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,qBAAa,WAAW;IAGpB,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,oBAAoB;IAC5B,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,MAAM;IALhB,OAAO,CAAC,WAAW,CAAsC;gBAE/C,UAAU,EAAE,MAAM,EAClB,oBAAoB,EAAE,oBAAoB,EAC1C,MAAM,EAAE,SAAS,EACjB,MAAM,yCAA8C;IA4B9D;;OAEG;IACI,QAAQ;IAkDf;;;OAGG;YACW,oBAAoB;IA8C5B,QAAQ,CAAC,IAAI,EAAE,UAAU;IAkB/B,OAAO,CAAC,cAAc;IAUtB,OAAO,CAAC,gBAAgB;CAezB"}
1
+ {"version":3,"file":"peer_manager.d.ts","sourceRoot":"","sources":["../../src/service/peer_manager.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAGhD,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,EAAE,KAAK,iBAAiB,EAAe,MAAM,mBAAmB,CAAC;AACxE,OAAO,EAAE,KAAK,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAYzD,qBAAa,WAAW;IAKpB,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,oBAAoB;IAC5B,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,MAAM;IAPhB,OAAO,CAAC,WAAW,CAAsC;IACzD,OAAO,CAAC,WAAW,CAAc;gBAGvB,UAAU,EAAE,YAAY,EACxB,oBAAoB,EAAE,oBAAoB,EAC1C,MAAM,EAAE,SAAS,EACjB,MAAM,yCAA8C;IA6BvD,SAAS;IAKT,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,iBAAiB;IAMvD,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;IAI3C;;OAEG;IACH,OAAO,CAAC,QAAQ;IAkDhB;;;OAGG;YACW,oBAAoB;YA8CpB,QAAQ;IAkBtB,OAAO,CAAC,cAAc;IAUtB,OAAO,CAAC,gBAAgB;CAezB"}
@@ -1,4 +1,5 @@
1
1
  import { createDebugLogger } from '@aztec/foundation/log';
2
+ import { PeerScoring } from './peer_scoring.js';
2
3
  const MAX_DIAL_ATTEMPTS = 3;
3
4
  const MAX_CACHED_PEERS = 100;
4
5
  export class PeerManager {
@@ -8,6 +9,7 @@ export class PeerManager {
8
9
  this.config = config;
9
10
  this.logger = logger;
10
11
  this.cachedPeers = new Map();
12
+ this.peerScoring = new PeerScoring(config);
11
13
  // Handle new established connections
12
14
  this.libP2PNode.addEventListener('peer:connect', evt => {
13
15
  const peerId = evt.detail;
@@ -33,6 +35,18 @@ export class PeerManager {
33
35
  await this.handleDiscoveredPeer(enr);
34
36
  });
35
37
  }
38
+ heartbeat() {
39
+ this.discover();
40
+ this.peerScoring.decayAllScores();
41
+ }
42
+ penalizePeer(peerId, penalty) {
43
+ const id = peerId.toString();
44
+ const penaltyValue = this.peerScoring.peerPenalties[penalty];
45
+ this.peerScoring.updateScore(id, -penaltyValue);
46
+ }
47
+ getPeerScore(peerId) {
48
+ return this.peerScoring.getScore(peerId);
49
+ }
36
50
  /**
37
51
  * Discovers peers.
38
52
  */
@@ -159,4 +173,4 @@ export class PeerManager {
159
173
  }
160
174
  }
161
175
  }
162
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGVlcl9tYW5hZ2VyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3NlcnZpY2UvcGVlcl9tYW5hZ2VyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBVTFELE1BQU0saUJBQWlCLEdBQUcsQ0FBQyxDQUFDO0FBQzVCLE1BQU0sZ0JBQWdCLEdBQUcsR0FBRyxDQUFDO0FBUzdCLE1BQU0sT0FBTyxXQUFXO0lBRXRCLFlBQ1UsVUFBa0IsRUFDbEIsb0JBQTBDLEVBQzFDLE1BQWlCLEVBQ2pCLFNBQVMsaUJBQWlCLENBQUMsd0JBQXdCLENBQUM7UUFIcEQsZUFBVSxHQUFWLFVBQVUsQ0FBUTtRQUNsQix5QkFBb0IsR0FBcEIsb0JBQW9CLENBQXNCO1FBQzFDLFdBQU0sR0FBTixNQUFNLENBQVc7UUFDakIsV0FBTSxHQUFOLE1BQU0sQ0FBOEM7UUFMdEQsZ0JBQVcsR0FBNEIsSUFBSSxHQUFHLEVBQUUsQ0FBQztRQU92RCxxQ0FBcUM7UUFDckMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxnQkFBZ0IsQ0FBQyxjQUFjLEVBQUUsR0FBRyxDQUFDLEVBQUU7WUFDckQsTUFBTSxNQUFNLEdBQUcsR0FBRyxDQUFDLE1BQU0sQ0FBQztZQUMxQixJQUFJLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxlQUFlLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQztnQkFDdEQsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsK0JBQStCLE1BQU0sQ0FBQyxRQUFRLEVBQUUsRUFBRSxDQUFDLENBQUM7WUFDeEUsQ0FBQztpQkFBTSxDQUFDO2dCQUNOLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLGlDQUFpQyxNQUFNLENBQUMsUUFBUSxFQUFFLEVBQUUsQ0FBQyxDQUFDO1lBQzFFLENBQUM7UUFDSCxDQUFDLENBQUMsQ0FBQztRQUVILDBCQUEwQjtRQUMxQixJQUFJLENBQUMs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
176
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGVlcl9tYW5hZ2VyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3NlcnZpY2UvcGVlcl9tYW5hZ2VyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBUTFELE9BQU8sRUFBMEIsV0FBVyxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFHeEUsTUFBTSxpQkFBaUIsR0FBRyxDQUFDLENBQUM7QUFDNUIsTUFBTSxnQkFBZ0IsR0FBRyxHQUFHLENBQUM7QUFTN0IsTUFBTSxPQUFPLFdBQVc7SUFJdEIsWUFDVSxVQUF3QixFQUN4QixvQkFBMEMsRUFDMUMsTUFBaUIsRUFDakIsU0FBUyxpQkFBaUIsQ0FBQyx3QkFBd0IsQ0FBQztRQUhwRCxlQUFVLEdBQVYsVUFBVSxDQUFjO1FBQ3hCLHlCQUFvQixHQUFwQixvQkFBb0IsQ0FBc0I7UUFDMUMsV0FBTSxHQUFOLE1BQU0sQ0FBVztRQUNqQixXQUFNLEdBQU4sTUFBTSxDQUE4QztRQVB0RCxnQkFBVyxHQUE0QixJQUFJLEdBQUcsRUFBRSxDQUFDO1FBU3ZELElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSxXQUFXLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDM0MscUNBQXFDO1FBQ3JDLElBQUksQ0FBQyxVQUFVLENBQUMsZ0JBQWdCLENBQUMsY0FBYyxFQUFFLEdBQUcsQ0FBQyxFQUFFO1lBQ3JELE1BQU0sTUFBTSxHQUFHLEdBQUcsQ0FBQyxNQUFNLENBQUM7WUFDMUIsSUFBSSxJQUFJLENBQUMsb0JBQW9CLENBQUMsZUFBZSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUM7Z0JBQ3RELElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLCtCQUErQixNQUFNLENBQUMsUUFBUSxFQUFFLEVBQUUsQ0FBQyxDQUFDO1lBQ3hFLENBQUM7aUJBQU0sQ0FBQztnQkFDTixJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxpQ0FBaUMsTUFBTSxDQUFDLFFBQVEsRUFBRSxFQUFFLENBQUMsQ0FBQztZQUMxRSxDQUFDO1FBQ0gsQ0FBQyxDQUFDLENBQUM7UUFFSCwwQkFBMEI7UUFDMUIsSUFBSSxDQUFDLFVBQVUsQ0FBQyxnQkFBZ0IsQ0FBQyxpQkFBaUIsRUFBRSxHQUFHLENBQUMsRUFBRTtZQUN4RCxNQUFNLE1BQU0sR0FBRyxHQUFHLENBQUMsTUFBTSxDQUFDO1lBQzFCLElBQUksSUFBSSxDQUFDLG9CQUFvQixDQUFDLGVBQWUsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDO2dCQUN0RCxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxvQ0FBb0MsTUFBTSxDQUFDLFFBQVEsRUFBRSxFQUFFLENBQUMsQ0FBQztZQUM3RSxDQUFDO2lCQUFNLENBQUM7Z0JBQ04sSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsc0NBQXNDLE1BQU0sQ0FBQyxRQUFRLEVBQUUsRUFBRSxDQUFDLENBQUM7WUFDL0UsQ0FBQztRQUNILENBQUMsQ0FBQyxDQUFDO1FBRUgsMEJBQTBCO1FBQzFCLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxFQUFFLENBQUMsaUJBQWlCLEVBQUUsS0FBSyxFQUFFLEdBQVEsRUFBRSxFQUFFO1lBQ2pFLE1BQU0sSUFBSSxDQUFDLG9CQUFvQixDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ3ZDLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVNLFNBQVM7UUFDZCxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUM7UUFDaEIsSUFBSSxDQUFDLFdBQVcsQ0FBQyxjQUFjLEVBQUUsQ0FBQztJQUNwQyxDQUFDO0lBRU0sWUFBWSxDQUFDLE1BQWMsRUFBRSxPQUEwQjtRQUM1RCxNQUFNLEVBQUUsR0FBRyxNQUFNLENBQUMsUUFBUSxFQUFFLENBQUM7UUFDN0IsTUFBTSxZQUFZLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxhQUFhLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDN0QsSUFBSSxDQUFDLFdBQVcsQ0FBQyxXQUFXLENBQUMsRUFBRSxFQUFFLENBQUMsWUFBWSxDQUFDLENBQUM7SUFDbEQsQ0FBQztJQUVNLFlBQVksQ0FBQyxNQUFjO1FBQ2hDLE9BQU8sSUFBSSxDQUFDLFdBQVcsQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDM0MsQ0FBQztJQUVEOztPQUVHO0lBQ0ssUUFBUTtRQUNkLDBCQUEwQjtRQUMxQixNQUFNLFdBQVcsR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLGNBQWMsRUFBRSxDQUFDO1FBRXJELHVEQUF1RDtRQUN2RCxNQUFNLGNBQWMsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLFlBQVksR0FBRyxXQUFXLENBQUMsTUFBTSxDQUFDO1FBRXJFLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUNmLGdCQUFnQixXQUFXLENBQUMsTUFBTSx1QkFBdUIsY0FBYyxtQkFBbUIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxZQUFZLGtCQUFrQixJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksRUFBRSxDQUM1SixDQUFDO1FBRUYsOEJBQThCO1FBQzlCLElBQUksY0FBYyxJQUFJLENBQUMsRUFBRSxDQUFDO1lBQ3hCLE9BQU87UUFDVCxDQUFDO1FBRUQsTUFBTSxpQkFBaUIsR0FBaUIsRUFBRSxDQUFDO1FBRTNDLE1BQU0sWUFBWSxHQUFHLElBQUksR0FBRyxDQUMxQixJQUFJLENBQUMsVUFBVTthQUNaLFlBQVksRUFBRTthQUNkLEdBQUcsQ0FBQyxXQUFXLENBQUMsRUFBRSxDQUFDLFdBQVcsQ0FBQyxNQUFNLEVBQUUsUUFBUSxFQUFFLENBQUM7YUFDbEQsTUFBTSxDQUFDLE9BQU8sQ0FBYSxDQUMvQixDQUFDO1FBRUYsS0FBSyxNQUFNLENBQUMsRUFBRSxFQUFFLFFBQVEsQ0FBQyxJQUFJLElBQUksQ0FBQyxXQUFXLENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FBQztZQUN4RCx5REFBeUQ7WUFDekQsSUFBSSxZQUFZLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxJQUFJLFdBQVcsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUMsRUFBRSxDQUFDO2dCQUM5RixJQUFJLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUM5QixDQUFDO2lCQUFNLENBQUM7Z0JBQ04sa0NBQWtDO2dCQUNsQyxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDbkMsQ0FBQztRQUNILENBQUM7UUFFRCxzQ0FBc0M7UUFDdEMsaUJBQWlCLENBQUMsT0FBTyxFQUFFLENBQUM7UUFFNUIsS0FBSyxNQUFNLElBQUksSUFBSSxpQkFBaUIsRUFBRSxDQUFDO1lBQ3JDLElBQUksQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQztZQUNoRCxLQUFLLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDM0IsQ0FBQztRQUVELGdEQUFnRDtRQUNoRCxJQUFJLGNBQWMsR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUN2QixJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyw0QkFBNEIsQ0FBQyxDQUFDO1lBQ2hELEtBQUssSUFBSSxDQUFDLG9CQUFvQixDQUFDLG1CQUFtQixFQUFFLENBQUM7UUFDdkQsQ0FBQztJQUNILENBQUM7SUFFRDs7O09BR0c7SUFDSyxLQUFLLENBQUMsb0JBQW9CLENBQUMsR0FBUTtRQUN6QywyQ0FBMkM7UUFFM0MscUNBQXFDO1FBQ3JDLE1BQU0sQ0FBQyxNQUFNLEVBQUUsWUFBWSxDQUFDLEdBQUcsTUFBTSxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLE1BQU0sRUFBRSxFQUFFLEdBQUcsQ0FBQyxnQkFBZ0IsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFFOUYsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsNEJBQTRCLE1BQU0sQ0FBQyxRQUFRLEVBQUUsS0FBSyxZQUFZLEVBQUUsUUFBUSxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBRWhHLG9DQUFvQztRQUNwQyxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7WUFDbEIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsa0RBQWtELEdBQUcsQ0FBQyxRQUFRLEVBQUUsRUFBRSxDQUFDLENBQUM7WUFDdEYsT0FBTztRQUNULENBQUM7UUFDRCxNQUFNLFdBQVcsR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLGNBQWMsRUFBRSxDQUFDO1FBQ3JELElBQUksV0FBVyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQUUsQ0FBQztZQUM3RCxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyw2QkFBNkIsTUFBTSxDQUFDLFFBQVEsRUFBRSxFQUFFLENBQUMsQ0FBQztZQUNwRSxPQUFPO1FBQ1QsQ0FBQztRQUVELG9DQUFvQztRQUNwQyxNQUFNLEVBQUUsR0FBRyxNQUFNLENBQUMsUUFBUSxFQUFFLENBQUM7UUFDN0IsSUFBSSxJQUFJLENBQUMsV0FBVyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDO1lBQzdCLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLG9CQUFvQixFQUFFLEVBQUUsQ0FBQyxDQUFDO1lBQzVDLE9BQU87UUFDVCxDQUFDO1FBRUQsNEJBQTRCO1FBQzVCLE1BQU0sVUFBVSxHQUFlO1lBQzdCLE1BQU07WUFDTixHQUFHO1lBQ0gsWUFBWTtZQUNaLFlBQVksRUFBRSxDQUFDO1NBQ2hCLENBQUM7UUFFRixpREFBaUQ7UUFDakQsSUFBSSxJQUFJLENBQUMsY0FBYyxFQUFFLEVBQUUsQ0FBQztZQUMxQixJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxnQkFBZ0IsRUFBRSxFQUFFLENBQUMsQ0FBQztZQUN4QyxLQUFLLElBQUksQ0FBQyxRQUFRLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDakMsQ0FBQzthQUFNLENBQUM7WUFDTixJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxnQkFBZ0IsRUFBRSxFQUFFLENBQUMsQ0FBQztZQUN4QyxJQUFJLENBQUMsV0FBVyxDQUFDLEdBQUcsQ0FBQyxFQUFFLEVBQUUsVUFBVSxDQUFDLENBQUM7WUFDckMsNEJBQTRCO1lBQzVCLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO1FBQzFCLENBQUM7SUFDSCxDQUFDO0lBRU8sS0FBSyxDQUFDLFFBQVEsQ0FBQyxJQUFnQjtRQUNyQyxNQUFNLEVBQUUsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsRUFBRSxDQUFDO1FBQ2xDLE1BQU0sSUFBSSxDQUFDLFVBQVUsQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsRUFBRSxVQUFVLEVBQUUsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBRXhGLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLGdCQUFnQixFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBQ3hDLElBQUksQ0FBQztZQUNILE1BQU0sSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDO1FBQ2hELENBQUM7UUFBQyxNQUFNLENBQUM7WUFDUCxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyx1QkFBdUIsRUFBRSxFQUFFLENBQUMsQ0FBQztZQUMvQyxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7WUFDcEIsSUFBSSxJQUFJLENBQUMsWUFBWSxHQUFHLGlCQUFpQixFQUFFLENBQUM7Z0JBQzFDLElBQUksQ0FBQyxXQUFXLENBQUMsR0FBRyxDQUFDLEVBQUUsRUFBRSxJQUFJLENBQUMsQ0FBQztZQUNqQyxDQUFDO2lCQUFNLENBQUM7Z0JBQ04sSUFBSSxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLENBQUM7WUFDOUIsQ0FBQztRQUNILENBQUM7SUFDSCxDQUFDO0lBRU8sY0FBYztRQUNwQixNQUFNLFdBQVcsR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLGNBQWMsRUFBRSxDQUFDLE1BQU0sQ0FBQztRQUM1RCxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxnQkFBZ0IsV0FBVyxtQkFBbUIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxZQUFZLEVBQUUsQ0FBQyxDQUFDO1FBQzVGLElBQUksV0FBVyxJQUFJLElBQUksQ0FBQyxNQUFNLENBQUMsWUFBWSxFQUFFLENBQUM7WUFDNUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsd0NBQXdDLENBQUMsQ0FBQztZQUM1RCxPQUFPLEtBQUssQ0FBQztRQUNmLENBQUM7UUFDRCxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFTyxnQkFBZ0I7UUFDdEIsSUFBSSxhQUFhLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLEdBQUcsZ0JBQWdCLENBQUM7UUFDN0QsSUFBSSxhQUFhLElBQUksQ0FBQyxFQUFFLENBQUM7WUFDdkIsT0FBTztRQUNULENBQUM7UUFFRCwwQkFBMEI7UUFDMUIsS0FBSyxNQUFNLEdBQUcsSUFBSSxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUM7WUFDMUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDN0IsYUFBYSxFQUFFLENBQUM7WUFDaEIsSUFBSSxhQUFhLElBQUksQ0FBQyxFQUFFLENBQUM7Z0JBQ3ZCLE1BQU07WUFDUixDQUFDO1FBQ0gsQ0FBQztJQUNILENBQUM7Q0FDRiJ9