@aztec/p2p 0.74.0 → 0.75.0-commit.c03ba01a2a4122e43e90d5133ba017e54b90e9d2
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 +41 -29
- package/dest/client/factory.js +8 -10
- package/dest/client/index.js +0 -1
- package/dest/client/p2p_client.js +513 -507
- package/dest/config.js +44 -39
- package/dest/errors/reqresp.error.js +6 -10
- package/dest/index.js +0 -1
- package/dest/mem_pools/attestation_pool/attestation_pool.js +6 -2
- package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.js +64 -32
- package/dest/mem_pools/attestation_pool/index.js +0 -1
- package/dest/mem_pools/attestation_pool/kv_attestation_pool.js +22 -19
- package/dest/mem_pools/attestation_pool/memory_attestation_pool.js +22 -26
- package/dest/mem_pools/attestation_pool/mocks.js +10 -6
- package/dest/mem_pools/epoch_proof_quote_pool/epoch_proof_quote_pool.js +1 -2
- package/dest/mem_pools/epoch_proof_quote_pool/index.js +0 -1
- package/dest/mem_pools/epoch_proof_quote_pool/memory_epoch_proof_quote_pool.js +5 -4
- package/dest/mem_pools/epoch_proof_quote_pool/test_utils.js +2 -3
- package/dest/mem_pools/index.js +1 -2
- package/dest/mem_pools/instrumentation.js +37 -42
- package/dest/mem_pools/interface.js +3 -2
- package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.js +127 -134
- package/dest/mem_pools/tx_pool/index.js +0 -1
- package/dest/mem_pools/tx_pool/memory_tx_pool.js +45 -43
- package/dest/mem_pools/tx_pool/priority.js +1 -3
- package/dest/mem_pools/tx_pool/tx_pool.js +3 -2
- package/dest/mem_pools/tx_pool/tx_pool_test_suite.js +107 -37
- package/dest/mocks/index.js +47 -38
- package/dest/msg_validators/attestation_validator/attestation_validator.js +3 -3
- package/dest/msg_validators/attestation_validator/index.js +0 -1
- package/dest/msg_validators/block_proposal_validator/block_proposal_validator.js +2 -2
- package/dest/msg_validators/block_proposal_validator/index.js +0 -1
- package/dest/msg_validators/epoch_proof_quote_validator/epoch_proof_quote_validator.js +2 -2
- package/dest/msg_validators/epoch_proof_quote_validator/index.js +0 -1
- package/dest/msg_validators/index.js +0 -1
- package/dest/msg_validators/tx_validator/aggregate_tx_validator.js +9 -11
- package/dest/msg_validators/tx_validator/block_header_validator.js +17 -12
- package/dest/msg_validators/tx_validator/data_validator.js +41 -32
- package/dest/msg_validators/tx_validator/double_spend_validator.js +22 -14
- package/dest/msg_validators/tx_validator/index.js +0 -1
- package/dest/msg_validators/tx_validator/metadata_validator.js +29 -26
- package/dest/msg_validators/tx_validator/tx_proof_validator.js +17 -12
- package/dest/services/data_store.js +57 -57
- package/dest/services/discv5/discV5_service.js +31 -23
- package/dest/services/dummy_service.js +40 -58
- package/dest/services/encoding.js +10 -9
- package/dest/services/index.js +0 -1
- package/dest/services/libp2p/libp2p_service.js +709 -695
- package/dest/services/peer-manager/metrics.js +14 -7
- package/dest/services/peer-manager/peer_manager.js +340 -342
- package/dest/services/peer-manager/peer_scoring.js +20 -18
- package/dest/services/reqresp/config.js +4 -5
- package/dest/services/reqresp/connection-sampler/batch_connection_sampler.js +35 -28
- package/dest/services/reqresp/connection-sampler/connection_sampler.js +60 -59
- package/dest/services/reqresp/index.js +1 -3
- package/dest/services/reqresp/interface.js +25 -30
- package/dest/services/reqresp/metrics.js +23 -10
- package/dest/services/reqresp/protocols/block.js +1 -2
- package/dest/services/reqresp/protocols/goodbye.js +35 -40
- package/dest/services/reqresp/protocols/index.js +1 -3
- package/dest/services/reqresp/protocols/ping.js +1 -3
- package/dest/services/reqresp/protocols/status.js +1 -3
- package/dest/services/reqresp/protocols/tx.js +5 -8
- package/dest/services/reqresp/rate-limiter/index.js +0 -1
- package/dest/services/reqresp/rate-limiter/rate_limiter.js +42 -36
- package/dest/services/reqresp/rate-limiter/rate_limits.js +16 -17
- package/dest/services/reqresp/reqresp.js +461 -395
- package/dest/services/reqresp/status.js +51 -0
- package/dest/services/service.js +3 -4
- package/dest/services/types.js +16 -23
- package/dest/util.js +23 -34
- package/package.json +8 -8
- package/src/client/p2p_client.ts +159 -125
- package/src/mem_pools/index.ts +3 -3
- package/src/mem_pools/instrumentation.ts +3 -2
- package/src/services/reqresp/interface.ts +11 -0
- package/src/services/reqresp/rate-limiter/rate_limiter.ts +3 -1
- package/src/services/reqresp/rate-limiter/rate_limits.ts +2 -2
- package/src/services/reqresp/reqresp.ts +111 -24
- package/src/services/reqresp/status.ts +59 -0
- package/dest/bootstrap/bootstrap.d.ts +0 -38
- package/dest/bootstrap/bootstrap.d.ts.map +0 -1
- package/dest/client/factory.d.ts +0 -19
- package/dest/client/factory.d.ts.map +0 -1
- package/dest/client/index.d.ts +0 -3
- package/dest/client/index.d.ts.map +0 -1
- package/dest/client/p2p_client.d.ts +0 -321
- package/dest/client/p2p_client.d.ts.map +0 -1
- package/dest/config.d.ts +0 -171
- package/dest/config.d.ts.map +0 -1
- package/dest/errors/reqresp.error.d.ts +0 -28
- package/dest/errors/reqresp.error.d.ts.map +0 -1
- package/dest/index.d.ts +0 -9
- package/dest/index.d.ts.map +0 -1
- package/dest/mem_pools/attestation_pool/attestation_pool.d.ts +0 -57
- package/dest/mem_pools/attestation_pool/attestation_pool.d.ts.map +0 -1
- package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.d.ts +0 -3
- package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.d.ts.map +0 -1
- package/dest/mem_pools/attestation_pool/index.d.ts +0 -3
- package/dest/mem_pools/attestation_pool/index.d.ts.map +0 -1
- package/dest/mem_pools/attestation_pool/kv_attestation_pool.d.ts +0 -22
- package/dest/mem_pools/attestation_pool/kv_attestation_pool.d.ts.map +0 -1
- package/dest/mem_pools/attestation_pool/memory_attestation_pool.d.ts +0 -17
- package/dest/mem_pools/attestation_pool/memory_attestation_pool.d.ts.map +0 -1
- package/dest/mem_pools/attestation_pool/mocks.d.ts +0 -18
- package/dest/mem_pools/attestation_pool/mocks.d.ts.map +0 -1
- package/dest/mem_pools/epoch_proof_quote_pool/epoch_proof_quote_pool.d.ts +0 -7
- package/dest/mem_pools/epoch_proof_quote_pool/epoch_proof_quote_pool.d.ts.map +0 -1
- package/dest/mem_pools/epoch_proof_quote_pool/index.d.ts +0 -4
- package/dest/mem_pools/epoch_proof_quote_pool/index.d.ts.map +0 -1
- package/dest/mem_pools/epoch_proof_quote_pool/memory_epoch_proof_quote_pool.d.ts +0 -12
- package/dest/mem_pools/epoch_proof_quote_pool/memory_epoch_proof_quote_pool.d.ts.map +0 -1
- package/dest/mem_pools/epoch_proof_quote_pool/test_utils.d.ts +0 -8
- package/dest/mem_pools/epoch_proof_quote_pool/test_utils.d.ts.map +0 -1
- package/dest/mem_pools/index.d.ts +0 -5
- package/dest/mem_pools/index.d.ts.map +0 -1
- package/dest/mem_pools/instrumentation.d.ts +0 -31
- package/dest/mem_pools/instrumentation.d.ts.map +0 -1
- package/dest/mem_pools/interface.d.ts +0 -13
- package/dest/mem_pools/interface.d.ts.map +0 -1
- package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts +0 -66
- package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts.map +0 -1
- package/dest/mem_pools/tx_pool/index.d.ts +0 -4
- package/dest/mem_pools/tx_pool/index.d.ts.map +0 -1
- package/dest/mem_pools/tx_pool/memory_tx_pool.d.ts +0 -56
- package/dest/mem_pools/tx_pool/memory_tx_pool.d.ts.map +0 -1
- package/dest/mem_pools/tx_pool/priority.d.ts +0 -8
- package/dest/mem_pools/tx_pool/priority.d.ts.map +0 -1
- package/dest/mem_pools/tx_pool/tx_pool.d.ts +0 -66
- package/dest/mem_pools/tx_pool/tx_pool.d.ts.map +0 -1
- package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts +0 -7
- package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts.map +0 -1
- package/dest/mocks/index.d.ts +0 -54
- package/dest/mocks/index.d.ts.map +0 -1
- package/dest/msg_validators/attestation_validator/attestation_validator.d.ts +0 -8
- package/dest/msg_validators/attestation_validator/attestation_validator.d.ts.map +0 -1
- package/dest/msg_validators/attestation_validator/index.d.ts +0 -2
- package/dest/msg_validators/attestation_validator/index.d.ts.map +0 -1
- package/dest/msg_validators/block_proposal_validator/block_proposal_validator.d.ts +0 -8
- package/dest/msg_validators/block_proposal_validator/block_proposal_validator.d.ts.map +0 -1
- package/dest/msg_validators/block_proposal_validator/index.d.ts +0 -2
- package/dest/msg_validators/block_proposal_validator/index.d.ts.map +0 -1
- package/dest/msg_validators/epoch_proof_quote_validator/epoch_proof_quote_validator.d.ts +0 -8
- package/dest/msg_validators/epoch_proof_quote_validator/epoch_proof_quote_validator.d.ts.map +0 -1
- package/dest/msg_validators/epoch_proof_quote_validator/index.d.ts +0 -2
- package/dest/msg_validators/epoch_proof_quote_validator/index.d.ts.map +0 -1
- package/dest/msg_validators/index.d.ts +0 -4
- package/dest/msg_validators/index.d.ts.map +0 -1
- package/dest/msg_validators/tx_validator/aggregate_tx_validator.d.ts +0 -7
- package/dest/msg_validators/tx_validator/aggregate_tx_validator.d.ts.map +0 -1
- package/dest/msg_validators/tx_validator/block_header_validator.d.ts +0 -11
- package/dest/msg_validators/tx_validator/block_header_validator.d.ts.map +0 -1
- package/dest/msg_validators/tx_validator/data_validator.d.ts +0 -6
- package/dest/msg_validators/tx_validator/data_validator.d.ts.map +0 -1
- package/dest/msg_validators/tx_validator/double_spend_validator.d.ts +0 -12
- package/dest/msg_validators/tx_validator/double_spend_validator.d.ts.map +0 -1
- package/dest/msg_validators/tx_validator/index.d.ts +0 -7
- package/dest/msg_validators/tx_validator/index.d.ts.map +0 -1
- package/dest/msg_validators/tx_validator/metadata_validator.d.ts +0 -10
- package/dest/msg_validators/tx_validator/metadata_validator.d.ts.map +0 -1
- package/dest/msg_validators/tx_validator/tx_proof_validator.d.ts +0 -8
- package/dest/msg_validators/tx_validator/tx_proof_validator.d.ts.map +0 -1
- package/dest/services/data_store.d.ts +0 -27
- package/dest/services/data_store.d.ts.map +0 -1
- package/dest/services/discv5/discV5_service.d.ts +0 -36
- package/dest/services/discv5/discV5_service.d.ts.map +0 -1
- package/dest/services/dummy_service.d.ts +0 -82
- package/dest/services/dummy_service.d.ts.map +0 -1
- package/dest/services/encoding.d.ts +0 -31
- package/dest/services/encoding.d.ts.map +0 -1
- package/dest/services/index.d.ts +0 -3
- package/dest/services/index.d.ts.map +0 -1
- package/dest/services/libp2p/libp2p_service.d.ts +0 -225
- package/dest/services/libp2p/libp2p_service.d.ts.map +0 -1
- package/dest/services/peer-manager/metrics.d.ts +0 -12
- package/dest/services/peer-manager/metrics.d.ts.map +0 -1
- package/dest/services/peer-manager/peer_manager.d.ts +0 -76
- package/dest/services/peer-manager/peer_manager.d.ts.map +0 -1
- package/dest/services/peer-manager/peer_scoring.d.ts +0 -28
- package/dest/services/peer-manager/peer_scoring.d.ts.map +0 -1
- package/dest/services/reqresp/config.d.ts +0 -16
- package/dest/services/reqresp/config.d.ts.map +0 -1
- package/dest/services/reqresp/connection-sampler/batch_connection_sampler.d.ts +0 -45
- package/dest/services/reqresp/connection-sampler/batch_connection_sampler.d.ts.map +0 -1
- package/dest/services/reqresp/connection-sampler/connection_sampler.d.ts +0 -61
- package/dest/services/reqresp/connection-sampler/connection_sampler.d.ts.map +0 -1
- package/dest/services/reqresp/index.d.ts +0 -6
- package/dest/services/reqresp/index.d.ts.map +0 -1
- package/dest/services/reqresp/interface.d.ts +0 -107
- package/dest/services/reqresp/interface.d.ts.map +0 -1
- package/dest/services/reqresp/metrics.d.ts +0 -15
- package/dest/services/reqresp/metrics.d.ts.map +0 -1
- package/dest/services/reqresp/protocols/block.d.ts +0 -4
- package/dest/services/reqresp/protocols/block.d.ts.map +0 -1
- package/dest/services/reqresp/protocols/goodbye.d.ts +0 -51
- package/dest/services/reqresp/protocols/goodbye.d.ts.map +0 -1
- package/dest/services/reqresp/protocols/index.d.ts +0 -9
- package/dest/services/reqresp/protocols/index.d.ts.map +0 -1
- package/dest/services/reqresp/protocols/ping.d.ts +0 -9
- package/dest/services/reqresp/protocols/ping.d.ts.map +0 -1
- package/dest/services/reqresp/protocols/status.d.ts +0 -9
- package/dest/services/reqresp/protocols/status.d.ts.map +0 -1
- package/dest/services/reqresp/protocols/tx.d.ts +0 -13
- package/dest/services/reqresp/protocols/tx.d.ts.map +0 -1
- package/dest/services/reqresp/rate-limiter/index.d.ts +0 -2
- package/dest/services/reqresp/rate-limiter/index.d.ts.map +0 -1
- package/dest/services/reqresp/rate-limiter/rate_limiter.d.ts +0 -102
- package/dest/services/reqresp/rate-limiter/rate_limiter.d.ts.map +0 -1
- package/dest/services/reqresp/rate-limiter/rate_limits.d.ts +0 -3
- package/dest/services/reqresp/rate-limiter/rate_limits.d.ts.map +0 -1
- package/dest/services/reqresp/reqresp.d.ts +0 -161
- package/dest/services/reqresp/reqresp.d.ts.map +0 -1
- package/dest/services/service.d.ts +0 -85
- package/dest/services/service.d.ts.map +0 -1
- package/dest/services/types.d.ts +0 -38
- package/dest/services/types.d.ts.map +0 -1
- package/dest/util.d.ts +0 -53
- package/dest/util.d.ts.map +0 -1
package/dest/config.js
CHANGED
|
@@ -1,162 +1,165 @@
|
|
|
1
|
-
import { booleanConfigHelper, getConfigFromMappings, getDefaultConfig, numberConfigHelper, pickConfigMappings
|
|
1
|
+
import { booleanConfigHelper, getConfigFromMappings, getDefaultConfig, numberConfigHelper, pickConfigMappings } from '@aztec/foundation/config';
|
|
2
2
|
import { dataConfigMappings } from '@aztec/kv-store/config';
|
|
3
3
|
import { p2pReqRespConfigMappings } from './services/reqresp/config.js';
|
|
4
4
|
export const p2pConfigMappings = {
|
|
5
5
|
p2pEnabled: {
|
|
6
6
|
env: 'P2P_ENABLED',
|
|
7
7
|
description: 'A flag dictating whether the P2P subsystem should be enabled.',
|
|
8
|
-
...booleanConfigHelper()
|
|
8
|
+
...booleanConfigHelper()
|
|
9
9
|
},
|
|
10
10
|
blockCheckIntervalMS: {
|
|
11
11
|
env: 'P2P_BLOCK_CHECK_INTERVAL_MS',
|
|
12
12
|
description: 'The frequency in which to check for new L2 blocks.',
|
|
13
|
-
...numberConfigHelper(100)
|
|
13
|
+
...numberConfigHelper(100)
|
|
14
14
|
},
|
|
15
15
|
peerCheckIntervalMS: {
|
|
16
16
|
env: 'P2P_PEER_CHECK_INTERVAL_MS',
|
|
17
17
|
description: 'The frequency in which to check for new peers.',
|
|
18
|
-
...numberConfigHelper(
|
|
18
|
+
...numberConfigHelper(30_000)
|
|
19
19
|
},
|
|
20
20
|
l2QueueSize: {
|
|
21
21
|
env: 'P2P_L2_QUEUE_SIZE',
|
|
22
22
|
description: 'Size of queue of L2 blocks to store.',
|
|
23
|
-
...numberConfigHelper(
|
|
23
|
+
...numberConfigHelper(1_000)
|
|
24
24
|
},
|
|
25
25
|
tcpListenAddress: {
|
|
26
26
|
env: 'P2P_TCP_LISTEN_ADDR',
|
|
27
27
|
defaultValue: '0.0.0.0:40400',
|
|
28
|
-
description: 'The listen address for TCP. Format: <IP_ADDRESS>:<PORT>.'
|
|
28
|
+
description: 'The listen address for TCP. Format: <IP_ADDRESS>:<PORT>.'
|
|
29
29
|
},
|
|
30
30
|
udpListenAddress: {
|
|
31
31
|
env: 'P2P_UDP_LISTEN_ADDR',
|
|
32
32
|
defaultValue: '0.0.0.0:40400',
|
|
33
|
-
description: 'The listen address for UDP. Format: <IP_ADDRESS>:<PORT>.'
|
|
33
|
+
description: 'The listen address for UDP. Format: <IP_ADDRESS>:<PORT>.'
|
|
34
34
|
},
|
|
35
35
|
tcpAnnounceAddress: {
|
|
36
36
|
env: 'P2P_TCP_ANNOUNCE_ADDR',
|
|
37
|
-
description: 'The announce address for TCP. Format: <IP_ADDRESS>:<PORT>. Leave IP_ADDRESS blank to query for public IP.'
|
|
37
|
+
description: 'The announce address for TCP. Format: <IP_ADDRESS>:<PORT>. Leave IP_ADDRESS blank to query for public IP.'
|
|
38
38
|
},
|
|
39
39
|
udpAnnounceAddress: {
|
|
40
40
|
env: 'P2P_UDP_ANNOUNCE_ADDR',
|
|
41
|
-
description: 'The announce address for UDP. Format: <IP_ADDRESS>:<PORT>. Leave IP_ADDRESS blank to query for public IP.'
|
|
41
|
+
description: 'The announce address for UDP. Format: <IP_ADDRESS>:<PORT>. Leave IP_ADDRESS blank to query for public IP.'
|
|
42
42
|
},
|
|
43
43
|
peerIdPrivateKey: {
|
|
44
44
|
env: 'PEER_ID_PRIVATE_KEY',
|
|
45
|
-
description: 'An optional peer id private key. If blank, will generate a random key.'
|
|
45
|
+
description: 'An optional peer id private key. If blank, will generate a random key.'
|
|
46
46
|
},
|
|
47
47
|
bootstrapNodes: {
|
|
48
48
|
env: 'BOOTSTRAP_NODES',
|
|
49
|
-
parseEnv: (val)
|
|
50
|
-
description: 'A list of bootstrap peer ENRs to connect to. Separated by commas.'
|
|
49
|
+
parseEnv: (val)=>val.split(','),
|
|
50
|
+
description: 'A list of bootstrap peer ENRs to connect to. Separated by commas.'
|
|
51
51
|
},
|
|
52
52
|
transactionProtocol: {
|
|
53
53
|
env: 'P2P_TX_PROTOCOL',
|
|
54
54
|
description: 'Protocol identifier for transaction gossiping.',
|
|
55
|
-
defaultValue: '/aztec/0.1.0'
|
|
55
|
+
defaultValue: '/aztec/0.1.0'
|
|
56
56
|
},
|
|
57
57
|
minPeerCount: {
|
|
58
58
|
env: 'P2P_MIN_PEERS',
|
|
59
59
|
description: 'The minimum number of peers to connect to.',
|
|
60
|
-
...numberConfigHelper(10)
|
|
60
|
+
...numberConfigHelper(10)
|
|
61
61
|
},
|
|
62
62
|
maxPeerCount: {
|
|
63
63
|
env: 'P2P_MAX_PEERS',
|
|
64
64
|
description: 'The maximum number of peers to connect to.',
|
|
65
|
-
...numberConfigHelper(100)
|
|
65
|
+
...numberConfigHelper(100)
|
|
66
66
|
},
|
|
67
67
|
queryForIp: {
|
|
68
68
|
env: 'P2P_QUERY_FOR_IP',
|
|
69
69
|
description: 'If announceUdpAddress or announceTcpAddress are not provided, query for the IP address of the machine. Default is false.',
|
|
70
|
-
...booleanConfigHelper()
|
|
70
|
+
...booleanConfigHelper()
|
|
71
71
|
},
|
|
72
72
|
keepProvenTxsInPoolFor: {
|
|
73
73
|
env: 'P2P_TX_POOL_KEEP_PROVEN_FOR',
|
|
74
74
|
description: 'How many blocks have to pass after a block is proven before its txs are deleted (zero to delete immediately once proven)',
|
|
75
|
-
...numberConfigHelper(0)
|
|
75
|
+
...numberConfigHelper(0)
|
|
76
76
|
},
|
|
77
77
|
keepAttestationsInPoolFor: {
|
|
78
78
|
env: 'P2P_ATTESTATION_POOL_KEEP_FOR',
|
|
79
79
|
description: 'How many slots to keep attestations for.',
|
|
80
|
-
...numberConfigHelper(96)
|
|
80
|
+
...numberConfigHelper(96)
|
|
81
81
|
},
|
|
82
82
|
gossipsubInterval: {
|
|
83
83
|
env: 'P2P_GOSSIPSUB_INTERVAL_MS',
|
|
84
84
|
description: 'The interval of the gossipsub heartbeat to perform maintenance tasks.',
|
|
85
|
-
...numberConfigHelper(
|
|
85
|
+
...numberConfigHelper(1_000)
|
|
86
86
|
},
|
|
87
87
|
gossipsubD: {
|
|
88
88
|
env: 'P2P_GOSSIPSUB_D',
|
|
89
89
|
description: 'The D parameter for the gossipsub protocol.',
|
|
90
|
-
...numberConfigHelper(8)
|
|
90
|
+
...numberConfigHelper(8)
|
|
91
91
|
},
|
|
92
92
|
gossipsubDlo: {
|
|
93
93
|
env: 'P2P_GOSSIPSUB_DLO',
|
|
94
94
|
description: 'The Dlo parameter for the gossipsub protocol.',
|
|
95
|
-
...numberConfigHelper(4)
|
|
95
|
+
...numberConfigHelper(4)
|
|
96
96
|
},
|
|
97
97
|
gossipsubDhi: {
|
|
98
98
|
env: 'P2P_GOSSIPSUB_DHI',
|
|
99
99
|
description: 'The Dhi parameter for the gossipsub protocol.',
|
|
100
|
-
...numberConfigHelper(12)
|
|
100
|
+
...numberConfigHelper(12)
|
|
101
101
|
},
|
|
102
102
|
gossipsubMcacheLength: {
|
|
103
103
|
env: 'P2P_GOSSIPSUB_MCACHE_LENGTH',
|
|
104
104
|
description: 'The number of gossipsub interval message cache windows to keep.',
|
|
105
|
-
...numberConfigHelper(5)
|
|
105
|
+
...numberConfigHelper(5)
|
|
106
106
|
},
|
|
107
107
|
gossipsubMcacheGossip: {
|
|
108
108
|
env: 'P2P_GOSSIPSUB_MCACHE_GOSSIP',
|
|
109
109
|
description: 'How many message cache windows to include when gossiping with other pears.',
|
|
110
|
-
...numberConfigHelper(3)
|
|
110
|
+
...numberConfigHelper(3)
|
|
111
111
|
},
|
|
112
112
|
gossipsubTxTopicWeight: {
|
|
113
113
|
env: 'P2P_GOSSIPSUB_TX_TOPIC_WEIGHT',
|
|
114
114
|
description: 'The weight of the tx topic for the gossipsub protocol.',
|
|
115
|
-
...numberConfigHelper(1)
|
|
115
|
+
...numberConfigHelper(1)
|
|
116
116
|
},
|
|
117
117
|
gossipsubTxInvalidMessageDeliveriesWeight: {
|
|
118
118
|
env: 'P2P_GOSSIPSUB_TX_INVALID_MESSAGE_DELIVERIES_WEIGHT',
|
|
119
119
|
description: 'The weight of the tx invalid message deliveries for the gossipsub protocol.',
|
|
120
|
-
...numberConfigHelper(-20)
|
|
120
|
+
...numberConfigHelper(-20)
|
|
121
121
|
},
|
|
122
122
|
gossipsubTxInvalidMessageDeliveriesDecay: {
|
|
123
123
|
env: 'P2P_GOSSIPSUB_TX_INVALID_MESSAGE_DELIVERIES_DECAY',
|
|
124
124
|
description: 'Determines how quickly the penalty for invalid message deliveries decays over time. Between 0 and 1.',
|
|
125
|
-
...numberConfigHelper(0.5)
|
|
125
|
+
...numberConfigHelper(0.5)
|
|
126
126
|
},
|
|
127
127
|
peerPenaltyValues: {
|
|
128
128
|
env: 'P2P_PEER_PENALTY_VALUES',
|
|
129
|
-
parseEnv: (val)
|
|
129
|
+
parseEnv: (val)=>val.split(',').map(Number),
|
|
130
130
|
description: 'The values for the peer scoring system. Passed as a comma separated list of values in order: low, mid, high tolerance errors.',
|
|
131
|
-
defaultValue: [
|
|
131
|
+
defaultValue: [
|
|
132
|
+
2,
|
|
133
|
+
10,
|
|
134
|
+
50
|
|
135
|
+
]
|
|
132
136
|
},
|
|
133
137
|
severePeerPenaltyBlockLength: {
|
|
134
138
|
env: 'P2P_SEVERE_PEER_PENALTY_BLOCK_LENGTH',
|
|
135
139
|
description: 'The "age" (in L2 blocks) of a tx after which we heavily penalize a peer for sending it.',
|
|
136
|
-
...numberConfigHelper(30)
|
|
140
|
+
...numberConfigHelper(30)
|
|
137
141
|
},
|
|
138
142
|
l1ChainId: {
|
|
139
143
|
env: 'L1_CHAIN_ID',
|
|
140
144
|
description: 'The chain id of the L1 chain.',
|
|
141
|
-
...numberConfigHelper(31337)
|
|
145
|
+
...numberConfigHelper(31337)
|
|
142
146
|
},
|
|
143
147
|
blockRequestBatchSize: {
|
|
144
148
|
env: 'P2P_BLOCK_REQUEST_BATCH_SIZE',
|
|
145
149
|
description: 'The number of blocks to fetch in a single batch.',
|
|
146
|
-
...numberConfigHelper(20)
|
|
150
|
+
...numberConfigHelper(20)
|
|
147
151
|
},
|
|
148
152
|
archivedTxLimit: {
|
|
149
153
|
env: 'P2P_ARCHIVED_TX_LIMIT',
|
|
150
154
|
description: 'The number of transactions that will be archived. If the limit is set to 0 then archiving will be disabled.',
|
|
151
|
-
...numberConfigHelper(0)
|
|
155
|
+
...numberConfigHelper(0)
|
|
152
156
|
},
|
|
153
|
-
...p2pReqRespConfigMappings
|
|
157
|
+
...p2pReqRespConfigMappings
|
|
154
158
|
};
|
|
155
159
|
/**
|
|
156
160
|
* Gets the config values for p2p client from environment variables.
|
|
157
161
|
* @returns The config values for p2p client.
|
|
158
|
-
*/
|
|
159
|
-
export function getP2PConfigFromEnv() {
|
|
162
|
+
*/ export function getP2PConfigFromEnv() {
|
|
160
163
|
return getConfigFromMappings(p2pConfigMappings);
|
|
161
164
|
}
|
|
162
165
|
export function getP2PDefaultConfig() {
|
|
@@ -169,7 +172,9 @@ const bootnodeConfigKeys = [
|
|
|
169
172
|
'maxPeerCount',
|
|
170
173
|
'udpListenAddress',
|
|
171
174
|
'dataDirectory',
|
|
172
|
-
'dataStoreMapSizeKB'
|
|
175
|
+
'dataStoreMapSizeKB'
|
|
173
176
|
];
|
|
174
|
-
export const bootnodeConfigMappings = pickConfigMappings({
|
|
175
|
-
|
|
177
|
+
export const bootnodeConfigMappings = pickConfigMappings({
|
|
178
|
+
...p2pConfigMappings,
|
|
179
|
+
...dataConfigMappings
|
|
180
|
+
}, bootnodeConfigKeys);
|
|
@@ -2,9 +2,8 @@
|
|
|
2
2
|
*
|
|
3
3
|
* This error will be thrown when a request to a specific peer times out.
|
|
4
4
|
* @category Errors
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
constructor() {
|
|
5
|
+
*/ export class IndividualReqRespTimeoutError extends Error {
|
|
6
|
+
constructor(){
|
|
8
7
|
super(`Request to peer timed out`);
|
|
9
8
|
}
|
|
10
9
|
}
|
|
@@ -12,9 +11,8 @@ export class IndividualReqRespTimeoutError extends Error {
|
|
|
12
11
|
*
|
|
13
12
|
* This error will be thrown when a req resp request times out regardless of the peer.
|
|
14
13
|
* @category Errors
|
|
15
|
-
*/
|
|
16
|
-
|
|
17
|
-
constructor() {
|
|
14
|
+
*/ export class CollectiveReqRespTimeoutError extends Error {
|
|
15
|
+
constructor(){
|
|
18
16
|
super(`Request to all peers timed out`);
|
|
19
17
|
}
|
|
20
18
|
}
|
|
@@ -25,10 +23,8 @@ export class CollectiveReqRespTimeoutError extends Error {
|
|
|
25
23
|
* This error does not need to be punished as message validators will handle punishing invalid
|
|
26
24
|
* requests
|
|
27
25
|
* @category Errors
|
|
28
|
-
*/
|
|
29
|
-
|
|
30
|
-
constructor() {
|
|
26
|
+
*/ export class InvalidResponseError extends Error {
|
|
27
|
+
constructor(){
|
|
31
28
|
super(`Invalid response received`);
|
|
32
29
|
}
|
|
33
30
|
}
|
|
34
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVxcmVzcC5lcnJvci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9lcnJvcnMvcmVxcmVzcC5lcnJvci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7OztHQUlHO0FBQ0gsTUFBTSxPQUFPLDZCQUE4QixTQUFRLEtBQUs7SUFDdEQ7UUFDRSxLQUFLLENBQUMsMkJBQTJCLENBQUMsQ0FBQztJQUNyQyxDQUFDO0NBQ0Y7QUFFRDs7OztHQUlHO0FBQ0gsTUFBTSxPQUFPLDZCQUE4QixTQUFRLEtBQUs7SUFDdEQ7UUFDRSxLQUFLLENBQUMsZ0NBQWdDLENBQUMsQ0FBQztJQUMxQyxDQUFDO0NBQ0Y7QUFFRDs7Ozs7OztHQU9HO0FBQ0gsTUFBTSxPQUFPLG9CQUFxQixTQUFRLEtBQUs7SUFDN0M7UUFDRSxLQUFLLENBQUMsMkJBQTJCLENBQUMsQ0FBQztJQUNyQyxDQUFDO0NBQ0YifQ==
|
package/dest/index.js
CHANGED
|
@@ -6,4 +6,3 @@ export * from './mem_pools/epoch_proof_quote_pool/index.js';
|
|
|
6
6
|
export * from './services/index.js';
|
|
7
7
|
export * from './mem_pools/tx_pool/index.js';
|
|
8
8
|
export * from './msg_validators/index.js';
|
|
9
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsY0FBYyx1Q0FBdUMsQ0FBQztBQUN0RCxjQUFjLDBCQUEwQixDQUFDO0FBQ3pDLGNBQWMsbUJBQW1CLENBQUM7QUFDbEMsY0FBYyxhQUFhLENBQUM7QUFDNUIsY0FBYyw2Q0FBNkMsQ0FBQztBQUM1RCxjQUFjLHFCQUFxQixDQUFDO0FBQ3BDLGNBQWMsOEJBQThCLENBQUM7QUFDN0MsY0FBYywyQkFBMkIsQ0FBQyJ9
|
|
@@ -1,2 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
/**
|
|
2
|
+
* An Attestation Pool contains attestations collected by a validator
|
|
3
|
+
*
|
|
4
|
+
* Attestations that are observed via the p2p network are stored for requests
|
|
5
|
+
* from the validator to produce a block, or to serve to other peers.
|
|
6
|
+
*/ export { };
|
|
@@ -10,29 +10,31 @@ export function describeAttestationPool(getAttestationPool) {
|
|
|
10
10
|
let signers;
|
|
11
11
|
// Check that metrics are recorded correctly
|
|
12
12
|
let metricsMock;
|
|
13
|
-
beforeEach(()
|
|
13
|
+
beforeEach(()=>{
|
|
14
14
|
ap = getAttestationPool();
|
|
15
|
-
signers = Array.from({
|
|
15
|
+
signers = Array.from({
|
|
16
|
+
length: NUMBER_OF_SIGNERS_PER_TEST
|
|
17
|
+
}, ()=>Secp256k1Signer.random());
|
|
16
18
|
metricsMock = mock();
|
|
17
19
|
// Can i overwrite this like this??
|
|
18
20
|
ap.metrics = metricsMock;
|
|
19
21
|
});
|
|
20
|
-
const createAttestationsForSlot = (slotNumber)
|
|
22
|
+
const createAttestationsForSlot = (slotNumber)=>{
|
|
21
23
|
const archive = Fr.random();
|
|
22
|
-
return Promise.all(signers.map(signer
|
|
24
|
+
return Promise.all(signers.map((signer)=>mockAttestation(signer, slotNumber, archive)));
|
|
23
25
|
};
|
|
24
26
|
// We compare buffers as the objects can have cached values attached to them which are not serialised
|
|
25
27
|
// using array containing as the kv store does not respect insertion order
|
|
26
|
-
const compareAttestations = (a1, a2)
|
|
27
|
-
const a1Buffer = a1.map(attestation
|
|
28
|
-
const a2Buffer = a2.map(attestation
|
|
28
|
+
const compareAttestations = (a1, a2)=>{
|
|
29
|
+
const a1Buffer = a1.map((attestation)=>attestation.toBuffer());
|
|
30
|
+
const a2Buffer = a2.map((attestation)=>attestation.toBuffer());
|
|
29
31
|
expect(a1Buffer.length).toBe(a2Buffer.length);
|
|
30
32
|
expect(a1Buffer).toEqual(expect.arrayContaining(a2Buffer));
|
|
31
33
|
};
|
|
32
|
-
it('should add attestations to pool', async ()
|
|
34
|
+
it('should add attestations to pool', async ()=>{
|
|
33
35
|
const slotNumber = 420;
|
|
34
36
|
const archive = Fr.random();
|
|
35
|
-
const attestations = await Promise.all(signers.map(signer
|
|
37
|
+
const attestations = await Promise.all(signers.map((signer)=>mockAttestation(signer, slotNumber, archive)));
|
|
36
38
|
await ap.addAttestations(attestations);
|
|
37
39
|
// Check metrics have been updated.
|
|
38
40
|
expect(metricsMock.recordAddedObjects).toHaveBeenCalledWith(attestations.length);
|
|
@@ -45,14 +47,21 @@ export function describeAttestationPool(getAttestationPool) {
|
|
|
45
47
|
const retreivedAttestationsAfterDelete = await ap.getAttestationsForSlot(BigInt(slotNumber), archive.toString());
|
|
46
48
|
expect(retreivedAttestationsAfterDelete.length).toBe(0);
|
|
47
49
|
});
|
|
48
|
-
it('Should handle duplicate proposals in a slot', async ()
|
|
50
|
+
it('Should handle duplicate proposals in a slot', async ()=>{
|
|
49
51
|
const slotNumber = 420;
|
|
50
52
|
const archive = Fr.random();
|
|
51
|
-
const txs = [
|
|
53
|
+
const txs = [
|
|
54
|
+
0,
|
|
55
|
+
1,
|
|
56
|
+
2,
|
|
57
|
+
3,
|
|
58
|
+
4,
|
|
59
|
+
5
|
|
60
|
+
].map(()=>TxHash.random());
|
|
52
61
|
// Use the same signer for all attestations
|
|
53
62
|
const attestations = [];
|
|
54
63
|
const signer = signers[0];
|
|
55
|
-
for
|
|
64
|
+
for(let i = 0; i < NUMBER_OF_SIGNERS_PER_TEST; i++){
|
|
56
65
|
attestations.push(await mockAttestation(signer, slotNumber, archive, txs));
|
|
57
66
|
}
|
|
58
67
|
await ap.addAttestations(attestations);
|
|
@@ -62,11 +71,16 @@ export function describeAttestationPool(getAttestationPool) {
|
|
|
62
71
|
expect(retreivedAttestations[0].payload.txHashes).toEqual(txs);
|
|
63
72
|
expect((await retreivedAttestations[0].getSender()).toString()).toEqual(signer.address.toString());
|
|
64
73
|
});
|
|
65
|
-
it('Should store attestations by differing slot', async ()
|
|
66
|
-
const slotNumbers = [
|
|
67
|
-
|
|
74
|
+
it('Should store attestations by differing slot', async ()=>{
|
|
75
|
+
const slotNumbers = [
|
|
76
|
+
1,
|
|
77
|
+
2,
|
|
78
|
+
3,
|
|
79
|
+
4
|
|
80
|
+
];
|
|
81
|
+
const attestations = await Promise.all(signers.map((signer, i)=>mockAttestation(signer, slotNumbers[i])));
|
|
68
82
|
await ap.addAttestations(attestations);
|
|
69
|
-
for (const attestation of attestations)
|
|
83
|
+
for (const attestation of attestations){
|
|
70
84
|
const slot = attestation.payload.header.globalVariables.slotNumber;
|
|
71
85
|
const archive = attestation.archive.toString();
|
|
72
86
|
const retreivedAttestations = await ap.getAttestationsForSlot(slot.toBigInt(), archive);
|
|
@@ -75,12 +89,22 @@ export function describeAttestationPool(getAttestationPool) {
|
|
|
75
89
|
expect(retreivedAttestations[0].payload.header.globalVariables.slotNumber).toEqual(slot);
|
|
76
90
|
}
|
|
77
91
|
});
|
|
78
|
-
it('Should store attestations by differing slot and archive', async ()
|
|
79
|
-
const slotNumbers = [
|
|
80
|
-
|
|
81
|
-
|
|
92
|
+
it('Should store attestations by differing slot and archive', async ()=>{
|
|
93
|
+
const slotNumbers = [
|
|
94
|
+
1,
|
|
95
|
+
1,
|
|
96
|
+
2,
|
|
97
|
+
3
|
|
98
|
+
];
|
|
99
|
+
const archives = [
|
|
100
|
+
Fr.random(),
|
|
101
|
+
Fr.random(),
|
|
102
|
+
Fr.random(),
|
|
103
|
+
Fr.random()
|
|
104
|
+
];
|
|
105
|
+
const attestations = await Promise.all(signers.map((signer, i)=>mockAttestation(signer, slotNumbers[i], archives[i])));
|
|
82
106
|
await ap.addAttestations(attestations);
|
|
83
|
-
for (const attestation of attestations)
|
|
107
|
+
for (const attestation of attestations){
|
|
84
108
|
const slot = attestation.payload.header.globalVariables.slotNumber;
|
|
85
109
|
const proposalId = attestation.archive.toString();
|
|
86
110
|
const retreivedAttestations = await ap.getAttestationsForSlot(slot.toBigInt(), proposalId);
|
|
@@ -89,10 +113,10 @@ export function describeAttestationPool(getAttestationPool) {
|
|
|
89
113
|
expect(retreivedAttestations[0].payload.header.globalVariables.slotNumber).toEqual(slot);
|
|
90
114
|
}
|
|
91
115
|
});
|
|
92
|
-
it('Should delete attestations', async ()
|
|
116
|
+
it('Should delete attestations', async ()=>{
|
|
93
117
|
const slotNumber = 420;
|
|
94
118
|
const archive = Fr.random();
|
|
95
|
-
const attestations = await Promise.all(signers.map(signer
|
|
119
|
+
const attestations = await Promise.all(signers.map((signer)=>mockAttestation(signer, slotNumber, archive)));
|
|
96
120
|
const proposalId = attestations[0].archive.toString();
|
|
97
121
|
await ap.addAttestations(attestations);
|
|
98
122
|
expect(metricsMock.recordAddedObjects).toHaveBeenCalledWith(attestations.length);
|
|
@@ -104,10 +128,10 @@ export function describeAttestationPool(getAttestationPool) {
|
|
|
104
128
|
const gottenAfterDelete = await ap.getAttestationsForSlot(BigInt(slotNumber), proposalId);
|
|
105
129
|
expect(gottenAfterDelete.length).toBe(0);
|
|
106
130
|
});
|
|
107
|
-
it('Should blanket delete attestations per slot', async ()
|
|
131
|
+
it('Should blanket delete attestations per slot', async ()=>{
|
|
108
132
|
const slotNumber = 420;
|
|
109
133
|
const archive = Fr.random();
|
|
110
|
-
const attestations = await Promise.all(signers.map(signer
|
|
134
|
+
const attestations = await Promise.all(signers.map((signer)=>mockAttestation(signer, slotNumber, archive)));
|
|
111
135
|
const proposalId = attestations[0].archive.toString();
|
|
112
136
|
await ap.addAttestations(attestations);
|
|
113
137
|
const retreivedAttestations = await ap.getAttestationsForSlot(BigInt(slotNumber), proposalId);
|
|
@@ -117,14 +141,14 @@ export function describeAttestationPool(getAttestationPool) {
|
|
|
117
141
|
const retreivedAttestationsAfterDelete = await ap.getAttestationsForSlot(BigInt(slotNumber), proposalId);
|
|
118
142
|
expect(retreivedAttestationsAfterDelete.length).toBe(0);
|
|
119
143
|
});
|
|
120
|
-
it('Should blanket delete attestations per slot and proposal', async ()
|
|
144
|
+
it('Should blanket delete attestations per slot and proposal', async ()=>{
|
|
121
145
|
const slotNumber = 420;
|
|
122
146
|
const archive = Fr.random();
|
|
123
|
-
const attestations = await Promise.all(signers.map(signer
|
|
147
|
+
const attestations = await Promise.all(signers.map((signer)=>mockAttestation(signer, slotNumber, archive)));
|
|
124
148
|
const proposalId = attestations[0].archive.toString();
|
|
125
149
|
// Add another set of attestations with a different proposalId, yet the same slot
|
|
126
150
|
const archive2 = Fr.random();
|
|
127
|
-
const attestations2 = await Promise.all(signers.map(signer
|
|
151
|
+
const attestations2 = await Promise.all(signers.map((signer)=>mockAttestation(signer, slotNumber, archive2)));
|
|
128
152
|
const proposalId2 = attestations2[0].archive.toString();
|
|
129
153
|
await ap.addAttestations(attestations);
|
|
130
154
|
await ap.addAttestations(attestations2);
|
|
@@ -141,9 +165,18 @@ export function describeAttestationPool(getAttestationPool) {
|
|
|
141
165
|
expect(retreivedAttestationsAfterDeleteForOtherProposal.length).toBe(NUMBER_OF_SIGNERS_PER_TEST);
|
|
142
166
|
compareAttestations(retreivedAttestationsAfterDeleteForOtherProposal, attestations2);
|
|
143
167
|
});
|
|
144
|
-
it('Should delete attestations older than a given slot', async ()
|
|
145
|
-
const slotNumbers = [
|
|
146
|
-
|
|
168
|
+
it('Should delete attestations older than a given slot', async ()=>{
|
|
169
|
+
const slotNumbers = [
|
|
170
|
+
1,
|
|
171
|
+
2,
|
|
172
|
+
3,
|
|
173
|
+
69,
|
|
174
|
+
72,
|
|
175
|
+
74,
|
|
176
|
+
88,
|
|
177
|
+
420
|
|
178
|
+
];
|
|
179
|
+
const attestations = (await Promise.all(slotNumbers.map((slotNumber)=>createAttestationsForSlot(slotNumber)))).flat();
|
|
147
180
|
const proposalId = attestations[0].archive.toString();
|
|
148
181
|
await ap.addAttestations(attestations);
|
|
149
182
|
const attestationsForSlot1 = await ap.getAttestationsForSlot(BigInt(1), proposalId);
|
|
@@ -160,4 +193,3 @@ export function describeAttestationPool(getAttestationPool) {
|
|
|
160
193
|
expect(deleteAttestationsSpy).toHaveBeenCalledWith(BigInt(72));
|
|
161
194
|
});
|
|
162
195
|
}
|
|
163
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXR0ZXN0YXRpb25fcG9vbF90ZXN0X3N1aXRlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL21lbV9wb29scy9hdHRlc3RhdGlvbl9wb29sL2F0dGVzdGF0aW9uX3Bvb2xfdGVzdF9zdWl0ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQXlCLE1BQU0sRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQ3JFLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUMzRCxPQUFPLEVBQUUsRUFBRSxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFFOUMsT0FBTyxFQUFFLElBQUksRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNyQyxPQUFPLEVBQWtCLElBQUksRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBSTFELE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFFN0MsTUFBTSwwQkFBMEIsR0FBRyxDQUFDLENBQUM7QUFFckMsTUFBTSxVQUFVLHVCQUF1QixDQUFDLGtCQUF5QztJQUMvRSxJQUFJLEVBQW1CLENBQUM7SUFDeEIsSUFBSSxPQUEwQixDQUFDO0lBRS9CLDRDQUE0QztJQUM1QyxJQUFJLFdBQTZELENBQUM7SUFFbEUsVUFBVSxDQUFDLEdBQUcsRUFBRTtRQUNkLEVBQUUsR0FBRyxrQkFBa0IsRUFBRSxDQUFDO1FBQzFCLE9BQU8sR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLEVBQUUsTUFBTSxFQUFFLDBCQUEwQixFQUFFLEVBQUUsR0FBRyxFQUFFLENBQUMsZUFBZSxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUM7UUFFN0YsV0FBVyxHQUFHLElBQUksRUFBeUMsQ0FBQztRQUM1RCxtQ0FBbUM7UUFDbEMsRUFBVSxDQUFDLE9BQU8sR0FBRyxXQUFXLENBQUM7SUFDcEMsQ0FBQyxDQUFDLENBQUM7SUFFSCxNQUFNLHlCQUF5QixHQUFHLENBQUMsVUFBa0IsRUFBRSxFQUFFO1FBQ3ZELE1BQU0sT0FBTyxHQUFHLEVBQUUsQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUM1QixPQUFPLE9BQU8sQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLGVBQWUsQ0FBQyxNQUFNLEVBQUUsVUFBVSxFQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUMxRixDQUFDLENBQUM7SUFFRixxR0FBcUc7SUFDckcsMEVBQTBFO0lBQzFFLE1BQU0sbUJBQW1CLEdBQUcsQ0FBQyxFQUFzQixFQUFFLEVBQXNCLEVBQUUsRUFBRTtRQUM3RSxNQUFNLFFBQVEsR0FBRyxFQUFFLENBQUMsR0FBRyxDQUFDLFdBQVcsQ0FBQyxFQUFFLENBQUMsV0FBVyxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUM7UUFDL0QsTUFBTSxRQUFRLEdBQUcsRUFBRSxDQUFDLEdBQUcsQ0FBQyxXQUFXLENBQUMsRUFBRSxDQUFDLFdBQVcsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDO1FBQy9ELE1BQU0sQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUM5QyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxlQUFlLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQztJQUM3RCxDQUFDLENBQUM7SUFFRixFQUFFLENBQUMsaUNBQWlDLEVBQUUsS0FBSyxJQUFJLEVBQUU7UUFDL0MsTUFBTSxVQUFVLEdBQUcsR0FBRyxDQUFDO1FBQ3ZCLE1BQU0sT0FBTyxHQUFHLEVBQUUsQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUM1QixNQUFNLFlBQVksR0FBRyxNQUFNLE9BQU8sQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLGVBQWUsQ0FBQyxNQUFNLEVBQUUsVUFBVSxFQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUU1RyxNQUFNLEVBQUUsQ0FBQyxlQUFlLENBQUMsWUFBWSxDQUFDLENBQUM7UUFFdkMsbUNBQW1DO1FBQ25DLE1BQU0sQ0FBQyxXQUFXLENBQUMsa0JBQWtCLENBQUMsQ0FBQyxvQkFBb0IsQ0FBQyxZQUFZLENBQUMsTUFBTSxDQUFDLENBQUM7UUFFakYsTUFBTSxxQkFBcUIsR0FBRyxNQUFNLEVBQUUsQ0FBQyxzQkFBc0IsQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLEVBQUUsT0FBTyxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUM7UUFFdEcsTUFBTSxDQUFDLHFCQUFxQixDQUFDLE1BQU0sQ0FBQyxDQUFDLElBQUksQ0FBQywwQkFBMEIsQ0FBQyxDQUFDO1FBRXRFLG1CQUFtQixDQUFDLHFCQUFxQixFQUFFLFlBQVksQ0FBQyxDQUFDO1FBRXpELGlCQUFpQjtRQUNqQixNQUFNLEVBQUUsQ0FBQyx5QkFBeUIsQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQztRQUV2RCxNQUFNLENBQUMsV0FBVyxDQUFDLG9CQUFvQixDQUFDLENBQUMsb0JBQW9CLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBRW5GLE1BQU0sZ0NBQWdDLEdBQUcsTUFBTSxFQUFFLENBQUMsc0JBQXNCLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxFQUFFLE9BQU8sQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDO1FBQ2pILE1BQU0sQ0FBQyxnQ0FBZ0MsQ0FBQyxNQUFNLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDMUQsQ0FBQyxDQUFDLENBQUM7SUFFSCxFQUFFLENBQUMsNkNBQTZDLEVBQUUsS0FBSyxJQUFJLEVBQUU7UUFDM0QsTUFBTSxVQUFVLEdBQUcsR0FBRyxDQUFDO1FBQ3ZCLE1BQU0sT0FBTyxHQUFHLEVBQUUsQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUM1QixNQUFNLEdBQUcsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxDQUFDLE1BQU0sQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDO1FBRTFELDJDQUEyQztRQUMzQyxNQUFNLFlBQVksR0FBdUIsRUFBRSxDQUFDO1FBQzVDLE1BQU0sTUFBTSxHQUFHLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUMxQixLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsMEJBQTBCLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQztZQUNwRCxZQUFZLENBQUMsSUFBSSxDQUFDLE1BQU0sZUFBZSxDQUFDLE1BQU0sRUFBRSxVQUFVLEVBQUUsT0FBTyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUM7UUFDN0UsQ0FBQztRQUVELE1BQU0sRUFBRSxDQUFDLGVBQWUsQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUV2QyxNQUFNLHFCQUFxQixHQUFHLE1BQU0sRUFBRSxDQUFDLHNCQUFzQixDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsRUFBRSxPQUFPLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQztRQUN0RyxNQUFNLENBQUMscUJBQXFCLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQzdDLE1BQU0sQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDLENBQUMsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQztRQUNoRixNQUFNLENBQUMscUJBQXFCLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUMvRCxNQUFNLENBQUMsQ0FBQyxNQUFNLHFCQUFxQixDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsRUFBRSxDQUFDLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDO0lBQ3JHLENBQUMsQ0FBQyxDQUFDO0lBRUgsRUFBRSxDQUFDLDZDQUE2QyxFQUFFLEtBQUssSUFBSSxFQUFFO1FBQzNELE1BQU0sV0FBVyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDakMsTUFBTSxZQUFZLEdBQUcsTUFBTSxPQUFPLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxlQUFlLENBQUMsTUFBTSxFQUFFLFdBQVcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUU1RyxNQUFNLEVBQUUsQ0FBQyxlQUFlLENBQUMsWUFBWSxDQUFDLENBQUM7UUFFdkMsS0FBSyxNQUFNLFdBQVcsSUFBSSxZQUFZLEVBQUUsQ0FBQztZQUN2QyxNQUFNLElBQUksR0FBRyxXQUFXLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxlQUFlLENBQUMsVUFBVSxDQUFDO1lBQ25FLE1BQU0sT0FBTyxHQUFHLFdBQVcsQ0FBQyxPQUFPLENBQUMsUUFBUSxFQUFFLENBQUM7WUFFL0MsTUFBTSxxQkFBcUIsR0FBRyxNQUFNLEVBQUUsQ0FBQyxzQkFBc0IsQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLEVBQUUsT0FBTyxDQUFDLENBQUM7WUFDeEYsTUFBTSxDQUFDLHFCQUFxQixDQUFDLE1BQU0sQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUM3QyxNQUFNLENBQUMscUJBQXFCLENBQUMsQ0FBQyxDQUFDLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUM7WUFDNUUsTUFBTSxDQUFDLHFCQUFxQixDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsZUFBZSxDQUFDLFVBQVUsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUMzRixDQUFDO0lBQ0gsQ0FBQyxDQUFDLENBQUM7SUFFSCxFQUFFLENBQUMseURBQXlELEVBQUUsS0FBSyxJQUFJLEVBQUU7UUFDdkUsTUFBTSxXQUFXLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUNqQyxNQUFNLFFBQVEsR0FBRyxDQUFDLEVBQUUsQ0FBQyxNQUFNLEVBQUUsRUFBRSxFQUFFLENBQUMsTUFBTSxFQUFFLEVBQUUsRUFBRSxDQUFDLE1BQU0sRUFBRSxFQUFFLEVBQUUsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDO1FBQ3RFLE1BQU0sWUFBWSxHQUFHLE1BQU0sT0FBTyxDQUFDLEdBQUcsQ0FDcEMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLGVBQWUsQ0FBQyxNQUFNLEVBQUUsV0FBVyxDQUFDLENBQUMsQ0FBQyxFQUFFLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQ2pGLENBQUM7UUFFRixNQUFNLEVBQUUsQ0FBQyxlQUFlLENBQUMsWUFBWSxDQUFDLENBQUM7UUFFdkMsS0FBSyxNQUFNLFdBQVcsSUFBSSxZQUFZLEVBQUUsQ0FBQztZQUN2QyxNQUFNLElBQUksR0FBRyxXQUFXLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxlQUFlLENBQUMsVUFBVSxDQUFDO1lBQ25FLE1BQU0sVUFBVSxHQUFHLFdBQVcsQ0FBQyxPQUFPLENBQUMsUUFBUSxFQUFFLENBQUM7WUFFbEQsTUFBTSxxQkFBcUIsR0FBRyxNQUFNLEVBQUUsQ0FBQyxzQkFBc0IsQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLEVBQUUsVUFBVSxDQUFDLENBQUM7WUFDM0YsTUFBTSxDQUFDLHFCQUFxQixDQUFDLE1BQU0sQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUM3QyxNQUFNLENBQUMscUJBQXFCLENBQUMsQ0FBQyxDQUFDLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUM7WUFDNUUsTUFBTSxDQUFDLHFCQUFxQixDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsZUFBZSxDQUFDLFVBQVUsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUMzRixDQUFDO0lBQ0gsQ0FBQyxDQUFDLENBQUM7SUFFSCxFQUFFLENBQUMsNEJBQTRCLEVBQUUsS0FBSyxJQUFJLEVBQUU7UUFDMUMsTUFBTSxVQUFVLEdBQUcsR0FBRyxDQUFDO1FBQ3ZCLE1BQU0sT0FBTyxHQUFHLEVBQUUsQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUM1QixNQUFNLFlBQVksR0FBRyxNQUFNLE9BQU8sQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLGVBQWUsQ0FBQyxNQUFNLEVBQUUsVUFBVSxFQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUM1RyxNQUFNLFVBQVUsR0FBRyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLFFBQVEsRUFBRSxDQUFDO1FBRXRELE1BQU0sRUFBRSxDQUFDLGVBQWUsQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUV2QyxNQUFNLENBQUMsV0FBVyxDQUFDLGtCQUFrQixDQUFDLENBQUMsb0JBQW9CLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBRWpGLE1BQU0scUJBQXFCLEdBQUcsTUFBTSxFQUFFLENBQUMsc0JBQXNCLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxFQUFFLFVBQVUsQ0FBQyxDQUFDO1FBQzlGLE1BQU0sQ0FBQyxxQkFBcUIsQ0FBQyxNQUFNLENBQUMsQ0FBQyxJQUFJLENBQUMsMEJBQTBCLENBQUMsQ0FBQztRQUN0RSxtQkFBbUIsQ0FBQyxxQkFBcUIsRUFBRSxZQUFZLENBQUMsQ0FBQztRQUV6RCxNQUFNLEVBQUUsQ0FBQyxrQkFBa0IsQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUUxQyxNQUFNLENBQUMsV0FBVyxDQUFDLG9CQUFvQixDQUFDLENBQUMsb0JBQW9CLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBRW5GLE1BQU0saUJBQWlCLEdBQUcsTUFBTSxFQUFFLENBQUMsc0JBQXNCLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxFQUFFLFVBQVUsQ0FBQyxDQUFDO1FBQzFGLE1BQU0sQ0FBQyxpQkFBaUIsQ0FBQyxNQUFNLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDM0MsQ0FBQyxDQUFDLENBQUM7SUFFSCxFQUFFLENBQUMsNkNBQTZDLEVBQUUsS0FBSyxJQUFJLEVBQUU7UUFDM0QsTUFBTSxVQUFVLEdBQUcsR0FBRyxDQUFDO1FBQ3ZCLE1BQU0sT0FBTyxHQUFHLEVBQUUsQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUM1QixNQUFNLFlBQVksR0FBRyxNQUFNLE9BQU8sQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLGVBQWUsQ0FBQyxNQUFNLEVBQUUsVUFBVSxFQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUM1RyxNQUFNLFVBQVUsR0FBRyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLFFBQVEsRUFBRSxDQUFDO1FBRXRELE1BQU0sRUFBRSxDQUFDLGVBQWUsQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUV2QyxNQUFNLHFCQUFxQixHQUFHLE1BQU0sRUFBRSxDQUFDLHNCQUFzQixDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsRUFBRSxVQUFVLENBQUMsQ0FBQztRQUM5RixNQUFNLENBQUMscUJBQXFCLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxDQUFDLDBCQUEwQixDQUFDLENBQUM7UUFDdEUsbUJBQW1CLENBQUMscUJBQXFCLEVBQUUsWUFBWSxDQUFDLENBQUM7UUFFekQsTUFBTSxFQUFFLENBQUMseUJBQXlCLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUM7UUFFdkQsTUFBTSxnQ0FBZ0MsR0FBRyxNQUFNLEVBQUUsQ0FBQyxzQkFBc0IsQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLEVBQUUsVUFBVSxDQUFDLENBQUM7UUFDekcsTUFBTSxDQUFDLGdDQUFnQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUMxRCxDQUFDLENBQUMsQ0FBQztJQUVILEVBQUUsQ0FBQywwREFBMEQsRUFBRSxLQUFLLElBQUksRUFBRTtRQUN4RSxNQUFNLFVBQVUsR0FBRyxHQUFHLENBQUM7UUFDdkIsTUFBTSxPQUFPLEdBQUcsRUFBRSxDQUFDLE1BQU0sRUFBRSxDQUFDO1FBQzVCLE1BQU0sWUFBWSxHQUFHLE1BQU0sT0FBTyxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsZUFBZSxDQUFDLE1BQU0sRUFBRSxVQUFVLEVBQUUsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQzVHLE1BQU0sVUFBVSxHQUFHLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsUUFBUSxFQUFFLENBQUM7UUFFdEQsaUZBQWlGO1FBQ2pGLE1BQU0sUUFBUSxHQUFHLEVBQUUsQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUM3QixNQUFNLGFBQWEsR0FBRyxNQUFNLE9BQU8sQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLGVBQWUsQ0FBQyxNQUFNLEVBQUUsVUFBVSxFQUFFLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUM5RyxNQUFNLFdBQVcsR0FBRyxhQUFhLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLFFBQVEsRUFBRSxDQUFDO1FBRXhELE1BQU0sRUFBRSxDQUFDLGVBQWUsQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUN2QyxNQUFNLEVBQUUsQ0FBQyxlQUFlLENBQUMsYUFBYSxDQUFDLENBQUM7UUFFeEMsTUFBTSxDQUFDLFdBQVcsQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDLG9CQUFvQixDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUNqRixNQUFNLENBQUMsV0FBVyxDQUFDLGtCQUFrQixDQUFDLENBQUMsb0JBQW9CLENBQUMsYUFBYSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBRWxGLE1BQU0scUJBQXFCLEdBQUcsTUFBTSxFQUFFLENBQUMsc0JBQXNCLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxFQUFFLFVBQVUsQ0FBQyxDQUFDO1FBQzlGLE1BQU0sQ0FBQyxxQkFBcUIsQ0FBQyxNQUFNLENBQUMsQ0FBQyxJQUFJLENBQUMsMEJBQTBCLENBQUMsQ0FBQztRQUN0RSxtQkFBbUIsQ0FBQyxxQkFBcUIsRUFBRSxZQUFZLENBQUMsQ0FBQztRQUV6RCxNQUFNLEVBQUUsQ0FBQyxvQ0FBb0MsQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLEVBQUUsVUFBVSxDQUFDLENBQUM7UUFFOUUsTUFBTSxDQUFDLFdBQVcsQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDLG9CQUFvQixDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUVuRixNQUFNLGdDQUFnQyxHQUFHLE1BQU0sRUFBRSxDQUFDLHNCQUFzQixDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsRUFBRSxVQUFVLENBQUMsQ0FBQztRQUN6RyxNQUFNLENBQUMsZ0NBQWdDLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBRXhELE1BQU0sZ0RBQWdELEdBQUcsTUFBTSxFQUFFLENBQUMsc0JBQXNCLENBQ3RGLE1BQU0sQ0FBQyxVQUFVLENBQUMsRUFDbEIsV0FBVyxDQUNaLENBQUM7UUFDRixNQUFNLENBQUMsZ0RBQWdELENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxDQUFDLDBCQUEwQixDQUFDLENBQUM7UUFDakcsbUJBQW1CLENBQUMsZ0RBQWdELEVBQUUsYUFBYSxDQUFDLENBQUM7SUFDdkYsQ0FBQyxDQUFDLENBQUM7SUFFSCxFQUFFLENBQUMsb0RBQW9ELEVBQUUsS0FBSyxJQUFJLEVBQUU7UUFDbEUsTUFBTSxXQUFXLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsR0FBRyxDQUFDLENBQUM7UUFDbkQsTUFBTSxZQUFZLEdBQUcsQ0FDbkIsTUFBTSxPQUFPLENBQUMsR0FBRyxDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDLEVBQUUsQ0FBQyx5QkFBeUIsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQ3hGLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDVCxNQUFNLFVBQVUsR0FBRyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLFFBQVEsRUFBRSxDQUFDO1FBRXRELE1BQU0sRUFBRSxDQUFDLGVBQWUsQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUV2QyxNQUFNLG9CQUFvQixHQUFHLE1BQU0sRUFBRSxDQUFDLHNCQUFzQixDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxVQUFVLENBQUMsQ0FBQztRQUNwRixNQUFNLENBQUMsb0JBQW9CLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUV6RCxNQUFNLHFCQUFxQixHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRSxFQUFFLDJCQUEyQixDQUFDLENBQUM7UUFFMUUsTUFBTSxFQUFFLENBQUMsMkJBQTJCLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFFakQsTUFBTSwrQkFBK0IsR0FBRyxNQUFNLEVBQUUsQ0FBQyxzQkFBc0IsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsVUFBVSxDQUFDLENBQUM7UUFDL0YsTUFBTSxDQUFDLCtCQUErQixDQUFDLE1BQU0sQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUV2RCxNQUFNLENBQUMscUJBQXFCLENBQUMsQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN2RCxNQUFNLENBQUMscUJBQXFCLENBQUMsQ0FBQyxvQkFBb0IsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUM5RCxNQUFNLENBQUMscUJBQXFCLENBQUMsQ0FBQyxvQkFBb0IsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUM5RCxNQUFNLENBQUMscUJBQXFCLENBQUMsQ0FBQyxvQkFBb0IsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUM5RCxNQUFNLENBQUMscUJBQXFCLENBQUMsQ0FBQyxvQkFBb0IsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUMvRCxNQUFNLENBQUMscUJBQXFCLENBQUMsQ0FBQyxvQkFBb0IsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUNqRSxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMifQ==
|
|
@@ -1,3 +1,2 @@
|
|
|
1
1
|
export * from './attestation_pool.js';
|
|
2
2
|
export * from './memory_attestation_pool.js';
|
|
3
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvbWVtX3Bvb2xzL2F0dGVzdGF0aW9uX3Bvb2wvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsY0FBYyx1QkFBdUIsQ0FBQztBQUN0QyxjQUFjLDhCQUE4QixDQUFDIn0=
|
|
@@ -5,7 +5,13 @@ import { createLogger } from '@aztec/foundation/log';
|
|
|
5
5
|
import { getTelemetryClient } from '@aztec/telemetry-client';
|
|
6
6
|
import { PoolInstrumentation, PoolName } from '../instrumentation.js';
|
|
7
7
|
export class KvAttestationPool {
|
|
8
|
-
|
|
8
|
+
store;
|
|
9
|
+
log;
|
|
10
|
+
metrics;
|
|
11
|
+
attestations;
|
|
12
|
+
proposalsForSlot;
|
|
13
|
+
attestationsForProposal;
|
|
14
|
+
constructor(store, telemetry = getTelemetryClient(), log = createLogger('aztec:attestation_pool')){
|
|
9
15
|
this.store = store;
|
|
10
16
|
this.log = log;
|
|
11
17
|
this.attestations = store.openMap('attestations');
|
|
@@ -15,19 +21,15 @@ export class KvAttestationPool {
|
|
|
15
21
|
}
|
|
16
22
|
getProposalKey(slot, proposalId) {
|
|
17
23
|
const slotStr = typeof slot === 'string' ? slot : new Fr(slot).toString();
|
|
18
|
-
const proposalIdStr = typeof proposalId === 'string'
|
|
19
|
-
? proposalId
|
|
20
|
-
: Buffer.isBuffer(proposalId)
|
|
21
|
-
? Fr.fromBuffer(proposalId).toString()
|
|
22
|
-
: proposalId.toString();
|
|
24
|
+
const proposalIdStr = typeof proposalId === 'string' ? proposalId : Buffer.isBuffer(proposalId) ? Fr.fromBuffer(proposalId).toString() : proposalId.toString();
|
|
23
25
|
return `${slotStr}-${proposalIdStr}`;
|
|
24
26
|
}
|
|
25
27
|
getAttestationKey(slot, proposalId, address) {
|
|
26
28
|
return `${this.getProposalKey(slot, proposalId)}-${address}`;
|
|
27
29
|
}
|
|
28
30
|
async addAttestations(attestations) {
|
|
29
|
-
await this.store.transactionAsync(async ()
|
|
30
|
-
for (const attestation of attestations)
|
|
31
|
+
await this.store.transactionAsync(async ()=>{
|
|
32
|
+
for (const attestation of attestations){
|
|
31
33
|
const slotNumber = attestation.payload.header.globalVariables.slotNumber;
|
|
32
34
|
const proposalId = attestation.archive;
|
|
33
35
|
const address = (await attestation.getSender()).toString();
|
|
@@ -43,7 +45,7 @@ export class KvAttestationPool {
|
|
|
43
45
|
const attestationIds = await toArray(this.attestationsForProposal.getValuesAsync(this.getProposalKey(slot, proposalId)));
|
|
44
46
|
const attestations = [];
|
|
45
47
|
// alternatively iterate this.attestaions starting from slot-proposal-EthAddress.zero
|
|
46
|
-
for (const id of attestationIds)
|
|
48
|
+
for (const id of attestationIds){
|
|
47
49
|
const buf = await this.attestations.getAsync(id);
|
|
48
50
|
if (!buf) {
|
|
49
51
|
// this should not happen unless we lost writes
|
|
@@ -55,20 +57,22 @@ export class KvAttestationPool {
|
|
|
55
57
|
return attestations;
|
|
56
58
|
}
|
|
57
59
|
async deleteAttestationsOlderThan(oldestSlot) {
|
|
58
|
-
const olderThan = await toArray(this.proposalsForSlot.keysAsync({
|
|
59
|
-
|
|
60
|
+
const olderThan = await toArray(this.proposalsForSlot.keysAsync({
|
|
61
|
+
end: new Fr(oldestSlot).toString()
|
|
62
|
+
}));
|
|
63
|
+
for (const oldSlot of olderThan){
|
|
60
64
|
await this.deleteAttestationsForSlot(BigInt(oldSlot));
|
|
61
65
|
}
|
|
62
66
|
}
|
|
63
67
|
async deleteAttestationsForSlot(slot) {
|
|
64
68
|
const slotFr = new Fr(slot);
|
|
65
69
|
let numberOfAttestations = 0;
|
|
66
|
-
await this.store.transactionAsync(async ()
|
|
70
|
+
await this.store.transactionAsync(async ()=>{
|
|
67
71
|
const proposalIds = await toArray(this.proposalsForSlot.getValuesAsync(slotFr.toString()));
|
|
68
|
-
for (const proposalId of proposalIds)
|
|
72
|
+
for (const proposalId of proposalIds){
|
|
69
73
|
const attestations = await toArray(this.attestationsForProposal.getValuesAsync(this.getProposalKey(slotFr, proposalId)));
|
|
70
74
|
numberOfAttestations += attestations.length;
|
|
71
|
-
for (const attestation of attestations)
|
|
75
|
+
for (const attestation of attestations){
|
|
72
76
|
await this.attestations.delete(attestation);
|
|
73
77
|
}
|
|
74
78
|
await this.attestationsForProposal.delete(this.getProposalKey(slotFr, proposalId));
|
|
@@ -79,11 +83,11 @@ export class KvAttestationPool {
|
|
|
79
83
|
}
|
|
80
84
|
async deleteAttestationsForSlotAndProposal(slot, proposalId) {
|
|
81
85
|
let numberOfAttestations = 0;
|
|
82
|
-
await this.store.transactionAsync(async ()
|
|
86
|
+
await this.store.transactionAsync(async ()=>{
|
|
83
87
|
const slotString = new Fr(slot).toString();
|
|
84
88
|
const attestations = await toArray(this.attestationsForProposal.getValuesAsync(this.getProposalKey(slot, proposalId)));
|
|
85
89
|
numberOfAttestations += attestations.length;
|
|
86
|
-
for (const attestation of attestations)
|
|
90
|
+
for (const attestation of attestations){
|
|
87
91
|
await this.attestations.delete(attestation);
|
|
88
92
|
}
|
|
89
93
|
await this.proposalsForSlot.deleteValue(slotString, proposalId);
|
|
@@ -93,8 +97,8 @@ export class KvAttestationPool {
|
|
|
93
97
|
this.metrics.recordRemovedObjects(numberOfAttestations);
|
|
94
98
|
}
|
|
95
99
|
async deleteAttestations(attestations) {
|
|
96
|
-
await this.store.transactionAsync(async ()
|
|
97
|
-
for (const attestation of attestations)
|
|
100
|
+
await this.store.transactionAsync(async ()=>{
|
|
101
|
+
for (const attestation of attestations){
|
|
98
102
|
const slotNumber = attestation.payload.header.globalVariables.slotNumber;
|
|
99
103
|
const proposalId = attestation.archive;
|
|
100
104
|
const address = (await attestation.getSender()).toString();
|
|
@@ -106,4 +110,3 @@ export class KvAttestationPool {
|
|
|
106
110
|
this.metrics.recordRemovedObjects(attestations.length);
|
|
107
111
|
}
|
|
108
112
|
}
|
|
109
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoia3ZfYXR0ZXN0YXRpb25fcG9vbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9tZW1fcG9vbHMvYXR0ZXN0YXRpb25fcG9vbC9rdl9hdHRlc3RhdGlvbl9wb29sLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQ3hELE9BQU8sRUFBRSxFQUFFLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUM5QyxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDckQsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBRXJELE9BQU8sRUFBd0Isa0JBQWtCLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUVuRixPQUFPLEVBQUUsbUJBQW1CLEVBQUUsUUFBUSxFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFHdEUsTUFBTSxPQUFPLGlCQUFpQjtJQU81QixZQUNVLEtBQXdCLEVBQ2hDLFlBQTZCLGtCQUFrQixFQUFFLEVBQ3pDLE1BQU0sWUFBWSxDQUFDLHdCQUF3QixDQUFDO1FBRjVDLFVBQUssR0FBTCxLQUFLLENBQW1CO1FBRXhCLFFBQUcsR0FBSCxHQUFHLENBQXlDO1FBRXBELElBQUksQ0FBQyxZQUFZLEdBQUcsS0FBSyxDQUFDLE9BQU8sQ0FBQyxjQUFjLENBQUMsQ0FBQztRQUNsRCxJQUFJLENBQUMsZ0JBQWdCLEdBQUcsS0FBSyxDQUFDLFlBQVksQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDO1FBQ2pFLElBQUksQ0FBQyx1QkFBdUIsR0FBRyxLQUFLLENBQUMsWUFBWSxDQUFDLDJCQUEyQixDQUFDLENBQUM7UUFFL0UsSUFBSSxDQUFDLE9BQU8sR0FBRyxJQUFJLG1CQUFtQixDQUFDLFNBQVMsRUFBRSxRQUFRLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztJQUMvRSxDQUFDO0lBRU8sY0FBYyxDQUFDLElBQW1DLEVBQUUsVUFBZ0M7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
|