@aztec/cli 0.0.0-test.0 → 0.0.1-commit.0208eb9
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/README.md +2 -428
- package/dest/cmds/aztec_node/block_number.d.ts +3 -0
- package/dest/cmds/aztec_node/block_number.d.ts.map +1 -0
- package/dest/cmds/aztec_node/block_number.js +10 -0
- package/dest/cmds/aztec_node/get_block.d.ts +3 -0
- package/dest/cmds/aztec_node/get_block.d.ts.map +1 -0
- package/dest/cmds/aztec_node/get_block.js +10 -0
- package/dest/cmds/aztec_node/get_current_min_fee.d.ts +3 -0
- package/dest/cmds/aztec_node/get_current_min_fee.d.ts.map +1 -0
- package/dest/cmds/aztec_node/get_current_min_fee.js +7 -0
- package/dest/cmds/aztec_node/get_l1_to_l2_message_witness.d.ts +5 -0
- package/dest/cmds/aztec_node/get_l1_to_l2_message_witness.d.ts.map +1 -0
- package/dest/cmds/aztec_node/get_l1_to_l2_message_witness.js +12 -0
- package/dest/cmds/aztec_node/get_logs.d.ts +7 -0
- package/dest/cmds/aztec_node/get_logs.d.ts.map +1 -0
- package/dest/cmds/{pxe → aztec_node}/get_logs.js +4 -4
- package/dest/cmds/aztec_node/get_node_info.d.ts +3 -0
- package/dest/cmds/aztec_node/get_node_info.d.ts.map +1 -0
- package/dest/cmds/{pxe → aztec_node}/get_node_info.js +14 -15
- package/dest/cmds/aztec_node/index.d.ts +4 -0
- package/dest/cmds/aztec_node/index.d.ts.map +1 -0
- package/dest/cmds/aztec_node/index.js +28 -0
- package/dest/cmds/contracts/index.d.ts +1 -1
- package/dest/cmds/contracts/inspect_contract.d.ts +1 -1
- package/dest/cmds/contracts/inspect_contract.d.ts.map +1 -1
- package/dest/cmds/contracts/inspect_contract.js +13 -15
- package/dest/cmds/contracts/parse_parameter_struct.d.ts +1 -1
- package/dest/cmds/infrastructure/index.d.ts +3 -3
- package/dest/cmds/infrastructure/index.d.ts.map +1 -1
- package/dest/cmds/infrastructure/index.js +8 -10
- package/dest/cmds/infrastructure/sequencers.d.ts +5 -6
- package/dest/cmds/infrastructure/sequencers.d.ts.map +1 -1
- package/dest/cmds/infrastructure/sequencers.js +38 -18
- package/dest/cmds/infrastructure/setup_l2_contract.d.ts +2 -2
- package/dest/cmds/infrastructure/setup_l2_contract.d.ts.map +1 -1
- package/dest/cmds/infrastructure/setup_l2_contract.js +11 -24
- package/dest/cmds/l1/advance_epoch.d.ts +2 -2
- package/dest/cmds/l1/advance_epoch.d.ts.map +1 -1
- package/dest/cmds/l1/advance_epoch.js +8 -6
- package/dest/cmds/l1/assume_proven_through.d.ts +3 -2
- package/dest/cmds/l1/assume_proven_through.d.ts.map +1 -1
- package/dest/cmds/l1/assume_proven_through.js +10 -10
- package/dest/cmds/l1/bridge_erc20.d.ts +3 -3
- package/dest/cmds/l1/bridge_erc20.d.ts.map +1 -1
- package/dest/cmds/l1/bridge_erc20.js +6 -5
- package/dest/cmds/l1/compute_genesis_values.d.ts +4 -0
- package/dest/cmds/l1/compute_genesis_values.d.ts.map +1 -0
- package/dest/cmds/l1/compute_genesis_values.js +17 -0
- package/dest/cmds/l1/create_l1_account.d.ts +1 -1
- package/dest/cmds/l1/deploy_l1_contracts_cmd.d.ts +4 -0
- package/dest/cmds/l1/deploy_l1_contracts_cmd.d.ts.map +1 -0
- package/dest/cmds/l1/deploy_l1_contracts_cmd.js +81 -0
- package/dest/cmds/l1/deploy_new_rollup.d.ts +4 -3
- package/dest/cmds/l1/deploy_new_rollup.d.ts.map +1 -1
- package/dest/cmds/l1/deploy_new_rollup.js +18 -9
- package/dest/cmds/l1/get_l1_addresses.d.ts +2 -2
- package/dest/cmds/l1/get_l1_addresses.d.ts.map +1 -1
- package/dest/cmds/l1/get_l1_addresses.js +5 -2
- package/dest/cmds/l1/get_l1_balance.d.ts +1 -1
- package/dest/cmds/l1/get_l1_balance.js +4 -2
- package/dest/cmds/l1/governance_utils.d.ts +5 -5
- package/dest/cmds/l1/governance_utils.d.ts.map +1 -1
- package/dest/cmds/l1/governance_utils.js +19 -17
- package/dest/cmds/l1/index.d.ts +1 -1
- package/dest/cmds/l1/index.d.ts.map +1 -1
- package/dest/cmds/l1/index.js +41 -44
- package/dest/cmds/l1/prover_stats.d.ts +1 -1
- package/dest/cmds/l1/prover_stats.d.ts.map +1 -1
- package/dest/cmds/l1/prover_stats.js +32 -30
- package/dest/cmds/l1/trigger_seed_snapshot.d.ts +6 -0
- package/dest/cmds/l1/trigger_seed_snapshot.d.ts.map +1 -0
- package/dest/cmds/l1/trigger_seed_snapshot.js +20 -0
- package/dest/cmds/l1/update_l1_validators.d.ts +21 -6
- package/dest/cmds/l1/update_l1_validators.d.ts.map +1 -1
- package/dest/cmds/l1/update_l1_validators.js +198 -103
- package/dest/cmds/misc/compute_selector.d.ts +1 -1
- package/dest/cmds/misc/example_contracts.d.ts +1 -1
- package/dest/cmds/misc/generate_bootnode_enr.d.ts +2 -2
- package/dest/cmds/misc/generate_bootnode_enr.d.ts.map +1 -1
- package/dest/cmds/misc/generate_bootnode_enr.js +2 -2
- package/dest/cmds/misc/generate_p2p_private_key.d.ts +1 -1
- package/dest/cmds/misc/generate_secret_and_hash.d.ts +2 -2
- package/dest/cmds/misc/generate_secret_and_hash.d.ts.map +1 -1
- package/dest/cmds/misc/generate_secret_and_hash.js +4 -4
- package/dest/cmds/misc/generate_secret_key.d.ts +2 -2
- package/dest/cmds/misc/generate_secret_key.d.ts.map +1 -1
- package/dest/cmds/misc/generate_secret_key.js +1 -1
- package/dest/cmds/misc/get_canonical_sponsored_fpc_address.d.ts +3 -0
- package/dest/cmds/misc/get_canonical_sponsored_fpc_address.d.ts.map +1 -0
- package/dest/cmds/misc/get_canonical_sponsored_fpc_address.js +4 -0
- package/dest/cmds/misc/index.d.ts +1 -1
- package/dest/cmds/misc/index.d.ts.map +1 -1
- package/dest/cmds/misc/index.js +8 -4
- package/dest/cmds/misc/update/common.d.ts +1 -1
- package/dest/cmds/misc/update/github.d.ts +1 -2
- package/dest/cmds/misc/update/github.d.ts.map +1 -1
- package/dest/cmds/misc/update/github.js +0 -1
- package/dest/cmds/misc/update/noir.d.ts +1 -1
- package/dest/cmds/misc/update/npm.d.ts +1 -1
- package/dest/cmds/misc/update/npm.js +1 -1
- package/dest/cmds/misc/update/utils.d.ts +1 -1
- package/dest/cmds/misc/update.d.ts +1 -1
- package/dest/cmds/misc/update.d.ts.map +1 -1
- package/dest/cmds/misc/update.js +2 -3
- package/dest/cmds/validator_keys/add.d.ts +5 -0
- package/dest/cmds/validator_keys/add.d.ts.map +1 -0
- package/dest/cmds/validator_keys/add.js +83 -0
- package/dest/cmds/validator_keys/generate_bls_keypair.d.ts +12 -0
- package/dest/cmds/validator_keys/generate_bls_keypair.d.ts.map +1 -0
- package/dest/cmds/validator_keys/generate_bls_keypair.js +27 -0
- package/dest/cmds/validator_keys/index.d.ts +4 -0
- package/dest/cmds/validator_keys/index.d.ts.map +1 -0
- package/dest/cmds/validator_keys/index.js +32 -0
- package/dest/cmds/validator_keys/new.d.ts +29 -0
- package/dest/cmds/validator_keys/new.d.ts.map +1 -0
- package/dest/cmds/validator_keys/new.js +134 -0
- package/dest/cmds/validator_keys/shared.d.ts +68 -0
- package/dest/cmds/validator_keys/shared.d.ts.map +1 -0
- package/dest/cmds/validator_keys/shared.js +274 -0
- package/dest/cmds/validator_keys/staker.d.ts +38 -0
- package/dest/cmds/validator_keys/staker.d.ts.map +1 -0
- package/dest/cmds/validator_keys/staker.js +210 -0
- package/dest/cmds/validator_keys/utils.d.ts +25 -0
- package/dest/cmds/validator_keys/utils.d.ts.map +1 -0
- package/dest/cmds/validator_keys/utils.js +52 -0
- package/dest/config/cached_fetch.d.ts +18 -0
- package/dest/config/cached_fetch.d.ts.map +1 -0
- package/dest/config/cached_fetch.js +54 -0
- package/dest/config/chain_l2_config.d.ts +14 -0
- package/dest/config/chain_l2_config.d.ts.map +1 -0
- package/dest/config/chain_l2_config.js +45 -0
- package/dest/config/enrich_env.d.ts +4 -0
- package/dest/config/enrich_env.d.ts.map +1 -0
- package/dest/config/enrich_env.js +12 -0
- package/dest/config/generated/networks.d.ts +205 -0
- package/dest/config/generated/networks.d.ts.map +1 -0
- package/dest/config/generated/networks.js +206 -0
- package/dest/config/get_l1_config.d.ts +9 -0
- package/dest/config/get_l1_config.d.ts.map +1 -0
- package/dest/config/get_l1_config.js +24 -0
- package/dest/config/index.d.ts +5 -0
- package/dest/config/index.d.ts.map +1 -0
- package/dest/config/index.js +4 -0
- package/dest/config/network_config.d.ts +22 -0
- package/dest/config/network_config.d.ts.map +1 -0
- package/dest/config/network_config.js +115 -0
- package/dest/utils/aztec.d.ts +15 -26
- package/dest/utils/aztec.d.ts.map +1 -1
- package/dest/utils/aztec.js +56 -72
- package/dest/utils/commands.d.ts +22 -13
- package/dest/utils/commands.d.ts.map +1 -1
- package/dest/utils/commands.js +43 -16
- package/dest/utils/encoding.d.ts +1 -1
- package/dest/utils/encoding.js +2 -2
- package/dest/utils/github.d.ts +1 -2
- package/dest/utils/github.d.ts.map +1 -1
- package/dest/utils/github.js +0 -1
- package/dest/utils/index.d.ts +2 -1
- package/dest/utils/index.d.ts.map +1 -1
- package/dest/utils/index.js +1 -0
- package/dest/utils/inspect.d.ts +5 -11
- package/dest/utils/inspect.d.ts.map +1 -1
- package/dest/utils/inspect.js +23 -110
- package/dest/utils/setup_contracts.d.ts +3 -0
- package/dest/utils/setup_contracts.d.ts.map +1 -0
- package/dest/utils/setup_contracts.js +16 -0
- package/package.json +61 -37
- package/public_include_metric_prefixes.json +1 -0
- package/src/cmds/aztec_node/block_number.ts +9 -0
- package/src/cmds/aztec_node/get_block.ts +11 -0
- package/src/cmds/aztec_node/get_current_min_fee.ts +9 -0
- package/src/cmds/aztec_node/get_l1_to_l2_message_witness.ts +27 -0
- package/src/cmds/{pxe → aztec_node}/get_logs.ts +11 -9
- package/src/cmds/{pxe → aztec_node}/get_node_info.ts +15 -23
- package/src/cmds/aztec_node/index.ts +87 -0
- package/src/cmds/contracts/inspect_contract.ts +20 -17
- package/src/cmds/infrastructure/index.ts +8 -11
- package/src/cmds/infrastructure/sequencers.ts +41 -22
- package/src/cmds/infrastructure/setup_l2_contract.ts +13 -25
- package/src/cmds/l1/advance_epoch.ts +7 -5
- package/src/cmds/l1/assume_proven_through.ts +11 -10
- package/src/cmds/l1/bridge_erc20.ts +8 -4
- package/src/cmds/l1/compute_genesis_values.ts +29 -0
- package/src/cmds/l1/deploy_l1_contracts_cmd.ts +107 -0
- package/src/cmds/l1/deploy_new_rollup.ts +24 -15
- package/src/cmds/l1/get_l1_addresses.ts +5 -3
- package/src/cmds/l1/get_l1_balance.ts +2 -2
- package/src/cmds/l1/governance_utils.ts +20 -24
- package/src/cmds/l1/index.ts +87 -113
- package/src/cmds/l1/prover_stats.ts +42 -31
- package/src/cmds/l1/trigger_seed_snapshot.ts +32 -0
- package/src/cmds/l1/update_l1_validators.ts +218 -97
- package/src/cmds/misc/generate_bootnode_enr.ts +3 -2
- package/src/cmds/misc/generate_secret_and_hash.ts +4 -4
- package/src/cmds/misc/generate_secret_key.ts +1 -1
- package/src/cmds/misc/get_canonical_sponsored_fpc_address.ts +7 -0
- package/src/cmds/misc/index.ts +14 -5
- package/src/cmds/misc/update/github.ts +0 -1
- package/src/cmds/misc/update/npm.ts +1 -1
- package/src/cmds/misc/update.ts +1 -7
- package/src/cmds/validator_keys/add.ts +123 -0
- package/src/cmds/validator_keys/generate_bls_keypair.ts +34 -0
- package/src/cmds/validator_keys/index.ts +142 -0
- package/src/cmds/validator_keys/new.ts +207 -0
- package/src/cmds/validator_keys/shared.ts +326 -0
- package/src/cmds/validator_keys/staker.ts +301 -0
- package/src/cmds/validator_keys/utils.ts +81 -0
- package/src/config/cached_fetch.ts +67 -0
- package/src/config/chain_l2_config.ts +57 -0
- package/src/config/enrich_env.ts +15 -0
- package/src/config/generated/networks.ts +210 -0
- package/src/config/get_l1_config.ts +31 -0
- package/src/config/index.ts +4 -0
- package/src/config/network_config.ts +147 -0
- package/src/utils/aztec.ts +74 -120
- package/src/utils/commands.ts +57 -20
- package/src/utils/encoding.ts +2 -2
- package/src/utils/github.ts +0 -1
- package/src/utils/index.ts +1 -0
- package/src/utils/inspect.ts +28 -124
- package/src/utils/setup_contracts.ts +19 -0
- package/dest/cmds/devnet/bootstrap_network.d.ts +0 -3
- package/dest/cmds/devnet/bootstrap_network.d.ts.map +0 -1
- package/dest/cmds/devnet/bootstrap_network.js +0 -196
- package/dest/cmds/devnet/faucet.d.ts +0 -4
- package/dest/cmds/devnet/faucet.d.ts.map +0 -1
- package/dest/cmds/devnet/faucet.js +0 -26
- package/dest/cmds/devnet/index.d.ts +0 -4
- package/dest/cmds/devnet/index.d.ts.map +0 -1
- package/dest/cmds/devnet/index.js +0 -14
- package/dest/cmds/l1/deploy_l1_contracts.d.ts +0 -4
- package/dest/cmds/l1/deploy_l1_contracts.d.ts.map +0 -1
- package/dest/cmds/l1/deploy_l1_contracts.js +0 -29
- package/dest/cmds/l1/deploy_l1_verifier.d.ts +0 -5
- package/dest/cmds/l1/deploy_l1_verifier.d.ts.map +0 -1
- package/dest/cmds/l1/deploy_l1_verifier.js +0 -54
- package/dest/cmds/misc/setup_contracts.d.ts +0 -7
- package/dest/cmds/misc/setup_contracts.d.ts.map +0 -1
- package/dest/cmds/misc/setup_contracts.js +0 -27
- package/dest/cmds/pxe/add_contract.d.ts +0 -5
- package/dest/cmds/pxe/add_contract.d.ts.map +0 -1
- package/dest/cmds/pxe/add_contract.js +0 -29
- package/dest/cmds/pxe/block_number.d.ts +0 -3
- package/dest/cmds/pxe/block_number.d.ts.map +0 -1
- package/dest/cmds/pxe/block_number.js +0 -10
- package/dest/cmds/pxe/get_account.d.ts +0 -4
- package/dest/cmds/pxe/get_account.d.ts.map +0 -1
- package/dest/cmds/pxe/get_account.js +0 -10
- package/dest/cmds/pxe/get_accounts.d.ts +0 -3
- package/dest/cmds/pxe/get_accounts.d.ts.map +0 -1
- package/dest/cmds/pxe/get_accounts.js +0 -25
- package/dest/cmds/pxe/get_block.d.ts +0 -3
- package/dest/cmds/pxe/get_block.d.ts.map +0 -1
- package/dest/cmds/pxe/get_block.js +0 -9
- package/dest/cmds/pxe/get_contract_data.d.ts +0 -4
- package/dest/cmds/pxe/get_contract_data.d.ts.map +0 -1
- package/dest/cmds/pxe/get_contract_data.js +0 -31
- package/dest/cmds/pxe/get_current_base_fee.d.ts +0 -3
- package/dest/cmds/pxe/get_current_base_fee.d.ts.map +0 -1
- package/dest/cmds/pxe/get_current_base_fee.js +0 -7
- package/dest/cmds/pxe/get_l1_to_l2_message_witness.d.ts +0 -4
- package/dest/cmds/pxe/get_l1_to_l2_message_witness.d.ts.map +0 -1
- package/dest/cmds/pxe/get_l1_to_l2_message_witness.js +0 -11
- package/dest/cmds/pxe/get_logs.d.ts +0 -4
- package/dest/cmds/pxe/get_logs.d.ts.map +0 -1
- package/dest/cmds/pxe/get_node_info.d.ts +0 -3
- package/dest/cmds/pxe/get_node_info.d.ts.map +0 -1
- package/dest/cmds/pxe/get_pxe_info.d.ts +0 -3
- package/dest/cmds/pxe/get_pxe_info.d.ts.map +0 -1
- package/dest/cmds/pxe/get_pxe_info.js +0 -11
- package/dest/cmds/pxe/index.d.ts +0 -4
- package/dest/cmds/pxe/index.d.ts.map +0 -1
- package/dest/cmds/pxe/index.js +0 -55
- package/src/cmds/devnet/bootstrap_network.ts +0 -318
- package/src/cmds/devnet/faucet.ts +0 -33
- package/src/cmds/devnet/index.ts +0 -60
- package/src/cmds/l1/deploy_l1_contracts.ts +0 -65
- package/src/cmds/l1/deploy_l1_verifier.ts +0 -105
- package/src/cmds/misc/setup_contracts.ts +0 -40
- package/src/cmds/pxe/add_contract.ts +0 -41
- package/src/cmds/pxe/block_number.ts +0 -9
- package/src/cmds/pxe/get_account.ts +0 -16
- package/src/cmds/pxe/get_accounts.ts +0 -35
- package/src/cmds/pxe/get_block.ts +0 -10
- package/src/cmds/pxe/get_contract_data.ts +0 -51
- package/src/cmds/pxe/get_current_base_fee.ts +0 -9
- package/src/cmds/pxe/get_l1_to_l2_message_witness.ts +0 -25
- package/src/cmds/pxe/get_pxe_info.ts +0 -13
- package/src/cmds/pxe/index.ts +0 -170
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { retrieveL2ProofVerifiedEvents } from '@aztec/archiver';
|
|
2
|
-
import { createEthereumChain } from '@aztec/ethereum';
|
|
2
|
+
import { createEthereumChain } from '@aztec/ethereum/chain';
|
|
3
3
|
import { compactArray, mapValues, unique } from '@aztec/foundation/collection';
|
|
4
4
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
5
5
|
import { createLogger } from '@aztec/foundation/log';
|
|
@@ -18,7 +18,9 @@ export async function proverStats(opts) {
|
|
|
18
18
|
const chain = createEthereumChain(l1RpcUrls, chainId).chainInfo;
|
|
19
19
|
const publicClient = createPublicClient({
|
|
20
20
|
chain,
|
|
21
|
-
transport: fallback(l1RpcUrls.map((url)=>http(url
|
|
21
|
+
transport: fallback(l1RpcUrls.map((url)=>http(url, {
|
|
22
|
+
batch: false
|
|
23
|
+
})))
|
|
22
24
|
});
|
|
23
25
|
const lastBlockNum = endBlock ?? await publicClient.getBlockNumber();
|
|
24
26
|
debugLog.verbose(`Querying events on rollup at ${rollup.toString()} from ${startBlock} up to ${lastBlockNum}`);
|
|
@@ -26,30 +28,30 @@ export async function proverStats(opts) {
|
|
|
26
28
|
const events = await getL2ProofVerifiedEvents(startBlock, lastBlockNum, batchSize, debugLog, publicClient, rollup);
|
|
27
29
|
// If we only care for raw logs, output them
|
|
28
30
|
if (rawLogs && !provingTimeout) {
|
|
29
|
-
log(`l1_block_number,
|
|
31
|
+
log(`l1_block_number, checkpoint_number, prover_id, tx_hash`);
|
|
30
32
|
for (const event of events){
|
|
31
|
-
const { l1BlockNumber,
|
|
32
|
-
log(`${l1BlockNumber}, ${
|
|
33
|
+
const { l1BlockNumber, checkpointNumber, proverId, txHash } = event;
|
|
34
|
+
log(`${l1BlockNumber}, ${checkpointNumber}, ${proverId}, ${txHash}`);
|
|
33
35
|
}
|
|
34
36
|
return;
|
|
35
37
|
}
|
|
36
|
-
// If we don't have a proving timeout, we can just count the number of unique
|
|
38
|
+
// If we don't have a proving timeout, we can just count the number of unique checkpoints per prover
|
|
37
39
|
if (!provingTimeout) {
|
|
38
40
|
const stats = groupBy(events, 'proverId');
|
|
39
|
-
log(`prover_id,
|
|
41
|
+
log(`prover_id, total_checkpoints_proven`);
|
|
40
42
|
for(const proverId in stats){
|
|
41
|
-
const
|
|
42
|
-
log(`${proverId}, ${
|
|
43
|
+
const uniqueCheckpoints = new Set(stats[proverId].map((e)=>e.checkpointNumber));
|
|
44
|
+
log(`${proverId}, ${uniqueCheckpoints.size}`);
|
|
43
45
|
}
|
|
44
46
|
return;
|
|
45
47
|
}
|
|
46
|
-
// But if we do, fetch the events for each
|
|
47
|
-
const
|
|
48
|
-
debugLog.verbose(`First
|
|
48
|
+
// But if we do, fetch the events for each checkpoint submitted, so we can look up their timestamp
|
|
49
|
+
const checkpointEvents = await getCheckpointProposedEvents(startBlock, lastBlockNum, batchSize, debugLog, publicClient, rollup);
|
|
50
|
+
debugLog.verbose(`First checkpoint within range is ${checkpointEvents[0]?.args.checkpointNumber} at L1 block ${checkpointEvents[0]?.blockNumber}`);
|
|
49
51
|
// Get the timestamps for every block on every log, both for proof and block submissions
|
|
50
52
|
const l1BlockNumbers = unique([
|
|
51
53
|
...events.map((e)=>e.l1BlockNumber),
|
|
52
|
-
...
|
|
54
|
+
...checkpointEvents.map((e)=>e.blockNumber)
|
|
53
55
|
]);
|
|
54
56
|
const l1BlockTimestamps = {};
|
|
55
57
|
for (const l1Batch of chunk(l1BlockNumbers, Number(batchSize))){
|
|
@@ -62,37 +64,37 @@ export async function proverStats(opts) {
|
|
|
62
64
|
l1BlockTimestamps[block.number.toString()] = block.timestamp;
|
|
63
65
|
}
|
|
64
66
|
}
|
|
65
|
-
// Map from
|
|
66
|
-
const
|
|
67
|
-
for (const
|
|
68
|
-
|
|
67
|
+
// Map from checkpoint number to the l1 block in which it was submitted
|
|
68
|
+
const checkpointSubmissions = {};
|
|
69
|
+
for (const checkpointEvent of checkpointEvents){
|
|
70
|
+
checkpointSubmissions[checkpointEvent.args.checkpointNumber.toString()] = checkpointEvent.blockNumber;
|
|
69
71
|
}
|
|
70
72
|
// If we want raw logs, output them
|
|
71
73
|
if (rawLogs) {
|
|
72
|
-
log(`l1_block_number,
|
|
74
|
+
log(`l1_block_number, checkpoint_number, checkpoint_submission_timestamp, proof_timestamp, prover_id, tx_hash`);
|
|
73
75
|
for (const event of events){
|
|
74
|
-
const { l1BlockNumber,
|
|
75
|
-
const uploadedBlockNumber =
|
|
76
|
+
const { l1BlockNumber, checkpointNumber, proverId, txHash } = event;
|
|
77
|
+
const uploadedBlockNumber = checkpointSubmissions[checkpointNumber.toString()];
|
|
76
78
|
if (!uploadedBlockNumber) {
|
|
77
79
|
continue;
|
|
78
80
|
}
|
|
79
81
|
const uploadedTimestamp = l1BlockTimestamps[uploadedBlockNumber.toString()];
|
|
80
82
|
const provenTimestamp = l1BlockTimestamps[l1BlockNumber.toString()];
|
|
81
|
-
log(`${l1BlockNumber}, ${
|
|
83
|
+
log(`${l1BlockNumber}, ${checkpointNumber}, ${uploadedTimestamp}, ${provenTimestamp}, ${proverId}, ${txHash}`);
|
|
82
84
|
}
|
|
83
85
|
return;
|
|
84
86
|
}
|
|
85
87
|
// Or calculate stats per prover
|
|
86
|
-
const stats = mapValues(groupBy(events, 'proverId'), (
|
|
88
|
+
const stats = mapValues(groupBy(events, 'proverId'), (checkpoints, proverId)=>compactArray(checkpoints.map((e)=>{
|
|
87
89
|
const provenTimestamp = l1BlockTimestamps[e.l1BlockNumber.toString()];
|
|
88
|
-
const uploadedBlockNumber =
|
|
90
|
+
const uploadedBlockNumber = checkpointSubmissions[e.checkpointNumber.toString()];
|
|
89
91
|
if (!uploadedBlockNumber) {
|
|
90
|
-
debugLog.verbose(`Skipping ${proverId}'s proof for
|
|
92
|
+
debugLog.verbose(`Skipping ${proverId}'s proof for checkpoint ${e.checkpointNumber} as it was before the start block`);
|
|
91
93
|
return undefined;
|
|
92
94
|
}
|
|
93
95
|
const uploadedTimestamp = l1BlockTimestamps[uploadedBlockNumber.toString()];
|
|
94
96
|
const provingTime = provenTimestamp - uploadedTimestamp;
|
|
95
|
-
debugLog.debug(`prover=${e.proverId}
|
|
97
|
+
debugLog.debug(`prover=${e.proverId} checkpointNumber=${e.checkpointNumber} uploaded=${uploadedTimestamp} proven=${provenTimestamp} time=${provingTime}`);
|
|
96
98
|
return {
|
|
97
99
|
provenTimestamp,
|
|
98
100
|
uploadedTimestamp,
|
|
@@ -104,8 +106,8 @@ export async function proverStats(opts) {
|
|
|
104
106
|
for(const proverId in stats){
|
|
105
107
|
const blocks = stats[proverId];
|
|
106
108
|
const withinTimeout = blocks.filter((b)=>b.provingTime <= provingTimeout);
|
|
107
|
-
const uniqueBlocksWithinTimeout = new Set(withinTimeout.map((e)=>e.
|
|
108
|
-
const uniqueBlocks = new Set(blocks.map((e)=>e.
|
|
109
|
+
const uniqueBlocksWithinTimeout = new Set(withinTimeout.map((e)=>e.checkpointNumber));
|
|
110
|
+
const uniqueBlocks = new Set(blocks.map((e)=>e.checkpointNumber));
|
|
109
111
|
const avgProvingTime = blocks.length === 0 ? 0 : Math.ceil(Number(blocks.reduce((acc, b)=>acc + b.provingTime, 0n)) / blocks.length);
|
|
110
112
|
log(`${proverId}, ${uniqueBlocksWithinTimeout.size}, ${uniqueBlocks.size}, ${avgProvingTime}`);
|
|
111
113
|
}
|
|
@@ -123,7 +125,7 @@ async function getL2ProofVerifiedEvents(startBlock, lastBlockNum, batchSize, deb
|
|
|
123
125
|
}
|
|
124
126
|
return events;
|
|
125
127
|
}
|
|
126
|
-
async function
|
|
128
|
+
async function getCheckpointProposedEvents(startBlock, lastBlockNum, batchSize, debugLog, publicClient, rollup) {
|
|
127
129
|
let blockNum = startBlock;
|
|
128
130
|
const events = [];
|
|
129
131
|
while(blockNum <= lastBlockNum){
|
|
@@ -132,13 +134,13 @@ async function getL2BlockEvents(startBlock, lastBlockNum, batchSize, debugLog, p
|
|
|
132
134
|
address: getAddress(rollup.toString()),
|
|
133
135
|
event: getAbiItem({
|
|
134
136
|
abi: RollupAbi,
|
|
135
|
-
name: '
|
|
137
|
+
name: 'CheckpointProposed'
|
|
136
138
|
}),
|
|
137
139
|
fromBlock: blockNum,
|
|
138
140
|
toBlock: end
|
|
139
141
|
});
|
|
140
142
|
events.push(...newEvents);
|
|
141
|
-
debugLog.verbose(`Got ${newEvents.length} events querying
|
|
143
|
+
debugLog.verbose(`Got ${newEvents.length} events querying checkpoints submitted from block ${blockNum} to ${end}`);
|
|
142
144
|
blockNum += batchSize;
|
|
143
145
|
}
|
|
144
146
|
return events;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { LogFn } from '@aztec/foundation/log';
|
|
2
|
+
import type { RollupCommandArgs } from './update_l1_validators.js';
|
|
3
|
+
export declare function triggerSeedSnapshot({ rpcUrls, chainId, privateKey, mnemonic, rollupAddress, log }: RollupCommandArgs & {
|
|
4
|
+
log: LogFn;
|
|
5
|
+
}): Promise<void>;
|
|
6
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJpZ2dlcl9zZWVkX3NuYXBzaG90LmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvY21kcy9sMS90cmlnZ2VyX3NlZWRfc25hcHNob3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBRUEsT0FBTyxLQUFLLEVBQUUsS0FBSyxFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFLbkQsT0FBTyxLQUFLLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUVuRSx3QkFBc0IsbUJBQW1CLENBQUMsRUFDeEMsT0FBTyxFQUNQLE9BQU8sRUFDUCxVQUFVLEVBQ1YsUUFBUSxFQUNSLGFBQWEsRUFDYixHQUFHLEVBQ0osRUFBRSxpQkFBaUIsR0FBRztJQUFFLEdBQUcsRUFBRSxLQUFLLENBQUE7Q0FBRSxpQkFlcEMifQ==
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trigger_seed_snapshot.d.ts","sourceRoot":"","sources":["../../../src/cmds/l1/trigger_seed_snapshot.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAKnD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAEnE,wBAAsB,mBAAmB,CAAC,EACxC,OAAO,EACP,OAAO,EACP,UAAU,EACV,QAAQ,EACR,aAAa,EACb,GAAG,EACJ,EAAE,iBAAiB,GAAG;IAAE,GAAG,EAAE,KAAK,CAAA;CAAE,iBAepC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { createEthereumChain } from '@aztec/ethereum/chain';
|
|
2
|
+
import { createExtendedL1Client } from '@aztec/ethereum/client';
|
|
3
|
+
import { RollupAbi } from '@aztec/l1-artifacts/RollupAbi';
|
|
4
|
+
import { getContract } from 'viem';
|
|
5
|
+
export async function triggerSeedSnapshot({ rpcUrls, chainId, privateKey, mnemonic, rollupAddress, log }) {
|
|
6
|
+
const chain = createEthereumChain(rpcUrls, chainId);
|
|
7
|
+
const client = createExtendedL1Client(rpcUrls, privateKey ?? mnemonic, chain.chainInfo);
|
|
8
|
+
const rollup = getContract({
|
|
9
|
+
address: rollupAddress.toString(),
|
|
10
|
+
abi: RollupAbi,
|
|
11
|
+
client
|
|
12
|
+
});
|
|
13
|
+
log('Triggering seed snapshot for next epoch');
|
|
14
|
+
const txHash = await rollup.write.checkpointRandao();
|
|
15
|
+
log(`Sent! | Seed snapshot setup for next epoch | tx hash: ${txHash}`);
|
|
16
|
+
const receipt = await client.waitForTransactionReceipt({
|
|
17
|
+
hash: txHash
|
|
18
|
+
});
|
|
19
|
+
log(`Done! | Seed snapshot setup for next epoch | tx hash: ${txHash} | status: ${receipt.status}`);
|
|
20
|
+
}
|
|
@@ -8,6 +8,13 @@ export interface RollupCommandArgs {
|
|
|
8
8
|
rollupAddress: EthAddress;
|
|
9
9
|
withdrawerAddress?: EthAddress;
|
|
10
10
|
}
|
|
11
|
+
export interface StakingAssetHandlerCommandArgs {
|
|
12
|
+
rpcUrls: string[];
|
|
13
|
+
chainId: number;
|
|
14
|
+
privateKey?: string;
|
|
15
|
+
mnemonic?: string;
|
|
16
|
+
stakingAssetHandlerAddress: EthAddress;
|
|
17
|
+
}
|
|
11
18
|
export interface LoggerArgs {
|
|
12
19
|
log: LogFn;
|
|
13
20
|
debugLogger: Logger;
|
|
@@ -16,15 +23,23 @@ export declare function generateL1Account(): {
|
|
|
16
23
|
privateKey: `0x${string}`;
|
|
17
24
|
address: `0x${string}`;
|
|
18
25
|
};
|
|
19
|
-
export declare function addL1Validator({ rpcUrls, chainId, privateKey, mnemonic,
|
|
20
|
-
|
|
26
|
+
export declare function addL1Validator({ rpcUrls, chainId, privateKey, mnemonic, attesterAddress, withdrawerAddress, stakingAssetHandlerAddress, proofParams, blsSecretKey, log, debugLogger }: StakingAssetHandlerCommandArgs & LoggerArgs & {
|
|
27
|
+
blsSecretKey: bigint;
|
|
28
|
+
attesterAddress: EthAddress;
|
|
29
|
+
withdrawerAddress: EthAddress;
|
|
30
|
+
proofParams: Buffer;
|
|
31
|
+
}): Promise<void>;
|
|
32
|
+
export declare function addL1ValidatorViaRollup({ rpcUrls, chainId, privateKey, mnemonic, attesterAddress, withdrawerAddress, blsSecretKey, moveWithLatestRollup, rollupAddress, log, debugLogger }: RollupCommandArgs & LoggerArgs & {
|
|
33
|
+
blsSecretKey: bigint;
|
|
34
|
+
attesterAddress: EthAddress;
|
|
35
|
+
moveWithLatestRollup: boolean;
|
|
21
36
|
}): Promise<void>;
|
|
22
|
-
export declare function removeL1Validator({ rpcUrls, chainId, privateKey, mnemonic, validatorAddress, rollupAddress, log, debugLogger
|
|
37
|
+
export declare function removeL1Validator({ rpcUrls, chainId, privateKey, mnemonic, validatorAddress, rollupAddress, log, debugLogger }: RollupCommandArgs & LoggerArgs & {
|
|
23
38
|
validatorAddress: EthAddress;
|
|
24
39
|
}): Promise<void>;
|
|
25
|
-
export declare function pruneRollup({ rpcUrls, chainId, privateKey, mnemonic, rollupAddress, log, debugLogger
|
|
26
|
-
export declare function fastForwardEpochs({ rpcUrls, chainId, rollupAddress, numEpochs, log, debugLogger
|
|
40
|
+
export declare function pruneRollup({ rpcUrls, chainId, privateKey, mnemonic, rollupAddress, log, debugLogger }: RollupCommandArgs & LoggerArgs): Promise<void>;
|
|
41
|
+
export declare function fastForwardEpochs({ rpcUrls, chainId, rollupAddress, numEpochs, log, debugLogger }: RollupCommandArgs & LoggerArgs & {
|
|
27
42
|
numEpochs: bigint;
|
|
28
43
|
}): Promise<void>;
|
|
29
44
|
export declare function debugRollup({ rpcUrls, chainId, rollupAddress, log }: RollupCommandArgs & LoggerArgs): Promise<void>;
|
|
30
|
-
//# sourceMappingURL=
|
|
45
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXBkYXRlX2wxX3ZhbGlkYXRvcnMuZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9jbWRzL2wxL3VwZGF0ZV9sMV92YWxpZGF0b3JzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQU1BLE9BQU8sS0FBSyxFQUFFLFVBQVUsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBQ2hFLE9BQU8sS0FBSyxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQVEzRCxNQUFNLFdBQVcsaUJBQWlCO0lBQ2hDLE9BQU8sRUFBRSxNQUFNLEVBQUUsQ0FBQztJQUNsQixPQUFPLEVBQUUsTUFBTSxDQUFDO0lBQ2hCLFVBQVUsQ0FBQyxFQUFFLE1BQU0sQ0FBQztJQUNwQixRQUFRLENBQUMsRUFBRSxNQUFNLENBQUM7SUFDbEIsYUFBYSxFQUFFLFVBQVUsQ0FBQztJQUMxQixpQkFBaUIsQ0FBQyxFQUFFLFVBQVUsQ0FBQztDQUNoQztBQUVELE1BQU0sV0FBVyw4QkFBOEI7SUFDN0MsT0FBTyxFQUFFLE1BQU0sRUFBRSxDQUFDO0lBQ2xCLE9BQU8sRUFBRSxNQUFNLENBQUM7SUFDaEIsVUFBVSxDQUFDLEVBQUUsTUFBTSxDQUFDO0lBQ3BCLFFBQVEsQ0FBQyxFQUFFLE1BQU0sQ0FBQztJQUNsQiwwQkFBMEIsRUFBRSxVQUFVLENBQUM7Q0FDeEM7QUFFRCxNQUFNLFdBQVcsVUFBVTtJQUN6QixHQUFHLEVBQUUsS0FBSyxDQUFDO0lBQ1gsV0FBVyxFQUFFLE1BQU0sQ0FBQztDQUNyQjtBQUVELHdCQUFnQixpQkFBaUI7OztFQVFoQztBQUVELHdCQUFzQixjQUFjLENBQUMsRUFDbkMsT0FBTyxFQUNQLE9BQU8sRUFDUCxVQUFVLEVBQ1YsUUFBUSxFQUNSLGVBQWUsRUFDZixpQkFBaUIsRUFDakIsMEJBQTBCLEVBQzFCLFdBQVcsRUFDWCxZQUFZLEVBQ1osR0FBRyxFQUNILFdBQVcsRUFDWixFQUFFLDhCQUE4QixHQUMvQixVQUFVLEdBQUc7SUFDWCxZQUFZLEVBQUUsTUFBTSxDQUFDO0lBQ3JCLGVBQWUsRUFBRSxVQUFVLENBQUM7SUFDNUIsaUJBQWlCLEVBQUUsVUFBVSxDQUFDO0lBQzlCLFdBQVcsRUFBRSxNQUFNLENBQUM7Q0FDckIsaUJBd0ZGO0FBRUQsd0JBQXNCLHVCQUF1QixDQUFDLEVBQzVDLE9BQU8sRUFDUCxPQUFPLEVBQ1AsVUFBVSxFQUNWLFFBQVEsRUFDUixlQUFlLEVBQ2YsaUJBQWlCLEVBQ2pCLFlBQVksRUFDWixvQkFBb0IsRUFDcEIsYUFBYSxFQUNiLEdBQUcsRUFDSCxXQUFXLEVBQ1osRUFBRSxpQkFBaUIsR0FDbEIsVUFBVSxHQUFHO0lBQ1gsWUFBWSxFQUFFLE1BQU0sQ0FBQztJQUNyQixlQUFlLEVBQUUsVUFBVSxDQUFDO0lBQzVCLG9CQUFvQixFQUFFLE9BQU8sQ0FBQztDQUMvQixpQkF1REY7QUFFRCx3QkFBc0IsaUJBQWlCLENBQUMsRUFDdEMsT0FBTyxFQUNQLE9BQU8sRUFDUCxVQUFVLEVBQ1YsUUFBUSxFQUNSLGdCQUFnQixFQUNoQixhQUFhLEVBQ2IsR0FBRyxFQUNILFdBQVcsRUFDWixFQUFFLGlCQUFpQixHQUFHLFVBQVUsR0FBRztJQUFFLGdCQUFnQixFQUFFLFVBQVUsQ0FBQTtDQUFFLGlCQWlCbkU7QUFFRCx3QkFBc0IsV0FBVyxDQUFDLEVBQ2hDLE9BQU8sRUFDUCxPQUFPLEVBQ1AsVUFBVSxFQUNWLFFBQVEsRUFDUixhQUFhLEVBQ2IsR0FBRyxFQUNILFdBQVcsRUFDWixFQUFFLGlCQUFpQixHQUFHLFVBQVUsaUJBZ0JoQztBQUVELHdCQUFzQixpQkFBaUIsQ0FBQyxFQUN0QyxPQUFPLEVBQ1AsT0FBTyxFQUNQLGFBQWEsRUFDYixTQUFTLEVBQ1QsR0FBRyxFQUNILFdBQVcsRUFDWixFQUFFLGlCQUFpQixHQUFHLFVBQVUsR0FBRztJQUFFLFNBQVMsRUFBRSxNQUFNLENBQUE7Q0FBRSxpQkF5QnhEO0FBRUQsd0JBQXNCLFdBQVcsQ0FBQyxFQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUUsYUFBYSxFQUFFLEdBQUcsRUFBRSxFQUFFLGlCQUFpQixHQUFHLFVBQVUsaUJBd0J6RyJ9
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"update_l1_validators.d.ts","sourceRoot":"","sources":["../../../src/cmds/l1/update_l1_validators.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"update_l1_validators.d.ts","sourceRoot":"","sources":["../../../src/cmds/l1/update_l1_validators.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAChE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAQ3D,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,UAAU,CAAC;IAC1B,iBAAiB,CAAC,EAAE,UAAU,CAAC;CAChC;AAED,MAAM,WAAW,8BAA8B;IAC7C,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,0BAA0B,EAAE,UAAU,CAAC;CACxC;AAED,MAAM,WAAW,UAAU;IACzB,GAAG,EAAE,KAAK,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,wBAAgB,iBAAiB;;;EAQhC;AAED,wBAAsB,cAAc,CAAC,EACnC,OAAO,EACP,OAAO,EACP,UAAU,EACV,QAAQ,EACR,eAAe,EACf,iBAAiB,EACjB,0BAA0B,EAC1B,WAAW,EACX,YAAY,EACZ,GAAG,EACH,WAAW,EACZ,EAAE,8BAA8B,GAC/B,UAAU,GAAG;IACX,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,EAAE,UAAU,CAAC;IAC5B,iBAAiB,EAAE,UAAU,CAAC;IAC9B,WAAW,EAAE,MAAM,CAAC;CACrB,iBAwFF;AAED,wBAAsB,uBAAuB,CAAC,EAC5C,OAAO,EACP,OAAO,EACP,UAAU,EACV,QAAQ,EACR,eAAe,EACf,iBAAiB,EACjB,YAAY,EACZ,oBAAoB,EACpB,aAAa,EACb,GAAG,EACH,WAAW,EACZ,EAAE,iBAAiB,GAClB,UAAU,GAAG;IACX,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,EAAE,UAAU,CAAC;IAC5B,oBAAoB,EAAE,OAAO,CAAC;CAC/B,iBAuDF;AAED,wBAAsB,iBAAiB,CAAC,EACtC,OAAO,EACP,OAAO,EACP,UAAU,EACV,QAAQ,EACR,gBAAgB,EAChB,aAAa,EACb,GAAG,EACH,WAAW,EACZ,EAAE,iBAAiB,GAAG,UAAU,GAAG;IAAE,gBAAgB,EAAE,UAAU,CAAA;CAAE,iBAiBnE;AAED,wBAAsB,WAAW,CAAC,EAChC,OAAO,EACP,OAAO,EACP,UAAU,EACV,QAAQ,EACR,aAAa,EACb,GAAG,EACH,WAAW,EACZ,EAAE,iBAAiB,GAAG,UAAU,iBAgBhC;AAED,wBAAsB,iBAAiB,CAAC,EACtC,OAAO,EACP,OAAO,EACP,aAAa,EACb,SAAS,EACT,GAAG,EACH,WAAW,EACZ,EAAE,iBAAiB,GAAG,UAAU,GAAG;IAAE,SAAS,EAAE,MAAM,CAAA;CAAE,iBAyBxD;AAED,wBAAsB,WAAW,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,GAAG,EAAE,EAAE,iBAAiB,GAAG,UAAU,iBAwBzG"}
|
|
@@ -1,6 +1,13 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { createEthereumChain, isAnvilTestChain } from '@aztec/ethereum/chain';
|
|
2
|
+
import { createExtendedL1Client, getPublicClient } from '@aztec/ethereum/client';
|
|
3
|
+
import { getL1ContractsConfigEnvVars } from '@aztec/ethereum/config';
|
|
4
|
+
import { GSEContract, RollupContract } from '@aztec/ethereum/contracts';
|
|
5
|
+
import { createL1TxUtilsFromViemWallet } from '@aztec/ethereum/l1-tx-utils';
|
|
6
|
+
import { EthCheatCodes } from '@aztec/ethereum/test';
|
|
7
|
+
import { DateProvider } from '@aztec/foundation/timer';
|
|
8
|
+
import { RollupAbi, StakingAssetHandlerAbi, TestERC20Abi } from '@aztec/l1-artifacts';
|
|
9
|
+
import { ZkPassportProofParams } from '@aztec/stdlib/zkpassport';
|
|
10
|
+
import { encodeFunctionData, formatEther, getContract, maxUint256 } from 'viem';
|
|
4
11
|
import { generatePrivateKey, mnemonicToAccount, privateKeyToAccount } from 'viem/accounts';
|
|
5
12
|
export function generateL1Account() {
|
|
6
13
|
const privateKey = generatePrivateKey();
|
|
@@ -11,106 +18,207 @@ export function generateL1Account() {
|
|
|
11
18
|
address: account.address
|
|
12
19
|
};
|
|
13
20
|
}
|
|
14
|
-
export async function addL1Validator({ rpcUrls, chainId, privateKey, mnemonic,
|
|
15
|
-
const config = getL1ContractsConfigEnvVars();
|
|
21
|
+
export async function addL1Validator({ rpcUrls, chainId, privateKey, mnemonic, attesterAddress, withdrawerAddress, stakingAssetHandlerAddress, proofParams, blsSecretKey, log, debugLogger }) {
|
|
16
22
|
const dualLog = makeDualLog(log, debugLogger);
|
|
17
|
-
const
|
|
18
|
-
const
|
|
23
|
+
const account = getAccount(privateKey, mnemonic);
|
|
24
|
+
const chain = createEthereumChain(rpcUrls, chainId);
|
|
25
|
+
const l1Client = createExtendedL1Client(rpcUrls, account, chain.chainInfo);
|
|
26
|
+
const stakingAssetHandler = getContract({
|
|
27
|
+
address: stakingAssetHandlerAddress.toString(),
|
|
28
|
+
abi: StakingAssetHandlerAbi,
|
|
29
|
+
client: l1Client
|
|
30
|
+
});
|
|
31
|
+
const rollupAddress = await stakingAssetHandler.read.getRollup();
|
|
32
|
+
dualLog(`Adding validator ${attesterAddress} to rollup ${rollupAddress.toString()}`);
|
|
19
33
|
const rollup = getContract({
|
|
20
|
-
address: rollupAddress
|
|
34
|
+
address: rollupAddress,
|
|
21
35
|
abi: RollupAbi,
|
|
22
|
-
client:
|
|
23
|
-
});
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
36
|
+
client: l1Client
|
|
37
|
+
});
|
|
38
|
+
const gseAddress = await rollup.read.getGSE();
|
|
39
|
+
const gse = new GSEContract(l1Client, gseAddress);
|
|
40
|
+
const registrationTuple = await gse.makeRegistrationTuple(blsSecretKey);
|
|
41
|
+
const l1TxUtils = createL1TxUtilsFromViemWallet(l1Client, {
|
|
42
|
+
logger: debugLogger
|
|
43
|
+
});
|
|
44
|
+
const proofParamsObj = ZkPassportProofParams.fromBuffer(proofParams);
|
|
45
|
+
// Step 1: Claim STK tokens from the faucet
|
|
46
|
+
dualLog(`Claiming STK tokens from faucet`);
|
|
47
|
+
const { receipt: claimReceipt } = await l1TxUtils.sendAndMonitorTransaction({
|
|
48
|
+
to: stakingAssetHandlerAddress.toString(),
|
|
49
|
+
data: encodeFunctionData({
|
|
50
|
+
abi: StakingAssetHandlerAbi,
|
|
51
|
+
functionName: 'claim',
|
|
52
|
+
args: [
|
|
53
|
+
proofParamsObj.toViem()
|
|
54
|
+
]
|
|
55
|
+
}),
|
|
56
|
+
abi: StakingAssetHandlerAbi
|
|
57
|
+
});
|
|
58
|
+
dualLog(`Claim transaction hash: ${claimReceipt.transactionHash}`);
|
|
59
|
+
await l1Client.waitForTransactionReceipt({
|
|
60
|
+
hash: claimReceipt.transactionHash
|
|
61
|
+
});
|
|
62
|
+
// Step 2: Approve the rollup to spend STK tokens
|
|
63
|
+
const stakingAssetAddress = await stakingAssetHandler.read.STAKING_ASSET();
|
|
64
|
+
dualLog(`Approving rollup to spend STK tokens`);
|
|
65
|
+
const { receipt: approveReceipt } = await l1TxUtils.sendAndMonitorTransaction({
|
|
66
|
+
to: stakingAssetAddress,
|
|
67
|
+
data: encodeFunctionData({
|
|
68
|
+
abi: TestERC20Abi,
|
|
69
|
+
functionName: 'approve',
|
|
70
|
+
args: [
|
|
71
|
+
rollupAddress,
|
|
72
|
+
maxUint256
|
|
73
|
+
]
|
|
74
|
+
}),
|
|
75
|
+
abi: TestERC20Abi
|
|
76
|
+
});
|
|
77
|
+
await l1Client.waitForTransactionReceipt({
|
|
78
|
+
hash: approveReceipt.transactionHash
|
|
79
|
+
});
|
|
80
|
+
// Step 3: Deposit into the rollup to register as a validator
|
|
81
|
+
dualLog(`Depositing into rollup to register validator`);
|
|
82
|
+
const { receipt } = await l1TxUtils.sendAndMonitorTransaction({
|
|
83
|
+
to: rollupAddress,
|
|
84
|
+
data: encodeFunctionData({
|
|
85
|
+
abi: RollupAbi,
|
|
86
|
+
functionName: 'deposit',
|
|
87
|
+
args: [
|
|
88
|
+
attesterAddress.toString(),
|
|
89
|
+
withdrawerAddress.toString(),
|
|
90
|
+
registrationTuple.publicKeyInG1,
|
|
91
|
+
registrationTuple.publicKeyInG2,
|
|
92
|
+
registrationTuple.proofOfPossession,
|
|
93
|
+
false
|
|
94
|
+
]
|
|
95
|
+
}),
|
|
96
|
+
abi: RollupAbi
|
|
97
|
+
});
|
|
98
|
+
dualLog(`Deposit transaction hash: ${receipt.transactionHash}`);
|
|
99
|
+
await l1Client.waitForTransactionReceipt({
|
|
100
|
+
hash: receipt.transactionHash
|
|
54
101
|
});
|
|
55
102
|
if (isAnvilTestChain(chainId)) {
|
|
56
103
|
dualLog(`Funding validator on L1`);
|
|
57
|
-
const cheatCodes = new EthCheatCodes(rpcUrls, debugLogger);
|
|
58
|
-
await cheatCodes.setBalance(
|
|
104
|
+
const cheatCodes = new EthCheatCodes(rpcUrls, new DateProvider(), debugLogger);
|
|
105
|
+
await cheatCodes.setBalance(attesterAddress, 10n ** 20n);
|
|
59
106
|
} else {
|
|
60
|
-
const balance = await
|
|
61
|
-
address:
|
|
107
|
+
const balance = await l1Client.getBalance({
|
|
108
|
+
address: attesterAddress.toString()
|
|
62
109
|
});
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
dualLog(`WARNING: Validator has no balance. Remember to fund it!`);
|
|
110
|
+
dualLog(`Validator balance: ${formatEther(balance)} ETH`);
|
|
111
|
+
if (balance === 0n) {
|
|
112
|
+
dualLog(`WARNING: Proposer has no balance. Remember to fund it!`);
|
|
67
113
|
}
|
|
68
114
|
}
|
|
69
115
|
}
|
|
70
|
-
export async function
|
|
116
|
+
export async function addL1ValidatorViaRollup({ rpcUrls, chainId, privateKey, mnemonic, attesterAddress, withdrawerAddress, blsSecretKey, moveWithLatestRollup, rollupAddress, log, debugLogger }) {
|
|
71
117
|
const dualLog = makeDualLog(log, debugLogger);
|
|
72
|
-
const
|
|
73
|
-
const
|
|
118
|
+
const account = getAccount(privateKey, mnemonic);
|
|
119
|
+
const chain = createEthereumChain(rpcUrls, chainId);
|
|
120
|
+
const l1Client = createExtendedL1Client(rpcUrls, account, chain.chainInfo);
|
|
121
|
+
dualLog(`Adding validator ${attesterAddress} to rollup ${rollupAddress.toString()} via direct deposit`);
|
|
122
|
+
if (!withdrawerAddress) {
|
|
123
|
+
throw new Error(`Withdrawer address required`);
|
|
124
|
+
}
|
|
74
125
|
const rollup = getContract({
|
|
75
126
|
address: rollupAddress.toString(),
|
|
76
127
|
abi: RollupAbi,
|
|
77
|
-
client:
|
|
128
|
+
client: l1Client
|
|
129
|
+
});
|
|
130
|
+
const gseAddress = await rollup.read.getGSE();
|
|
131
|
+
const gse = new GSEContract(l1Client, gseAddress);
|
|
132
|
+
const registrationTuple = await gse.makeRegistrationTuple(blsSecretKey);
|
|
133
|
+
const l1TxUtils = createL1TxUtilsFromViemWallet(l1Client, {
|
|
134
|
+
logger: debugLogger
|
|
135
|
+
});
|
|
136
|
+
const { receipt } = await l1TxUtils.sendAndMonitorTransaction({
|
|
137
|
+
to: rollupAddress.toString(),
|
|
138
|
+
data: encodeFunctionData({
|
|
139
|
+
abi: RollupAbi,
|
|
140
|
+
functionName: 'deposit',
|
|
141
|
+
args: [
|
|
142
|
+
attesterAddress.toString(),
|
|
143
|
+
withdrawerAddress.toString(),
|
|
144
|
+
registrationTuple.publicKeyInG1,
|
|
145
|
+
registrationTuple.publicKeyInG2,
|
|
146
|
+
registrationTuple.proofOfPossession,
|
|
147
|
+
moveWithLatestRollup
|
|
148
|
+
]
|
|
149
|
+
}),
|
|
150
|
+
abi: StakingAssetHandlerAbi
|
|
151
|
+
});
|
|
152
|
+
dualLog(`Transaction hash: ${receipt.transactionHash}`);
|
|
153
|
+
await l1Client.waitForTransactionReceipt({
|
|
154
|
+
hash: receipt.transactionHash
|
|
155
|
+
});
|
|
156
|
+
if (isAnvilTestChain(chainId)) {
|
|
157
|
+
dualLog(`Funding validator on L1`);
|
|
158
|
+
const cheatCodes = new EthCheatCodes(rpcUrls, new DateProvider(), debugLogger);
|
|
159
|
+
await cheatCodes.setBalance(attesterAddress, 10n ** 20n);
|
|
160
|
+
} else {
|
|
161
|
+
const balance = await l1Client.getBalance({
|
|
162
|
+
address: attesterAddress.toString()
|
|
163
|
+
});
|
|
164
|
+
dualLog(`Validator balance: ${formatEther(balance)} ETH`);
|
|
165
|
+
if (balance === 0n) {
|
|
166
|
+
dualLog(`WARNING: Proposer has no balance. Remember to fund it!`);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
export async function removeL1Validator({ rpcUrls, chainId, privateKey, mnemonic, validatorAddress, rollupAddress, log, debugLogger }) {
|
|
171
|
+
const dualLog = makeDualLog(log, debugLogger);
|
|
172
|
+
const account = getAccount(privateKey, mnemonic);
|
|
173
|
+
const chain = createEthereumChain(rpcUrls, chainId);
|
|
174
|
+
const l1Client = createExtendedL1Client(rpcUrls, account, chain.chainInfo);
|
|
175
|
+
const l1TxUtils = createL1TxUtilsFromViemWallet(l1Client, {
|
|
176
|
+
logger: debugLogger
|
|
78
177
|
});
|
|
79
178
|
dualLog(`Removing validator ${validatorAddress.toString()} from rollup ${rollupAddress.toString()}`);
|
|
80
|
-
const
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
179
|
+
const { receipt } = await l1TxUtils.sendAndMonitorTransaction({
|
|
180
|
+
to: rollupAddress.toString(),
|
|
181
|
+
data: encodeFunctionData({
|
|
182
|
+
abi: RollupAbi,
|
|
183
|
+
functionName: 'initiateWithdraw',
|
|
184
|
+
args: [
|
|
185
|
+
validatorAddress.toString(),
|
|
186
|
+
validatorAddress.toString()
|
|
187
|
+
]
|
|
188
|
+
})
|
|
87
189
|
});
|
|
190
|
+
dualLog(`Transaction hash: ${receipt.transactionHash}`);
|
|
88
191
|
}
|
|
89
192
|
export async function pruneRollup({ rpcUrls, chainId, privateKey, mnemonic, rollupAddress, log, debugLogger }) {
|
|
90
193
|
const dualLog = makeDualLog(log, debugLogger);
|
|
91
|
-
const
|
|
92
|
-
const
|
|
93
|
-
const
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
client: walletClient
|
|
194
|
+
const account = getAccount(privateKey, mnemonic);
|
|
195
|
+
const chain = createEthereumChain(rpcUrls, chainId);
|
|
196
|
+
const l1Client = createExtendedL1Client(rpcUrls, account, chain.chainInfo);
|
|
197
|
+
const l1TxUtils = createL1TxUtilsFromViemWallet(l1Client, {
|
|
198
|
+
logger: debugLogger
|
|
97
199
|
});
|
|
98
200
|
dualLog(`Trying prune`);
|
|
99
|
-
const
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
201
|
+
const { receipt } = await l1TxUtils.sendAndMonitorTransaction({
|
|
202
|
+
to: rollupAddress.toString(),
|
|
203
|
+
data: encodeFunctionData({
|
|
204
|
+
abi: RollupAbi,
|
|
205
|
+
functionName: 'prune'
|
|
206
|
+
})
|
|
103
207
|
});
|
|
208
|
+
dualLog(`Transaction hash: ${receipt.transactionHash}`);
|
|
104
209
|
}
|
|
105
210
|
export async function fastForwardEpochs({ rpcUrls, chainId, rollupAddress, numEpochs, log, debugLogger }) {
|
|
106
211
|
const dualLog = makeDualLog(log, debugLogger);
|
|
107
|
-
const publicClient = getPublicClient(
|
|
212
|
+
const publicClient = getPublicClient({
|
|
213
|
+
l1RpcUrls: rpcUrls,
|
|
214
|
+
l1ChainId: chainId
|
|
215
|
+
});
|
|
108
216
|
const rollup = getContract({
|
|
109
217
|
address: rollupAddress.toString(),
|
|
110
218
|
abi: RollupAbi,
|
|
111
219
|
client: publicClient
|
|
112
220
|
});
|
|
113
|
-
const cheatCodes = new EthCheatCodes(rpcUrls, debugLogger);
|
|
221
|
+
const cheatCodes = new EthCheatCodes(rpcUrls, new DateProvider(), debugLogger);
|
|
114
222
|
const currentSlot = await rollup.read.getCurrentSlot();
|
|
115
223
|
const l2SlotsInEpoch = await rollup.read.getEpochDuration();
|
|
116
224
|
const timestamp = await rollup.read.getTimestampForSlot([
|
|
@@ -118,7 +226,9 @@ export async function fastForwardEpochs({ rpcUrls, chainId, rollupAddress, numEp
|
|
|
118
226
|
]);
|
|
119
227
|
dualLog(`Fast forwarding ${numEpochs} epochs to ${timestamp}`);
|
|
120
228
|
try {
|
|
121
|
-
await cheatCodes.warp(Number(timestamp)
|
|
229
|
+
await cheatCodes.warp(Number(timestamp), {
|
|
230
|
+
resetBlockInterval: true
|
|
231
|
+
});
|
|
122
232
|
dualLog(`Fast forwarded ${numEpochs} epochs to ${timestamp}`);
|
|
123
233
|
} catch (error) {
|
|
124
234
|
if (error instanceof Error && error.message.includes("is lower than or equal to previous block's timestamp")) {
|
|
@@ -131,32 +241,29 @@ export async function fastForwardEpochs({ rpcUrls, chainId, rollupAddress, numEp
|
|
|
131
241
|
}
|
|
132
242
|
export async function debugRollup({ rpcUrls, chainId, rollupAddress, log }) {
|
|
133
243
|
const config = getL1ContractsConfigEnvVars();
|
|
134
|
-
const publicClient = getPublicClient(
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
abi: RollupAbi,
|
|
138
|
-
client: publicClient
|
|
244
|
+
const publicClient = getPublicClient({
|
|
245
|
+
l1RpcUrls: rpcUrls,
|
|
246
|
+
l1ChainId: chainId
|
|
139
247
|
});
|
|
140
|
-
const
|
|
248
|
+
const rollup = new RollupContract(publicClient, rollupAddress);
|
|
249
|
+
const pendingNum = await rollup.getCheckpointNumber();
|
|
141
250
|
log(`Pending block num: ${pendingNum}`);
|
|
142
|
-
const provenNum = await rollup.
|
|
251
|
+
const provenNum = await rollup.getProvenCheckpointNumber();
|
|
143
252
|
log(`Proven block num: ${provenNum}`);
|
|
144
|
-
const validators = await rollup.
|
|
253
|
+
const validators = await rollup.getAttesters();
|
|
145
254
|
log(`Validators: ${validators.map((v)=>v.toString()).join(', ')}`);
|
|
146
|
-
const committee = await rollup.
|
|
147
|
-
log(`Committee: ${committee
|
|
148
|
-
const archive = await rollup.
|
|
255
|
+
const committee = await rollup.getCurrentEpochCommittee();
|
|
256
|
+
log(`Committee: ${committee?.map((v)=>v.toString()).join(', ')}`);
|
|
257
|
+
const archive = await rollup.archive();
|
|
149
258
|
log(`Archive: ${archive}`);
|
|
150
|
-
const epochNum = await rollup.
|
|
259
|
+
const epochNum = await rollup.getCurrentEpochNumber();
|
|
151
260
|
log(`Current epoch: ${epochNum}`);
|
|
152
|
-
const slot = await rollup.
|
|
261
|
+
const slot = await rollup.getSlotNumber();
|
|
153
262
|
log(`Current slot: ${slot}`);
|
|
154
|
-
const proposerDuringPrevL1Block = await rollup.
|
|
263
|
+
const proposerDuringPrevL1Block = await rollup.getCurrentProposer();
|
|
155
264
|
log(`Proposer during previous L1 block: ${proposerDuringPrevL1Block}`);
|
|
156
265
|
const nextBlockTS = BigInt((await publicClient.getBlock()).timestamp + BigInt(config.ethereumSlotDuration));
|
|
157
|
-
const proposer = await rollup.
|
|
158
|
-
nextBlockTS
|
|
159
|
-
]);
|
|
266
|
+
const proposer = await rollup.getProposerAt(nextBlockTS);
|
|
160
267
|
log(`Proposer NOW: ${proposer.toString()}`);
|
|
161
268
|
}
|
|
162
269
|
function makeDualLog(log, debugLogger) {
|
|
@@ -165,22 +272,10 @@ function makeDualLog(log, debugLogger) {
|
|
|
165
272
|
debugLogger.info(msg);
|
|
166
273
|
};
|
|
167
274
|
}
|
|
168
|
-
function
|
|
169
|
-
const chain = createEthereumChain(rpcUrls, chainId);
|
|
170
|
-
return createPublicClient({
|
|
171
|
-
chain: chain.chainInfo,
|
|
172
|
-
transport: fallback(rpcUrls.map((url)=>http(url)))
|
|
173
|
-
});
|
|
174
|
-
}
|
|
175
|
-
function getWalletClient(rpcUrls, chainId, privateKey, mnemonic) {
|
|
275
|
+
function getAccount(privateKey, mnemonic) {
|
|
176
276
|
if (!privateKey && !mnemonic) {
|
|
177
277
|
throw new Error('Either privateKey or mnemonic must be provided to create a wallet client');
|
|
178
278
|
}
|
|
179
|
-
const chain = createEthereumChain(rpcUrls, chainId);
|
|
180
279
|
const account = !privateKey ? mnemonicToAccount(mnemonic) : privateKeyToAccount(`${privateKey.startsWith('0x') ? '' : '0x'}${privateKey}`);
|
|
181
|
-
return
|
|
182
|
-
account,
|
|
183
|
-
chain: chain.chainInfo,
|
|
184
|
-
transport: fallback(rpcUrls.map((url)=>http(url)))
|
|
185
|
-
});
|
|
280
|
+
return account;
|
|
186
281
|
}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import type { LogFn } from '@aztec/foundation/log';
|
|
2
2
|
export declare function computeSelector(functionSignature: string, log: LogFn): Promise<void>;
|
|
3
|
-
//# sourceMappingURL=
|
|
3
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tcHV0ZV9zZWxlY3Rvci5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2NtZHMvbWlzYy9jb21wdXRlX3NlbGVjdG9yLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxFQUFFLEtBQUssRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBR25ELHdCQUFzQixlQUFlLENBQUMsaUJBQWlCLEVBQUUsTUFBTSxFQUFFLEdBQUcsRUFBRSxLQUFLLGlCQUcxRSJ9
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import type { LogFn } from '@aztec/foundation/log';
|
|
2
2
|
export declare function exampleContracts(log: LogFn): Promise<void>;
|
|
3
|
-
//# sourceMappingURL=
|
|
3
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXhhbXBsZV9jb250cmFjdHMuZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9jbWRzL21pc2MvZXhhbXBsZV9jb250cmFjdHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLEVBQUUsS0FBSyxFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFJbkQsd0JBQXNCLGdCQUFnQixDQUFDLEdBQUcsRUFBRSxLQUFLLGlCQU9oRCJ9
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import type { LogFn } from '@aztec/foundation/log';
|
|
2
|
-
export declare function generateEncodedBootnodeENR(privateKey: string,
|
|
3
|
-
//# sourceMappingURL=
|
|
2
|
+
export declare function generateEncodedBootnodeENR(privateKey: string, p2pIp: string, p2pPort: number, l1ChainId: number, log: LogFn): Promise<void>;
|
|
3
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2VuZXJhdGVfYm9vdG5vZGVfZW5yLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvY21kcy9taXNjL2dlbmVyYXRlX2Jvb3Rub2RlX2Vuci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssRUFBRSxLQUFLLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUduRCx3QkFBc0IsMEJBQTBCLENBQzlDLFVBQVUsRUFBRSxNQUFNLEVBQ2xCLEtBQUssRUFBRSxNQUFNLEVBQ2IsT0FBTyxFQUFFLE1BQU0sRUFDZixTQUFTLEVBQUUsTUFBTSxFQUNqQixHQUFHLEVBQUUsS0FBSyxpQkFJWCJ9
|