diff --git a/core/sr-eth-primitives/src/header.rs b/core/sr-eth-primitives/src/header.rs index 079155baa..4d3a31f2c 100644 --- a/core/sr-eth-primitives/src/header.rs +++ b/core/sr-eth-primitives/src/header.rs @@ -223,6 +223,10 @@ impl EthHeader { hash } + pub fn re_compute_hash(&self) -> H256 { + keccak_hash::keccak(self.rlp(Seal::With)) + } + /// Get the hash of this header (keccak of the RLP with seal). pub fn hash(&self) -> H256 { self.hash.unwrap_or_else(|| keccak_hash::keccak(self.rlp(Seal::With))) diff --git a/core/sr-eth-primitives/src/receipt.rs b/core/sr-eth-primitives/src/receipt.rs index 14ac81a9a..210ca4923 100644 --- a/core/sr-eth-primitives/src/receipt.rs +++ b/core/sr-eth-primitives/src/receipt.rs @@ -143,25 +143,32 @@ mod tests { } #[test] - /// kovan tx hash: 0xc654b4c4a183386722d42605ca91e23bc93919db8aa160b10cf50ab6a320ad9f - /// corresponding status - /// - gas used: 21000 - /// - root: null - /// status: 0x01 - /// logs: [] + /// ropsten tx hash: 0xce62c3d1d2a43cfcc39707b98de53e61a7ef7b7f8853e943d85e511b3451aa7e fn test_basic() { + // https://ropsten.etherscan.io/tx/0xce62c3d1d2a43cfcc39707b98de53e61a7ef7b7f8853e943d85e511b3451aa7e#eventlog let log_entries = vec![LogEntry { - address: Address::from_str("674943d6003783cf20125caad89525983dbfd050").unwrap(), - topics: vec![], - data: vec![], + address: Address::from_str("ad52e0f67b6f44cd5b9a6f4fbc7c0f78f37e094b").unwrap(), + topics: vec![ + H256::from(hex!("6775ce244ff81f0a82f87d6fd2cf885affb38416e3a04355f713c6f008dd126a")), + H256::from(hex!("0000000000000000000000000000000000000000000000000000000000000006")), + H256::from(hex!("0000000000000000000000000000000000000000000000000000000000000000")), + ], + data: "00000000000000000000000074241db5f3ebaeecf9506e4ae9881860933416048eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48000000000000000000000000000000000000000000000000002386f26fc10000".from_hex().unwrap(), }]; - let _r = construct_receipts(None, U256::from(U128::from(21000)), Some(1), log_entries); + // let receipt = Receipt::new( + // TransactionOutcome::StatusCode(1), + // // TransactionOutcome::StateRoot(H256::from(hex!("a21cdf375ebef58f606c298d6211f4edee58f2dd6430edbdd0ed3cd886a16863"))), + // U256::from(U128::from(1123401)), + // log_entries, + // ); + + let r = construct_receipts(None, U256::from(U128::from(1123401)), Some(1), log_entries); // let rs = &rlp::encode(&r)[..]; - // TODO: fix logbloom not match here! - // assert_eq!(r.log_bloom, Bloom::from_str( - // "00000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - // ).unwrap()); + // TODO: Check the log bloom generation logic + assert_eq!(r.log_bloom, Bloom::from_str( + "00000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000820000000000000020000000000000000000800000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000200000000020000000000000000000000000000080000000000000800000000000000000000000" + ).unwrap()); } #[test] diff --git a/srml/eth-relay/src/lib.rs b/srml/eth-relay/src/lib.rs index a06fcbcee..58d3467c3 100644 --- a/srml/eth-relay/src/lib.rs +++ b/srml/eth-relay/src/lib.rs @@ -86,7 +86,8 @@ decl_storage! { if let Some(h) = &config.header { let header: EthHeader = rlp::decode(&h).expect("Deserialize Genesis Header - FAILED"); - >::init_genesis_header(&header,config.genesis_difficulty); + // Discard the result even it fail. + let _ = >::init_genesis_header(&header,config.genesis_difficulty); // TODO: initialize other parameters. } @@ -106,7 +107,7 @@ decl_module! { // TODO: Check authority // TODO: Just for easy testing. - Self::init_genesis_header(&header, genesis_difficulty); + Self::init_genesis_header(&header, genesis_difficulty)?; >::deposit_event(RawEvent::NewHeader(header)); } @@ -157,8 +158,11 @@ decl_event! { impl Module { // TOOD: what is the total difficulty for genesis/begin header - pub fn init_genesis_header(header: &EthHeader, genesis_difficulty: u64) { + pub fn init_genesis_header(header: &EthHeader, genesis_difficulty: u64) -> result::Result<(), &'static str> { let header_hash = header.hash(); + + ensure!(header_hash == header.re_compute_hash(), "Header Hash - MISMATCHED"); + let block_number = header.number(); HeaderOf::insert(&header_hash, header); @@ -180,6 +184,8 @@ impl Module { // Initialize the header. BeginHeader::put(header.clone()); + + Ok(()) } fn verify_receipt(proof_record: &ActionRecord) -> result::Result { @@ -201,7 +207,8 @@ impl Module { /// 2. proof of pow (mixhash) /// 3. challenge fn verify_header(header: &EthHeader) -> Result { - // TODO: check parent hash, + ensure!(header.hash() == header.re_compute_hash(), "Header Hash - MISMATCHED"); + let parent_hash = header.parent_hash(); let number = header.number(); @@ -211,8 +218,9 @@ impl Module { "Block Number - TOO SMALL", ); + // TODO: check parent hash is the last header, ignore or reorg let prev_header = Self::header_of(parent_hash).ok_or("Previous Header - NOT EXISTED")?; - ensure!((prev_header.number() + 1) == number, "Block Number - NOT MATCHED"); + ensure!((prev_header.number() + 1) == number, "Block Number - MISMATCHED"); // check difficulty let ethash_params = match T::EthNetwork::get() { @@ -239,14 +247,11 @@ impl Module { let mix_hash = light_dag.hashimoto(partial_header_hash, seal.nonce).0; if mix_hash != seal.mix_hash { - return Err("Mixhash - NOT MATCHED"); + return Err("Mixhash - MISMATCHED"); } } }; - // ensure!(best_header.height == block_number, "Block height does not match."); - // ensure!(best_header.hash == *header.parent_hash(), "Block hash does not match."); - Ok(()) } diff --git a/srml/eth-relay/src/tests.rs b/srml/eth-relay/src/tests.rs index 216045b31..f7fb42d6e 100644 --- a/srml/eth-relay/src/tests.rs +++ b/srml/eth-relay/src/tests.rs @@ -9,6 +9,8 @@ use sr_eth_primitives::{ Address, Bloom, H64, U128, }; +use support::assert_ok; + use super::*; use mock::{EthRelay, ExtBuilder, System}; @@ -21,6 +23,7 @@ fn verify_receipt_proof() { .execute_with(|| { System::inc_account_nonce(&2); + // https://ropsten.etherscan.io/tx/0xce62c3d1d2a43cfcc39707b98de53e61a7ef7b7f8853e943d85e511b3451aa7e#eventlog let log_entries = vec![LogEntry { address: Address::from_str("ad52e0f67b6f44cd5b9a6f4fbc7c0f78f37e094b").unwrap(), topics: vec![ @@ -47,8 +50,8 @@ fn verify_receipt_proof() { // let proof: Proof = rlp::decode(&proof_record.proof).unwrap(); - let mixh = H256::from(hex!("5a85e328a8bb041a386ffb25db029b7f0df4665a8a55b331b30a576761404fa6")); - let nonce = H64::from(hex!("650ea83006bb108d")); + let mixh = H256::from(hex!("1e2fc5a540b8f1cdaf50de52c388b1f53856cc61eb3ad20d91b9fcc2de3e3e2a")); + let nonce = H64::from(hex!("339140bca72c49cd")); let header = EthHeader { parent_hash: H256::from(hex!("91553997d11a1d978f2ea363f230f5f525aee914a726d01e1deb4ea51de315cd")), @@ -68,7 +71,7 @@ fn verify_receipt_proof() { hash: Some(H256::from(hex!("f1a5bc27877e219b859b0bb1f2f440134553019f9bb5a2eca7a4703263e736c9"))), }; - EthRelay::init_genesis_header(&header, 0x624c22d93f8e59_u64); + assert_ok!(EthRelay::init_genesis_header(&header, 0x624c22d93f8e59_u64)); assert_eq!(EthRelay::verify_receipt(&proof_record), Ok(receipt)); }); @@ -78,8 +81,8 @@ fn verify_receipt_proof() { fn relay_header() { ExtBuilder::default().monied(true).build().execute_with(|| { // 6760579 - let mixh1 = H256::from(hex!("5a85e328a8bb041a386ffb25db029b7f0df4665a8a55b331b30a576761404fa6")); - let nonce1 = H64::from(hex!("650ea83006bb108d")); + let mixh1 = H256::from(hex!("1e2fc5a540b8f1cdaf50de52c388b1f53856cc61eb3ad20d91b9fcc2de3e3e2a")); + let nonce1 = H64::from(hex!("339140bca72c49cd")); let header1 = EthHeader { parent_hash: H256::from(hex!("91553997d11a1d978f2ea363f230f5f525aee914a726d01e1deb4ea51de315cd")), @@ -126,7 +129,7 @@ fn relay_header() { }; - EthRelay::init_genesis_header(&header1, 0x624c22d93f8e59_u64); + assert_ok!(EthRelay::init_genesis_header(&header1, 0x624c22d93f8e59_u64)); // let light_dag2 = DAG::new(header2.number().into()); // let partial_header_hash2 = header2.bare_hash(); @@ -141,9 +144,9 @@ fn relay_header() { // mixh2 // ); - EthRelay::verify_header(&header2).expect("Verify Failed."); + assert_ok!(EthRelay::verify_header(&header2)); - EthRelay::store_header(&header2).expect("Store Failed."); + assert_ok!(EthRelay::store_header(&header2)); // 6760581 @@ -168,8 +171,8 @@ fn relay_header() { hash: Some(H256::from(hex!("c86b090d12fa61c34f075530618e40a89654d8d85ac6aaa26149fb56b596a15a"))), }; - EthRelay::verify_header(&header3).expect("Verify Failed."); + assert_ok!(EthRelay::verify_header(&header3)); - EthRelay::store_header(&header3).expect("Store Failed."); + assert_ok!(EthRelay::store_header(&header3)); }); }