From 0b71638ee5b6f0d267f4650ab1371374429702c3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Mon, 11 Feb 2019 11:45:52 +0000 Subject: [PATCH 1/4] chore(deps): bump proptest from 0.8.7 to 0.9.1 Bumps [proptest](https://github.com/altsysrq/proptest) from 0.8.7 to 0.9.1. - [Release notes](https://github.com/altsysrq/proptest/releases) - [Changelog](https://github.com/AltSysrq/proptest/blob/master/CHANGELOG.md) - [Commits](https://github.com/altsysrq/proptest/commits) Signed-off-by: dependabot[bot] --- Cargo.lock | 25 ++- miner/Cargo.toml | 2 +- pow/Cargo.toml | 2 +- pow/src/cuckoo.rs | 11 +- script/Cargo.toml | 2 +- script/src/syscalls/mod.rs | 245 ++++++++++++++------------- util/jsonrpc-types/Cargo.toml | 2 +- util/jsonrpc-types/src/blockchain.rs | 15 +- 8 files changed, 166 insertions(+), 138 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0b1880eb83..d4af75472f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -450,7 +450,7 @@ dependencies = [ "lru-cache 0.1.0 (git+https://github.com/nervosnetwork/lru-cache)", "numext-fixed-hash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "numext-fixed-uint 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "proptest 0.8.7 (registry+https://github.com/rust-lang/crates.io-index)", + "proptest 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.87 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.87 (registry+https://github.com/rust-lang/crates.io-index)", @@ -531,7 +531,7 @@ dependencies = [ "crossbeam-channel 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "hash 0.6.0-pre", "numext-fixed-hash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "proptest 0.8.7 (registry+https://github.com/rust-lang/crates.io-index)", + "proptest 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.87 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.87 (registry+https://github.com/rust-lang/crates.io-index)", @@ -601,7 +601,7 @@ dependencies = [ "hash 0.6.0-pre", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "numext-fixed-hash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "proptest 0.8.7 (registry+https://github.com/rust-lang/crates.io-index)", + "proptest 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1400,7 +1400,7 @@ dependencies = [ "jsonrpc-core 9.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "numext-fixed-hash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "numext-fixed-uint 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "proptest 0.8.7 (registry+https://github.com/rust-lang/crates.io-index)", + "proptest 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.87 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.87 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1429,6 +1429,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" name = "lazy_static" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "spin 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", +] [[package]] name = "lazycell" @@ -2260,7 +2263,7 @@ dependencies = [ [[package]] name = "proptest" -version = "0.8.7" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bit-set 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2269,7 +2272,9 @@ dependencies = [ "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", "quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "regex-syntax 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "rusty-fork 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "tempfile 3.0.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2835,6 +2840,11 @@ dependencies = [ "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "spin" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "stable_deref_trait" version = "1.1.1" @@ -3659,7 +3669,7 @@ dependencies = [ "checksum plain 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6" "checksum proc-macro2 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "77997c53ae6edd6d187fec07ec41b207063b5ee6f33680e9fa86d405cdd313d4" "checksum proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)" = "4d317f9caece796be1980837fd5cb3dfec5613ebdb04ad0956deea83ce168915" -"checksum proptest 0.8.7 (registry+https://github.com/rust-lang/crates.io-index)" = "926d0604475349f463fe44130aae73f2294b5309ab2ca0310b998bd334ef191f" +"checksum proptest 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8ea66c78d75f2c6e9f304269eaef90899798daecc69f1a625d5a3dd793ff3522" "checksum protobuf 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d82d117bc7565ce6be0150159251c9b1eeec7b129f5a2aa86e10acb5970de1cb" "checksum quick-error 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5fb6ccf8db7bbcb9c2eae558db5ab4f3da1c2a87e4e597ed394726bc8ea6ca1d" "checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0" @@ -3728,6 +3738,7 @@ dependencies = [ "checksum smallvec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1347484b6f8bc4b32a9323d9800b6d934376391002ad9c528cc659fe8afc08ee" "checksum smallvec 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)" = "88aea073965ab29f6edb5493faf96ad662fb18aa9eeb186a3b7057951605ed15" "checksum snap 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "95d697d63d44ad8b78b8d235bf85b34022a78af292c8918527c5f0cffdde7f43" +"checksum spin 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "ceac490aa12c567115b40b7b7fceca03a6c9d53d5defea066123debc83c5dc1f" "checksum stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8" "checksum stdweb 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ef5430c8e36b713e13b48a9f709cc21e046723fe44ce34587b73a830203b533e" "checksum string 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b639411d0b9c738748b5397d5ceba08e648f4f1992231aa859af1a017f31f60b" diff --git a/miner/Cargo.toml b/miner/Cargo.toml index 00698545c7..a3b858bc75 100644 --- a/miner/Cargo.toml +++ b/miner/Cargo.toml @@ -28,7 +28,7 @@ lru-cache = { git = "https://github.com/nervosnetwork/lru-cache" } stop-handler = { path = "../util/stop-handler" } [dev-dependencies] -proptest = "0.8" +proptest = "0.9" ckb-chain = { path = "../chain" } ckb-chain-spec = { path = "../spec" } numext-fixed-hash = { version = "0.1", features = ["support_rand", "support_heapsize", "support_serde"] } diff --git a/pow/Cargo.toml b/pow/Cargo.toml index 42e00c79c3..3c2cd47bc8 100644 --- a/pow/Cargo.toml +++ b/pow/Cargo.toml @@ -17,4 +17,4 @@ serde_derive = "1.0" [dev-dependencies] -proptest = "0.8" +proptest = "0.9" diff --git a/pow/src/cuckoo.rs b/pow/src/cuckoo.rs index f87a3fc769..1f9c42b1f7 100644 --- a/pow/src/cuckoo.rs +++ b/pow/src/cuckoo.rs @@ -306,21 +306,20 @@ impl Cuckoo { mod test { use super::Cuckoo; - use proptest::{collection::size_range, prelude::any_with, proptest, proptest_helper}; + use proptest::{collection::size_range, prelude::*}; - fn _cuckoo_solve(message: &[u8]) -> bool { + fn _cuckoo_solve(message: &[u8]) -> Result<(), TestCaseError> { let cuckoo = Cuckoo::new(3, 6); if let Some(proof) = cuckoo.solve(message) { - assert!(cuckoo.verify(message, &proof)); + prop_assert!(cuckoo.verify(message, &proof)); } - true + Ok(()) } proptest! { #[test] - #[allow(clippy::unnecessary_operation)] fn cuckoo_solve(ref message in any_with::>(size_range(80).lift())) { - _cuckoo_solve(message) + _cuckoo_solve(message)?; } } diff --git a/script/Cargo.toml b/script/Cargo.toml index 1703a15182..fd7a6f0132 100644 --- a/script/Cargo.toml +++ b/script/Cargo.toml @@ -20,4 +20,4 @@ ckb-protocol = { path = "../protocol" } [dev-dependencies] -proptest = "0.8" +proptest = "0.9" diff --git a/script/src/syscalls/mod.rs b/script/src/syscalls/mod.rs index c9661c20cc..d7e0a69f90 100644 --- a/script/src/syscalls/mod.rs +++ b/script/src/syscalls/mod.rs @@ -96,11 +96,9 @@ mod tests { use flatbuffers::FlatBufferBuilder; use hash::sha3_256; use numext_fixed_hash::H256; - use proptest::{ - collection::size_range, prelude::any, prelude::any_with, proptest, proptest_helper, - }; + use proptest::{collection::size_range, prelude::*}; - fn _test_load_tx_all(tx: &[u8]) { + fn _test_load_tx_all(tx: &[u8]) -> Result<(), TestCaseError> { let mut machine = DefaultCoreMachine::::default(); let size_addr = 0; let addr = 100; @@ -110,28 +108,29 @@ mod tests { machine.registers_mut()[A2] = 0; // offset machine.registers_mut()[A7] = LOAD_TX_SYSCALL_NUMBER; // syscall number - assert!(machine + prop_assert!(machine .memory_mut() .store64(size_addr as usize, tx.len() as u64) .is_ok()); let mut load_tx = LoadTx::new(tx); - assert!(load_tx.ecall(&mut machine).is_ok()); + prop_assert!(load_tx.ecall(&mut machine).is_ok()); - assert_eq!(machine.registers()[A0], u64::from(SUCCESS)); + prop_assert_eq!(machine.registers()[A0], u64::from(SUCCESS)); for (i, addr) in (addr as usize..addr as usize + tx.len()).enumerate() { - assert_eq!(machine.memory_mut().load8(addr), Ok(tx[i])); + prop_assert_eq!(machine.memory_mut().load8(addr), Ok(tx[i])); } + Ok(()) } proptest! { #[test] fn test_load_tx_all(ref tx in any_with::>(size_range(1000).lift())) { - _test_load_tx_all(tx); + _test_load_tx_all(tx)?; } } - fn _test_load_tx_length(tx: &[u8]) { + fn _test_load_tx_length(tx: &[u8]) -> Result<(), TestCaseError> { let mut machine = DefaultCoreMachine::::default(); let size_addr = 0; let addr = 100; @@ -141,13 +140,13 @@ mod tests { machine.registers_mut()[A2] = 0; // offset machine.registers_mut()[A7] = LOAD_TX_SYSCALL_NUMBER; // syscall number - assert!(machine.memory_mut().store64(size_addr as usize, 0).is_ok()); + prop_assert!(machine.memory_mut().store64(size_addr as usize, 0).is_ok()); let mut load_tx = LoadTx::new(tx); - assert!(load_tx.ecall(&mut machine).is_ok()); + prop_assert!(load_tx.ecall(&mut machine).is_ok()); - assert_eq!(machine.registers()[A0], u64::from(SUCCESS)); - assert_eq!( + prop_assert_eq!(machine.registers()[A0], u64::from(SUCCESS)); + prop_assert_eq!( machine.memory_mut().load64(size_addr as usize), Ok(tx.len() as u64) ); @@ -155,25 +154,26 @@ mod tests { machine.registers_mut()[A0] = addr; // addr machine.registers_mut()[A2] = 100; // offset - assert!(machine.memory_mut().store64(size_addr as usize, 0).is_ok()); + prop_assert!(machine.memory_mut().store64(size_addr as usize, 0).is_ok()); - assert!(load_tx.ecall(&mut machine).is_ok()); + prop_assert!(load_tx.ecall(&mut machine).is_ok()); - assert_eq!(machine.registers()[A0], u64::from(SUCCESS)); - assert_eq!( + prop_assert_eq!(machine.registers()[A0], u64::from(SUCCESS)); + prop_assert_eq!( machine.memory_mut().load64(size_addr as usize), Ok(tx.len() as u64 - 100) ); + Ok(()) } proptest! { #[test] fn test_load_tx_length(ref tx in any_with::>(size_range(1000).lift())) { - _test_load_tx_length(tx); + _test_load_tx_length(tx)?; } } - fn _test_load_tx_partial(tx: &[u8]) { + fn _test_load_tx_partial(tx: &[u8]) -> Result<(), TestCaseError> { let mut machine = DefaultCoreMachine::::default(); let size_addr = 0; let addr = 100; @@ -184,32 +184,33 @@ mod tests { machine.registers_mut()[A2] = offset as u64; // offset machine.registers_mut()[A7] = LOAD_TX_SYSCALL_NUMBER; // syscall number - assert!(machine + prop_assert!(machine .memory_mut() .store64(size_addr as usize, tx.len() as u64) .is_ok()); let mut load_tx = LoadTx::new(tx); - assert!(load_tx.ecall(&mut machine).is_ok()); + prop_assert!(load_tx.ecall(&mut machine).is_ok()); - assert_eq!(machine.registers()[A0], u64::from(SUCCESS)); - assert_eq!( + prop_assert_eq!(machine.registers()[A0], u64::from(SUCCESS)); + prop_assert_eq!( machine.memory_mut().load64(size_addr as usize), Ok((tx.len() - offset) as u64) ); for (i, addr) in (addr as usize..addr as usize + tx.len() - offset).enumerate() { - assert_eq!(machine.memory_mut().load8(addr), Ok(tx[i + offset])); + prop_assert_eq!(machine.memory_mut().load8(addr), Ok(tx[i + offset])); } + Ok(()) } proptest! { #[test] fn test_load_tx_partial(ref tx in any_with::>(size_range(1000).lift())) { - _test_load_tx_partial(tx); + _test_load_tx_partial(tx)?; } } - fn _test_load_cell_item_missing(data: &[u8]) { + fn _test_load_cell_item_missing(data: &[u8]) -> Result<(), TestCaseError> { let mut machine = DefaultCoreMachine::::default(); let size_addr = 0; let addr = 100; @@ -221,7 +222,7 @@ mod tests { machine.registers_mut()[A4] = Source::Input as u64; //source: 1 input machine.registers_mut()[A7] = LOAD_CELL_SYSCALL_NUMBER; // syscall number - assert!(machine + prop_assert!(machine .memory_mut() .store64(size_addr as usize, data.len() as u64) .is_ok()); @@ -238,18 +239,19 @@ mod tests { let dep_cells = vec![]; let mut load_cell = LoadCell::new(&outputs, &input_cells, &input_cell, &dep_cells); - assert!(load_cell.ecall(&mut machine).is_ok()); - assert_eq!(machine.registers()[A0], u64::from(ITEM_MISSING)); + prop_assert!(load_cell.ecall(&mut machine).is_ok()); + prop_assert_eq!(machine.registers()[A0], u64::from(ITEM_MISSING)); + Ok(()) } proptest! { #[test] fn test_load_cell_item_missing(ref data in any_with::>(size_range(1000).lift())) { - _test_load_cell_item_missing(data); + _test_load_cell_item_missing(data)?; } } - fn _test_load_cell_all(data: &[u8]) { + fn _test_load_cell_all(data: &[u8]) -> Result<(), TestCaseError> { let mut machine = DefaultCoreMachine::::default(); let size_addr = 0; let addr = 100; @@ -284,56 +286,57 @@ mod tests { let output_correct_data = builder.finished_data(); // test input - assert!(machine + prop_assert!(machine .memory_mut() .store64(size_addr as usize, input_correct_data.len() as u64) .is_ok()); - assert!(load_cell.ecall(&mut machine).is_ok()); - assert_eq!(machine.registers()[A0], u64::from(SUCCESS)); + prop_assert!(load_cell.ecall(&mut machine).is_ok()); + prop_assert_eq!(machine.registers()[A0], u64::from(SUCCESS)); - assert_eq!( + prop_assert_eq!( machine.memory_mut().load64(size_addr as usize), Ok(input_correct_data.len() as u64) ); for (i, addr) in (addr as usize..addr as usize + input_correct_data.len()).enumerate() { - assert_eq!(machine.memory_mut().load8(addr), Ok(input_correct_data[i])); + prop_assert_eq!(machine.memory_mut().load8(addr), Ok(input_correct_data[i])); } // clean memory - assert!(machine.memory_mut().store_byte(0, 1100, 0).is_ok()); + prop_assert!(machine.memory_mut().store_byte(0, 1100, 0).is_ok()); // test output machine.registers_mut()[A0] = addr; // addr machine.registers_mut()[A1] = size_addr; // size_addr machine.registers_mut()[A4] = Source::Output as u64; //source: 2 output - assert!(machine + prop_assert!(machine .memory_mut() .store64(size_addr as usize, output_correct_data.len() as u64 + 10) .is_ok()); - assert!(load_cell.ecall(&mut machine).is_ok()); - assert_eq!(machine.registers()[A0], u64::from(SUCCESS)); + prop_assert!(load_cell.ecall(&mut machine).is_ok()); + prop_assert_eq!(machine.registers()[A0], u64::from(SUCCESS)); - assert_eq!( + prop_assert_eq!( machine.memory_mut().load64(size_addr as usize), Ok(output_correct_data.len() as u64) ); for (i, addr) in (addr as usize..addr as usize + output_correct_data.len()).enumerate() { - assert_eq!(machine.memory_mut().load8(addr), Ok(output_correct_data[i])); + prop_assert_eq!(machine.memory_mut().load8(addr), Ok(output_correct_data[i])); } + Ok(()) } proptest! { #[test] fn test_load_cell_all(ref tx in any_with::>(size_range(1000).lift())) { - _test_load_cell_all(tx); + _test_load_cell_all(tx)?; } } - fn _test_load_cell_length(data: &[u8]) { + fn _test_load_cell_length(data: &[u8]) -> Result<(), TestCaseError> { let mut machine = DefaultCoreMachine::::default(); let size_addr = 0; let addr = 100; @@ -362,25 +365,26 @@ mod tests { builder.finish(fbs_offset, None); let input_correct_data = builder.finished_data(); - assert!(machine.memory_mut().store64(size_addr as usize, 0).is_ok()); + prop_assert!(machine.memory_mut().store64(size_addr as usize, 0).is_ok()); - assert!(load_cell.ecall(&mut machine).is_ok()); - assert_eq!(machine.registers()[A0], u64::from(SUCCESS)); + prop_assert!(load_cell.ecall(&mut machine).is_ok()); + prop_assert_eq!(machine.registers()[A0], u64::from(SUCCESS)); - assert_eq!( + prop_assert_eq!( machine.memory_mut().load64(size_addr as usize), Ok(input_correct_data.len() as u64) ); + Ok(()) } proptest! { #[test] fn test_load_cell_length(ref tx in any_with::>(size_range(1000).lift())) { - _test_load_cell_length(tx); + _test_load_cell_length(tx)?; } } - fn _test_load_cell_partial(data: &[u8]) { + fn _test_load_cell_partial(data: &[u8]) -> Result<(), TestCaseError> { let mut machine = DefaultCoreMachine::::default(); let size_addr = 0; let addr = 100; @@ -410,32 +414,33 @@ mod tests { builder.finish(fbs_offset, None); let input_correct_data = builder.finished_data(); - assert!(machine + prop_assert!(machine .memory_mut() .store64(size_addr as usize, input_correct_data.len() as u64) .is_ok()); - assert!(load_cell.ecall(&mut machine).is_ok()); - assert_eq!(machine.registers()[A0], u64::from(SUCCESS)); + prop_assert!(load_cell.ecall(&mut machine).is_ok()); + prop_assert_eq!(machine.registers()[A0], u64::from(SUCCESS)); for (i, addr) in (addr as usize..addr as usize + input_correct_data.len() - offset).enumerate() { - assert_eq!( + prop_assert_eq!( machine.memory_mut().load8(addr), Ok(input_correct_data[i + offset]) ); } + Ok(()) } proptest! { #[test] fn test_load_cell_partial(ref data in any_with::>(size_range(1000).lift())) { - _test_load_cell_partial(data); + _test_load_cell_partial(data)?; } } - fn _test_load_current_cell(data: &[u8]) { + fn _test_load_current_cell(data: &[u8]) -> Result<(), TestCaseError> { let mut machine = DefaultCoreMachine::::default(); let size_addr = 0; let addr = 100; @@ -464,32 +469,33 @@ mod tests { let input_correct_data = builder.finished_data(); // test input - assert!(machine + prop_assert!(machine .memory_mut() .store64(size_addr as usize, input_correct_data.len() as u64 + 5) .is_ok()); - assert!(load_cell.ecall(&mut machine).is_ok()); - assert_eq!(machine.registers()[A0], u64::from(SUCCESS)); + prop_assert!(load_cell.ecall(&mut machine).is_ok()); + prop_assert_eq!(machine.registers()[A0], u64::from(SUCCESS)); - assert_eq!( + prop_assert_eq!( machine.memory_mut().load64(size_addr as usize), Ok(input_correct_data.len() as u64) ); for (i, addr) in (addr as usize..addr as usize + input_correct_data.len()).enumerate() { - assert_eq!(machine.memory_mut().load8(addr), Ok(input_correct_data[i])); + prop_assert_eq!(machine.memory_mut().load8(addr), Ok(input_correct_data[i])); } + Ok(()) } proptest! { #[test] fn test_load_current_cell(ref tx in any_with::>(size_range(1000).lift())) { - _test_load_current_cell(tx); + _test_load_current_cell(tx)?; } } - fn _test_load_cell_capacity(capacity: u64) { + fn _test_load_cell_capacity(capacity: u64) -> Result<(), TestCaseError> { let mut machine = DefaultCoreMachine::::default(); let size_addr = 0; let addr = 100; @@ -508,29 +514,30 @@ mod tests { let dep_cells = vec![]; let mut load_cell = LoadCellByField::new(&outputs, &input_cells, &input_cell, &dep_cells); - assert!(machine.memory_mut().store64(size_addr as usize, 16).is_ok()); + prop_assert!(machine.memory_mut().store64(size_addr as usize, 16).is_ok()); - assert!(load_cell.ecall(&mut machine).is_ok()); - assert_eq!(machine.registers()[A0], u64::from(SUCCESS)); + prop_assert!(load_cell.ecall(&mut machine).is_ok()); + prop_assert_eq!(machine.registers()[A0], u64::from(SUCCESS)); - assert_eq!(machine.memory_mut().load64(size_addr as usize), Ok(8)); + prop_assert_eq!(machine.memory_mut().load64(size_addr as usize), Ok(8)); let mut buffer = vec![]; buffer.write_u64::(capacity).unwrap(); for (i, addr) in (addr as usize..addr as usize + buffer.len() as usize).enumerate() { - assert_eq!(machine.memory_mut().load8(addr), Ok(buffer[i])); + prop_assert_eq!(machine.memory_mut().load8(addr), Ok(buffer[i])); } + Ok(()) } proptest! { #[test] fn test_load_cell_capacity(capacity in any::()) { - _test_load_cell_capacity(capacity); + _test_load_cell_capacity(capacity)?; } } - fn _test_load_self_lock_hash(data: &[u8]) { + fn _test_load_self_lock_hash(data: &[u8]) -> Result<(), TestCaseError> { let mut machine = DefaultCoreMachine::::default(); let size_addr = 0; let addr = 100; @@ -550,36 +557,37 @@ mod tests { let dep_cells = vec![]; let mut load_cell = LoadCellByField::new(&outputs, &input_cells, &input_cell, &dep_cells); - assert!(machine.memory_mut().store64(size_addr as usize, 64).is_ok()); + prop_assert!(machine.memory_mut().store64(size_addr as usize, 64).is_ok()); - assert!(load_cell.ecall(&mut machine).is_ok()); - assert_eq!(machine.registers()[A0], u64::from(SUCCESS)); + prop_assert!(load_cell.ecall(&mut machine).is_ok()); + prop_assert_eq!(machine.registers()[A0], u64::from(SUCCESS)); - assert_eq!( + prop_assert_eq!( machine.memory_mut().load64(size_addr as usize), Ok(sha3_data.len() as u64) ); for (i, addr) in (addr as usize..addr as usize + sha3_data.len() as usize).enumerate() { - assert_eq!(machine.memory_mut().load8(addr), Ok(sha3_data[i])); + prop_assert_eq!(machine.memory_mut().load8(addr), Ok(sha3_data[i])); } machine.registers_mut()[A0] = addr; // addr - assert!(machine.memory_mut().store64(size_addr as usize, 0).is_ok()); + prop_assert!(machine.memory_mut().store64(size_addr as usize, 0).is_ok()); - assert!(load_cell.ecall(&mut machine).is_ok()); - assert_eq!(machine.registers()[A0], u64::from(SUCCESS)); + prop_assert!(load_cell.ecall(&mut machine).is_ok()); + prop_assert_eq!(machine.registers()[A0], u64::from(SUCCESS)); - assert_eq!( + prop_assert_eq!( machine.memory_mut().load64(size_addr as usize), Ok(sha3_data.len() as u64) ); + Ok(()) } proptest! { #[test] fn test_load_self_lock_hash(ref data in any_with::>(size_range(1000).lift())) { - _test_load_self_lock_hash(data); + _test_load_self_lock_hash(data)?; } } @@ -618,7 +626,7 @@ mod tests { } } - fn _test_load_input_unlock_script(data: Vec) { + fn _test_load_input_unlock_script(data: Vec) -> Result<(), TestCaseError> { let mut machine = DefaultCoreMachine::::default(); let size_addr = 0; let addr = 100; @@ -641,32 +649,33 @@ mod tests { let inputs = vec![&input]; let mut load_input = LoadInputByField::new(&inputs, Some(&input)); - assert!(machine + prop_assert!(machine .memory_mut() .store64(size_addr as usize, unlock_data.len() as u64) .is_ok()); - assert!(load_input.ecall(&mut machine).is_ok()); - assert_eq!(machine.registers()[A0], u64::from(SUCCESS)); + prop_assert!(load_input.ecall(&mut machine).is_ok()); + prop_assert_eq!(machine.registers()[A0], u64::from(SUCCESS)); - assert_eq!( + prop_assert_eq!( machine.memory_mut().load64(size_addr as usize), Ok(unlock_data.len() as u64) ); for (i, addr) in (addr as usize..addr as usize + unlock_data.len() as usize).enumerate() { - assert_eq!(machine.memory_mut().load8(addr), Ok(unlock_data[i])); + prop_assert_eq!(machine.memory_mut().load8(addr), Ok(unlock_data[i])); } + Ok(()) } proptest! { #[test] fn test_load_input_unlock_script(data in any_with::>(size_range(1000).lift())) { - _test_load_input_unlock_script(data); + _test_load_input_unlock_script(data)?; } } - fn _test_load_missing_output_unlock_script(data: Vec) { + fn _test_load_missing_output_unlock_script(data: Vec) -> Result<(), TestCaseError> { let mut machine = DefaultCoreMachine::::default(); let size_addr = 0; let addr = 100; @@ -689,32 +698,33 @@ mod tests { let inputs = vec![&input]; let mut load_input = LoadInputByField::new(&inputs, Some(&input)); - assert!(machine + prop_assert!(machine .memory_mut() .store64(size_addr as usize, unlock_data.len() as u64 + 10) .is_ok()); - assert!(load_input.ecall(&mut machine).is_ok()); - assert_eq!(machine.registers()[A0], u64::from(ITEM_MISSING)); + prop_assert!(load_input.ecall(&mut machine).is_ok()); + prop_assert_eq!(machine.registers()[A0], u64::from(ITEM_MISSING)); - assert_eq!( + prop_assert_eq!( machine.memory_mut().load64(size_addr as usize), Ok(unlock_data.len() as u64 + 10) ); for addr in addr as usize..addr as usize + unlock_data.len() as usize { - assert_eq!(machine.memory_mut().load8(addr), Ok(0)); + prop_assert_eq!(machine.memory_mut().load8(addr), Ok(0)); } + Ok(()) } proptest! { #[test] fn test_load_missing_output_unlock_script(data in any_with::>(size_range(1000).lift())) { - _test_load_missing_output_unlock_script(data); + _test_load_missing_output_unlock_script(data)?; } } - fn _test_load_self_input_out_point(data: &[u8]) { + fn _test_load_self_input_out_point(data: &[u8]) -> Result<(), TestCaseError> { let mut machine = DefaultCoreMachine::::default(); let size_addr = 0; let addr = 100; @@ -739,29 +749,30 @@ mod tests { let inputs = vec![]; let mut load_input = LoadInputByField::new(&inputs, Some(&input)); - assert!(machine + prop_assert!(machine .memory_mut() .store64(size_addr as usize, out_point_data.len() as u64 + 5) .is_ok()); - assert!(load_input.ecall(&mut machine).is_ok()); - assert_eq!(machine.registers()[A0], u64::from(SUCCESS)); + prop_assert!(load_input.ecall(&mut machine).is_ok()); + prop_assert_eq!(machine.registers()[A0], u64::from(SUCCESS)); - assert_eq!( + prop_assert_eq!( machine.memory_mut().load64(size_addr as usize), Ok(out_point_data.len() as u64) ); for (i, addr) in (addr as usize..addr as usize + out_point_data.len() as usize).enumerate() { - assert_eq!(machine.memory_mut().load8(addr), Ok(out_point_data[i])); + prop_assert_eq!(machine.memory_mut().load8(addr), Ok(out_point_data[i])); } + Ok(()) } proptest! { #[test] fn test_load_self_input_out_point(ref data in any_with::>(size_range(1000).lift())) { - _test_load_self_input_out_point(data); + _test_load_self_input_out_point(data)?; } } @@ -794,7 +805,7 @@ mod tests { } } - fn _test_load_dep_cell_data(data: &[u8]) { + fn _test_load_dep_cell_data(data: &[u8]) -> Result<(), TestCaseError> { let mut machine = DefaultCoreMachine::::default(); let size_addr = 0; let addr = 100; @@ -814,32 +825,33 @@ mod tests { let dep_cells = vec![&dep_cell]; let mut load_cell = LoadCellByField::new(&outputs, &input_cells, &input_cell, &dep_cells); - assert!(machine + prop_assert!(machine .memory_mut() .store64(size_addr as usize, data.len() as u64 + 20) .is_ok()); - assert!(load_cell.ecall(&mut machine).is_ok()); - assert_eq!(machine.registers()[A0], u64::from(SUCCESS)); + prop_assert!(load_cell.ecall(&mut machine).is_ok()); + prop_assert_eq!(machine.registers()[A0], u64::from(SUCCESS)); - assert_eq!( + prop_assert_eq!( machine.memory_mut().load64(size_addr as usize), Ok(data.len() as u64) ); for (i, addr) in (addr as usize..addr as usize + data.len() as usize).enumerate() { - assert_eq!(machine.memory_mut().load8(addr), Ok(data[i])); + prop_assert_eq!(machine.memory_mut().load8(addr), Ok(data[i])); } + Ok(()) } proptest! { #[test] fn test_load_dep_cell_data(ref data in any_with::>(size_range(1000).lift())) { - _test_load_dep_cell_data(data); + _test_load_dep_cell_data(data)?; } } - fn _test_load_dep_cell_data_hash(data: &[u8]) { + fn _test_load_dep_cell_data_hash(data: &[u8]) -> Result<(), TestCaseError> { let mut machine = DefaultCoreMachine::::default(); let size_addr = 0; let addr = 100; @@ -861,28 +873,29 @@ mod tests { let data_hash = sha3_256(&data); - assert!(machine + prop_assert!(machine .memory_mut() .store64(size_addr as usize, data_hash.len() as u64 + 20) .is_ok()); - assert!(load_cell.ecall(&mut machine).is_ok()); - assert_eq!(machine.registers()[A0], u64::from(SUCCESS)); + prop_assert!(load_cell.ecall(&mut machine).is_ok()); + prop_assert_eq!(machine.registers()[A0], u64::from(SUCCESS)); - assert_eq!( + prop_assert_eq!( machine.memory_mut().load64(size_addr as usize), Ok(data_hash.len() as u64) ); for (i, addr) in (addr as usize..addr as usize + data_hash.len() as usize).enumerate() { - assert_eq!(machine.memory_mut().load8(addr), Ok(data_hash[i])); + prop_assert_eq!(machine.memory_mut().load8(addr), Ok(data_hash[i])); } + Ok(()) } proptest! { #[test] fn test_load_dep_cell_data_hash(ref data in any_with::>(size_range(1000).lift())) { - _test_load_dep_cell_data_hash(data); + _test_load_dep_cell_data_hash(data)?; } } } diff --git a/util/jsonrpc-types/Cargo.toml b/util/jsonrpc-types/Cargo.toml index 9f08b6aa93..2ba71a314e 100644 --- a/util/jsonrpc-types/Cargo.toml +++ b/util/jsonrpc-types/Cargo.toml @@ -16,4 +16,4 @@ faster-hex = "0.3" jsonrpc-core = "9.0" [dev-dependencies] -proptest = "0.8" +proptest = "0.9" diff --git a/util/jsonrpc-types/src/blockchain.rs b/util/jsonrpc-types/src/blockchain.rs index a411d9cf73..fccc76d3cc 100644 --- a/util/jsonrpc-types/src/blockchain.rs +++ b/util/jsonrpc-types/src/blockchain.rs @@ -351,7 +351,7 @@ impl From for CoreBlock { mod tests { use super::*; use ckb_core::transaction::ProposalShortId as CoreProposalShortId; - use proptest::{collection::size_range, prelude::any_with, proptest, proptest_helper}; + use proptest::{collection::size_range, prelude::*}; fn mock_script(arg: Vec, binary: Vec, signed_arg: Vec) -> CoreScript { CoreScript::new( @@ -432,25 +432,30 @@ mod tests { .build() } - fn _test_block_convert(data: Vec, arg: Vec, binary: Vec, signed_arg: Vec) { + fn _test_block_convert( + data: Vec, + arg: Vec, + binary: Vec, + signed_arg: Vec, + ) -> Result<(), TestCaseError> { let block = mock_full_block(data, arg, binary, signed_arg); let json_block: Block = (&block).into(); let encoded = serde_json::to_string(&json_block).unwrap(); let decode: Block = serde_json::from_str(&encoded).unwrap(); let decode_block: CoreBlock = decode.into(); - assert_eq!(decode_block, block); + prop_assert_eq!(decode_block, block); + Ok(()) } proptest! { #[test] - #[allow(clippy::unnecessary_operation)] fn test_block_convert( data in any_with::>(size_range(80).lift()), arg in any_with::>(size_range(80).lift()), binary in any_with::>(size_range(80).lift()), signed_arg in any_with::>(size_range(80).lift()) ) { - _test_block_convert(data, arg, binary, signed_arg) + _test_block_convert(data, arg, binary, signed_arg)?; } } } From a7523584ca78595bbedbe6f3f0b082c984df653a Mon Sep 17 00:00:00 2001 From: zhangsoledad <787953403@qq.com> Date: Tue, 12 Feb 2019 19:11:57 +0800 Subject: [PATCH 2/4] fix: fetch fork logic --- chain/src/chain.rs | 91 ++++++++++++++++++++++++----------------- rpc/Cargo.toml | 2 +- rpc/src/module/chain.rs | 2 +- rpc/src/module/miner.rs | 46 +++++++++++++-------- 4 files changed, 85 insertions(+), 56 deletions(-) diff --git a/chain/src/chain.rs b/chain/src/chain.rs index 9f502fa9be..91ada9a2cc 100644 --- a/chain/src/chain.rs +++ b/chain/src/chain.rs @@ -117,6 +117,8 @@ impl ChainService { } } + // process_block will do block verify + // but invoker should guarantee block header be verified fn process_block(&mut self, block: Arc) -> Result<(), ProcessBlockError> { debug!(target: "chain", "begin processing block: {}", block.header().hash()); if self.verification { @@ -165,6 +167,7 @@ impl ChainService { received_at: unix_time_as_millis(), total_difficulty: cannon_total_difficulty.clone(), total_uncles_count: parent_ext.total_uncles_count + block.uncles().len() as u64, + // if txs in parent is invalid, txs in block is also invalid valid: if parent_ext.valid == Some(false) { Some(false) } else { @@ -286,7 +289,7 @@ impl ChainService { new_tip_block: &Block, new_tip_ext: BlockExt, ) -> Option { - let mut number = new_tip_block.header().number() - 1; + let new_tip_number = new_tip_block.header().number(); let mut old_blocks = Vec::new(); let mut new_blocks = Vec::new(); let mut open_exts = Vec::new(); @@ -294,60 +297,72 @@ impl ChainService { if new_tip_ext.valid.is_none() { open_exts.push(new_tip_ext); } else { - // must be Some(false) + // txs in block are invalid return None; } - let mut is_open = true; + let mut is_new_record = true; - // The old fork may longer than new fork - if number < current_tip_number { - for n in number..=current_tip_number { - let hash = self.shared.block_hash(n).unwrap(); + // new_blocks = forks[latest_common + 1 .. new_tip] + // old_blocks = chain[latest_common + 1 .. old_tip] + new_blocks.push(new_tip_block.clone()); + let mut index = new_tip_number - 1; + let mut index_hash = new_tip_block.header().parent_hash().clone(); + + // if new_tip_number <= current_tip_number + // then old_blocks.extend(chain[new_tip_number .. =current_tip_number]) + // if new_tip_number > current_tip_number + // then new_blocks.extend(forks[current_tip_number + 1 .. =new_tip_number]) + if new_tip_number <= current_tip_number { + for bn in new_tip_number..=current_tip_number { + let hash = self.shared.block_hash(bn).unwrap(); let old_block = self.shared.block(&hash).unwrap(); - old_blocks.push(old_block); } - } - - //TODO: remove this clone - new_blocks.push(new_tip_block.clone()); + } else { + while index > current_tip_number { + let new_block = self.shared.block(&index_hash).unwrap(); + + if is_new_record { + let ext = self.shared.block_ext(&index_hash).unwrap(); + if ext.valid.is_none() { + open_exts.push(ext) + } else { + is_new_record = false; + } + } - let mut hash = new_tip_block.header().parent_hash().clone(); + index_hash = new_block.header().parent_hash().clone(); + new_blocks.push(new_block); + index -= 1; + } + } + // find latest common ancestor loop { - if number <= current_tip_number { - let old_hash = self.shared.block_hash(number).unwrap(); - - if old_hash == hash { - break; - } - - let old_block = self.shared.block(&old_hash).unwrap(); - old_blocks.push(old_block); + if index == 0 { + break; + } + let old_hash = self.shared.block_hash(index).unwrap(); + if old_hash == index_hash { + break; } + let old_block = self.shared.block(&old_hash).unwrap(); + old_blocks.push(old_block); - if is_open { - let ext = self.shared.block_ext(&hash).unwrap(); + let new_block = self.shared.block(&index_hash).unwrap(); + index_hash = new_block.header().parent_hash().clone(); + new_blocks.push(new_block); + + if is_new_record { + let ext = self.shared.block_ext(&index_hash).unwrap(); if ext.valid.is_none() { open_exts.push(ext) } else { - is_open = false; + is_new_record = false; } } - - let new_block = self.shared.block(&hash).unwrap(); - - hash = new_block.header().parent_hash().clone(); - - new_blocks.push(new_block); - - // If the genesis block is different? - if number == 0 { - break; - } else { - number -= 1; - } + index -= 1; } Some(Fork { diff --git a/rpc/Cargo.toml b/rpc/Cargo.toml index 1216e11c54..3cb7d8622c 100644 --- a/rpc/Cargo.toml +++ b/rpc/Cargo.toml @@ -33,7 +33,7 @@ faster-hex = "0.3" jsonrpc-types = { path = "../util/jsonrpc-types" } build-info = { path = "../util/build-info" } futures = "0.1" +ckb-verification = { path = "../verification" } [dev-dependencies] ckb-db = { path = "../db" } -ckb-verification = { path = "../verification" } diff --git a/rpc/src/module/chain.rs b/rpc/src/module/chain.rs index f8909fabe4..a07cd4d03d 100644 --- a/rpc/src/module/chain.rs +++ b/rpc/src/module/chain.rs @@ -67,13 +67,13 @@ impl ChainRpc for ChainRpcImpl { to: BlockNumber, ) -> Result> { let mut result = Vec::new(); + let chain_state = self.shared.chain_state().read(); for block_number in from..=to { if let Some(block_hash) = self.shared.block_hash(block_number) { let block = self .shared .block(&block_hash) .ok_or_else(Error::internal_error)?; - let chain_state = self.shared.chain_state().read(); for transaction in block.commit_transactions() { let transaction_meta = chain_state .txo_set() diff --git a/rpc/src/module/miner.rs b/rpc/src/module/miner.rs index dd8a9d56a2..1cbcddbe5d 100644 --- a/rpc/src/module/miner.rs +++ b/rpc/src/module/miner.rs @@ -3,8 +3,10 @@ use ckb_core::block::Block as CoreBlock; use ckb_miner::BlockAssemblerController; use ckb_network::NetworkService; use ckb_protocol::RelayMessage; +use ckb_shared::shared::ChainProvider; use ckb_shared::{index::ChainIndex, shared::Shared}; use ckb_sync::RELAY_PROTOCOL_ID; +use ckb_verification::{HeaderResolverWrapper, HeaderVerifier, Verifier}; use flatbuffers::FlatBufferBuilder; use jsonrpc_core::{Error, Result}; use jsonrpc_derive::rpc; @@ -27,7 +29,7 @@ pub trait MinerRpc { // curl -d '{"id": 2, "jsonrpc": "2.0", "method":"submit_block","params": [{"header":{}, "uncles":[], "commit_transactions":[], "proposal_transactions":[]}]}' -H 'content-type:application/json' 'http://localhost:8114' #[rpc(name = "submit_block")] - fn submit_block(&self, _work_id: String, _data: Block) -> Result; + fn submit_block(&self, _work_id: String, _data: Block) -> Result>; } pub(crate) struct MinerRpcImpl { @@ -49,23 +51,35 @@ impl MinerRpc for MinerRpcImpl { .map_err(|_| Error::internal_error()) } - fn submit_block(&self, _work_id: String, data: Block) -> Result { + fn submit_block(&self, _work_id: String, data: Block) -> Result> { let block: Arc = Arc::new(data.into()); - let ret = self.chain.process_block(Arc::clone(&block)); - if ret.is_ok() { - // announce new block - self.network.with_protocol_context(RELAY_PROTOCOL_ID, |nc| { - let fbb = &mut FlatBufferBuilder::new(); - let message = RelayMessage::build_compact_block(fbb, &block, &HashSet::new()); - fbb.finish(message, None); - for peer in nc.connected_peers() { - let _ = nc.send(peer, fbb.finished_data().to_vec()); - } - }); - Ok(block.header().hash().clone()) + let resolver = HeaderResolverWrapper::new(block.header(), self.shared.clone()); + let header_verifier = HeaderVerifier::new( + self.shared.clone(), + Arc::clone(&self.shared.consensus().pow_engine()), + ); + + let header_verify_ret = header_verifier.verify(&resolver); + if header_verify_ret.is_ok() { + let ret = self.chain.process_block(Arc::clone(&block)); + if ret.is_ok() { + // announce new block + self.network.with_protocol_context(RELAY_PROTOCOL_ID, |nc| { + let fbb = &mut FlatBufferBuilder::new(); + let message = RelayMessage::build_compact_block(fbb, &block, &HashSet::new()); + fbb.finish(message, None); + for peer in nc.connected_peers() { + let _ = nc.send(peer, fbb.finished_data().to_vec()); + } + }); + Ok(Some(block.header().hash().clone())) + } else { + debug!(target: "rpc", "submit_block process_block {:?}", ret); + Ok(None) + } } else { - debug!(target: "rpc", "submit_block process_block {:?}", ret); - Err(Error::internal_error()) + debug!(target: "rpc", "submit_block header verifier {:?}", header_verify_ret); + Ok(None) } } } From b9d371e0a6b232e649fdfd278cf839c3b3bac23e Mon Sep 17 00:00:00 2001 From: zhangsoledad <787953403@qq.com> Date: Wed, 13 Feb 2019 17:28:33 +0800 Subject: [PATCH 3/4] chore: improve core types debug format --- core/src/header.rs | 40 +++++++++++++++++++++++++-- core/src/script.rs | 60 ++++++++++++++++++++++++++++++++++++++++- core/src/transaction.rs | 27 +++++++++++++++++-- 3 files changed, 122 insertions(+), 5 deletions(-) diff --git a/core/src/header.rs b/core/src/header.rs index 6752cb88b5..7f4011a91c 100644 --- a/core/src/header.rs +++ b/core/src/header.rs @@ -1,17 +1,31 @@ use bincode::{deserialize, serialize}; +use faster_hex::hex_string; use hash::sha3_256; use numext_fixed_hash::H256; use numext_fixed_uint::U256; use serde_derive::{Deserialize, Serialize}; +use std::fmt; pub use crate::{BlockNumber, Version}; -#[derive(Clone, Serialize, Deserialize, PartialEq, Eq, Debug, Default)] +#[derive(Clone, Serialize, Deserialize, PartialEq, Eq, Default)] pub struct Seal { nonce: u64, proof: Vec, } +impl fmt::Debug for Seal { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("Seal") + .field("nonce", &self.nonce) + .field( + "proof", + &format_args!("0x{}", &hex_string(&self.proof).expect("hex proof")), + ) + .finish() + } +} + impl Seal { pub fn new(nonce: u64, proof: Vec) -> Self { Seal { nonce, proof } @@ -75,13 +89,35 @@ impl RawHeader { } } -#[derive(Clone, Serialize, Deserialize, Debug, Default, Eq)] +#[derive(Clone, Serialize, Deserialize, Default, Eq)] pub struct Header { raw: RawHeader, /// proof seal seal: Seal, } +impl fmt::Debug for Header { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("Header") + .field("hash", &format_args!("{:#x}", &self.hash())) + .field("version", &self.raw.version) + .field("parent_hash", &format_args!("{:#x}", self.raw.parent_hash)) + .field("timestamp", &self.raw.timestamp) + .field("number", &self.raw.number) + .field("txs_commit", &format_args!("{:#x}", self.raw.txs_commit)) + .field( + "txs_proposal", + &format_args!("{:#x}", self.raw.txs_proposal), + ) + .field("difficulty", &format_args!("{:#x}", self.raw.difficulty)) + .field("cellbase_id", &format_args!("{:#x}", self.raw.cellbase_id)) + .field("uncles_hash", &format_args!("{:#x}", self.raw.uncles_hash)) + .field("uncles_count", &self.raw.uncles_count) + .field("seal", &self.seal) + .finish() + } +} + impl Header { pub fn version(&self) -> u32 { self.raw.version diff --git a/core/src/script.rs b/core/src/script.rs index 8cc577f02f..1c543564b6 100644 --- a/core/src/script.rs +++ b/core/src/script.rs @@ -1,13 +1,15 @@ +use faster_hex::hex_encode; use hash::sha3_256; use numext_fixed_hash::H256; use occupied_capacity::OccupiedCapacity; use serde_derive::{Deserialize, Serialize}; +use std::fmt; use std::io::Write; use std::mem; // TODO: when flatbuffer work is done, remove Serialize/Deserialize here and // implement proper From trait -#[derive(Clone, Default, Serialize, Deserialize, PartialEq, Eq, Hash, Debug)] +#[derive(Clone, Default, Serialize, Deserialize, PartialEq, Eq, Hash)] pub struct Script { pub version: u8, pub args: Vec>, @@ -50,6 +52,62 @@ pub struct Script { pub signed_args: Vec>, } +struct OptionDisplay(Option); + +impl fmt::Display for OptionDisplay { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self.0 { + Some(ref v) => write!(f, "Some({})", v), + None => write!(f, "None"), + } + } +} + +fn prefix_hex(bytes: &[u8]) -> String { + let mut dst = vec![0u8; bytes.len() * 2 + 2]; + dst[0] = b'0'; + dst[1] = b'x'; + let _ = hex_encode(bytes, &mut dst[2..]); + unsafe { String::from_utf8_unchecked(dst) } +} + +impl fmt::Debug for Script { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "Script {{ version: {}, args: ", self.version,)?; + f.debug_list() + .entries(self.args.iter().map(|arg| prefix_hex(arg))) + .finish()?; + + write!( + f, + ", reference: {}", + OptionDisplay( + self.reference + .as_ref() + .map(|reference| format!("{:#x}", reference)) + ) + )?; + + write!( + f, + ", binary: {}", + OptionDisplay(self.binary.as_ref().map(|binary| prefix_hex(binary))) + )?; + + write!(f, " , signed_args: ")?; + + f.debug_list() + .entries( + self.signed_args + .iter() + .map(|signed_arg| prefix_hex(signed_arg)), + ) + .finish()?; + + write!(f, " }}") + } +} + type ScriptTuple = ( u8, Vec>, diff --git a/core/src/transaction.rs b/core/src/transaction.rs index 3cbbab7ce7..9a3a735d1b 100644 --- a/core/src/transaction.rs +++ b/core/src/transaction.rs @@ -12,7 +12,7 @@ use serde_derive::{Deserialize, Serialize}; use std::fmt; use std::ops::{Deref, DerefMut}; -#[derive(Clone, Serialize, Deserialize, Eq, PartialEq, Hash, Debug, OccupiedCapacity)] +#[derive(Clone, Serialize, Deserialize, Eq, PartialEq, Hash, OccupiedCapacity)] pub struct OutPoint { // Hash of Transaction pub hash: H256, @@ -20,6 +20,15 @@ pub struct OutPoint { pub index: u32, } +impl fmt::Debug for OutPoint { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("OutPoint") + .field("hash", &format_args!("{:#x}", self.hash)) + .field("index", &self.index) + .finish() + } +} + impl Default for OutPoint { fn default() -> Self { OutPoint { @@ -86,7 +95,7 @@ impl CellInput { } } -#[derive(Clone, Default, Serialize, Deserialize, PartialEq, Eq, Hash, Debug, OccupiedCapacity)] +#[derive(Clone, Default, Serialize, Deserialize, PartialEq, Eq, Hash, OccupiedCapacity)] pub struct CellOutput { pub capacity: Capacity, pub data: Vec, @@ -95,6 +104,20 @@ pub struct CellOutput { pub type_: Option