@aztec/cli 0.0.0-test.1 → 0.0.1-commit.017a351
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 +33 -0
- package/dest/cmds/aztec_node/get_logs.d.ts.map +1 -0
- package/dest/cmds/aztec_node/get_logs.js +61 -0
- 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 +13 -16
- 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 +38 -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 +15 -23
- 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 +80 -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 +16 -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 -104
- 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 +27 -0
- package/dest/config/cached_fetch.d.ts.map +1 -0
- package/dest/config/cached_fetch.js +132 -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 +47 -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 +221 -0
- package/dest/config/generated/networks.d.ts.map +1 -0
- package/dest/config/generated/networks.js +222 -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 +119 -0
- package/dest/utils/aztec.d.ts +14 -26
- package/dest/utils/aztec.d.ts.map +1 -1
- package/dest/utils/aztec.js +54 -71
- package/dest/utils/commands.d.ts +34 -17
- package/dest/utils/commands.d.ts.map +1 -1
- package/dest/utils/commands.js +61 -24
- 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 +30 -117
- 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/aztec_node/get_logs.ts +100 -0
- package/src/cmds/{pxe → aztec_node}/get_node_info.ts +15 -25
- package/src/cmds/aztec_node/index.ts +92 -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 +18 -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 +106 -0
- package/src/cmds/l1/deploy_new_rollup.ts +22 -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 +95 -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 -98
- 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 +155 -0
- package/src/config/chain_l2_config.ts +59 -0
- package/src/config/enrich_env.ts +15 -0
- package/src/config/generated/networks.ts +226 -0
- package/src/config/get_l1_config.ts +31 -0
- package/src/config/index.ts +4 -0
- package/src/config/network_config.ts +151 -0
- package/src/utils/aztec.ts +77 -129
- package/src/utils/commands.ts +78 -28
- 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 +33 -130
- 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_logs.js +0 -51
- 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_logs.ts +0 -66
- 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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXBkYXRlX2wxX3ZhbGlkYXRvcnMuZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9jbWRzL2wxL3VwZGF0ZV9sMV92YWxpZGF0b3JzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQU1BLE9BQU8sS0FBSyxFQUFFLFVBQVUsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBQ2hFLE9BQU8sS0FBSyxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQVEzRCxNQUFNLFdBQVcsaUJBQWlCO0lBQ2hDLE9BQU8sRUFBRSxNQUFNLEVBQUUsQ0FBQztJQUNsQixPQUFPLEVBQUUsTUFBTSxDQUFDO0lBQ2hCLFVBQVUsQ0FBQyxFQUFFLE1BQU0sQ0FBQztJQUNwQixRQUFRLENBQUMsRUFBRSxNQUFNLENBQUM7SUFDbEIsYUFBYSxFQUFFLFVBQVUsQ0FBQztJQUMxQixpQkFBaUIsQ0FBQyxFQUFFLFVBQVUsQ0FBQztDQUNoQztBQUVELE1BQU0sV0FBVyw4QkFBOEI7SUFDN0MsT0FBTyxFQUFFLE1BQU0sRUFBRSxDQUFDO0lBQ2xCLE9BQU8sRUFBRSxNQUFNLENBQUM7SUFDaEIsVUFBVSxDQUFDLEVBQUUsTUFBTSxDQUFDO0lBQ3BCLFFBQVEsQ0FBQyxFQUFFLE1BQU0sQ0FBQztJQUNsQiwwQkFBMEIsRUFBRSxVQUFVLENBQUM7Q0FDeEM7QUFFRCxNQUFNLFdBQVcsVUFBVTtJQUN6QixHQUFHLEVBQUUsS0FBSyxDQUFDO0lBQ1gsV0FBVyxFQUFFLE1BQU0sQ0FBQztDQUNyQjtBQUVELHdCQUFnQixpQkFBaUI7OztFQU9oQztBQUVELHdCQUFzQixjQUFjLENBQUMsRUFDbkMsT0FBTyxFQUNQLE9BQU8sRUFDUCxVQUFVLEVBQ1YsUUFBUSxFQUNSLGVBQWUsRUFDZixpQkFBaUIsRUFDakIsMEJBQTBCLEVBQzFCLFdBQVcsRUFDWCxZQUFZLEVBQ1osR0FBRyxFQUNILFdBQVcsRUFDWixFQUFFLDhCQUE4QixHQUMvQixVQUFVLEdBQUc7SUFDWCxZQUFZLEVBQUUsTUFBTSxDQUFDO0lBQ3JCLGVBQWUsRUFBRSxVQUFVLENBQUM7SUFDNUIsaUJBQWlCLEVBQUUsVUFBVSxDQUFDO0lBQzlCLFdBQVcsRUFBRSxNQUFNLENBQUM7Q0FDckIsaUJBd0ZGO0FBRUQsd0JBQXNCLHVCQUF1QixDQUFDLEVBQzVDLE9BQU8sRUFDUCxPQUFPLEVBQ1AsVUFBVSxFQUNWLFFBQVEsRUFDUixlQUFlLEVBQ2YsaUJBQWlCLEVBQ2pCLFlBQVksRUFDWixvQkFBb0IsRUFDcEIsYUFBYSxFQUNiLEdBQUcsRUFDSCxXQUFXLEVBQ1osRUFBRSxpQkFBaUIsR0FDbEIsVUFBVSxHQUFHO0lBQ1gsWUFBWSxFQUFFLE1BQU0sQ0FBQztJQUNyQixlQUFlLEVBQUUsVUFBVSxDQUFDO0lBQzVCLG9CQUFvQixFQUFFLE9BQU8sQ0FBQztDQUMvQixpQkF1REY7QUFFRCx3QkFBc0IsaUJBQWlCLENBQUMsRUFDdEMsT0FBTyxFQUNQLE9BQU8sRUFDUCxVQUFVLEVBQ1YsUUFBUSxFQUNSLGdCQUFnQixFQUNoQixhQUFhLEVBQ2IsR0FBRyxFQUNILFdBQVcsRUFDWixFQUFFLGlCQUFpQixHQUFHLFVBQVUsR0FBRztJQUFFLGdCQUFnQixFQUFFLFVBQVUsQ0FBQTtDQUFFLGlCQWlCbkU7QUFFRCx3QkFBc0IsV0FBVyxDQUFDLEVBQ2hDLE9BQU8sRUFDUCxPQUFPLEVBQ1AsVUFBVSxFQUNWLFFBQVEsRUFDUixhQUFhLEVBQ2IsR0FBRyxFQUNILFdBQVcsRUFDWixFQUFFLGlCQUFpQixHQUFHLFVBQVUsaUJBZ0JoQztBQUVELHdCQUFzQixpQkFBaUIsQ0FBQyxFQUN0QyxPQUFPLEVBQ1AsT0FBTyxFQUNQLGFBQWEsRUFDYixTQUFTLEVBQ1QsR0FBRyxFQUNILFdBQVcsRUFDWixFQUFFLGlCQUFpQixHQUFHLFVBQVUsR0FBRztJQUFFLFNBQVMsRUFBRSxNQUFNLENBQUE7Q0FBRSxpQkF5QnhEO0FBRUQsd0JBQXNCLFdBQVcsQ0FBQyxFQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUUsYUFBYSxFQUFFLEdBQUcsRUFBRSxFQUFFLGlCQUFpQixHQUFHLFVBQVUsaUJBd0J6RyJ9
|
|
@@ -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;;;EAOhC;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,116 +1,223 @@
|
|
|
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 { createL1TxUtils } 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();
|
|
7
14
|
const account = privateKeyToAccount(privateKey);
|
|
8
|
-
account.address;
|
|
9
15
|
return {
|
|
10
16
|
privateKey,
|
|
11
17
|
address: account.address
|
|
12
18
|
};
|
|
13
19
|
}
|
|
14
|
-
export async function addL1Validator({ rpcUrls, chainId, privateKey, mnemonic,
|
|
15
|
-
const config = getL1ContractsConfigEnvVars();
|
|
20
|
+
export async function addL1Validator({ rpcUrls, chainId, privateKey, mnemonic, attesterAddress, withdrawerAddress, stakingAssetHandlerAddress, proofParams, blsSecretKey, log, debugLogger }) {
|
|
16
21
|
const dualLog = makeDualLog(log, debugLogger);
|
|
17
|
-
const
|
|
18
|
-
const
|
|
22
|
+
const account = getAccount(privateKey, mnemonic);
|
|
23
|
+
const chain = createEthereumChain(rpcUrls, chainId);
|
|
24
|
+
const l1Client = createExtendedL1Client(rpcUrls, account, chain.chainInfo);
|
|
25
|
+
const stakingAssetHandler = getContract({
|
|
26
|
+
address: stakingAssetHandlerAddress.toString(),
|
|
27
|
+
abi: StakingAssetHandlerAbi,
|
|
28
|
+
client: l1Client
|
|
29
|
+
});
|
|
30
|
+
const rollupAddress = await stakingAssetHandler.read.getRollup();
|
|
31
|
+
dualLog(`Adding validator ${attesterAddress} to rollup ${rollupAddress.toString()}`);
|
|
19
32
|
const rollup = getContract({
|
|
20
|
-
address: rollupAddress
|
|
33
|
+
address: rollupAddress,
|
|
21
34
|
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
|
-
|
|
35
|
+
client: l1Client
|
|
36
|
+
});
|
|
37
|
+
const gseAddress = await rollup.read.getGSE();
|
|
38
|
+
const gse = new GSEContract(l1Client, gseAddress);
|
|
39
|
+
const registrationTuple = await gse.makeRegistrationTuple(blsSecretKey);
|
|
40
|
+
const l1TxUtils = createL1TxUtils(l1Client, {
|
|
41
|
+
logger: debugLogger
|
|
42
|
+
});
|
|
43
|
+
const proofParamsObj = ZkPassportProofParams.fromBuffer(proofParams);
|
|
44
|
+
// Step 1: Claim STK tokens from the faucet
|
|
45
|
+
dualLog(`Claiming STK tokens from faucet`);
|
|
46
|
+
const { receipt: claimReceipt } = await l1TxUtils.sendAndMonitorTransaction({
|
|
47
|
+
to: stakingAssetHandlerAddress.toString(),
|
|
48
|
+
data: encodeFunctionData({
|
|
49
|
+
abi: StakingAssetHandlerAbi,
|
|
50
|
+
functionName: 'claim',
|
|
51
|
+
args: [
|
|
52
|
+
proofParamsObj.toViem()
|
|
53
|
+
]
|
|
54
|
+
}),
|
|
55
|
+
abi: StakingAssetHandlerAbi
|
|
56
|
+
});
|
|
57
|
+
dualLog(`Claim transaction hash: ${claimReceipt.transactionHash}`);
|
|
58
|
+
await l1Client.waitForTransactionReceipt({
|
|
59
|
+
hash: claimReceipt.transactionHash
|
|
60
|
+
});
|
|
61
|
+
// Step 2: Approve the rollup to spend STK tokens
|
|
62
|
+
const stakingAssetAddress = await stakingAssetHandler.read.STAKING_ASSET();
|
|
63
|
+
dualLog(`Approving rollup to spend STK tokens`);
|
|
64
|
+
const { receipt: approveReceipt } = await l1TxUtils.sendAndMonitorTransaction({
|
|
65
|
+
to: stakingAssetAddress,
|
|
66
|
+
data: encodeFunctionData({
|
|
67
|
+
abi: TestERC20Abi,
|
|
68
|
+
functionName: 'approve',
|
|
69
|
+
args: [
|
|
70
|
+
rollupAddress,
|
|
71
|
+
maxUint256
|
|
72
|
+
]
|
|
73
|
+
}),
|
|
74
|
+
abi: TestERC20Abi
|
|
75
|
+
});
|
|
76
|
+
await l1Client.waitForTransactionReceipt({
|
|
77
|
+
hash: approveReceipt.transactionHash
|
|
78
|
+
});
|
|
79
|
+
// Step 3: Deposit into the rollup to register as a validator
|
|
80
|
+
dualLog(`Depositing into rollup to register validator`);
|
|
81
|
+
const { receipt } = await l1TxUtils.sendAndMonitorTransaction({
|
|
82
|
+
to: rollupAddress,
|
|
83
|
+
data: encodeFunctionData({
|
|
84
|
+
abi: RollupAbi,
|
|
85
|
+
functionName: 'deposit',
|
|
86
|
+
args: [
|
|
87
|
+
attesterAddress.toString(),
|
|
88
|
+
withdrawerAddress.toString(),
|
|
89
|
+
registrationTuple.publicKeyInG1,
|
|
90
|
+
registrationTuple.publicKeyInG2,
|
|
91
|
+
registrationTuple.proofOfPossession,
|
|
92
|
+
false
|
|
93
|
+
]
|
|
94
|
+
}),
|
|
95
|
+
abi: RollupAbi
|
|
96
|
+
});
|
|
97
|
+
dualLog(`Deposit transaction hash: ${receipt.transactionHash}`);
|
|
98
|
+
await l1Client.waitForTransactionReceipt({
|
|
99
|
+
hash: receipt.transactionHash
|
|
54
100
|
});
|
|
55
101
|
if (isAnvilTestChain(chainId)) {
|
|
56
102
|
dualLog(`Funding validator on L1`);
|
|
57
|
-
const cheatCodes = new EthCheatCodes(rpcUrls, debugLogger);
|
|
58
|
-
await cheatCodes.setBalance(
|
|
103
|
+
const cheatCodes = new EthCheatCodes(rpcUrls, new DateProvider(), debugLogger);
|
|
104
|
+
await cheatCodes.setBalance(attesterAddress, 10n ** 20n);
|
|
59
105
|
} else {
|
|
60
|
-
const balance = await
|
|
61
|
-
address:
|
|
106
|
+
const balance = await l1Client.getBalance({
|
|
107
|
+
address: attesterAddress.toString()
|
|
62
108
|
});
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
dualLog(`WARNING: Validator has no balance. Remember to fund it!`);
|
|
109
|
+
dualLog(`Validator balance: ${formatEther(balance)} ETH`);
|
|
110
|
+
if (balance === 0n) {
|
|
111
|
+
dualLog(`WARNING: Proposer has no balance. Remember to fund it!`);
|
|
67
112
|
}
|
|
68
113
|
}
|
|
69
114
|
}
|
|
70
|
-
export async function
|
|
115
|
+
export async function addL1ValidatorViaRollup({ rpcUrls, chainId, privateKey, mnemonic, attesterAddress, withdrawerAddress, blsSecretKey, moveWithLatestRollup, rollupAddress, log, debugLogger }) {
|
|
71
116
|
const dualLog = makeDualLog(log, debugLogger);
|
|
72
|
-
const
|
|
73
|
-
const
|
|
117
|
+
const account = getAccount(privateKey, mnemonic);
|
|
118
|
+
const chain = createEthereumChain(rpcUrls, chainId);
|
|
119
|
+
const l1Client = createExtendedL1Client(rpcUrls, account, chain.chainInfo);
|
|
120
|
+
dualLog(`Adding validator ${attesterAddress} to rollup ${rollupAddress.toString()} via direct deposit`);
|
|
121
|
+
if (!withdrawerAddress) {
|
|
122
|
+
throw new Error(`Withdrawer address required`);
|
|
123
|
+
}
|
|
74
124
|
const rollup = getContract({
|
|
75
125
|
address: rollupAddress.toString(),
|
|
76
126
|
abi: RollupAbi,
|
|
77
|
-
client:
|
|
127
|
+
client: l1Client
|
|
128
|
+
});
|
|
129
|
+
const gseAddress = await rollup.read.getGSE();
|
|
130
|
+
const gse = new GSEContract(l1Client, gseAddress);
|
|
131
|
+
const registrationTuple = await gse.makeRegistrationTuple(blsSecretKey);
|
|
132
|
+
const l1TxUtils = createL1TxUtils(l1Client, {
|
|
133
|
+
logger: debugLogger
|
|
134
|
+
});
|
|
135
|
+
const { receipt } = await l1TxUtils.sendAndMonitorTransaction({
|
|
136
|
+
to: rollupAddress.toString(),
|
|
137
|
+
data: encodeFunctionData({
|
|
138
|
+
abi: RollupAbi,
|
|
139
|
+
functionName: 'deposit',
|
|
140
|
+
args: [
|
|
141
|
+
attesterAddress.toString(),
|
|
142
|
+
withdrawerAddress.toString(),
|
|
143
|
+
registrationTuple.publicKeyInG1,
|
|
144
|
+
registrationTuple.publicKeyInG2,
|
|
145
|
+
registrationTuple.proofOfPossession,
|
|
146
|
+
moveWithLatestRollup
|
|
147
|
+
]
|
|
148
|
+
}),
|
|
149
|
+
abi: StakingAssetHandlerAbi
|
|
150
|
+
});
|
|
151
|
+
dualLog(`Transaction hash: ${receipt.transactionHash}`);
|
|
152
|
+
await l1Client.waitForTransactionReceipt({
|
|
153
|
+
hash: receipt.transactionHash
|
|
154
|
+
});
|
|
155
|
+
if (isAnvilTestChain(chainId)) {
|
|
156
|
+
dualLog(`Funding validator on L1`);
|
|
157
|
+
const cheatCodes = new EthCheatCodes(rpcUrls, new DateProvider(), debugLogger);
|
|
158
|
+
await cheatCodes.setBalance(attesterAddress, 10n ** 20n);
|
|
159
|
+
} else {
|
|
160
|
+
const balance = await l1Client.getBalance({
|
|
161
|
+
address: attesterAddress.toString()
|
|
162
|
+
});
|
|
163
|
+
dualLog(`Validator balance: ${formatEther(balance)} ETH`);
|
|
164
|
+
if (balance === 0n) {
|
|
165
|
+
dualLog(`WARNING: Proposer has no balance. Remember to fund it!`);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
export async function removeL1Validator({ rpcUrls, chainId, privateKey, mnemonic, validatorAddress, rollupAddress, log, debugLogger }) {
|
|
170
|
+
const dualLog = makeDualLog(log, debugLogger);
|
|
171
|
+
const account = getAccount(privateKey, mnemonic);
|
|
172
|
+
const chain = createEthereumChain(rpcUrls, chainId);
|
|
173
|
+
const l1Client = createExtendedL1Client(rpcUrls, account, chain.chainInfo);
|
|
174
|
+
const l1TxUtils = createL1TxUtils(l1Client, {
|
|
175
|
+
logger: debugLogger
|
|
78
176
|
});
|
|
79
177
|
dualLog(`Removing validator ${validatorAddress.toString()} from rollup ${rollupAddress.toString()}`);
|
|
80
|
-
const
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
178
|
+
const { receipt } = await l1TxUtils.sendAndMonitorTransaction({
|
|
179
|
+
to: rollupAddress.toString(),
|
|
180
|
+
data: encodeFunctionData({
|
|
181
|
+
abi: RollupAbi,
|
|
182
|
+
functionName: 'initiateWithdraw',
|
|
183
|
+
args: [
|
|
184
|
+
validatorAddress.toString(),
|
|
185
|
+
validatorAddress.toString()
|
|
186
|
+
]
|
|
187
|
+
})
|
|
87
188
|
});
|
|
189
|
+
dualLog(`Transaction hash: ${receipt.transactionHash}`);
|
|
88
190
|
}
|
|
89
191
|
export async function pruneRollup({ rpcUrls, chainId, privateKey, mnemonic, rollupAddress, log, debugLogger }) {
|
|
90
192
|
const dualLog = makeDualLog(log, debugLogger);
|
|
91
|
-
const
|
|
92
|
-
const
|
|
93
|
-
const
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
client: walletClient
|
|
193
|
+
const account = getAccount(privateKey, mnemonic);
|
|
194
|
+
const chain = createEthereumChain(rpcUrls, chainId);
|
|
195
|
+
const l1Client = createExtendedL1Client(rpcUrls, account, chain.chainInfo);
|
|
196
|
+
const l1TxUtils = createL1TxUtils(l1Client, {
|
|
197
|
+
logger: debugLogger
|
|
97
198
|
});
|
|
98
199
|
dualLog(`Trying prune`);
|
|
99
|
-
const
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
200
|
+
const { receipt } = await l1TxUtils.sendAndMonitorTransaction({
|
|
201
|
+
to: rollupAddress.toString(),
|
|
202
|
+
data: encodeFunctionData({
|
|
203
|
+
abi: RollupAbi,
|
|
204
|
+
functionName: 'prune'
|
|
205
|
+
})
|
|
103
206
|
});
|
|
207
|
+
dualLog(`Transaction hash: ${receipt.transactionHash}`);
|
|
104
208
|
}
|
|
105
209
|
export async function fastForwardEpochs({ rpcUrls, chainId, rollupAddress, numEpochs, log, debugLogger }) {
|
|
106
210
|
const dualLog = makeDualLog(log, debugLogger);
|
|
107
|
-
const publicClient = getPublicClient(
|
|
211
|
+
const publicClient = getPublicClient({
|
|
212
|
+
l1RpcUrls: rpcUrls,
|
|
213
|
+
l1ChainId: chainId
|
|
214
|
+
});
|
|
108
215
|
const rollup = getContract({
|
|
109
216
|
address: rollupAddress.toString(),
|
|
110
217
|
abi: RollupAbi,
|
|
111
218
|
client: publicClient
|
|
112
219
|
});
|
|
113
|
-
const cheatCodes = new EthCheatCodes(rpcUrls, debugLogger);
|
|
220
|
+
const cheatCodes = new EthCheatCodes(rpcUrls, new DateProvider(), debugLogger);
|
|
114
221
|
const currentSlot = await rollup.read.getCurrentSlot();
|
|
115
222
|
const l2SlotsInEpoch = await rollup.read.getEpochDuration();
|
|
116
223
|
const timestamp = await rollup.read.getTimestampForSlot([
|
|
@@ -118,7 +225,9 @@ export async function fastForwardEpochs({ rpcUrls, chainId, rollupAddress, numEp
|
|
|
118
225
|
]);
|
|
119
226
|
dualLog(`Fast forwarding ${numEpochs} epochs to ${timestamp}`);
|
|
120
227
|
try {
|
|
121
|
-
await cheatCodes.warp(Number(timestamp)
|
|
228
|
+
await cheatCodes.warp(Number(timestamp), {
|
|
229
|
+
resetBlockInterval: true
|
|
230
|
+
});
|
|
122
231
|
dualLog(`Fast forwarded ${numEpochs} epochs to ${timestamp}`);
|
|
123
232
|
} catch (error) {
|
|
124
233
|
if (error instanceof Error && error.message.includes("is lower than or equal to previous block's timestamp")) {
|
|
@@ -131,32 +240,29 @@ export async function fastForwardEpochs({ rpcUrls, chainId, rollupAddress, numEp
|
|
|
131
240
|
}
|
|
132
241
|
export async function debugRollup({ rpcUrls, chainId, rollupAddress, log }) {
|
|
133
242
|
const config = getL1ContractsConfigEnvVars();
|
|
134
|
-
const publicClient = getPublicClient(
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
abi: RollupAbi,
|
|
138
|
-
client: publicClient
|
|
243
|
+
const publicClient = getPublicClient({
|
|
244
|
+
l1RpcUrls: rpcUrls,
|
|
245
|
+
l1ChainId: chainId
|
|
139
246
|
});
|
|
140
|
-
const
|
|
247
|
+
const rollup = new RollupContract(publicClient, rollupAddress);
|
|
248
|
+
const pendingNum = await rollup.getCheckpointNumber();
|
|
141
249
|
log(`Pending block num: ${pendingNum}`);
|
|
142
|
-
const provenNum = await rollup.
|
|
250
|
+
const provenNum = await rollup.getProvenCheckpointNumber();
|
|
143
251
|
log(`Proven block num: ${provenNum}`);
|
|
144
|
-
const validators = await rollup.
|
|
252
|
+
const validators = await rollup.getAttesters();
|
|
145
253
|
log(`Validators: ${validators.map((v)=>v.toString()).join(', ')}`);
|
|
146
|
-
const committee = await rollup.
|
|
147
|
-
log(`Committee: ${committee
|
|
148
|
-
const archive = await rollup.
|
|
254
|
+
const committee = await rollup.getCurrentEpochCommittee();
|
|
255
|
+
log(`Committee: ${committee?.map((v)=>v.toString()).join(', ')}`);
|
|
256
|
+
const archive = await rollup.archive();
|
|
149
257
|
log(`Archive: ${archive}`);
|
|
150
|
-
const epochNum = await rollup.
|
|
258
|
+
const epochNum = await rollup.getCurrentEpochNumber();
|
|
151
259
|
log(`Current epoch: ${epochNum}`);
|
|
152
|
-
const slot = await rollup.
|
|
260
|
+
const slot = await rollup.getSlotNumber();
|
|
153
261
|
log(`Current slot: ${slot}`);
|
|
154
|
-
const proposerDuringPrevL1Block = await rollup.
|
|
262
|
+
const proposerDuringPrevL1Block = await rollup.getCurrentProposer();
|
|
155
263
|
log(`Proposer during previous L1 block: ${proposerDuringPrevL1Block}`);
|
|
156
264
|
const nextBlockTS = BigInt((await publicClient.getBlock()).timestamp + BigInt(config.ethereumSlotDuration));
|
|
157
|
-
const proposer = await rollup.
|
|
158
|
-
nextBlockTS
|
|
159
|
-
]);
|
|
265
|
+
const proposer = await rollup.getProposerAt(nextBlockTS);
|
|
160
266
|
log(`Proposer NOW: ${proposer.toString()}`);
|
|
161
267
|
}
|
|
162
268
|
function makeDualLog(log, debugLogger) {
|
|
@@ -165,22 +271,10 @@ function makeDualLog(log, debugLogger) {
|
|
|
165
271
|
debugLogger.info(msg);
|
|
166
272
|
};
|
|
167
273
|
}
|
|
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) {
|
|
274
|
+
function getAccount(privateKey, mnemonic) {
|
|
176
275
|
if (!privateKey && !mnemonic) {
|
|
177
276
|
throw new Error('Either privateKey or mnemonic must be provided to create a wallet client');
|
|
178
277
|
}
|
|
179
|
-
const chain = createEthereumChain(rpcUrls, chainId);
|
|
180
278
|
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
|
-
});
|
|
279
|
+
return account;
|
|
186
280
|
}
|
|
@@ -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
|