diff --git a/Makefile b/Makefile index ed0d91ed6..05dd4bd28 100644 --- a/Makefile +++ b/Makefile @@ -30,10 +30,12 @@ start-bsc: cli/index.js clean cli/index.js prepare cli/index.js start near-node - cli/index.js start binance-smart-chain + cli/index.js start binance-smart-chain \ + --eth-node-url https://data-seed-prebsc-1-s1.binance.org:8545 \ + --eth-master-sk 0x2bdd21761a483f71054e14f5b827213567971c676928d9a1808cbfa4b7501200 # deploy contracts -full-bsc-contracts: +full-contracts: cli/index.js init-near-contracts cli/index.js init-eth-ed25519 cli/index.js init-eth-client --eth-client-lock-eth-amount 1000 --eth-client-lock-duration 10 @@ -61,6 +63,6 @@ build-eth-client: cd contracts/near/eth-client && sudo ./build.sh test-eth-client: - cd contracts/near/eth-client && ./test.sh + cd contracts/near/eth-client && sudo ./test.sh .PHONY: help init yarn-init gen-contracts start-bsc full-bsc-contracts light-bsc-contracts start-relayer stop-all build-eth-client test-eth-client start-ethash \ No newline at end of file diff --git a/cli/commands/start/binance-smart-chain.js b/cli/commands/start/binance-smart-chain.js index a8d93d0de..c9e83c57f 100644 --- a/cli/commands/start/binance-smart-chain.js +++ b/cli/commands/start/binance-smart-chain.js @@ -5,9 +5,17 @@ class StartBinanceSmartChainNodeCommand { nearClientValidateHeader = 'true' } + if (ethNodeUrl === '') { + throw new Error('--eth-node-url not set') + } + + if (ethMasterSk === '') { + throw new Error('--eth-master-sk not set') + } + return { - ethNodeUrl: ethNodeUrl !== '' ? ethNodeUrl : 'https://data-seed-prebsc-1-s1.binance.org:8545', - ethMasterSk: ethMasterSk !== '' ? ethMasterSk : '0x2bdd21761a483f71054e14f5b827213567971c676928d9a1808cbfa4b7501200', + ethNodeUrl: ethNodeUrl, + ethMasterSk: ethMasterSk, nearClientValidateHeader: nearClientValidateHeader, nearClientValidateHeaderMode: 'bsc' } diff --git a/contracts/near/eth-client/src/lib.rs b/contracts/near/eth-client/src/lib.rs index 25ebe4cd1..7f8510ccd 100644 --- a/contracts/near/eth-client/src/lib.rs +++ b/contracts/near/eth-client/src/lib.rs @@ -1,10 +1,10 @@ use admin_controlled::Mask; use borsh::{BorshDeserialize, BorshSerialize}; use eth_types::*; +use libsecp256k1::{recover, Message, RecoveryId, Signature}; use near_sdk::collections::UnorderedMap; use near_sdk::AccountId; use near_sdk::{env, near_bindgen, PanicOnDefault}; -use libsecp256k1::{RecoveryId, Signature, Message, recover}; use tiny_keccak::{Hasher, Keccak}; #[cfg(not(target_arch = "wasm32"))] @@ -67,7 +67,7 @@ const PAUSE_ADD_BLOCK_HEADER: Mask = 1; #[near_bindgen] #[derive(BorshDeserialize, BorshSerialize, PanicOnDefault)] -pub struct EthClient { +pub struct EthClient { /// Whether client validates the PoW or POSA when accepting the header. Should only be set to `false` /// for debugging, testing, diagnostic purposes when used with Ganache or in PoA testnets validate_header: bool, @@ -109,7 +109,7 @@ pub struct EthClient { trusted_signer: Option, /// Mask determining all paused functions paused: Mask, - /// Store the bsc epoch header key + /// Store the bsc epoch header key epoch_header: H256, /// chain id chain_id: u64, @@ -117,6 +117,49 @@ pub struct EthClient { #[near_bindgen] impl EthClient { + #[private] + #[init(ignore_state)] + pub fn migrate_state() -> Self { + // Old EthClient + #[derive(BorshDeserialize)] + pub struct OldEthClient { + validate_ethash: bool, + dags_start_epoch: u64, + dags_merkle_roots: Vec, + best_header_hash: H256, + hashes_gc_threshold: u64, + finalized_gc_threshold: u64, + num_confirmations: u64, + canonical_header_hashes: UnorderedMap, + all_header_hashes: UnorderedMap>, + headers: UnorderedMap, + infos: UnorderedMap, + trusted_signer: Option, + paused: Mask, + } + + // Deserialize the state using the old contract structure. + let old_contract: OldEthClient = env::state_read().expect("Old state doesn't exist"); + Self { + validate_header: old_contract.validate_ethash, + validate_header_mode: String::from(""), + dags_start_epoch: old_contract.dags_start_epoch, + dags_merkle_roots: old_contract.dags_merkle_roots, + best_header_hash: old_contract.best_header_hash, + hashes_gc_threshold: old_contract.hashes_gc_threshold, + finalized_gc_threshold: old_contract.finalized_gc_threshold, + num_confirmations: old_contract.num_confirmations, + canonical_header_hashes: old_contract.canonical_header_hashes, + all_header_hashes: old_contract.all_header_hashes, + headers: old_contract.headers, + infos: old_contract.infos, + trusted_signer: old_contract.trusted_signer, + paused: old_contract.paused, + epoch_header: H256([0; 32].into()), + chain_id: 0, + } + } + #[init] pub fn init( #[serializer(borsh)] validate_header: bool, @@ -137,13 +180,13 @@ impl EthClient { let mut epoch_header: H256 = H256([0; 32].into()); // check if the current mode is bsc POSA, then store the epoch header. - if validate_header_mode == String::from("bsc"){ - if !EthClient::is_epoch(header.number){ + if validate_header_mode == String::from("bsc") { + if !EthClient::is_epoch(header.number) { panic!("The initial header for POSA have to be an epoch header"); } epoch_header = header.hash.unwrap(); } - + let mut res = Self { validate_header_mode, epoch_header: epoch_header, @@ -258,13 +301,13 @@ impl EthClient { fn record_header(&mut self, header: BlockHeader) { let best_info = self.infos.get(&self.best_header_hash).unwrap(); let header_hash = header.hash.unwrap(); - let header_number = header.number; + let header_number = header.number; if header_number + self.finalized_gc_threshold < best_info.number { panic!("Header is too old to have a chance to appear on the canonical chain."); } - if EthClient::is_epoch(header.number) && self.validate_header_mode == String::from("bsc"){ - self.epoch_header = header.hash.unwrap(); + if EthClient::is_epoch(header.number) && self.validate_header_mode == String::from("bsc") { + self.epoch_header = header.hash.unwrap(); } let parent_info = self .infos @@ -380,44 +423,45 @@ impl EthClient { prev: &BlockHeader, dag_nodes: &[DoubleNodeWithMerkleProof], ) -> bool { - if self.validate_header_mode == String::from("ethash") { - // validate ethash POW headers - return self.verify_header_pow(&header, &prev, &dag_nodes); - }else if self.validate_header_mode == String::from("bsc") { - // validate bsc POSA headers - return self.verify_header_bsc(&header, &prev); + match &self.validate_header_mode[..] { + "ethash" => return self.verify_header_ethash(&header, &prev, &dag_nodes), + "bsc" => return self.verify_header_bsc(&header, &prev), + _ => return false, } - false + + // if self.validate_header_mode == String::from("ethash") { + // // validate ethash POW headers + // return self.verify_header_ethash(&header, &prev, &dag_nodes); + // }else if self.validate_header_mode == String::from("bsc") { + // // validate bsc POSA headers + // return self.verify_header_bsc(&header, &prev); + // } + // false } - fn verify_basic( - &self, - header: &BlockHeader, - prev: &BlockHeader - ) -> bool{ + fn verify_basic(&self, header: &BlockHeader, prev: &BlockHeader) -> bool { header.gas_used <= header.gas_limit - && header.gas_limit >= U256(5000.into()) - && header.timestamp > prev.timestamp - && header.number == prev.number + 1 - && header.parent_hash == prev.hash.unwrap() + && header.gas_limit >= U256(5000.into()) + && header.timestamp > prev.timestamp + && header.number == prev.number + 1 + && header.parent_hash == prev.hash.unwrap() } // seal and hash bsc header. - fn seal_hash(&self, header: &BlockHeader, chain_id: U256)-> [u8; 32]{ - let d = SealData{chain_id, header}; + fn seal_hash(&self, header: &BlockHeader, chain_id: U256) -> [u8; 32] { + let d = SealData { chain_id, header }; d.seal_hash() } // Verify POSA of the binance chain header. fn verify_header_bsc(&self, header: &BlockHeader, prev: &BlockHeader) -> bool { - // The genesis block is the always valid dead-end if header.number == 0 { return true; } - + // verift basic header properties. - if !self.verify_basic(header, prev){ + if !self.verify_basic(header, prev) { return false; } @@ -425,60 +469,59 @@ impl EthClient { let is_epoch = EthClient::is_epoch(header.number); let signers_bytes = header.extra_data.len() - (extra_vanity + extra_seal); // check it is not an epoch header but contains the signers. - if !is_epoch && signers_bytes != 0{ + if !is_epoch && signers_bytes != 0 { return false; } - + // check if it is an epoch header and contains the signers. - if is_epoch && signers_bytes % validator_bytes_length != 0{ + if is_epoch && signers_bytes % validator_bytes_length != 0 { return false; } - + // Ensure that the mix digest is zero as we don't have fork protection currently if header.mix_hash != H256([0; 32].into()) { return false; } - + // uncles_hash should be zero if header.uncles_hash == H256([0; 32].into()) { return false; } - + // Verify that the gas limit is <= 2^63-1 if header.gas_limit > U256((0x7fffffffffffffff as u64).into()) { return false; } - + let prev_gas_limit = format!("{}", prev.gas_limit).parse::().unwrap(); let header_gas_limit = format!("{}", header.gas_limit).parse::().unwrap(); - let diff = (prev_gas_limit-header_gas_limit).abs(); + let diff = (prev_gas_limit - header_gas_limit).abs(); let limit = prev_gas_limit / 256; - + // Verify that the gas limit remains within allowed bounds if diff >= limit { return false; } - - if !self.is_author(&header){ - return false + + if !self.is_author(&header) { + return false; } - + self.is_validator(&header) } - + // check if the block is an epoch header. - fn is_epoch(number: u64)->bool{ - number%200==0 + fn is_epoch(number: u64) -> bool { + number % 200 == 0 } - + // check if the author is the signer. - fn is_author(&self, header: &BlockHeader) -> bool{ - + fn is_author(&self, header: &BlockHeader) -> bool { let extra_seal = 65; let seal_hash = self.seal_hash(header, U256(self.chain_id.into())); // get the signature from header extra_data - let signature = header.extra_data[header.extra_data.len()-extra_seal..].to_vec(); + let signature = header.extra_data[header.extra_data.len() - extra_seal..].to_vec(); let mut sig = [0u8; 65]; sig.copy_from_slice(&signature[..]); @@ -487,7 +530,7 @@ impl EthClient { let mut s = [0u8; 32]; r.copy_from_slice(&signature[0..32]); s.copy_from_slice(&signature[32..64]); - + let rec_id = RecoveryId::parse(v).unwrap(); let mut data = [0u8; 64]; data[0..32].copy_from_slice(&r[..]); @@ -508,12 +551,12 @@ impl EthClient { H160(address.into()) == header.author } - fn get_epoch_header(&self) -> BlockHeader{ + fn get_epoch_header(&self) -> BlockHeader { self.headers.get(&self.epoch_header).unwrap() } // check if the auther address is valid and is in the validator set. - fn is_validator(&self, header: &BlockHeader) -> bool{ + fn is_validator(&self, header: &BlockHeader) -> bool { let (extra_vanity, extra_seal, address_size) = (32, 65, 20); let epoch_header = if EthClient::is_epoch(header.number) { @@ -525,26 +568,27 @@ impl EthClient { if !self.is_in_validator_set(&epoch_header, header.author) { return false; } - - + // skip difficulty verification - if self.validate_header{ + if self.validate_header { // Ensure that the difficulty corresponds to the turn-ness of the signer - let validators = - epoch_header.extra_data[extra_vanity..(epoch_header.extra_data.len() - extra_seal)].to_vec(); - + let validators = epoch_header.extra_data + [extra_vanity..(epoch_header.extra_data.len() - extra_seal)] + .to_vec(); + // Get validator offset postion. let offset = (header.number % ((validators.len() / address_size) as u64)) as usize; - + // validate the current author if it's turn with the difficulty. let (diff_in_turn, diff_no_turn) = (2, 1); - let is_turn = Address::from(&validators[(offset * address_size)..((offset + 1) * address_size)]); - - if is_turn == header.author && header.difficulty != U256(diff_in_turn.into()){ + let is_turn = + Address::from(&validators[(offset * address_size)..((offset + 1) * address_size)]); + + if is_turn == header.author && header.difficulty != U256(diff_in_turn.into()) { return false; } - - if !(is_turn == header.author) && header.difficulty != U256(diff_no_turn.into()){ + + if !(is_turn == header.author) && header.difficulty != U256(diff_no_turn.into()) { return false; } } @@ -552,7 +596,7 @@ impl EthClient { } /// Verify PoW of the header. - fn verify_header_pow( + fn verify_header_ethash( &self, header: &BlockHeader, prev: &BlockHeader, @@ -573,7 +617,7 @@ impl EthClient { U256((result.0).0.into()) < U256(ethash::cross_boundary(header.difficulty.0)) && (!self.validate_header || (header.difficulty < prev.difficulty * 101 / 100 - && header.difficulty > prev.difficulty * 99 / 100)) + && header.difficulty > prev.difficulty * 99 / 100)) && header.gas_limit < prev.gas_limit * 1025 / 1024 && header.gas_limit > prev.gas_limit * 1023 / 1024 && self.verify_basic(header, prev) @@ -620,20 +664,20 @@ impl EthClient { ); (H256(pair.0), H256(pair.1)) - } + } // check if the author is in the validators set. - fn is_in_validator_set (&self, epoch_header: &BlockHeader, add: Address) -> bool{ - + fn is_in_validator_set(&self, epoch_header: &BlockHeader, add: Address) -> bool { let (extra_vanity, extra_seal, address_size) = (32, 65, 20); - let validators = - epoch_header.extra_data[extra_vanity..(epoch_header.extra_data.len() - extra_seal)].to_vec(); - + let validators = epoch_header.extra_data + [extra_vanity..(epoch_header.extra_data.len() - extra_seal)] + .to_vec(); + for x in 0..(validators.len() / address_size) { let value = &validators[(x * address_size)..((x + 1) * address_size)]; let _add: Address = Address::from(value); - if _add == add{ - return true + if _add == add { + return true; } } false diff --git a/contracts/near/eth-client/src/tests.rs b/contracts/near/eth-client/src/tests.rs index 1a78fa01e..aba4f4398 100644 --- a/contracts/near/eth-client/src/tests.rs +++ b/contracts/near/eth-client/src/tests.rs @@ -162,12 +162,9 @@ lazy_static! { eloop.into_remote(); web3::Web3::new(transport) }; - static ref BSC_WEB3RS: web3::Web3 = { - let (eloop, transport) = web3::transports::Http::new( - "https://data-seed-prebsc-1-s1.binance.org:8545", - ) - .unwrap(); + let (eloop, transport) = + web3::transports::Http::new("https://data-seed-prebsc-1-s1.binance.org:8545").unwrap(); eloop.into_remote(); web3::Web3::new(transport) }; @@ -236,16 +233,17 @@ fn read_block_raw(filename: String) -> BlockWithProofsRaw { serde_json::from_reader(std::fs::File::open(std::path::Path::new(&filename)).unwrap()).unwrap() } -fn assert_hashes_equal_to_contract_hashes(contract: &EthClient, heights: &[u64], real_hashes: &[H256]) { +fn assert_hashes_equal_to_contract_hashes( + contract: &EthClient, + heights: &[u64], + real_hashes: &[H256], +) { let hashes_from_contract: Vec = heights .iter() .map(|height| contract.block_hash(*height).unwrap()) .collect(); - for (hash, hash_from_contract) in real_hashes - .into_iter() - .zip(hashes_from_contract.iter()) - { + for (hash, hash_from_contract) in real_hashes.into_iter().zip(hashes_from_contract.iter()) { assert_eq!(hash, hash_from_contract); } } @@ -254,7 +252,7 @@ fn assert_hashes_equal_to_contract_hashes(contract: &EthClient, heights: &[u64], fn add_dags_merkle_roots() { testing_env!(get_context(vec![], false)); let (blocks, _) = get_blocks(&WEB3RS, 400_000, 400_001); - + let chain_id = 3; let dmr = read_roots_collection(); let contract = EthClient::init( true, @@ -266,7 +264,7 @@ fn add_dags_merkle_roots() { 10, 10, None, - 97, + chain_id, ); assert_eq!(dmr.dag_merkle_roots[0], contract.dag_merkle_root(0)); @@ -289,7 +287,7 @@ fn add_blocks_2_and_3() { .iter() .map(|filename| read_block((&filename).to_string())) .collect(); - + let chain_id = 3; let mut contract = EthClient::init( true, String::from("ethash"), @@ -300,7 +298,7 @@ fn add_blocks_2_and_3() { 10, 10, None, - 97, + chain_id, ); for (block, proof) in blocks @@ -322,21 +320,17 @@ fn add_blocks_before_and_after_istanbul_fork() { testing_env!(get_context(vec![], false)); const FORK_HEIGHT_ISTANBUL: usize = 9_069_000; - let (blocks, hashes) = get_blocks( - &WEB3RS, - FORK_HEIGHT_ISTANBUL - 2, - FORK_HEIGHT_ISTANBUL + 2 - ); + let (blocks, hashes) = get_blocks(&WEB3RS, FORK_HEIGHT_ISTANBUL - 2, FORK_HEIGHT_ISTANBUL + 2); let blocks_with_proofs: Vec = [ format!("./src/data/proof_block_{}.json", FORK_HEIGHT_ISTANBUL - 1), format!("./src/data/proof_block_{}.json", FORK_HEIGHT_ISTANBUL), format!("./src/data/proof_block_{}.json", FORK_HEIGHT_ISTANBUL + 1), ] - .iter() - .map(|filename| read_block((&filename).to_string())) - .collect(); - + .iter() + .map(|filename| read_block((&filename).to_string())) + .collect(); + let chain_id = 3; let mut contract = EthClient::init( true, String::from("ethash"), @@ -347,7 +341,7 @@ fn add_blocks_before_and_after_istanbul_fork() { 10, 10, None, - 97, + chain_id, ); for (block, proof) in blocks @@ -358,7 +352,6 @@ fn add_blocks_before_and_after_istanbul_fork() { contract.add_block_header(block, proof.to_double_node_with_merkle_proof_vec()); } - let heights = [ FORK_HEIGHT_ISTANBUL as u64 - 1, FORK_HEIGHT_ISTANBUL as u64, @@ -378,18 +371,27 @@ fn add_blocks_before_and_after_nov11_2020_unannounced_fork() { let (blocks, hashes) = get_blocks( &WEB3RS, FORK_HEIGHT_UNANNOUNCED_NOV_11_2020 - 2, - FORK_HEIGHT_UNANNOUNCED_NOV_11_2020 + 2 + FORK_HEIGHT_UNANNOUNCED_NOV_11_2020 + 2, ); let blocks_with_proofs: Vec = [ - format!("./src/data/proof_block_{}.json", FORK_HEIGHT_UNANNOUNCED_NOV_11_2020 - 1), - format!("./src/data/proof_block_{}.json", FORK_HEIGHT_UNANNOUNCED_NOV_11_2020), - format!("./src/data/proof_block_{}.json", FORK_HEIGHT_UNANNOUNCED_NOV_11_2020 + 1), + format!( + "./src/data/proof_block_{}.json", + FORK_HEIGHT_UNANNOUNCED_NOV_11_2020 - 1 + ), + format!( + "./src/data/proof_block_{}.json", + FORK_HEIGHT_UNANNOUNCED_NOV_11_2020 + ), + format!( + "./src/data/proof_block_{}.json", + FORK_HEIGHT_UNANNOUNCED_NOV_11_2020 + 1 + ), ] - .iter() - .map(|filename| read_block((&filename).to_string())) - .collect(); - + .iter() + .map(|filename| read_block((&filename).to_string())) + .collect(); + let chain_id = 3; let mut contract = EthClient::init( true, String::from("ethash"), @@ -400,7 +402,7 @@ fn add_blocks_before_and_after_nov11_2020_unannounced_fork() { 10, 10, None, - 97, + chain_id, ); for (block, proof) in blocks @@ -425,10 +427,17 @@ fn add_block_diverged_until_ethashproof_dataset_fix() { testing_env!(get_context(vec![], false)); const HEIGHT_DIVERGED_BLOCK: usize = 11_703_828; - let (blocks, hashes) = get_blocks(&WEB3RS, HEIGHT_DIVERGED_BLOCK - 1, HEIGHT_DIVERGED_BLOCK + 1); + let (blocks, hashes) = get_blocks( + &WEB3RS, + HEIGHT_DIVERGED_BLOCK - 1, + HEIGHT_DIVERGED_BLOCK + 1, + ); // Jan 22 2021 - let block_with_proof = read_block(format!("./src/data/proof_block_{}.json", HEIGHT_DIVERGED_BLOCK)); - + let block_with_proof = read_block(format!( + "./src/data/proof_block_{}.json", + HEIGHT_DIVERGED_BLOCK + )); + let chain_id = 3; let mut contract = EthClient::init( true, String::from("ethash"), @@ -439,11 +448,17 @@ fn add_block_diverged_until_ethashproof_dataset_fix() { 500, 20, None, - 97, + chain_id, ); - contract.add_block_header(blocks[1].clone(), block_with_proof.to_double_node_with_merkle_proof_vec()); - assert_eq!(hashes[1], contract.block_hash(HEIGHT_DIVERGED_BLOCK as u64).unwrap()); + contract.add_block_header( + blocks[1].clone(), + block_with_proof.to_double_node_with_merkle_proof_vec(), + ); + assert_eq!( + hashes[1], + contract.block_hash(HEIGHT_DIVERGED_BLOCK as u64).unwrap() + ); } #[test] @@ -459,7 +474,7 @@ fn add_400000_block_only() { // ethash result: 0x00000000000ca599ebe9913fa00da78a4d1dd2fa154c4fd2aad10ccbca52a2a1 // Proof length: 24 // [400000.json] - + let chain_id = 3; let block_with_proof = read_block(format!("./src/data/{}.json", block_height)); let mut contract = EthClient::init( true, @@ -471,9 +486,12 @@ fn add_400000_block_only() { 10, 10, None, - 97 + chain_id, + ); + contract.add_block_header( + blocks[1].clone(), + block_with_proof.to_double_node_with_merkle_proof_vec(), ); - contract.add_block_header(blocks[1].clone(), block_with_proof.to_double_node_with_merkle_proof_vec()); assert_eq!(hashes[1], contract.block_hash(block_height as u64).unwrap()); } @@ -490,9 +508,10 @@ fn add_two_blocks_from_8996776() { format!("./src/data/{}.json", block_height), format!("./src/data/{}.json", block_height + 1), ] - .iter() - .map(|filename| read_block((&filename).to_string())) - .collect(); + .iter() + .map(|filename| read_block((&filename).to_string())) + .collect(); + let chain_id = 3; let mut contract = EthClient::init( true, @@ -504,7 +523,7 @@ fn add_two_blocks_from_8996776() { 10, 10, None, - 97, + chain_id, ); for (block, proof) in blocks @@ -515,22 +534,19 @@ fn add_two_blocks_from_8996776() { contract.add_block_header(block, proof.to_double_node_with_merkle_proof_vec()); } - let heights = [ - block_height as u64, - block_height as u64 + 1, - ]; + let heights = [block_height as u64, block_height as u64 + 1]; // Skip parent header hash let hashes = &hashes[1..]; assert_hashes_equal_to_contract_hashes(&contract, &heights, &hashes); } #[test] -// Test init bsc bridge. -fn bsc_add_epoch_header(){ +// Test init bsc bridge. +fn bsc_add_epoch_header() { testing_env!(get_context(vec![], false)); let (blocks, hashes) = get_blocks(&BSC_WEB3RS, 10_161_600, 10_161_601); - - let contract = EthClient::init( + let chain_id = 97; + let contract = EthClient::init( true, String::from("bsc"), 0, @@ -540,7 +556,7 @@ fn bsc_add_epoch_header(){ 10, 10, None, - 97, + chain_id, ); assert!(hashes[0] == contract.epoch_header) @@ -548,11 +564,11 @@ fn bsc_add_epoch_header(){ #[test] // test validate bsc headers. -fn bsc_update_epoch_header(){ +fn bsc_update_epoch_header() { testing_env!(get_context(vec![], false)); let (blocks, hashes) = get_blocks(&BSC_WEB3RS, 10_161_400, 10_161_450); - - let mut contract = EthClient::init( + let chain_id = 97; + let mut contract = EthClient::init( true, String::from("bsc"), 0, @@ -562,13 +578,10 @@ fn bsc_update_epoch_header(){ 51, 51, None, - 97, + chain_id, ); - - for block in blocks - .into_iter() - .skip(1) - { + + for block in blocks.into_iter().skip(1) { contract.add_block_header(block, vec![]); } assert!(hashes[0] == contract.epoch_header); @@ -593,9 +606,10 @@ fn add_two_blocks_from_400000() { format!("./src/data/{}.json", block_height), format!("./src/data/{}.json", block_height + 1), ] - .iter() - .map(|filename| read_block((&filename).to_string())) - .collect(); + .iter() + .map(|filename| read_block((&filename).to_string())) + .collect(); + let chain_id = 3; let mut contract = EthClient::init( true, @@ -607,7 +621,7 @@ fn add_two_blocks_from_400000() { 10, 10, None, - 97, + chain_id, ); for (block, proof) in blocks @@ -618,10 +632,7 @@ fn add_two_blocks_from_400000() { contract.add_block_header(block, proof.to_double_node_with_merkle_proof_vec()); } - let heights = [ - block_height as u64, - block_height as u64 + 1, - ]; + let heights = [block_height as u64, block_height as u64 + 1]; // Skip parent header hash let hashes = &hashes[1..]; assert_hashes_equal_to_contract_hashes(&contract, &heights, &hashes); @@ -659,7 +670,7 @@ fn predumped_block_can_be_added() { let start_block_height = blocks_with_proofs.first().unwrap().0; let first_block_with_proof = read_block(blocks_with_proofs.first().unwrap().1.to_string()); - + let chain_id = 3; let mut contract = EthClient::init( true, String::from("ethash"), @@ -670,7 +681,7 @@ fn predumped_block_can_be_added() { 10, 10, None, - 97, + chain_id, ); let bar = ProgressBar::new(blocks_with_proofs.len() as _); diff --git a/contracts/near/res/eth_client.wasm b/contracts/near/res/eth_client.wasm index e8da2fcb0..b6ac55a3c 100755 Binary files a/contracts/near/res/eth_client.wasm and b/contracts/near/res/eth_client.wasm differ