From 3845dcfb8b5e6a3fe24b0ec4fa77f08178229dfb Mon Sep 17 00:00:00 2001 From: Dimo99 Date: Tue, 27 Jun 2023 17:57:44 +0300 Subject: [PATCH 1/5] doc(zk): Add description of the validator accumulator --- .../validator_accumulator_description.md | 78 +++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 beacon-light-client/circom/scripts/validator_balances/validator_accumulator_description.md diff --git a/beacon-light-client/circom/scripts/validator_balances/validator_accumulator_description.md b/beacon-light-client/circom/scripts/validator_balances/validator_accumulator_description.md new file mode 100644 index 000000000..db0ce4709 --- /dev/null +++ b/beacon-light-client/circom/scripts/validator_balances/validator_accumulator_description.md @@ -0,0 +1,78 @@ +`validatorsAccumulator` is a Merkle tree accumulator that contains the public keys of validators and their corresponding Eth1 deposit indexes. +The purpose of storing the Eth1 deposit index is to ascertain whether a particular validator is already a participant in the beacon chain. + +A Merkle tree accumulator is a binary tree of hashes, which is used for efficiently proving membership of an element in a set. In this context, the set comprises of validators. + +This is a sample solidity implementation of the `validatorsAccumulator` + +``` +// The depth of the validator accumulator tree +uint constant VALIDATOR_ACCUMULATOR_TREE_DEPTH = 32; + +// An array to hold the branch hashes for the Merkle tree +bytes32[VALIDATOR_ACCUMULATOR_TREE_DEPTH] branch; + +// A counter for the total number of validators +uint validators_count; + +constructor() { + // Compute hashes in empty Merkle tree + for (uint height = 0; height < DEPOSIT_CONTRACT_TREE_DEPTH - 1; height++) + zero_hashes[height + 1] = sha256(abi.encodePacked(zero_hashes[height], zero_hashes[height])); +} + +// Function to calculate and return the Merkle accumulator root of the validators +function get_validators_accumulator() override external view returns (bytes32) { + bytes32 node; + uint size = validators_count; + + // Calculate the Merkle accumulator root + for (uint height = 0; height < VALIDATOR_ACCUMULATOR_TREE_DEPTH; height++) { + // This if-else structure supports tree balancing + // If size is odd, the new node will be hashed with the previous node on this level + // If size is even, the new node will be hashed with a predefined zero hash + if ((size & 1) == 1) + node = sha256(abi.encodePacked(branch[height], node)); + else + node = sha256(abi.encodePacked(node, zero_hashes[height])); + + size /= 2; + } + + return node; +} + +// Function to handle deposits from validators +function deposit( + bytes calldata pubkey, + bytes calldata withdrawal_credentials, + bytes calldata signature, + bytes32 deposit_data_root) { + // Perform the deposit using the DepositContract + IDepositContract(depositAddress).deposit(pubkey, withdrawal_credentials, signature, deposit_data_root); + + // Get the deposit count and increase the validator count + bytes deposit_index = IDepositContract(depositAddress).get_deposit_count(); + validators_count += 1; + + // Create a node for the validator + bytes32 node = sha256(abi.encodePacked(pubkey, deposit_index)); + + // Insert the node into the Merkle accumulator tree + uint size = validators_count; + for(uint height = 0; height < VALIDATOR_ACCUMULATOR_TREE_DEPTH; height++) { + if ((size & 1) == 1) { + branch[height] = node; + return; + } + node = sha256(abi.encodePacked(branch[height], node)); + size /= 2; + } +} +``` + +In the deposit function, each validator's public key and their Eth1 deposit index are packed together and hashed to form a node. This node represents the validator in the Merkle tree. + +The node is then inserted into the Merkle tree at the appropriate level, based on the current number of validators. The path to insert the node is determined using the binary representation of the total validator count. The leftmost branch is taken for every 0, and the rightmost branch for every 1. + +The get_validators_accumulator function calculates and returns the Merkle root of the validatorsAccumulator. This root is a single hash that effectively represents all the validators in the accumulator. From 6c8d8d307d5cf7d7af036866c427572dd05c070e Mon Sep 17 00:00:00 2001 From: Dimo99 Date: Thu, 29 Jun 2023 14:15:15 +0300 Subject: [PATCH 2/5] feat(solidity): Add ValidatorsAccumulator.sol --- .github/workflows/ci.yml | 3 + Makefile | 4 + .../scripts/validator_balances/get_input.ts | 5 +- .../validator_accumulator_description.md | 158 ++- .../ValidatorsAccumulator.sol | 122 ++ .../solidity/hardhat.config.ts | 33 +- .../test/ValidatorAccumulator.test.ts | 1047 +++++++++++++++++ libs/typescript/ts-utils/ssz-utils.ts | 34 +- 8 files changed, 1343 insertions(+), 63 deletions(-) create mode 100644 beacon-light-client/solidity/contracts/validators_accumulator/ValidatorsAccumulator.sol create mode 100644 beacon-light-client/solidity/test/ValidatorAccumulator.test.ts diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1224e0b83..df9a5fecc 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -64,6 +64,9 @@ jobs: - name: Run Verifier in Cosmos - Relayer test run: nix develop -c yarn test './tests/cosmosLightClient/test-verifier-in-cosmos-relay.ts' + - name: Run Solidity Validators accumulator tests + run: nix develop -c make test-validator-accumulator + # - name: Run Verifier in EOS test # run: nix develop -c yarn test './tests/eosLightClient/test-verifier-in-EOS.ts' diff --git a/Makefile b/Makefile index b49671103..bdb61fd5e 100644 --- a/Makefile +++ b/Makefile @@ -10,6 +10,10 @@ build-relay-image: docker build -t relayimage -f Dockerfile.relay . +test-validator-accumulator: yarn-check + cd beacon-light-client/solidity && \ + yarn hardhat test test/ValidatorAccumulator.test.ts + evm-simulation: yarn-check cd beacon-light-client/solidity && \ yarn hardhat test test/BeaconLightClientReadyProofs.test.ts diff --git a/beacon-light-client/circom/scripts/validator_balances/get_input.ts b/beacon-light-client/circom/scripts/validator_balances/get_input.ts index d6e0a58d9..909439428 100644 --- a/beacon-light-client/circom/scripts/validator_balances/get_input.ts +++ b/beacon-light-client/circom/scripts/validator_balances/get_input.ts @@ -23,7 +23,8 @@ function getValidatorTree(validator, ssz): Tree { return new Tree(validatorView.node); } -function calculateValidatorsAccumulator( +// TODO: fix so it matches the test in beacon-light-client/solidity +export function calculateValidatorsAccumulator( validatorsPubkeys: Uint8Array[], eth1DepositIndexes: BigInt[], ) { @@ -41,7 +42,7 @@ function calculateValidatorsAccumulator( ); } - const validatorsAccumulator = hexToBytes(hashTreeRoot(leaves)); + const validatorsAccumulator = hexToBytes(hashTreeRoot(leaves, leaves.length)); return bytesToBinaryArray(validatorsAccumulator); } diff --git a/beacon-light-client/circom/scripts/validator_balances/validator_accumulator_description.md b/beacon-light-client/circom/scripts/validator_balances/validator_accumulator_description.md index db0ce4709..2ded291dd 100644 --- a/beacon-light-client/circom/scripts/validator_balances/validator_accumulator_description.md +++ b/beacon-light-client/circom/scripts/validator_balances/validator_accumulator_description.md @@ -6,69 +6,129 @@ A Merkle tree accumulator is a binary tree of hashes, which is used for efficien This is a sample solidity implementation of the `validatorsAccumulator` ``` -// The depth of the validator accumulator tree -uint constant VALIDATOR_ACCUMULATOR_TREE_DEPTH = 32; +// SPDX-License-Identifier: MIT +pragma solidity 0.8.18; + +// This interface is designed to be compatible with the Vyper version. +/// @notice This is the Ethereum 2.0 deposit contract interface. +/// For more information see the Phase 0 specification under https://github.com/ethereum/eth2.0-specs +interface IDepositContract { + /// @notice A processed deposit event. + event DepositEvent( + bytes pubkey, + bytes withdrawal_credentials, + bytes amount, + bytes signature, + bytes index + ); + + /// @notice Submit a Phase 0 DepositData object. + /// @param pubkey A BLS12-381 public key. + /// @param withdrawal_credentials Commitment to a public key for withdrawals. + /// @param signature A BLS12-381 signature. + /// @param deposit_data_root The SHA-256 hash of the SSZ-encoded DepositData object. + /// Used as a protection against malformed input. + function deposit( + bytes calldata pubkey, + bytes calldata withdrawal_credentials, + bytes calldata signature, + bytes32 deposit_data_root + ) external payable; + + /// @notice Query the current deposit root hash. + /// @return The deposit root hash. + function get_deposit_root() external view returns (bytes32); + + /// @notice Query the current deposit count. + /// @return The deposit count encoded as a little endian 64-bit number. + function get_deposit_count() external view returns (bytes memory); +} -// An array to hold the branch hashes for the Merkle tree -bytes32[VALIDATOR_ACCUMULATOR_TREE_DEPTH] branch; +contract ValidatorsAccumulator { + address depositAddress; -// A counter for the total number of validators -uint validators_count; + // The depth of the validator accumulator tree + uint constant VALIDATOR_ACCUMULATOR_TREE_DEPTH = 32; -constructor() { - // Compute hashes in empty Merkle tree - for (uint height = 0; height < DEPOSIT_CONTRACT_TREE_DEPTH - 1; height++) - zero_hashes[height + 1] = sha256(abi.encodePacked(zero_hashes[height], zero_hashes[height])); -} + // An array to hold the branch hashes for the Merkle tree + bytes32[VALIDATOR_ACCUMULATOR_TREE_DEPTH] branch; + + bytes32[VALIDATOR_ACCUMULATOR_TREE_DEPTH] zero_hashes; + + // A counter for the total number of validators + uint validators_count; + + constructor(address _depositAddress) { + depositAddress = _depositAddress; -// Function to calculate and return the Merkle accumulator root of the validators -function get_validators_accumulator() override external view returns (bytes32) { + // Compute hashes in empty Merkle tree + for ( + uint height = 0; + height < VALIDATOR_ACCUMULATOR_TREE_DEPTH - 1; + height++ + ) + zero_hashes[height + 1] = sha256( + abi.encodePacked(zero_hashes[height], zero_hashes[height]) + ); + } + + // Function to calculate and return the Merkle accumulator root of the validators + function get_validators_accumulator() external view returns (bytes32) { bytes32 node; uint size = validators_count; // Calculate the Merkle accumulator root for (uint height = 0; height < VALIDATOR_ACCUMULATOR_TREE_DEPTH; height++) { - // This if-else structure supports tree balancing - // If size is odd, the new node will be hashed with the previous node on this level - // If size is even, the new node will be hashed with a predefined zero hash - if ((size & 1) == 1) - node = sha256(abi.encodePacked(branch[height], node)); - else - node = sha256(abi.encodePacked(node, zero_hashes[height])); - - size /= 2; + // This if-else structure supports tree balancing + // If size is odd, the new node will be hashed with the previous node on this level + // If size is even, the new node will be hashed with a predefined zero hash + if ((size & 1) == 1) + node = sha256(abi.encodePacked(branch[height], node)); + else node = sha256(abi.encodePacked(node, zero_hashes[height])); + + size /= 2; } return node; -} - -// Function to handle deposits from validators -function deposit( - bytes calldata pubkey, - bytes calldata withdrawal_credentials, - bytes calldata signature, - bytes32 deposit_data_root) { - // Perform the deposit using the DepositContract - IDepositContract(depositAddress).deposit(pubkey, withdrawal_credentials, signature, deposit_data_root); - - // Get the deposit count and increase the validator count - bytes deposit_index = IDepositContract(depositAddress).get_deposit_count(); - validators_count += 1; - - // Create a node for the validator - bytes32 node = sha256(abi.encodePacked(pubkey, deposit_index)); - - // Insert the node into the Merkle accumulator tree - uint size = validators_count; - for(uint height = 0; height < VALIDATOR_ACCUMULATOR_TREE_DEPTH; height++) { - if ((size & 1) == 1) { - branch[height] = node; - return; + } + + // Function to handle deposits from validators + function deposit( + bytes calldata pubkey, + bytes calldata withdrawal_credentials, + bytes calldata signature, + bytes32 deposit_data_root + ) public payable { + // Perform the deposit using the DepositContract + + IDepositContract(depositAddress).deposit{value: msg.value}( + pubkey, + withdrawal_credentials, + signature, + deposit_data_root + ); + + // Get the deposit count and increase the validator count + bytes memory deposit_index = IDepositContract(depositAddress) + .get_deposit_count(); + validators_count += 1; + + // Create a node for the validator + bytes32 node = sha256(abi.encodePacked(pubkey, deposit_index)); + + // Insert the node into the Merkle accumulator tree + uint size = validators_count; + for (uint height = 0; height < VALIDATOR_ACCUMULATOR_TREE_DEPTH; height++) { + if ((size & 1) == 1) { + branch[height] = node; + return; + } + node = sha256(abi.encodePacked(branch[height], node)); + size /= 2; } - node = sha256(abi.encodePacked(branch[height], node)); - size /= 2; - } + } } + ``` In the deposit function, each validator's public key and their Eth1 deposit index are packed together and hashed to form a node. This node represents the validator in the Merkle tree. diff --git a/beacon-light-client/solidity/contracts/validators_accumulator/ValidatorsAccumulator.sol b/beacon-light-client/solidity/contracts/validators_accumulator/ValidatorsAccumulator.sol new file mode 100644 index 000000000..da5fb4516 --- /dev/null +++ b/beacon-light-client/solidity/contracts/validators_accumulator/ValidatorsAccumulator.sol @@ -0,0 +1,122 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.18; + +// This interface is designed to be compatible with the Vyper version. +/// @notice This is the Ethereum 2.0 deposit contract interface. +/// For more information see the Phase 0 specification under https://github.com/ethereum/eth2.0-specs +interface IDepositContract { + /// @notice A processed deposit event. + event DepositEvent( + bytes pubkey, + bytes withdrawal_credentials, + bytes amount, + bytes signature, + bytes index + ); + + /// @notice Submit a Phase 0 DepositData object. + /// @param pubkey A BLS12-381 public key. + /// @param withdrawal_credentials Commitment to a public key for withdrawals. + /// @param signature A BLS12-381 signature. + /// @param deposit_data_root The SHA-256 hash of the SSZ-encoded DepositData object. + /// Used as a protection against malformed input. + function deposit( + bytes calldata pubkey, + bytes calldata withdrawal_credentials, + bytes calldata signature, + bytes32 deposit_data_root + ) external payable; + + /// @notice Query the current deposit root hash. + /// @return The deposit root hash. + function get_deposit_root() external view returns (bytes32); + + /// @notice Query the current deposit count. + /// @return The deposit count encoded as a little endian 64-bit number. + function get_deposit_count() external view returns (bytes memory); +} + +contract ValidatorsAccumulator { + address depositAddress; + + // The depth of the validator accumulator tree + uint constant VALIDATOR_ACCUMULATOR_TREE_DEPTH = 32; + + // An array to hold the branch hashes for the Merkle tree + bytes32[VALIDATOR_ACCUMULATOR_TREE_DEPTH] branch; + + bytes32[VALIDATOR_ACCUMULATOR_TREE_DEPTH] zero_hashes; + + // A counter for the total number of validators + uint validators_count; + + constructor(address _depositAddress) { + depositAddress = _depositAddress; + + // Compute hashes in empty Merkle tree + for ( + uint height = 0; + height < VALIDATOR_ACCUMULATOR_TREE_DEPTH - 1; + height++ + ) + zero_hashes[height + 1] = sha256( + abi.encodePacked(zero_hashes[height], zero_hashes[height]) + ); + } + + // Function to calculate and return the Merkle accumulator root of the validators + function get_validators_accumulator() external view returns (bytes32) { + bytes32 node; + uint size = validators_count; + + // Calculate the Merkle accumulator root + for (uint height = 0; height < VALIDATOR_ACCUMULATOR_TREE_DEPTH; height++) { + // This if-else structure supports tree balancing + // If size is odd, the new node will be hashed with the previous node on this level + // If size is even, the new node will be hashed with a predefined zero hash + if ((size & 1) == 1) + node = sha256(abi.encodePacked(branch[height], node)); + else node = sha256(abi.encodePacked(node, zero_hashes[height])); + + size /= 2; + } + + return node; + } + + // Function to handle deposits from validators + function deposit( + bytes calldata pubkey, + bytes calldata withdrawal_credentials, + bytes calldata signature, + bytes32 deposit_data_root + ) public payable { + // Perform the deposit using the DepositContract + + IDepositContract(depositAddress).deposit{value: msg.value}( + pubkey, + withdrawal_credentials, + signature, + deposit_data_root + ); + + // Get the deposit count and increase the validator count + bytes memory deposit_index = IDepositContract(depositAddress) + .get_deposit_count(); + validators_count += 1; + + // Create a node for the validator + bytes32 node = sha256(abi.encodePacked(pubkey, deposit_index)); + + // Insert the node into the Merkle accumulator tree + uint size = validators_count; + for (uint height = 0; height < VALIDATOR_ACCUMULATOR_TREE_DEPTH; height++) { + if ((size & 1) == 1) { + branch[height] = node; + return; + } + node = sha256(abi.encodePacked(branch[height], node)); + size /= 2; + } + } +} diff --git a/beacon-light-client/solidity/hardhat.config.ts b/beacon-light-client/solidity/hardhat.config.ts index 0e9c88cc0..b887426e6 100644 --- a/beacon-light-client/solidity/hardhat.config.ts +++ b/beacon-light-client/solidity/hardhat.config.ts @@ -39,13 +39,26 @@ if (!/^0x[0-9a-fA-F]{64}$/.test(conf.USER_PRIVATE_KEY ?? '')) { export default { solidity: { - version: '0.8.9', - settings: { - optimizer: { - enabled: true, - runs: 200, + compilers: [ + { + version: '0.8.9', + settings: { + optimizer: { + enabled: true, + runs: 200, + }, + }, }, - }, + { + version: '0.8.18', + settings: { + optimizer: { + enabled: true, + runs: 200, + }, + }, + }, + ], }, defaultNetwork: 'hardhat', networks: { @@ -54,8 +67,10 @@ export default { accounts: [conf.LOCAL_HARDHAT_PRIVATE_KEY], }, hardhat: { - blockGasLimit: 30000000, - allowUnlimitedContractSize: true, + forking: { + url: 'https://eth.llamarpc.com', + blockNumber: 17578101, + }, }, ropsten: { url: `https://ropsten.infura.io/v3/${conf.INFURA_API_KEY}`, @@ -118,7 +133,7 @@ export default { accounts: [conf.USER_PRIVATE_KEY], }, gnosis: { - url: `https://gnosis.api.onfinality.io/public`, + url: `https://rpc.gnosis.gateway.fm`, accounts: [conf.USER_PRIVATE_KEY], }, }, diff --git a/beacon-light-client/solidity/test/ValidatorAccumulator.test.ts b/beacon-light-client/solidity/test/ValidatorAccumulator.test.ts new file mode 100644 index 000000000..47ccb86a0 --- /dev/null +++ b/beacon-light-client/solidity/test/ValidatorAccumulator.test.ts @@ -0,0 +1,1047 @@ +import * as path from 'path'; +import { ethers } from 'hardhat'; +import { getFilesInDir, Proof } from './utils'; +import { convertProofToSolidityCalldata } from '../../../libs/typescript/ts-utils/zk-utils'; +import INITIAL_UPDATE from '../../../vendor/eth2-light-client-updates/prater/capella-updates-94/update_5601823_5609044.json'; +import { Contract } from 'ethers'; +import { sha256 } from 'ethers/lib/utils'; +import { hashTreeRoot } from '../../../libs/typescript/ts-utils/ssz-utils'; +import { + bytesToHex, + formatHex, + hexToBytes, +} from '../../../libs/typescript/ts-utils/bls'; +import { expect } from 'chai'; + +const depositContractAbi = [ + { inputs: [], stateMutability: 'nonpayable', type: 'constructor' }, + { + anonymous: false, + inputs: [ + { indexed: false, internalType: 'bytes', name: 'pubkey', type: 'bytes' }, + { + indexed: false, + internalType: 'bytes', + name: 'withdrawal_credentials', + type: 'bytes', + }, + { indexed: false, internalType: 'bytes', name: 'amount', type: 'bytes' }, + { + indexed: false, + internalType: 'bytes', + name: 'signature', + type: 'bytes', + }, + { indexed: false, internalType: 'bytes', name: 'index', type: 'bytes' }, + ], + name: 'DepositEvent', + type: 'event', + }, + { + inputs: [ + { internalType: 'bytes', name: 'pubkey', type: 'bytes' }, + { internalType: 'bytes', name: 'withdrawal_credentials', type: 'bytes' }, + { internalType: 'bytes', name: 'signature', type: 'bytes' }, + { internalType: 'bytes32', name: 'deposit_data_root', type: 'bytes32' }, + ], + name: 'deposit', + outputs: [], + stateMutability: 'payable', + type: 'function', + }, + { + inputs: [], + name: 'get_deposit_count', + outputs: [{ internalType: 'bytes', name: '', type: 'bytes' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'get_deposit_root', + outputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'bytes4', name: 'interfaceId', type: 'bytes4' }], + name: 'supportsInterface', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'pure', + type: 'function', + }, +]; + +const depositItems = [ + { + pubkey: + '0x89bcf22c91a560d95d09c1192664eea1baab0780b6d4441ca39d1cb5094b177b17f47a67b16fb972bfd3b78b602ffeee', + withdrawalCredentials: + '0x0100000000000000000000008ead0e8fec8319fd62c8508c71a90296efd4f042', + signature: + '0xaf92ccc88c4b1eca2f7dffb7c9288c014b2dc358d4846037a71f22a7ebab387795fd88fd29ab6304e25021fae7d99e320b8f9cbf6a5809a9b61e6612a2c838cea8f90a2e90172f111d17c429215d61452ee341ab17915c415696531ff9a69fe8', + depositDataRoot: + '0x757b092b9157a2a946ebf5209660433a71ccabe15b50dbf0cfcc21b9f090e1b5', + }, + { + pubkey: + '0x957882961f53250f9b2b0ca1ad5b5f4fc1a89c3a55cd2dbba3df9e851f06c93e9fe2e691971884a269d4e40f3d054604', + withdrawalCredentials: + '0x0100000000000000000000008ead0e8fec8319fd62c8508c71a90296efd4f042', + signature: + '0x90b6e69502e7cf0bf1f385d121d1f60bd57d83081fcf96e130a7abc2beac046e1e28ec360e5455d226602d6ddd2eb39c162f09bc9420271eb8199c891d7bb52984a09fe416807ff7ed0eddd5eeeb2c07b13b38afafad77ec4f109828c8a73587', + depositDataRoot: + '0xe3d15b9aaa074aac4a55583a13f463d6b565ed8e4b1366c203616e75642ab2db', + }, + { + pubkey: + '0x92d0fcb9349a39352519c9f3930916d7c36ca3e4f8610dc41698622becddb39ea0bf27173a56233474ef95cb7f035f80', + withdrawalCredentials: + '0x0100000000000000000000008ead0e8fec8319fd62c8508c71a90296efd4f042', + signature: + '0xaafeee8adaf0b486d14c7eefc9164b0e0adab47fd9014c604bf629955185e111863797a8e9a6ade9c387f79daaaaf8530faa8cfd6d4d6e9964e206fc02618f5b0bb8a497f5271d0e542cb5d3bb27701cb5a38b1d65d278ff931ed1057f65b684', + depositDataRoot: + '0xc4bfe4fadc951bdd1ce9d63d9c65c9189670c19c6d535be5ca121070b7138855', + }, + { + pubkey: + '0x965e2f75c43c93fc7b5efbc03649f13b5bd18bd1fd02a6294a6941b314989c9a5ba729276c2f3981a763d008f1957fe4', + withdrawalCredentials: + '0x0100000000000000000000008ead0e8fec8319fd62c8508c71a90296efd4f042', + signature: + '0xb792cb5952280a52a23b14d39158911016214fda575b6884fbaa8b66d29a7fa55d8909380021a38410f4a2b25edb47cd0222bb9d175ddfe4e6545b58d5bcd0b099d6193db5e8d161fac6c0292ae24aac0e24fa2a17484e2112e89ef505b25a46', + depositDataRoot: + '0xc004a0e0c4a536077caacf346c1a868d6ba5a605a40f80d9e4d0e786d3324bef', + }, + { + pubkey: + '0xa7a3e154aed45c46b01953f74695bf4a0ee50b15ad0f89157dddd7d8783fd3bafb1ad7c279b2e57e2c58071162c35e81', + withdrawalCredentials: + '0x0100000000000000000000008ead0e8fec8319fd62c8508c71a90296efd4f042', + signature: + '0x8ae6a82e2a51cf69dc962c08b65a5c6d769ecdc47bc518a6d3d8f65525237e03e09f154159183831296f65bdeae47be506f0ac5bfaa9f8f95c081c2d9318d55a84f580b2dd3ee8b35a84d849eaa01324065cd32785ea89850ce761bb91cb107f', + depositDataRoot: + '0x9713ebfa939e06f42066ddc605a0a866eb75c4d7bb78091588273a8c8c70afbc', + }, + { + pubkey: + '0x90e25c49b32bda80d9d07738f01f7550f0adbbedf598fc34c5bb7b084fad6f38cebf39046d79f51a1ab99526e1cbfebd', + withdrawalCredentials: + '0x0100000000000000000000008ead0e8fec8319fd62c8508c71a90296efd4f042', + signature: + '0x88411327903f1f341524e671284a9c5b0df540b5915515710e51bf3f82b254abba36d110b3571ccccdd5d0fe3921ad4512f1fc63b493d5afe746cbe349440dceebee8a6a6cc13607be82bf1c93e94beebefde23cb078515a4f575eebb80f4bb7', + depositDataRoot: + '0xd462d74e6425e06ca174ad3ed805a5742c1b87404c6ef17dd8dcd810e3fd6fa9', + }, + { + pubkey: + '0x81d30decfd9ef8fdebc115998be6f6d36ad48d29defb31a19d7f4eca9501f2bb467a843203aaa4a0a9df25cd2e1de9f8', + withdrawalCredentials: + '0x0100000000000000000000008ead0e8fec8319fd62c8508c71a90296efd4f042', + signature: + '0x8dc3b898805de91fe98da49f3937cbed88b8fc1450734870e792082873346de2e976683bc7a02e81f0d5e8afc625c54a00a697acbcfcc1ad61c8577dc3e26a647806abcc8c11ad327c3b6382887d8537b28e17673e74e5692257c16ef318ed4f', + depositDataRoot: + '0x5878b7d122477ecd4c30cfa69ac6f6ae3131435b17a9244f15d1c09c7ca9b618', + }, + { + pubkey: + '0xb08620c051d972e6e74613f3491933a32c6fb7244de106d004eaee230299bd019164874ea5df124560a467f8888e43f1', + withdrawalCredentials: + '0x0100000000000000000000008ead0e8fec8319fd62c8508c71a90296efd4f042', + signature: + '0xb61357a9a275eb09c1c00f3edf69d18d3a54c0ea9073a500a242113fffb59b0da579bc65f48580a5969e45c53352ebcd02d6e8240960b89f8da39b338a5a5a851e6156ef8510a9ca2facd6f274745f73ec80349ebbd8248a13afd5362f26c4ed', + depositDataRoot: + '0x2e60d40c133d6e8e159787089936c392b3018c09bb861d45dd0ef883fe2097ac', + }, + { + pubkey: + '0xad6ba9d6b7e87373568b42cc3b8df4717812092c6f5ea91dbd72b59c827623bafe3999ca7fec5f1c4af8b66b305c9b13', + withdrawalCredentials: + '0x0100000000000000000000008ead0e8fec8319fd62c8508c71a90296efd4f042', + signature: + '0xa09cb7d15872bbd62409dcc96e04c92fa7419098ed7108a1d7b9d6bcf8cdb9f8c27123b9d20ede944eeef47c01bab2180dfdd6cb3381259135100a57d8de48a2f70d5f681a13f1cf98e2b1a78c6420910132096713dadbcca17cf9004bf97052', + depositDataRoot: + '0xca97880108c27ab520daee9298aa04abcbbfb5111d3d7588b39af2eabfbd0b96', + }, + { + pubkey: + '0xb79c926fb0e5dff048b2a8a89506c87a317d0fc7318c8723f67b6518617692df0ca02a3679db65c34f6a8041da4ae961', + withdrawalCredentials: + '0x0100000000000000000000008ead0e8fec8319fd62c8508c71a90296efd4f042', + signature: + '0x9815aec7424bc1918c1e0e3b2fa1d1e77ea5609e3c29485a281b6d83812a7d023d703e061d4cffa78171d360544e361811e1746bb90fbc010d16310e330103c8fd8378b5f9f692a1a5153d69459e3955a97fb170f3b4ba47d3acae2e471a7d4a', + depositDataRoot: + '0x5c1643e2c735ad3e493efdc154192106d442db19b5b9b8c5b87e62b327e50637', + }, + { + pubkey: + '0xa3f714a37e0fa87a96256bf58a0ab29c156148131c87fdfefee1c8201025ce3fafbb97a3fff67f77e454df622e2a9bee', + withdrawalCredentials: + '0x0100000000000000000000008ead0e8fec8319fd62c8508c71a90296efd4f042', + signature: + '0x8fd9712c371b18aa5d868bf191576d5cd1da84f07994086ca15374d400d5f4349c0547d303852663371eb547b0e44dfd0b3c6dcec44d64fd709e990a48cb03c3228e46fa4e5c272608ba6d73411c44b31d20a4edce78991c0b07c08875fb587a', + depositDataRoot: + '0xa11bbce086b7d3394a87d9f0a7a4836d317033eedda55cb099d969d4fea31b76', + }, + { + pubkey: + '0x94767f1d73c4cd2e0588c2fdbcede391ca26977f78522fc9cdf9dbb519244df7381783c54bf822aef872a59f73e3dcd4', + withdrawalCredentials: + '0x0100000000000000000000008ead0e8fec8319fd62c8508c71a90296efd4f042', + signature: + '0x98c4039ea7f696aeb8a2e8d941fde3fd779522dd42af56a149fa8629d276639ea446f2ad1bae8e18543e1ccf54afdb360911958d9d96749a5c3af6fecd687c99bd2579adc00c6b2fbde9aedbf93e50062c7dfb5238dfdaad0a35503afb921c8c', + depositDataRoot: + '0xcf9613088b05c0420f02432c380f9f234eef3ab5f6f17a42b1152a6b17479ff1', + }, + { + pubkey: + '0x900ac4c458401824a12023d1cbc71684230de02cf5e86369657f7de083079d54080bbb6a22c46e11b77a2a8ed80c4798', + withdrawalCredentials: + '0x0100000000000000000000008ead0e8fec8319fd62c8508c71a90296efd4f042', + signature: + '0x8cd1c985e861a18113f8c76b36947ad3b56b0b72368c6d739d7081a804aa0b23d6d5af53af65e7b4401814c6a012288f145fea62c55d143bdd4a823158790ea131db415ea31807c0e14e45ea6bd9ee9bc672e24a4a13636e5e5eaf021f3d04e6', + depositDataRoot: + '0x69cb6592f039ea2cc27d2350e98beeb5a5f895b301c3cbda4cd213cbf85fd193', + }, + { + pubkey: + '0x89f36f1f4f86ba98a899ab021ef39f10e9ac761e8e770e99be1b90b215a14d9409f946cc93d1b1e21b00b6de2a79445b', + withdrawalCredentials: + '0x0100000000000000000000008ead0e8fec8319fd62c8508c71a90296efd4f042', + signature: + '0x95bfd017dea1ec956310461f0bb846f094d8aea6d9111ead55f16269bc25257cec31e5bf561ca2b6aba26cfd5fca67010fe2d32a7bfb6cc69b68d49625a3038d7a46d4eb053f7a75bd2ce3ffd9dd48ff651e0956e5270330a88d6d3eb7e04bbe', + depositDataRoot: + '0xcff086cff1f83727b7e135b7a133755cf67277fa32beaf65c67ebb0f94cbfd96', + }, + { + pubkey: + '0x8b85c0e1ebcf9a8e6980ef94fd3933db8144916fac01eec83f7f7de74df9ad90923b6c57cc9744da2f2e078a230cf708', + withdrawalCredentials: + '0x0100000000000000000000008ead0e8fec8319fd62c8508c71a90296efd4f042', + signature: + '0x93e4c6b4f3eb4181036b6c43d9f0a7ecb64f590497c75d5add9c7be92da68a5918e9521666cefac59d4e3bcb8e4059eb07b57144f6803ac732a75fbc61388f34f5680c2edbe427ee85b23bcdf4467868a1fb87fba5c613289555765731b44ace', + depositDataRoot: + '0xb35b88b53cd8d73ae68a20856f0a03719efd59da21c627c08346a547c29d5b2f', + }, + { + pubkey: + '0x9175495df91ea6bce297e1e8b6fd3dedf4d38b68ad3098ad741e495abcb592a24becee47e75048ce43fc6dd9ca8c4c0d', + withdrawalCredentials: + '0x0100000000000000000000008ead0e8fec8319fd62c8508c71a90296efd4f042', + signature: + '0xa3bb7be5f60b6e1df64cd0d3b63afd280f59849515c96b52bf48a0fda0c75897ac812a395e4cec6fd3590adedd99a8dd164cc6b5d39b4f4c95e69893f02ff07764976cd5ab0317e1b050b6e69db241bc06be42244d204edb265756d46f48e5b4', + depositDataRoot: + '0x19f5b694738e77a29b9f6bdfbb25c14be12a853fb8b891efcb8ed32cd8994ac1', + }, + { + pubkey: + '0xa462be8b2b9b616991ac4ebea15cabe09de067c76ad85fd81a771f34e56efbb30cc7742f80464edce56b0e738df67f7a', + withdrawalCredentials: + '0x0100000000000000000000008ead0e8fec8319fd62c8508c71a90296efd4f042', + signature: + '0x830c823669d2f3b0834a03c864dcc4cc80173d41025dc61fb9d4ea908afd03895fa4712d94b64d1e2be04124ddadfefc0e7edc4abc74b3cbcf5b9486c12533748ac824381b3a60c74bddb927a7941fcc422456af6b8dc4a09f7ef60e4716bc3a', + depositDataRoot: + '0x749ede17afb7414cbaf413d2c5c439220be90cf0b751a6334337493247131762', + }, + { + pubkey: + '0xb13902f76467bf13710a77f8c8b0028beef845823426237b91cc066b462794a8b70785002475900844bdd9b820608cd5', + withdrawalCredentials: + '0x0100000000000000000000008ead0e8fec8319fd62c8508c71a90296efd4f042', + signature: + '0xa1450df77809a48b24d7ecdda42c936268cd6540a595beefb54784db1e38d9cb76c41fbb7d23c29b76666f3b9d1756191578dd67aae5679d5d3f6c50e583a6b39bd1de7bd7865ec18c2c1a8e75ed3524dd7ece8ace9026ac75f5c57fed7c70df', + depositDataRoot: + '0xa2dc07230095c4506ca4851cf595f8a197cc27a2fb8704059ff69d3191c6d40a', + }, + { + pubkey: + '0x966e99e202db09cfa407cedb176fc692ad620474ec37c2bce23fdb1c565b1f50bff989245200e3b7dd33edc8c204c938', + withdrawalCredentials: + '0x0100000000000000000000008ead0e8fec8319fd62c8508c71a90296efd4f042', + signature: + '0xb39521083226d7b13c4bbbe5f749f6fac5104de6742c9088f256d5e4048b9910042e097c5846dff50327593ee9e4324f0295426ee43972ca9bf261e1932bb020ed3b4bf66e495b5fb9ef854e11f159fe53cf601923f5360e80efffd235c816c5', + depositDataRoot: + '0xe5e380e59ef85764ebb7837ba1133e50f6fa25e050deaaba078b62a68a9c4dbc', + }, + { + pubkey: + '0x8373ace9d9201e08f0e424722ed4b68f2b236c0ccde0f82cfa9e87fa5fcfdd09eeb057d0da88a10cbd07f187a888c073', + withdrawalCredentials: + '0x0100000000000000000000008ead0e8fec8319fd62c8508c71a90296efd4f042', + signature: + '0xb849fad5b877a8bd1176f4a0b313b0ea6cb4ce38b1267525c5c0b338fed1416130e0501a68edc0520f6baa71d9cef9610f399a645f8f6d5611d77eb8229f2892a5994eb4331026f2c957fedad26e26a58164ea6c896ba9c3f279f01d2ccf6e6c', + depositDataRoot: + '0xe8743c77286dc9a3cd373b20d703cf2d9714949788d6fd3ae482d1c29da12702', + }, + { + pubkey: + '0xb4e215f7e7dca63ec0cfa8309e1f852892f50f2c90873082c04cc2b73b4b968abb9dce1930e1888e8fd949312768a517', + withdrawalCredentials: + '0x0100000000000000000000008ead0e8fec8319fd62c8508c71a90296efd4f042', + signature: + '0xa73c20b1bce035a81dfb0118896b2ea795e01c114fff464731dd14c29e5aa37e200fe8816a5b71922dc820f42312be6c0befb90717750bcea2165fcad71d47ad15db84c85cff0c3b43d5ae176ef2b555aedeacff62a0aa54b09f382cb42351ff', + depositDataRoot: + '0xd1be80ab0a2c9f6cc1b45555c8cfcc25fa1f9c8d26ed0a37c8673201aa0afa8b', + }, + { + pubkey: + '0x8bb50657366de1bbd904b53763cebae471d171888c887cf769a823d88704e413b4b0f59921e313c291f05aaf092d343b', + withdrawalCredentials: + '0x0100000000000000000000008ead0e8fec8319fd62c8508c71a90296efd4f042', + signature: + '0x84922c523d337ea189210fbb9ae6af79af61d2eaa9e2f6b2c875e31c97ee617ccc304e7f98782b312fecdd0fd86b60c70b3458dea5ce892b5c2d037d6f02601976fdebd22e4fe9c46182347da6f92fe82ae0b027541a89d1573b2d34f5fd7fcb', + depositDataRoot: + '0x51036d18c80d4a7c6c680582ed98d267081b3920103252f599f6398490b3587b', + }, + { + pubkey: + '0xa00f9d801ef265436ad251c33895667bab7e5e0098d945ad5ba99eb576dff65adc8295d2ad44c78827ad911bf2bc3d86', + withdrawalCredentials: + '0x0100000000000000000000008ead0e8fec8319fd62c8508c71a90296efd4f042', + signature: + '0x86528f09304a2c87b41cd8812cc6b4a44ebcb079549331f3723c353bdd87a35ff62b587520fb0d6fb3d6cf34dfa2103205cef4bbb1d49b488464e1a43c0d2bd11c5385a4d7adc352ab67abb6fa0135f93d429cddd39695c3c7a192af38898e44', + depositDataRoot: + '0xfc409460d51d097e7b55edf8b42ed7964623d152a19e851bad26cb0b0c190f3d', + }, + { + pubkey: + '0x8c08481744bf74828f368a583bdc2d8dd6d0d1335a4397c23e73ff19e8a871eda607df33ebe3fcdacd8ed6cf9c1abee9', + withdrawalCredentials: + '0x0100000000000000000000008ead0e8fec8319fd62c8508c71a90296efd4f042', + signature: + '0x8c1ac6dba7fa04fd6a93214096ac7d952b1ad3dad749da9b594964974dda82911b9508bfcd0ec753641e45072c627f750da0d039e2896c71f908904f2bc50840871f420eedfada10c491c78f24bc9f698f9fbfa51b930e1fa74963d2c4f01a25', + depositDataRoot: + '0x7bb8e59bd9c15e25e07dcbc1d2eac1216a88c9706a9364f2b465821a3cd53eed', + }, + { + pubkey: + '0xa6e9c962abca48b0fd81564bc0f62007ad0f71964c29759ce2ebe7d106e2d10bac08f585ec9459ef275e5e1c5c528049', + withdrawalCredentials: + '0x0100000000000000000000008ead0e8fec8319fd62c8508c71a90296efd4f042', + signature: + '0x939073b9cd70affe327a1fbc7a208a6ab9e3c33d2fa0bc723eb54843e391c6954c9a0e49056ff9c465247bad7fc8c8bf0ef12e11a7c6dbd144b553757044a17d3703f35ecfdcc51fc4cfb6f971bd186c9995085cdc87d377d6b11931acc3d572', + depositDataRoot: + '0x479a777dab71194b694390d6545f95c5d57294bd86ee8b2f7642966ab57f73d1', + }, + { + pubkey: + '0xb4f7fa7be9751c7aee510d5fad843a93114178fc21155f611c6fb53ac4ff712f1ff8815dc2440e44510405b55277ae19', + withdrawalCredentials: + '0x0100000000000000000000008ead0e8fec8319fd62c8508c71a90296efd4f042', + signature: + '0xb984f363e279f735b9cfdb9ff92f0338261c2adb42f0d4fee9626d8f58266089ec0f2d3b9da6074819bf4e4d9f6b754a0d3994a819480f2f1a0370a1dfc4013ccb114423bb6057ddd5c0dbed6ab2231233f78ab19b0955f56a9048b2c9bd119e', + depositDataRoot: + '0xbd6243636dd89abe2c9982829091c7dbef74f99df1ae424da05b0b5fce3eb895', + }, + { + pubkey: + '0xa4d8b3541d2230e6add4cc860784a7b82f06742c1136668d79a46186f527cf557e45c51189a41c21d7c54a97c1a55c59', + withdrawalCredentials: + '0x0100000000000000000000008ead0e8fec8319fd62c8508c71a90296efd4f042', + signature: + '0xb5bcfb34deb16c034883824325e527b32838f5232b2f6a3dc7d04eb65ab1daab8059496e63378503581c5db8e6ee723b07f7cecb2e5271d3d0cf2f809d098f30dd660acf6328aba64fed760e2a8e0a9fa911685977f07eb138c9a4ffbf587a06', + depositDataRoot: + '0x738166674190e18fe4ff7eca6fba2cc9be7796326ca02c49ce15c66a7ac46e6e', + }, + { + pubkey: + '0xa624973ae52339f139105250b68f1aeea61dabd818ddd43471f820003eb97129cd279a27ca109e903f536c104faa17a5', + withdrawalCredentials: + '0x0100000000000000000000008ead0e8fec8319fd62c8508c71a90296efd4f042', + signature: + '0x93647af0d8d2584ffb228219cdd2c560eef8f5b76bcc42b12cb81eff6a41b609f9af20e5df49d22c1132705b41f7e04606cb7df3ce27b8713a01d20bd1ca00a2deb750d08e691e8278559b2a5a0090587c07d5c5c92e30081dc77ad374fbd059', + depositDataRoot: + '0xdd35f76017f1879040211a386203d6ea4589b49b3c0c64b5bbc6634a6c49c716', + }, + { + pubkey: + '0xb6c098d6f05550ec1f215409d6f684b488927f13a26d2397710c792c9221ded1f9ac5f588434b01726e10581ad6f3c4a', + withdrawalCredentials: + '0x0100000000000000000000008ead0e8fec8319fd62c8508c71a90296efd4f042', + signature: + '0x8c28a9851aecca30b577fa15e03504ae8d079ece9f3231299976162c9c80c6ef4acfa2bb0a164b6765a6cbb9ecae1b2a12c4fcbac9d3c375c512377126b64dbba74d8000282c816edb7c7e660e427b1d63ee6604b6ecfb59461ed5aba663652f', + depositDataRoot: + '0x73ee8d5c8692567357114fe958a663792b134309fc98751fc2ad95b9e8201dd3', + }, + { + pubkey: + '0xa0d6f34abe5c9df47d36410d3a8f6b68d517d3d2bbcac4aaa4f17d29cd8b618a326cd7eb14fe13af2f4c7927075a9e0f', + withdrawalCredentials: + '0x0100000000000000000000008ead0e8fec8319fd62c8508c71a90296efd4f042', + signature: + '0x938ebe82a9314597fbaf60c1aa507aa3899f2e62479d3b086b8e481431df0a49fcfcc16fc0a4cd9f48106ffb52b8302115ba5c554a39b54f8fc9a97c2bbd5bbd23c239764d294f830888de1e6195db61f46fe9e101c9a6439e26176578e0f085', + depositDataRoot: + '0xf509089de47badce14105966188e5c9a420f2c377e7d56d2aa9b04f06678a764', + }, + { + pubkey: + '0xa1a374b55950cd4ce36fd7a423a50bdab1246896224859239f920ccd0356cc69eb4598dbfeb15517d8d14c511bc3474b', + withdrawalCredentials: + '0x0100000000000000000000008ead0e8fec8319fd62c8508c71a90296efd4f042', + signature: + '0xacae5f159a98e3fdae448fd8a2bf7a8cce7f197c0e99cc83176fcd4f77e9e361a42c70a8314da0c203e57983b591e8a7037789cffa86b8e5b71e1aef123aba17c576153c4f688e742cbe49ebf36de3f62eb2556b973e2b1db4d11f8535cbd695', + depositDataRoot: + '0x4d3aec5be99856efd078b8e11c02a807baf6a47ed5b1cd8469b64478d6806c69', + }, + { + pubkey: + '0x9049ba59d8c58c6afaae3ba9dd4520a21433a4b640d3e21fb8ac01bf76db0da7b4a0e503b57cacb33faa8d91e4f6fc15', + withdrawalCredentials: + '0x0100000000000000000000008ead0e8fec8319fd62c8508c71a90296efd4f042', + signature: + '0xa0ec2ef54400491dccc126b95ccd7ba1c2977dd91dc929c080aa4d7dffdd96853813b6e2f455cf7ce0d2b9cd078f0ff2158d068bf13fb6cc4a982106cc79c37c250fb23150c5431dffeda300e3dacbebe45b7e9d6bac02a7461c93f6cb625480', + depositDataRoot: + '0x7821d47452510ebdf759f096ff3cdd6c70d9fdb0f1902889c9446775519e6b08', + }, + { + pubkey: + '0x972ef891ac655333bc1cf99543dfd0cdc09e10abcf5fee635fb4457553549a07be6fd96ca75418b3c761952775837b23', + withdrawalCredentials: + '0x0100000000000000000000008ead0e8fec8319fd62c8508c71a90296efd4f042', + signature: + '0xa25d9ad3a4fa2bb96e774be9c1ad47bad90c4d1f61b197d8a756d40cfcb8abd56894e61c4a7e06b100b39c5d614c56c2056cc80f5b25c9996e473d90f384b5ffbfa05a525a9c9694dfc13128df45bab7ef867252655ddfc5f967ab57f1177def', + depositDataRoot: + '0xcef875096ddfd5d018dab7459d7a9e7d2bdbe7416109e118e49383494732bfa3', + }, + { + pubkey: + '0x83201635b83797c4b600306f6c469497d126d71257910314ffff972f827c766fc2552da554ff64c7685c740b5ba4afb6', + withdrawalCredentials: + '0x0100000000000000000000008ead0e8fec8319fd62c8508c71a90296efd4f042', + signature: + '0x92e67ab1bf26ace00783c026b6154ecf0da7a7f9ac52f872732a07aa609cb7418f06d332c850932009d3289b8f1c8d430369ece513145a3b68b560bbc26020b157f85df265eb175f08958d13f9c88dce698804030c5981967b50cb11941b776c', + depositDataRoot: + '0xb620b3f0938cc03b9047fdeb47e6693f132779443e9c495031691bb7b67cacbc', + }, + { + pubkey: + '0xaf30664280a679cf3205b034dd825f297881bd1e5e4ff7003048dd54fd58dd5983f2e7867a83d27129e84ab97c2ff977', + withdrawalCredentials: + '0x0100000000000000000000008ead0e8fec8319fd62c8508c71a90296efd4f042', + signature: + '0xa5af3844a980f76e9d02eb0e22025dd60723056138e2e30a120ce6c00d18d21dfb641a5fe314d85f7a0a8e90c3f51b430eef2935c73f3e8814f149e79b9cd71e494c0a8c2100a871e3cd7472446fbaf217a04cb1ead459bd8d78b0b5d7bcd3b1', + depositDataRoot: + '0xde1aad0e6148a1efe85763a24cd90254beb78814dcd736acd77d130207d83f25', + }, + { + pubkey: + '0xa4f3745b1bafb0805c12c227010688956598c5c5178778de34ba400b2fa276fcdecf2fc4179300c500e047e8e02d8d41', + withdrawalCredentials: + '0x0100000000000000000000008ead0e8fec8319fd62c8508c71a90296efd4f042', + signature: + '0xa772ad562fccda797c80f51189eab3ef1363387f5b4e285b49b42720becb6d13726a7d4287035dded03416cc346056b713eac3664d72e4a5ebe333161684c38882e389d798ba7b8cdbbd1fe84bacbc95952f9f7a0252c480d3db0c4a38177396', + depositDataRoot: + '0xa1ab0ac4aafee4d60fefa44bcbcbc47628159dd0424fcfcec9b517f2be67fd28', + }, + { + pubkey: + '0xa24e76f2e77d5bc884e34c4bc866db378a777e104d8b2ee1243e8f4c9c09d97df784fd317bb3448d1d44b30482c2cc4f', + withdrawalCredentials: + '0x0100000000000000000000008ead0e8fec8319fd62c8508c71a90296efd4f042', + signature: + '0x8c247b51a8bf443236616ebf01631a50800cd470eb556f97d95ab6c3a0a8d0161eaa049ad0562b9291b84f8c21f651810d756bfbc187a59edaa6898fea39996c778079d7c9188d14e82c6d164b31fe28ade18aac8b1d8798276ea23ea2696bcd', + depositDataRoot: + '0xba84eb151ad0a0dc23acb2c6b845e5a2e8c1011d582103121bd4281c5017eb8b', + }, + { + pubkey: + '0x84aa94f113104113b7b02732cef95911bdcf7bef99010c272f3f605310b11fba01a7305c7e7ba11fc8f87a2f44e1ac31', + withdrawalCredentials: + '0x0100000000000000000000008ead0e8fec8319fd62c8508c71a90296efd4f042', + signature: + '0x812480b17cdeaf305edc72ff5dcb13d1a9d2d750f052348da9e760f0d89c7a0b7084c47bb21ee921dcea1912c47ac2551563fbfedca768389d4ca3a8b3fb88516b038205045ca29658b7e983f8ebb3169c31f7cb10fe54e7282f00cd7953bb6c', + depositDataRoot: + '0xc4e8504874a426e85d5e4063bea82534e8cfe9aaf0ccebf61eac1099ca76926e', + }, + { + pubkey: + '0x928c6475e450b8b8d70cae68189229bf35bf5c7b0ac72a72eaa1657f82fd5dc9adbdf5b060f41575aa9698976e16ec9e', + withdrawalCredentials: + '0x0100000000000000000000008ead0e8fec8319fd62c8508c71a90296efd4f042', + signature: + '0xa897534b779899129579aacd0e787ac8118c724cc92f3ae7723616a859bcfe8d70353c74d2e65377d1fffa06205879fb0860f5d29c6beea742867f09c83359a934dec704aae142bbc77dafda164978782a99195312a7e1991904ccd4b9ed5de6', + depositDataRoot: + '0x3d7eee2804b993b96e875abbdacfbcfae91e3d0402259fc28a608b07654c68e4', + }, + { + pubkey: + '0x867bfa6fee3a93fed71b7ff065e465d33f332502b083899603ba7ee38977e91037b6efd08fe0bed0ee19c9391eacc0c5', + withdrawalCredentials: + '0x0100000000000000000000008ead0e8fec8319fd62c8508c71a90296efd4f042', + signature: + '0x99ddbffeaf6d317b600698da67e1bc9903cc6c9c3813c633d03052ce4d248b63841eb526add836e95aa95f62fc0a5d170ab14717f9b3504a6fd273fa046b9ea791c08e10148a711150f606b4777dceac00f2973c70749be91b50aee4ae71533a', + depositDataRoot: + '0xfc8b953f60c8f46afef6ed40c06dbffbe4808300de5fb7738ccce2df9adeb832', + }, + { + pubkey: + '0xb996325d00142b292d7496ab394b9daf4a639b7c5328f13a1a806c94510839694ca2868843fc9afe4f2830111c781458', + withdrawalCredentials: + '0x0100000000000000000000008ead0e8fec8319fd62c8508c71a90296efd4f042', + signature: + '0xa6f70902d8efa72dddb767314fc4359765a2cd7eb3785c39d2f5de37b58ed1cd3fe9e9347f38c0978c72cc4342192ee202153c841137845aa64f09a32e2b55154f7bf790423554df697c7115e638354cfb8d0747e1ef94b976ca1b4414335333', + depositDataRoot: + '0x3e19cfad789fb293b412ad27704f709d92437d9d7b26174e02d96658d5c12a2e', + }, + { + pubkey: + '0x8c3c12979805edd47672325d71abe668f41af144add0207184d662762f2dd02b2081cf373b7dd805e4ed2167e456a44c', + withdrawalCredentials: + '0x0100000000000000000000008ead0e8fec8319fd62c8508c71a90296efd4f042', + signature: + '0x83725eb631b8e4aedb19b5f933ed77a1c7df16f6bfc81914ca5b150c5d788e720514898445a0dbb114a779a0cb2dcb1c0c388400a2f908edf2fa7d9783d1524445b9eb40a211d522698dbf1b808aaae55a4a0943566c7662b6f1515e1ce02e3d', + depositDataRoot: + '0x84db6f103e56f587275b602faa0716e511981f6dc398a2737ba08aad8574c578', + }, + { + pubkey: + '0xb0843a4c9c43fdc96b6c819b6a9ddc16a9175ab405278381c20830b62409b14e61c42fd07855fca886b4b51142a5b649', + withdrawalCredentials: + '0x0100000000000000000000008ead0e8fec8319fd62c8508c71a90296efd4f042', + signature: + '0x9290077b1f20b1bfc25920ad9b9d83c673366efb744cde3d09005c5e0ad6955b8e89f91ca3da929cc27923a02f34c44e0ce3974155a5709ba0071d03b97173a5f150ab2726cee2ab0240f6c1f68338bed1d0e2a08a1bcc9f4bf78c7d25e9dcb2', + depositDataRoot: + '0x2c85b3df635819ad21fd8297b6ad453c729f3f4011d0d6444c70237f57fbf5e6', + }, + { + pubkey: + '0x90d4d4d5b3180c14305a07a7ed8e418a1a1a6169de93a11b38011b80735ce6546e33825ca2aaf6d7fde36c30a47db28b', + withdrawalCredentials: + '0x0100000000000000000000008ead0e8fec8319fd62c8508c71a90296efd4f042', + signature: + '0x9451f9cf00ebe8e705dcc83d86c269a1510037c44fa80bcf526a6541143fb5d858487445397e026e6184987ef9c801e10fcdf32f316af34f9581a54d6207a7dd47349ac73d224e0c4dc9302b0f5793fc26e29d2c0cfbec4c9f6edc02654a30f4', + depositDataRoot: + '0x5e3fffcabfb9f97388bc47f81df6d1850080867f616d6a3722f15c469860e33e', + }, + { + pubkey: + '0x98e1f977d2261ddabc3d281627f8b7f36b973b0d66ac9723c243da6cdc2c408d53cba8a6b8dfe298a5d396d19596ecd7', + withdrawalCredentials: + '0x0100000000000000000000008ead0e8fec8319fd62c8508c71a90296efd4f042', + signature: + '0x98c480eb2508dced8e41b68c7427d6ccae3481e79ab7f54e267faa1f10637978f810b84c879362dd7ec5cac9920c857c123cf09092ca9960c15e52b87fc38e5249f61b7b7b998d87beb8569f580e131842b1f531a811e068db06593d5e534a9e', + depositDataRoot: + '0xe859beb3ac42a3caa9fc4f4a75aff4698554309f32ea0a44284a7d0284dabd76', + }, + { + pubkey: + '0x9348651b6582f78775be8afa4e94ee564089a1da640e5347060f6a4b54e30ef8c3c7b024a51e2d9b8c8a557abf724640', + withdrawalCredentials: + '0x0100000000000000000000008ead0e8fec8319fd62c8508c71a90296efd4f042', + signature: + '0xa8992f24c3e349714ff0211a966ed07f9bf81803d6a6b5dc372c15d5bf55fe913c7e78c1ade9c40dd45baa65906bd42f087656b83f490a0f50d43e95a62d7cb04c6b2df4e4e31886a0d8408bf72764c397221e2c771a3e150db52738c67893f9', + depositDataRoot: + '0xd376c75c38641b4c40bf8cda170ea9b0c6f7bc653375804ebc23802388ac93ac', + }, + { + pubkey: + '0x80d88b1861724839b0f88d27205c1d58705855726d6b46a2cd4b7b2f4dc1e3293285681353c87b6ebfa08a3dc284e218', + withdrawalCredentials: + '0x0100000000000000000000008ead0e8fec8319fd62c8508c71a90296efd4f042', + signature: + '0xa53106415008c640232b99f4c5c21acd9c83695b73a5f6c6a96abf16bce3d0b675b94c9dee3c2c83dc15002c856150da093c2f4bbe904c290c26b9591bf116f17b93a65fe621898d1a8ef7267070059660e8561fe2e98ec8b03974f872ec14cd', + depositDataRoot: + '0xe84a2020d96aa25bc32eb3880ba4ec961d42b2c6e0cbebe6a199df87ed28c06f', + }, + { + pubkey: + '0xb9a72268e4a40088e8d86f591420b0fe898c0c9c0e9da2e2dab94511ebd03ae665e7b91e450183393f1b1d085939aeac', + withdrawalCredentials: + '0x0100000000000000000000008ead0e8fec8319fd62c8508c71a90296efd4f042', + signature: + '0xb44c3597cfb1164941176e18ee22719b030fa0ce7983d9d67342180f93103f34bd4e39349cde131d950ca670c9010fb00179f71d797211063a9ddf0863aa3533aca92004dbd276d0bd04d0f169d04a351e5abd141c6bbcaae379db3446a2715c', + depositDataRoot: + '0x8f5b2d6989564ff8698d946d8071939de9f27267f99f1dc33213b57d25721e14', + }, + { + pubkey: + '0x97a8972ec398ca98a239744df60dcc3696ad5baf0f71df51c1994e37d4e3853e7ea54895d95503e773c4b1a6588c7d9c', + withdrawalCredentials: + '0x0100000000000000000000008ead0e8fec8319fd62c8508c71a90296efd4f042', + signature: + '0x81aea62e0778ad25da5fcdcfe084cb60c1f64aac68467db6869a0694356307bb7c046c42fcfb73de4eba52dea6a184180218db535b389aa548780c7d2dbff357f8f70d6fa9b7b08e3d445910bbf87307c4b40638e9fad8275ec86ee4b2d005bf', + depositDataRoot: + '0xfc73c98d151beaaa70457f76ab515d8ae213f57aaabe6dbfd2fcf642807a0ce8', + }, + { + pubkey: + '0x85f56d7ccdca63a3b30118d49314d3adef4001f3730bbb2454863b0f072c6549872c47978f89bd2c1bc5ac5e0843a495', + withdrawalCredentials: + '0x0100000000000000000000008ead0e8fec8319fd62c8508c71a90296efd4f042', + signature: + '0x83a7aae322e41bcb5aa9dffe8c8ef7ade3760c3af657ab7d780b4e998981b66f311c8e42f0ff9c3c9943d5f9184d95dd0475819100704d70a3f126830b89170680dfc353e24b0714438cbe3db42e19845a4ddff3f050f9f35b181f2405b42721', + depositDataRoot: + '0x57394d0d6e84ff8c2f85eb4392bda59faa4d4d4a2ef3d2aa42c2034da728baa3', + }, + { + pubkey: + '0xb977442770e725d38d62ebf5a179c3f3a35a3c97318b127b85ca5a7c0eb375796ee94499f50fae6deb05bc203f877648', + withdrawalCredentials: + '0x0100000000000000000000008ead0e8fec8319fd62c8508c71a90296efd4f042', + signature: + '0x9658daf44cbf9ed63293ac2dbc8904df40c4604816bf6125bd8f548a90871264c355908878b7e4ddb8472e8de07e9cfd11623a3a857a417b7c7d76d3b23b7e02ab335add818db9244e4fa6ed1ba9a9a5e0d1e141ddc36641476df79c27591f6d', + depositDataRoot: + '0xd6d7dce52b979ca8d520b8d7ba379071736d37530a782d03e127f31241cbffa2', + }, + { + pubkey: + '0xa98ad562baf8c5b358fffc5a38ac2a1c31a40ad1fdefcb1b855481e5fd24d4796b5097165724e3ddec6db057104d68fc', + withdrawalCredentials: + '0x0100000000000000000000008ead0e8fec8319fd62c8508c71a90296efd4f042', + signature: + '0x903ff98eefda4f22e3477fd801d6af87e67e0b36629edddf88b6988d27f7629ac44a75e2bf9132ddb0c45a8ecd1f68dc000d9959d88ee9592a8d72797610d3dd11016bc4833c8d9db19bc6e806e116547741dcb8445d6580eb1530e4d837af75', + depositDataRoot: + '0x4e664e7af54a16170b003f702c1c4e1f530b3de02f5c1c5413a66b62e5a41015', + }, + { + pubkey: + '0x9680290d285945351569b9e80c1c517e6a21dca20cd890c762562b5376d282a29ae5db15c6100f406a9829fae0103ff2', + withdrawalCredentials: + '0x0100000000000000000000008ead0e8fec8319fd62c8508c71a90296efd4f042', + signature: + '0x834009e22c4684978d36762b3aa3873e447de33530ec73e8244307cc60aab8bd2ba61f8ae69c55963dc6642c66fa6a6d1159d119c377d8021b25bd65fa351b3cd13b0bca1453fac94476ab419cfff02f9fcc49a95a12e98276611ae1075f0165', + depositDataRoot: + '0xf0d60e0a87abe9a55908c6ce95d450430ac120e32d470c4d902d2aacae30fa41', + }, + { + pubkey: + '0x90a6dc52c9be3ea6c4760ce1bd8852924bfb2a16a7458aac1574868e8bf6262ead93f7bd5abc0c28eb21276007871dc4', + withdrawalCredentials: + '0x0100000000000000000000008ead0e8fec8319fd62c8508c71a90296efd4f042', + signature: + '0xa8c274bc21a1df15c32f7fbdc19776b9a6541358cc36cdb044f4e9ac8e2bcd0b45479714b9f6affbdb4e1468eeacaec203c4b30daf4d8f78713a3fc5fca15b30b81e301432edba90a9053a52136a26459ab98b384a5953fe22c25eb6acbbf52b', + depositDataRoot: + '0x8002a17ca41644cc57c8d7583468366ee44abaeae8aed37e007a6188034aa8ff', + }, + { + pubkey: + '0xb0279fc59acd376123f9a4de9330ccc1c330ae820d5ac0d17443f98617e86963bb02fc78f60c6deb4dda808c52e4d513', + withdrawalCredentials: + '0x0100000000000000000000008ead0e8fec8319fd62c8508c71a90296efd4f042', + signature: + '0x82ee29eb29f5c19ecf0dd0cebf308a9ad1b1a70aa76007875041ec89e3cd2fd6b3bc457f3554806e5fd135452fa537b915c0ce7ea9b614e10c2b05ae9c0de1ed44bb274a25814e5eaea3314e0e24fd869963e48ba32873c0827fe452853b418d', + depositDataRoot: + '0x6301918a55b3e7423e785a50c984359b2138ba1cbfb5a4b3afa2746421f27c1a', + }, + { + pubkey: + '0x8283a2a3fac680fff115303eddc823edf42766050ecbfe3bfa5d8e7ef2759692c85b63becae97966839d407f0df2658b', + withdrawalCredentials: + '0x0100000000000000000000008ead0e8fec8319fd62c8508c71a90296efd4f042', + signature: + '0xac8340e401493fac6c3c871d0bbccb3133843d0d3c58458073c0ac894f16d5034b0e507eeeab52f61e39b158c2d97e9c0f1a0dd920726a366524601712bf7f54d193ba0e569c8c4bf5dd3d849554ad15f5005a9049579dc157b37b360410e9e1', + depositDataRoot: + '0x12f303d5e7e147e42dd8c9b2d44cffdae26db58f071dce41b6de8f43b0ef8679', + }, + { + pubkey: + '0x93ff1812acac88e8795ed99aec46171efee197ca4af0025364741a194c0d6a0f0bb7d01810b5f7a5c77f7be8f59bcef4', + withdrawalCredentials: + '0x0100000000000000000000008ead0e8fec8319fd62c8508c71a90296efd4f042', + signature: + '0xb73d5e94e047c0a2150b8a8a04807320b35edb2bf11d8b84de60260f6f988414ea0a05fece79c557cd16274107ea4924123c47e0b7955c2faf375ed1bcab54a4a003bdec526ae19467823e5977e313d19ad5952953dce045d3087af3cf907265', + depositDataRoot: + '0x14ab450ab5452b812e57ca7b2b45a50447b5d20a5b0f541bc991c31a2ec5c64d', + }, + { + pubkey: + '0xb977357369b95d9f7f364cf0236c4389a478a1e86592ffff54f6afd6e579798457a3c9c4aff64296a0b034cf2d9b264e', + withdrawalCredentials: + '0x0100000000000000000000008ead0e8fec8319fd62c8508c71a90296efd4f042', + signature: + '0x8403452eaba03118156e4a9010e5e6592752c93499e2c93367f66f62055485e0429c3233db251656f5c2eed0c46db36701f37ca905441e2e5a76e96a92340d8e724f8e11a235cf3cd435719d1e4036fe6a67bf8626a1402fb32bcf8723b8e66a', + depositDataRoot: + '0xc7cc1d35f029795df31f4c8071eb841d7e548be0963ab00f26dcd47f31d8787d', + }, + { + pubkey: + '0xa8bed576dcb4c4019ab975826bfee4590056aa61a868134bd51458c5d74324633709e5432fe193d3e1ee0405e0a645bc', + withdrawalCredentials: + '0x0100000000000000000000008ead0e8fec8319fd62c8508c71a90296efd4f042', + signature: + '0x9845e03c7f2e608f085056731db11eaf8cc2c05c57ed9e9ffaf6c26b3f0ca286dd69bc0a9b3468b8554ae9e4b6d5c67f00b1ca25398af88a5f6cf2994c839a3d8fe53dfd11af45748305a3a91398772fb5eb296ab2e87da2328e593d0b319bbb', + depositDataRoot: + '0xabe0081caeccdbab39eb1a60298f06adaa5f9e5519606ee6156a73b516ba8062', + }, + { + pubkey: + '0x8f97d11db5658a2c13ab427ab75b7d080b7199b978d1df4fa8efe88fa58153bb873e85de306877df5f32eada58faa345', + withdrawalCredentials: + '0x0100000000000000000000008ead0e8fec8319fd62c8508c71a90296efd4f042', + signature: + '0xa10127f0e14159b2ad5c685c6461272a6e720fc2abe45d15d3b01ca2aeef2ee44e932fe6d1473607808dd028739432c0006b2ec50f13a0f433273b6f08d5759d44d8277aad9663fe80f373630b6c487333f5a57cd7b0310dd858f05de32d8079', + depositDataRoot: + '0xb8010334d99364ce959077fd143be39c7e9e7a26cae42c983ab9f5122f3dd67c', + }, + { + pubkey: + '0xa51521ecc49a47f8124b9514bff1108a412bcb91fb68d665b4e99fe1021e8d5c7b9ae9c12f7053944384b593868c6946', + withdrawalCredentials: + '0x0100000000000000000000008ead0e8fec8319fd62c8508c71a90296efd4f042', + signature: + '0x877682114673b230fedcc758fc0a2388b3c1e118ab41d906fad0fcc4bd74b145f1f19defe32f6fac9bfc54491ebf0622091587dc0d2f2f3b6ff95a3c2e060f3a66385b9c1dee7af4950c5453f0f4d54e8c87de6ceb828bb1f90a5aac20af9f3b', + depositDataRoot: + '0x65804da937127af18df81788d7736e7bb7a53b387751615665307812bd55d59e', + }, + { + pubkey: + '0x9411b3579efdec6fe865d6d78dc564063a81a6c85b39cd5f0141fed8c590081d5538afe9eb2e29d725974397feb98bb4', + withdrawalCredentials: + '0x0100000000000000000000008ead0e8fec8319fd62c8508c71a90296efd4f042', + signature: + '0x994931c679fd0542cd0d8cc6f391e1f88830f365f2756c55888254b94be3fa23dfed4d2c0b38681dcb3603f5245462f30f0b69168999a5c32faed2f4b2e44f886030f643bd3e32e6f4e217477f640d90e8cc79e48dcbb6111276b28c73c41d71', + depositDataRoot: + '0x2cbe6a69bbd4606588a707ff0599d4001e15da5d79c22800ea29cc60b1a0f230', + }, + { + pubkey: + '0x8ae257ec2f4e1cc3ec5b7160f09f294c5b78c14b2dcfca5e905c25ad1ddaa0071f4ed0df0f96889ca34da7308d2335d7', + withdrawalCredentials: + '0x0100000000000000000000008ead0e8fec8319fd62c8508c71a90296efd4f042', + signature: + '0x86effb8be7ba32715bd68cddd5f4554c1446898f15886ed1dc6e413aeb15356fc0d8649f9f1aa5a0b6475efaf23fa7450b883118d536712addc34c5fe2b4e4545f6c14a662ae1cd13ab9c53631aed38ef48e9fd9e3e232c0e06b00ca9dd6410e', + depositDataRoot: + '0x12d45588d5b0f20cc34f94e2bbf4af748813cd4f8b6fc86b0d2596e55a7a11e0', + }, + { + pubkey: + '0xaf2d528d7f12e180334658baf63272725f2012ce5476990bc82eced85ecbe89e01e7ee47e02cb8db9d16c48c5fda6b69', + withdrawalCredentials: + '0x0100000000000000000000008ead0e8fec8319fd62c8508c71a90296efd4f042', + signature: + '0xa596a04c4d1bc721e6cbbfcf68488580162a644ce0a57c195560137fc4aa17eeca7aecc296843bd8e636aa99d84f0d0a02ca31f0f8e5d57c8373ad6c0b76180b82d27ac208ec75957da52c87fbb17cebf20aec02ff7caf383a6cb37e9f4911b7', + depositDataRoot: + '0x7bb13dccffb958b107ef5a8e56f20e3d4d91e35505e247b3fdc3a31f44dcc7a1', + }, + { + pubkey: + '0xa82295a10363818d8360d014f6cc0d1a6817ad9689dabb5d344418ae7487087c95abde42ec9ae5d91b869cc8d3c97d21', + withdrawalCredentials: + '0x0100000000000000000000008ead0e8fec8319fd62c8508c71a90296efd4f042', + signature: + '0x988ac3c6713e78b497d6fea053cbff226d7df1f03f8455aceb43cbcd78b734b15cef128b23c1881db3f0c12fa8c2c9a6121e4d336ed2f148ebf918fac7cd8dacb2e9db94252b7c373586e6c480fc854218066a210e836625d27f3bd1b5803920', + depositDataRoot: + '0xfe00d823213e9a456ba8afd5c487101e1387def0b70502d54dd1695376f07e51', + }, + { + pubkey: + '0xa4bbef25dd5aa10d5663fd7dde738f50c2dd026ab2b52e28a5390af11e0baeab8db9e64017d13be84478b4a9e71be99d', + withdrawalCredentials: + '0x0100000000000000000000008ead0e8fec8319fd62c8508c71a90296efd4f042', + signature: + '0xac8b7f0b2e74f5a6d0c1c27d88b45496560372d5fc1635f503a53d62a44d261c346af0bdad1567c520161d45fb0a33660fb4aa8a6659a0a085b45460f3220f623ab301ab32a2a6dffd191423f2a3ed8a66308eade87e68ffa8b520d1b4c5b271', + depositDataRoot: + '0xe6c8838960eb553b5ca1a819ff8e093b0ec05f2fa7fa43928833a9b8d02784c5', + }, + { + pubkey: + '0x8245a537e592e1e1d01686c5bfaa730327b84e827a18b891db37437f1c1c6e6e27e5bfd3703e00fe4f4e9ff06e5d9cfe', + withdrawalCredentials: + '0x0100000000000000000000008ead0e8fec8319fd62c8508c71a90296efd4f042', + signature: + '0x8f5928ffe56f11260ea1411ad025de7652aa8d89a7b164b1a8f66bd4f84b2b50cf078921dc0ecdc559994297bf3a250a19b1adfd8745381e641c3c262181434ecd3c4f073810d509662959f2793900d364e2375022b61ea58ed9d19a2f3479d2', + depositDataRoot: + '0x998cef58a606d1e088a73a977c2b746b557ebdab2e1da2be227200583164d23c', + }, + { + pubkey: + '0xafa99b5577d57bf0a0b955a621b017b60593bbcd17e40a70b90d3009a944c405c2b199928642dd6b0541c23df5a09977', + withdrawalCredentials: + '0x0100000000000000000000008ead0e8fec8319fd62c8508c71a90296efd4f042', + signature: + '0xb21d43931e79a4efb850433f66b1db56610cca17ef05ee4f65a26f2d609042c04c31bd1be37ea75d5fe0a8ee7e5ed09308cee1bcd9a5341f2a3a46d618ba9e47bb56525f4aad955f91d38a45c9b443f3cb282288e3b958b5617dcc3282bb8721', + depositDataRoot: + '0x40adae5add2557c8ed4d0163ba017dd27baedcc2220a6eef8e11eb766775022a', + }, + { + pubkey: + '0x8548f2e2f1b2fdf6b1033b5bf6bd9fa7c2017de000c5f85d0103e16133f3f38e194f303293933123d0ba4fe9744cce92', + withdrawalCredentials: + '0x0100000000000000000000008ead0e8fec8319fd62c8508c71a90296efd4f042', + signature: + '0x8ec2fba70324d991efc784ee2082bf4a4ec271525927435ed8b0674544628b3fecdd0f46069d69a3055438f4b36f49da0c5537eff0a0c076db003e00fde1198ad527d2d456c1a9443b1a132bf6541a6bea481cd8f2590373ee573996197c4283', + depositDataRoot: + '0x5cdfe6f4099fdf6d12d7202dc930dfdec9d2efccef076ac42b8a0e9f49ccee65', + }, + { + pubkey: + '0x8c74c9742f8c464a8469cb3802b354c05622090bc84272b10be268baaf3762c8d6fa607a6cefc8d3d5f304750439d968', + withdrawalCredentials: + '0x0100000000000000000000008ead0e8fec8319fd62c8508c71a90296efd4f042', + signature: + '0x803e030f80c219f47cb1d79729b107bd81bf67a50fe146dafaaeb02506fc5a3e5b74f295836dbcc500a79cf26c9f1f521590627b511c915020408100280470323a127f9bd3662eb000e23ef176454b55d1261879b04ba94b6a640e24e054a2f6', + depositDataRoot: + '0x4aabf0c232c3104b2f1627cd5f8e4566dbd87f5e2a5af096bb1ef3a4036145db', + }, + { + pubkey: + '0x82029b3a16aed0b1b58c37f2252b4d7415614cd1ee444f4b9a9b1b1e7a4d8bd2a019414b66d46b63b625f7f5c96d4256', + withdrawalCredentials: + '0x0100000000000000000000008ead0e8fec8319fd62c8508c71a90296efd4f042', + signature: + '0x854cb318106f29b49f4cced38d7848e460cf0a992ffb5438d03d23c01625c63c45b224d74d79edb9bc1d89402a1266430f6833f30985067cf203158fdc296a6a0598fa8965c3e7bd28463f2418a583de1ec81d960e8d5c568fb88ba189e9570f', + depositDataRoot: + '0x5821fc19effb5a536be7399f21a7ff057a1497341a3db4f11dec76f0bc28378a', + }, + { + pubkey: + '0x8b1ba3b72dcefef5a18082e127dbf5297f971d12f01dc8a58bfb2296826b40fb2687b8acbfc8c3d893e9b1a1f04ad323', + withdrawalCredentials: + '0x0100000000000000000000008ead0e8fec8319fd62c8508c71a90296efd4f042', + signature: + '0xa2b4349fe7e7aec14f697ba82a62a4c47b6c65b1a4a8dd476a5296aad59787f10083608cf3a6deb70dd8b6d5abb286fe0864b26b3347ad36484dbb7986d763ba992397f70276dd37ea7b1cc738eb799c5892c6c233c9f4431a00520072826a43', + depositDataRoot: + '0x4464a121c10bdb13c75392e166c3f1a0f5f640d90d8f3df26b2d3333b00fa580', + }, + { + pubkey: + '0x856be8761baaae096b0473eddc93e1e99910bf0c1b850d22f30881dafbf7ae74eebf6dc7cc6d4f70f01bf00e202475fa', + withdrawalCredentials: + '0x0100000000000000000000008ead0e8fec8319fd62c8508c71a90296efd4f042', + signature: + '0x912365d4aed2bddcfc533d9d9587606f2cac7e1c48bac8a9eafcbe218eb1f09a7fc35d17fb3ed64eeec4d2e4c022a93801bbaadfcbae52b859ff2d032577b98bb98c7d374092f706e7b2f8399616932b16cb9ab7bb43d8df585fe1fe7a1c0124', + depositDataRoot: + '0x0ac97ced8ecc2237fd301e69894feeb85de71da08d40e21ee31529d4d9d7835b', + }, + { + pubkey: + '0x8794f2a3ccf056ac37e00cb840c25c1b60416fbf36ff7618d76403c6975096baeeb8ce3899f38bf605e747e30de7aab4', + withdrawalCredentials: + '0x0100000000000000000000008ead0e8fec8319fd62c8508c71a90296efd4f042', + signature: + '0xabbbfe9b867b51f38f62ee73595d3b33fae281d064e5a3af9b9a4ee47c33d413e328cd3f43181de5a60a6c69dde312f519db98d865cd52e942207e7de040b9db858161f85b33d57732a8abb540b9073ca409cb4a52e5b50634e9e5e445ef916a', + depositDataRoot: + '0xf69b17a90b44ec1bc5329ea51d6b59f879d3b97dbbb5dbb4371e3d24704c9fe5', + }, + { + pubkey: + '0xa0efa257a4181b195440dc3a1a12b734d32fe7a5a9bd2530fc06d438f56742cb3b979d1b181a674052abc8b16ec0caf6', + withdrawalCredentials: + '0x0100000000000000000000008ead0e8fec8319fd62c8508c71a90296efd4f042', + signature: + '0x8c6b16f8ff0827524fe288ab9a26b9a93bb693db8783420d03b4b5ca569a12cde66ef7e5879a84b4d374af940a5fe0df1379c09fedaa7a00229edfdc3d7a4ccf2aa7c1a80fa273782854b4303e3bd21fe2daa97f37bf97db6e2328b47b4cbbea', + depositDataRoot: + '0x1ae1232267d1fe813ff6a1d551e53386ba8c68d8107982a5e987af9609750fc6', + }, + { + pubkey: + '0x883ca1959878c4fb8ec57d91e8c4620973374411c5a2aa8071ebcc29f9310a5840768cb2efae5382ab82ac7d109f13b9', + withdrawalCredentials: + '0x0100000000000000000000008ead0e8fec8319fd62c8508c71a90296efd4f042', + signature: + '0xa05c551e30ad904cfd49b78fe4e8609123f6161c4b9738c2c606ebc111594ff569f33e3849684124dbc4e94ea9b104df020ddd885786b482487619bde3c51d55f376e8a77f17b9157a7bba4c7f5098746d615e207e7963b80bf49025eff07ed5', + depositDataRoot: + '0x876f11b5e5965237a8359ea937806e80360fae3b295b15bb997b9194701a22ea', + }, + { + pubkey: + '0xb6397284a5218013fe98172d27be3723d247d6c9f7f117cc250900fe560f7b5c20311c80264ceaac415c8f254c4f40dc', + withdrawalCredentials: + '0x0100000000000000000000008ead0e8fec8319fd62c8508c71a90296efd4f042', + signature: + '0x83f118e22e2b042eb83e91400eb624bdc85936c7c25dbebd82f20b98a5597a1a5d391e3dd71f9bd0d90bcb456ddfc62a064bbe65f29e18e6ae72535e7130c6878d420f8611e41c286e0454c2c4a4c0fc57b0909b435496934f25c336a9dea5e8', + depositDataRoot: + '0xe846507ab8b2a1f3233d0197576234ff447eb3d75e60a0911f51c403b9350260', + }, + { + pubkey: + '0x9107618fb9ef426c532b27bbc7f61cc8f7c36b4de0a34f18a116eed1a15ce159b11fdc5deaa7092a66b7debc029883a0', + withdrawalCredentials: + '0x0100000000000000000000008ead0e8fec8319fd62c8508c71a90296efd4f042', + signature: + '0x9032d242f173f1bf1428bfa34dfc017e32b6a8b085f628acba9d91c0035115b5c54d6663b433880682b93da263accc6212ed2c999e3471c63848199366c5facf026a82920aefa4b3b45503eaf09ad99fd2a4c51f7fc074864f2ea3655994721b', + depositDataRoot: + '0xae47feb399f1c4dcd580c72577c971cbb0cb4cbfbfb35c29d0e31736fcdd52c9', + }, + { + pubkey: + '0x97f4675c8b33872d70e9189f89aacbfc6a2a2b0033f2b1a4d02b422fe9dd4dd01fdd16efb391e03763b69c69b91e41bb', + withdrawalCredentials: + '0x0100000000000000000000008ead0e8fec8319fd62c8508c71a90296efd4f042', + signature: + '0x83f95fda2e90ef217bbda7c1125247357d7bcd08a2052f22e25e8ace4f3305f4385b466f6abffba68afa01e64ae1342712f64a5786c9e0d89f00db7aef8b666ce9a2583a188b352bfaf375bdfeb6af0d0b5f363fb118590972889e223666eb19', + depositDataRoot: + '0x996a78cc473784011ff167bf7c4a831b52923e9b4144361e87d91bf07d075696', + }, + { + pubkey: + '0x94c9d809a78def0a7542f995a2e30915f6f09576b1c99a503eac1a40f31266994ea331bee6e9e787172852282b24cf99', + withdrawalCredentials: + '0x0100000000000000000000008ead0e8fec8319fd62c8508c71a90296efd4f042', + signature: + '0x835411a188ab9be5d61375879cb191aaf9e158814e9f0ec8c8d32068f3cba678b0d842f010a1712a2e96836480adbf4918e5fd6c3f080dc3a86318f6c308d12636c7fdc3fffbdfb95812728af593f382060ea89276facd840c615f47a3fa2bd2', + depositDataRoot: + '0x36d3bc7d9ab0f7aee133e93f074925bd23bb23444771b953d230e893af487865', + }, + { + pubkey: + '0x881466c4ede19c0cd04b57d735d19143edf6141f67f8422478a161a3aaf1b9294f53ff2931184bb005d6ffef723e55c4', + withdrawalCredentials: + '0x0100000000000000000000008ead0e8fec8319fd62c8508c71a90296efd4f042', + signature: + '0x85a8959210b3126ec116d751113725eaaf74f2d611041facfccdc67ac92b8f1c666a649d717271da8fded95fb9b4230801d450a8cb087c25928e3936709bcdccf1f36916df2ca9b342ad9734480f6cb7309e8f26dd489bbd6139dfdd965c2c1e', + depositDataRoot: + '0xcf55c58cd8963413e9a10243a2514fb77dee565c01ed1acd4d05e7bd8ab850a9', + }, + { + pubkey: + '0x958937c1059860821de619e6ee61a647ff33523d670806ab1aec8edfeb13faca944a612ebfe0a359fdc596d70e0b2516', + withdrawalCredentials: + '0x0100000000000000000000008ead0e8fec8319fd62c8508c71a90296efd4f042', + signature: + '0x8041f8a26e76cbac8e3d53330968a80bca2cf2b3e05aac369a5819b34a9c1ddd041f57667655dc1660a8f79c53c2fe80166cc4859ab783b81705d43306699dce3b3bb997b1b5bcd09c3900057b38b945036f292976a607001125c805d1215bc3', + depositDataRoot: + '0xb40f33b765d67893ac8149caf5a15ff804c17ef4dfca3ce298030394080e7e18', + }, + { + pubkey: + '0x801f5200ccd592053ba6e8fc442309c7bf5d5a7c89b4ae0813fdd0d75e30939c77c108445cfc50598fd9d0eb29207a56', + withdrawalCredentials: + '0x0100000000000000000000008ead0e8fec8319fd62c8508c71a90296efd4f042', + signature: + '0xb5decddd9dddacea83e74f17db3bd35695d843019de63c9b30da4d95fc235fe90ffb1d50eaa980d8abcb96b6862c7855084ac22798537b44ad8610750c5fd145e9fb9b6c9d621cc93d8c83aa0d7643aecf58b6ea930df2b4be17072b0204f05f', + depositDataRoot: + '0x292f86f3ff84574a016f7c61003be70648865df6c1c6d929047517eab13c2661', + }, + { + pubkey: + '0xb4976ac8f9755cb85cdfd791f636511bd87244e5c93afcb7b69b75b888ea767910e5a4522b5a3aa81a2da51ba166aefb', + withdrawalCredentials: + '0x0100000000000000000000008ead0e8fec8319fd62c8508c71a90296efd4f042', + signature: + '0xb063a33cdd922d8da9279c27ac6914c24ed289f882cdba0595dc06be44c9acfad657f9e6b24b7e4986f415cad38883220b39d6670cdb7c1aff89f68d2cc3209c5b4dc929ecacb2484bd5c725863752a30f9f12a43f9c3ac5c4b01108323a6501', + depositDataRoot: + '0xfd575b934098cf01c7f16b7b8790d63af68ff0e94bc85e17774d3aed62656864', + }, + { + pubkey: + '0xb997141bd45fa4edc4246d6facebe8608ca4df46d1cb095ee09278ce4b1ce55e3f04a2d8fe8dcdb85416474dabfea915', + withdrawalCredentials: + '0x0100000000000000000000008ead0e8fec8319fd62c8508c71a90296efd4f042', + signature: + '0x84cd71555c729d91f2c2c241ef6e0a1c38683b10ff811f49b0fb9cfec31796c96f50eb4a585f95f6dccf7990d04f758a05493eb94e11c85964b0cdb57986636ee6405bece464a8d6e790de9af1e3bd84df784c2a742aaca37a725e6929bdab22', + depositDataRoot: + '0xdd62ae2901dfb98fbc7a18eedd5d9e6e3d40df52094d65cafdd9fc3df0f94048', + }, + { + pubkey: + '0xa5fadae6fae0d2eb3709e18741c4804acaafe6f685c49e598d2be523381fda8678ebdcf905417e32e007bb36bdfeab68', + withdrawalCredentials: + '0x0100000000000000000000008ead0e8fec8319fd62c8508c71a90296efd4f042', + signature: + '0x865423fb473e67849cd0d439886ea4be2236c596051c7b96d0b0f921d459f066b1d4b089754f4fdf72f0c4e6b83c49ab0d6e515c7a729c355ac881c237bf11ed1853d9ff45cb57c652b928fc7260b197a81b5d0875aef73f2a133bcdee1fd4f9', + depositDataRoot: + '0xfaa6aca095138a8fa1449bbc9cc2b0aba95a0a3d9644c262972a82f8d41e5ef4', + }, + { + pubkey: + '0xae8c6be869d23bf14a0f85e28ba3b94fed089bc85f83cf2cd87280ba8defa9bf2ae9bea8d8ff8bb96133b9529986960d', + withdrawalCredentials: + '0x0100000000000000000000008ead0e8fec8319fd62c8508c71a90296efd4f042', + signature: + '0xadd9f35acf6996a2ea4f660539620bacb5930522be05a3c70e6805bffbf4cc5a59e3aa0b961c99b1f644e1d7f187c25114b6299cc557b28ebc2dd82f348b791d7669fbfcf1763e74a91d4771a55c79d28069b88453d0143d4297ff0cb0cc7224', + depositDataRoot: + '0x6a29310647900458320294dc8174009c98e0af148070743bd9bcb425936b8097', + }, + { + pubkey: + '0xb4338229a52cc05475f0c286a313b37e1ab9ed83c774d3daceaa6c63f815062e8d31bf2b9593999ce168b0a544807825', + withdrawalCredentials: + '0x0100000000000000000000008ead0e8fec8319fd62c8508c71a90296efd4f042', + signature: + '0x93147471ecdd8f41b7c9c8070858698a8340c90582fb884bfed3cae5d3e09cf2b3755d455a13ac374b664ba183b181440dcb3f23c70c8ebd3247cac14b2fe8afff9d8fcee59f4b1988a189c502904d0f81db0068d37c5a347b4096ee8bd71da7', + depositDataRoot: + '0xe09b81f2a711303bdc0a8da62cbb54858d2a707b0a6879b944d067d9fc50c2a5', + }, + { + pubkey: + '0xa0da8aff80f7cb0ce0b5e0ca03edc292d89588624c4d62862bc3f1fa33f46d84071b7ff67266c8608d67699020e8b0bf', + withdrawalCredentials: + '0x0100000000000000000000008ead0e8fec8319fd62c8508c71a90296efd4f042', + signature: + '0x869a8831db5591eb49a0c0215f56231afcc141c54165c6375f68ed2d19fae96a2b0d2208c938a02c7e2148c4d590095000a5f8a00ed19732e3c4aaadefba5e55d06ece2609616bf8ec4fef914db47a360effd7a313a581e7b6bb14db7a93b82d', + depositDataRoot: + '0xe338702fdf04d583b23d94f70ff23146caa7d2527debcf3e7bc70f00e3381e87', + }, + { + pubkey: + '0x8498a47d75b9c4a37f8867496f37655465f5fa687cf217382fe8f6c118d3265f3f512deca2629b2286b8ea01cacae30a', + withdrawalCredentials: + '0x0100000000000000000000008ead0e8fec8319fd62c8508c71a90296efd4f042', + signature: + '0x8af164af59caa4ced3eeaf0c5e43f20011ebef30da4ae16be6bf0484e0881f3d835f26ba353e017ece16db3e4e24d4f11605e0d7b1ec513a33298e56f608af0e21636933a42f84d09a503793bac4762a2b69ed67d474c28adfe2b023c830ae5d', + depositDataRoot: + '0xce19f076205d248e29bf11b450f8c02305d87109e5be64e056fba8366f38e6de', + }, +]; + +export function calculateValidatorsAccumulator( + validatorsPubkeys: Uint8Array[], + eth1DepositIndexes: Uint8Array[], +): string { + const leaves = validatorsPubkeys.map((pubkey, i) => { + const validatorPubkey = bytesToHex(pubkey).padStart(96, '0'); + const eth1DepositIndex = bytesToHex(eth1DepositIndexes[i]).padStart( + 16, + '0', + ); + + return sha256( + '0x' + formatHex(validatorPubkey) + formatHex(eth1DepositIndex), + ); + }); + + return hashTreeRoot(leaves, 32); +} + +describe.only('ValidatorsAccumulator tests', async function () { + let blc: Contract; + let depositContract: Contract; + let pubkeys: Uint8Array[] = []; + let eth1DepositIndexes: Uint8Array[] = []; + + beforeEach(async function () { + const [signer] = await ethers.getSigners(); + + depositContract = new Contract( + '0x00000000219ab540356cBB839Cbe05303d7705Fa', + depositContractAbi, + signer, + ); + + const contractFactory = await ethers.getContractFactory( + 'ValidatorsAccumulator', + ); + blc = await contractFactory.deploy( + '0x00000000219ab540356cBB839Cbe05303d7705Fa', + ); + }); + + async function deposit(depositItem) { + console.log('Deposit', depositItem); + await ( + await blc.deposit( + depositItem.pubkey, + depositItem.withdrawalCredentials, + depositItem.signature, + depositItem.depositDataRoot, + { value: ethers.utils.parseEther('32').toString() }, + ) + ).wait(); + + const pubkey = hexToBytes(depositItem.pubkey); + const eth1DepositIndex = await depositContract.get_deposit_count(); + + pubkeys.push(pubkey); + eth1DepositIndexes.push(hexToBytes(eth1DepositIndex)); + } + + it('Deposit', async function () { + for (const depositItem of depositItems) { + await deposit(depositItem); + expect(await blc.get_validators_accumulator()).to.equal( + calculateValidatorsAccumulator(pubkeys, eth1DepositIndexes), + ); + } + }); +}); diff --git a/libs/typescript/ts-utils/ssz-utils.ts b/libs/typescript/ts-utils/ssz-utils.ts index 0f37f1d00..dcc684615 100644 --- a/libs/typescript/ts-utils/ssz-utils.ts +++ b/libs/typescript/ts-utils/ssz-utils.ts @@ -25,8 +25,28 @@ export function verifyMerkleProof( return formatHex(hash) === formatHex(hashTreeRoot); } -export function hashTreeRoot(_leaves: string[]) { - const leaves = [..._leaves]; +function nearestUpperPowerOfTwo(num) { + let power = Math.ceil(Math.log2(num)); + return Math.pow(2, power); +} + +export function hashTreeRoot(_leaves: string[], treeDepth: number): string { + const zero_hashes: string[] = []; + + zero_hashes[0] = '0x' + '0'.repeat(64); + + for (let height = 0; height < treeDepth - 1; height++) { + zero_hashes[height + 1] = sha256( + '0x' + formatHex(zero_hashes[height]) + formatHex(zero_hashes[height]), + ); + } + + const leavesLength = _leaves.length; + const treeLeaves = nearestUpperPowerOfTwo(leavesLength); + const leaves = [ + ..._leaves, + ...Array(treeLeaves - leavesLength).fill('0x' + '0'.repeat(64)), + ]; const UPPER_SIZE = leaves.length; let n = 2; @@ -41,7 +61,15 @@ export function hashTreeRoot(_leaves: string[]) { n *= 2; } - return leaves[0]; + let subtreeRoot = leaves[0]; + + for (let i = Math.log2(treeLeaves); i < treeDepth; i++) { + subtreeRoot = sha256( + '0x' + formatHex(subtreeRoot) + formatHex(zero_hashes[i]), + ); + } + + return subtreeRoot; } export async function jsonToSerializedBase64( From 1846d45dba385021e6f55f0114872218530feb91 Mon Sep 17 00:00:00 2001 From: Zahary Karadjov Date: Tue, 27 Jun 2023 15:13:40 +0300 Subject: [PATCH 3/5] docs(relay-node): Improve style and reference the official docker images --- Dockerfile.relay | 2 +- Makefile | 9 +++-- README.md | 89 ++++++++++++++---------------------------------- 3 files changed, 32 insertions(+), 68 deletions(-) diff --git a/Dockerfile.relay b/Dockerfile.relay index f9c9bc58c..382ea5e8f 100644 --- a/Dockerfile.relay +++ b/Dockerfile.relay @@ -34,6 +34,6 @@ COPY ./scripts ./scripts ENV INFURA_API_KEY=asd ETHERSCAN_API_KEY=asd RUN cd beacon-light-client/solidity && yarn hardhat compile -VOLUME relayvolume DendrETH/build +VOLUME relayvolume DendrETH/data ENTRYPOINT ["./relay/run-relay.sh"] diff --git a/Makefile b/Makefile index bdb61fd5e..758c649a8 100644 --- a/Makefile +++ b/Makefile @@ -3,12 +3,15 @@ yarn-check: echo "Please run yarn install"; exit 1; \ } -.PHONY: build-relay-image -build-relay-image: +.PHONY: dendreth-relay-node +dendreth-relay-node: nix run '.#docker-image-yarn.copyToDockerDaemon' nix run '.?submodules=1#docker-image-all.copyToDockerDaemon' - docker build -t relayimage -f Dockerfile.relay . + docker build -t metacraft/dendeth-relay-node -f Dockerfile.relay . + +publish-dendreth-relay-node: dendreth-relay-node + docker push metacraft/dendeth-relay-node test-validator-accumulator: yarn-check cd beacon-light-client/solidity && \ diff --git a/README.md b/README.md index 13ddf54c3..7c588ade5 100644 --- a/README.md +++ b/README.md @@ -119,45 +119,47 @@ You should see a [Hardhat simulation](https://hardhat.org/hardhat-runner/docs/ge sequentially processing all available updates. At the time of this writing, each update costs around 330K in gas. -### Run relayer +### Running the DendrETH relay node -To run the relayer you can execute +The DendrETH relay node efficiently generates proofs and publishes updates for +all blockchains supported by the DendrETH project. To simplify the process of +running a relay, we provide up-to-date Docker images. -```bash -make build-relay-image -``` +> You can also build a custom image yourself by executing the +> `make dendreth-relay-node` command within the development environment +> provided by this repository. -Which will build the relayimage for you. To run it +To run the relay node, please follow these steps: -You can also pull the image from docker hub - -``` -docker pull dimaranti/dendreth -``` +1. Ensure that you have Docker installed on your system. +2. Open a terminal or command prompt. +3. Execute the following command: ```bash -docker run -it --env-file .env -v relayvolume:/DendrETH/build relayimage +docker run --env-file .env -v relay-node-data:/DendrETH/data metacraft/dendreth-relay-node ``` -Passing the .env file with needed configurations. +This command assumes that you want to store all runtime data in a local directory +called `relay-node-data`. If you prefer to use a different directory, please modify +the command accordingly. -The .env file must contain the following things +The provided `.env` file must supply the following variables: -For accessing the networks and signing transactions: +#### For accessing the networks and signing transactions: ```bash USER_PRIVATE_KEY=private_key ALCHEMY_API_KEY=api_key ``` -To configure from which slot should the relayer start generating updates. And what step it should use +#### To configure the starting point and frequency of updates: ```bash INITIAL_SLOT=5355991 SLOTS_JUMP=64 ``` -To configure relayer what network it should follow. Currently the script only supports following one network. You can mannually run the tasks for publishing and updating on a second network. +#### To configure which networks should be followed: ```bash PRATTER=TRUE @@ -165,7 +167,10 @@ MAINNET=FALSE FOLLOW_NETWORK=pratter ``` -You can also provide for addresses on different networks if you skip a network transactions won't be broadcasted to it +Currently the scripts within the container support following a single network. +You can manually run the tasks for publishing updates on a second network. + +#### To specify the deployed instances of the DendrETH smart contracts: ```bash LC_GOERLI=0xf65B59bc947865490eF92D8461e8B5D0eA87c343 @@ -180,52 +185,8 @@ LC_CHIADO=0xAa5eeb05D0B080b366CB6feA00d16216B24FB9bE LC_EVMOS=0x8E4D36CD13015EA6F384cab3342156b3dC5d0a53 ``` -And also it needs to contain the hashi adapter addresses - -Sample `.env` - -``` -USER_PRIVATE_KEY=private_key -ALCHEMY_API_KEY=api_key -REDIS_HOST=localhost -REDIS_PORT=6379 -PROVER_SERVER_HOST=http://127.0.0.1 -PROVER_SERVER_PORT=5000 -INITIAL_SLOT=5860953 -SLOTS_JUMP=32 -PRATTER=TRUE -MAINNET=FALSE -LC_GOERLI=0xf65B59bc947865490eF92D8461e8B5D0eA87c343 -LC_OPTIMISTIC_GOERLI= -LC_BASE_GOERLI= -LC_ARBITRUM_GOERLI= -LC_SEPOLIA= -LC_MUMBAI= -LC_FUJI= -LC_FANTOM= -LC_ALFAJORES= -LC_BSC= -LC_AURORA= -LC_GNOSIS= -LC_CHIADO= -LC_EVMOS= -LC_MALAGA= -GOERLI_HASHI=0x4169ea397fe83F55e732E11390807b3722374f78 -OPTIMISTIC_HASHI='' -BASE_HASHI='' -ARBITRUM_HASHI='' -SEPOLIA_HASHI='' -MUMBAI_HASHI='' -FANTOM_HASHI='' -ALFAJORES_HASHI='' -CHIADO_HASHI='' -EVMOS_HASHI='' -MALAGA_HASHI='' -AURORA_HASHI='' -GNOSIS_HASHI='' -FUJI_HASHI='' -BSC_HASHI='' -``` +If you skip some of these variables, the relay node won't publish updates for +the particular network. ### How does the relayer work? From f7efbbcd28058aed09920c1545e08a322a6e405e Mon Sep 17 00:00:00 2001 From: Zahary Karadjov Date: Wed, 28 Jun 2023 19:24:36 +0300 Subject: [PATCH 4/5] chore(relay): rename the 'build' dir to 'data' --- Dockerfile.relay | 2 +- conf.d/programs.conf | 2 +- relay/run-relay.sh | 29 ++++++++++++++--------------- 3 files changed, 16 insertions(+), 17 deletions(-) diff --git a/Dockerfile.relay b/Dockerfile.relay index 382ea5e8f..01d943192 100644 --- a/Dockerfile.relay +++ b/Dockerfile.relay @@ -34,6 +34,6 @@ COPY ./scripts ./scripts ENV INFURA_API_KEY=asd ETHERSCAN_API_KEY=asd RUN cd beacon-light-client/solidity && yarn hardhat compile -VOLUME relayvolume DendrETH/data +VOLUME DendrETH/data ENTRYPOINT ["./relay/run-relay.sh"] diff --git a/conf.d/programs.conf b/conf.d/programs.conf index e647ec2f9..81dec8e81 100644 --- a/conf.d/programs.conf +++ b/conf.d/programs.conf @@ -7,7 +7,7 @@ stdout_logfile=./redis-server/redis.log [program:proverserver] autostart=false -command=proverServer %(ENV_PROVER_SERVER_PORT)s ./build/light_client.zkey +command=proverServer %(ENV_PROVER_SERVER_PORT)s ./data/light_client.zkey stderr_logfile=./prover_server.log stdout_logfile=./prover_server.log diff --git a/relay/run-relay.sh b/relay/run-relay.sh index ae9049cdb..929df30ad 100755 --- a/relay/run-relay.sh +++ b/relay/run-relay.sh @@ -11,12 +11,12 @@ calculate_checksum() { download_zkey_file() { echo "Downloading zkey file from http://dendreth.metacraft-labs.com/capella_94.zkey ..." - curl http://dendreth.metacraft-labs.com/capella_94.zkey > "build/light_client.zkey" + curl http://dendreth.metacraft-labs.com/capella_94.zkey > "data/light_client.zkey" - CALCULATED_ZKEY_SUM=$(calculate_checksum build/light_client.zkey) + CALCULATED_ZKEY_SUM=$(calculate_checksum data/light_client.zkey) if [ "$ZKEY_B3SUM_SUM" = "$CALCULATED_ZKEY_SUM" ]; then - echo "Zkey file downloaded successfully to build/light_client.zkey" + echo "Zkey file downloaded successfully to data/light_client.zkey" else echo "Failed to download zkey file from http://dendreth.metacraft-labs.com/capella_94.zkey" exit 1 @@ -26,47 +26,46 @@ download_zkey_file() { download_dat_file() { echo "Downloading .dat file from https://media.githubusercontent.com/media/metacraft-labs/DendrETH-build-artifacts/master/light_client_cpp/light_client.dat ..." - curl -k https://media.githubusercontent.com/media/metacraft-labs/DendrETH-build-artifacts/master/light_client_cpp/light_client.dat > "build/light_client.dat" + curl -k https://media.githubusercontent.com/media/metacraft-labs/DendrETH-build-artifacts/master/light_client_cpp/light_client.dat > "datalight_client.dat" - CALCULATED_DAT_SUM=$(calculate_checksum build/light_client.dat) + CALCULATED_DAT_SUM=$(calculate_checksum data/light_client.dat) if [ "$DAT_B3SUM_SUM" = "$CALCULATED_DAT_SUM" ]; then - echo ".dat file downloaded successfully to build/light_client.dat" + echo ".dat file downloaded successfully to data/light_client.dat" else echo "Failed to download .dat file from https://media.githubusercontent.com/media/metacraft-labs/DendrETH-build-artifacts/master/light_client_cpp/light_client.dat" exit 1 fi } -if [ ! -f "build/light_client.zkey" ]; then +if [ ! -f "data/light_client.zkey" ]; then download_zkey_file else - CALCULATED_ZKEY_SUM=$(calculate_checksum build/light_client.zkey) + CALCULATED_ZKEY_SUM=$(calculate_checksum data/light_client.zkey) echo $CALCULATED_ZKEY_SUM if [ "$ZKEY_B3SUM_SUM" = "$CALCULATED_ZKEY_SUM" ]; then - echo "Using cached zkey file at build/light_client.zkey" + echo "Using cached zkey file at data/light_client.zkey" else echo "Wrong version of light_client.zkey cached downloading again..." download_zkey_file fi fi -if [ ! -f "build/light_client.dat" ]; then +if [ ! -f "data/light_client.dat" ]; then download_dat_file else - CALCULATED_DAT_SUM=$(calculate_checksum build/light_client.dat) + CALCULATED_DAT_SUM=$(calculate_checksum data/light_client.dat) echo $CALCULATED_DAT_SUM if [ "$DAT_B3SUM_SUM" = "$CALCULATED_DAT_SUM" ]; then - echo "Using cached .dat file at build/light_client.dat" + echo "Using cached .dat file at data/light_client.dat" else echo "Wrong version of light_client.dat cached downloading again..." download_dat_file fi fi -cp relay/light_client build/light_client - -cp build/light_client.dat light_client.dat +cp relay/light_client data/light_client +cp data/light_client.dat light_client.dat if [[ -z "$REDIS_HOST" ]] && [[ -z "$REDIS_PORT" ]]; then echo "REDIS_HOST and REDIS_PORT environment variables are not set. Using default values." From b415ce0772c6934a5cc1f38de821ac9873189420 Mon Sep 17 00:00:00 2001 From: Zahary Karadjov Date: Wed, 28 Jun 2023 19:29:25 +0300 Subject: [PATCH 5/5] docs(relay-node): provide an example .env file --- .env.example | 40 ++++++++++++++++++++++++++++++++++++++++ README.md | 3 +++ 2 files changed, 43 insertions(+) create mode 100644 .env.example diff --git a/.env.example b/.env.example new file mode 100644 index 000000000..0cec152fb --- /dev/null +++ b/.env.example @@ -0,0 +1,40 @@ +USER_PRIVATE_KEY=private_key +ALCHEMY_API_KEY=api_key +REDIS_HOST=localhost +REDIS_PORT=6379 +PROVER_SERVER_HOST=http://127.0.0.1 +PROVER_SERVER_PORT=5000 +INITIAL_SLOT=5860953 +SLOTS_JUMP=32 +PRATTER=TRUE +MAINNET=FALSE +LC_GOERLI=0xf65B59bc947865490eF92D8461e8B5D0eA87c343 +LC_OPTIMISTIC_GOERLI= +LC_BASE_GOERLI= +LC_ARBITRUM_GOERLI= +LC_SEPOLIA= +LC_MUMBAI= +LC_FUJI= +LC_FANTOM= +LC_ALFAJORES= +LC_BSC= +LC_AURORA= +LC_GNOSIS= +LC_CHIADO= +LC_EVMOS= +LC_MALAGA= +GOERLI_HASHI=0x4169ea397fe83F55e732E11390807b3722374f78 +OPTIMISTIC_HASHI='' +BASE_HASHI='' +ARBITRUM_HASHI='' +SEPOLIA_HASHI='' +MUMBAI_HASHI='' +FANTOM_HASHI='' +ALFAJORES_HASHI='' +CHIADO_HASHI='' +EVMOS_HASHI='' +MALAGA_HASHI='' +AURORA_HASHI='' +GNOSIS_HASHI='' +FUJI_HASHI='' +BSC_HASHI='' diff --git a/README.md b/README.md index 7c588ade5..c1ae49297 100644 --- a/README.md +++ b/README.md @@ -188,6 +188,9 @@ LC_EVMOS=0x8E4D36CD13015EA6F384cab3342156b3dC5d0a53 If you skip some of these variables, the relay node won't publish updates for the particular network. +For a full list of supported ENV variables, please see the provided +[example .env file](.env.example). + ### How does the relayer work? We utilize BullMQ for our system.