From e34637188837f544b9f3cf4e847ee0082f159815 Mon Sep 17 00:00:00 2001 From: zhangsoledad <787953403@qq.com> Date: Wed, 9 Oct 2019 11:43:38 +0800 Subject: [PATCH 1/7] chore: issuance comment --- spec/src/consensus.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/spec/src/consensus.rs b/spec/src/consensus.rs index 90ac1daff1..91b55e5217 100644 --- a/spec/src/consensus.rs +++ b/spec/src/consensus.rs @@ -24,8 +24,9 @@ use ckb_types::{ use std::cmp; use std::sync::Arc; -// TODO: add secondary reward for miner +// 1.344 billion per year pub(crate) const DEFAULT_SECONDARY_EPOCH_REWARD: Capacity = Capacity::shannons(613_698_63013698); +// 4.2 billion per year pub(crate) const INITIAL_PRIMARY_EPOCH_REWARD: Capacity = Capacity::shannons(1_917_808_21917808); const MAX_UNCLE_NUM: usize = 2; pub(crate) const TX_PROPOSAL_WINDOW: ProposalWindow = ProposalWindow(2, 10); @@ -34,7 +35,7 @@ pub(crate) const TX_PROPOSAL_WINDOW: ProposalWindow = ProposalWindow(2, 10); // This is to reduce the risk of later txs being reversed if a chain reorganization occurs. pub(crate) const CELLBASE_MATURITY: EpochNumberWithFraction = EpochNumberWithFraction::new_unchecked(4, 0, 1); -// TODO: should adjust this value based on CKB average block time + const MEDIAN_TIME_BLOCK_COUNT: usize = 37; // dampening factor From 675980334a23815b7a34ad69416ba928ad8ef860 Mon Sep 17 00:00:00 2001 From: zhangsoledad <787953403@qq.com> Date: Wed, 9 Oct 2019 16:38:01 +0800 Subject: [PATCH 2/7] chore: speed up maturity test --- test/src/specs/tx_pool/reference_header_maturity.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/src/specs/tx_pool/reference_header_maturity.rs b/test/src/specs/tx_pool/reference_header_maturity.rs index b4f6e5d509..2da401da6f 100644 --- a/test/src/specs/tx_pool/reference_header_maturity.rs +++ b/test/src/specs/tx_pool/reference_header_maturity.rs @@ -108,6 +108,8 @@ impl Spec for ReferenceHeaderMaturity { fn modify_chain_spec(&self) -> Box ()> { Box::new(|spec_config| { spec_config.params.cellbase_maturity = CELLBASE_MATURITY_VALUE; + spec_config.params.epoch_duration_target = 30; + spec_config.params.genesis_epoch_length = 5; }) } } From 014fe925489300bfa76be46849e66fb09dc8265d Mon Sep 17 00:00:00 2001 From: zhangsoledad <787953403@qq.com> Date: Wed, 9 Oct 2019 16:01:48 +0800 Subject: [PATCH 3/7] ci: Make sure cargo-audit up-to-date --- .travis.yml | 5 +++++ Makefile | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index f15ed451d9..0a7ec8e908 100644 --- a/.travis.yml +++ b/.travis.yml @@ -80,6 +80,11 @@ matrix: - make check-cargotoml - make check-whitespaces - make check-dirty-rpc-doc + - name: Security Audit + if: 'tag IS NOT present AND (type = pull_request OR branch in (master, staging, trying) OR repo != nervosnetwork/ckb)' + os: linux + rust: nightly + script: make security-audit - name: Test benchmarks on Linux env: CACHE_NAME=bench diff --git a/Makefile b/Makefile index f58ec2f5b8..b199bb380b 100644 --- a/Makefile +++ b/Makefile @@ -107,8 +107,8 @@ clippy: setup-ckb-test ## Run linter to examine Rust source codes. .PHONY: security-audit security-audit: ## Use cargo-audit to audit Cargo.lock for crates with security vulnerabilities. - @cargo audit --version || cargo install cargo-audit - @cargo audit + @cargo +nightly install cargo-audit -Z install-upgrade + cargo audit # expecting to see "Success No vulnerable packages found" .PHONY: bench-test From 103247c46a55b159fd08056c3b3003219d23d2e5 Mon Sep 17 00:00:00 2001 From: ian Date: Thu, 10 Oct 2019 09:46:44 +0800 Subject: [PATCH 4/7] fix: set `next_epoch_diff` to one instead of panic when it is zero --- spec/src/consensus.rs | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/spec/src/consensus.rs b/spec/src/consensus.rs index 90ac1daff1..7182395cbc 100644 --- a/spec/src/consensus.rs +++ b/spec/src/consensus.rs @@ -622,10 +622,9 @@ impl Consensus { &adjusted_last_epoch_hash_rate * epoch_duration_target, U256::one(), ); - let next_epoch_diff = if bound { + let diff_denominator = if bound { if last_orphan_rate.is_zero() { - let denominator = U256::from(next_epoch_length); - (diff_numerator / denominator).into_u256() + RationalU256::new(next_epoch_length_u256, U256::one()) } else { let orphan_rate_estimation_recip = ((&last_orphan_rate + U256::one()) * &epoch_duration_target_u256 @@ -633,24 +632,24 @@ impl Consensus { / (&last_orphan_rate * &last_epoch_duration * &next_epoch_length_u256)) .saturating_sub_u256(U256::one()); - let denominator = if orphan_rate_estimation_recip.is_zero() { + if orphan_rate_estimation_recip.is_zero() { // small probability event, use o_ideal for now (orphan_rate_target + U256::one()) * next_epoch_length_u256 } else { let orphan_rate_estimation = RationalU256::one() / orphan_rate_estimation_recip; (orphan_rate_estimation + U256::one()) * next_epoch_length_u256 - }; - (diff_numerator / denominator).into_u256() + } } } else { - let denominator = (orphan_rate_target + U256::one()) * next_epoch_length_u256; - (diff_numerator / denominator).into_u256() + (orphan_rate_target + U256::one()) * next_epoch_length_u256 }; - debug_assert!( - next_epoch_diff > U256::zero(), - "next_epoch_diff should greater than one" - ); + let next_epoch_diff = if diff_numerator > diff_denominator { + (diff_numerator / diff_denominator).into_u256() + } else { + // next_epoch_diff cannot be zero + U256::one() + }; let primary_epoch_reward = self.primary_epoch_reward_of_next_epoch(last_epoch).as_u64(); let block_reward = Capacity::shannons(primary_epoch_reward / next_epoch_length); From 77a27699663633bf21361a6ef3ffa8b56d3ef3b4 Mon Sep 17 00:00:00 2001 From: zhangsoledad <787953403@qq.com> Date: Fri, 4 Oct 2019 19:45:04 +0800 Subject: [PATCH 5/7] fix: get_block_transactions_process should fill missing uncle in response --- sync/src/relayer/compact_block_process.rs | 2 -- sync/src/relayer/get_block_transactions_process.rs | 8 ++++++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/sync/src/relayer/compact_block_process.rs b/sync/src/relayer/compact_block_process.rs index e3d4232276..8a8dd91946 100644 --- a/sync/src/relayer/compact_block_process.rs +++ b/sync/src/relayer/compact_block_process.rs @@ -226,8 +226,6 @@ impl<'a> CompactBlockProcess<'a> { } } - assert!(!missing_transactions.is_empty() || !missing_uncles.is_empty()); - pending_compact_blocks .entry(block_hash.clone()) .or_insert_with(|| (compact_block, HashMap::default())) diff --git a/sync/src/relayer/get_block_transactions_process.rs b/sync/src/relayer/get_block_transactions_process.rs index 01fbfb384d..a56e548628 100644 --- a/sync/src/relayer/get_block_transactions_process.rs +++ b/sync/src/relayer/get_block_transactions_process.rs @@ -49,9 +49,17 @@ impl<'a> GetBlockTransactionsProcess<'a> { }) .collect::>(); + let uncles = self + .message + .uncle_indexes() + .iter() + .filter_map(|i| block.uncles().get(Unpack::::unpack(&i) as usize)) + .collect::>(); + let content = packed::BlockTransactions::new_builder() .block_hash(block_hash) .transactions(transactions.into_iter().map(|tx| tx.data()).pack()) + .uncles(uncles.into_iter().map(|uncle| uncle.data()).pack()) .build(); let message = packed::RelayMessage::new_builder().set(content).build(); let data = message.as_slice().into(); From ecc0d7d59bde354c72582c65e74aa530b07b2a40 Mon Sep 17 00:00:00 2001 From: zhangsoledad <787953403@qq.com> Date: Thu, 10 Oct 2019 10:15:58 +0800 Subject: [PATCH 6/7] test: missing uncle request --- test/src/main.rs | 1 + .../relay/get_block_transactions_process.rs | 77 +++++++++++++++++++ test/src/specs/relay/mod.rs | 2 + 3 files changed, 80 insertions(+) create mode 100644 test/src/specs/relay/get_block_transactions_process.rs diff --git a/test/src/main.rs b/test/src/main.rs index 745d6ec03f..fa4f4c620b 100644 --- a/test/src/main.rs +++ b/test/src/main.rs @@ -286,6 +286,7 @@ fn all_specs() -> SpecMap { Box::new(ProposeButNotCommit), Box::new(ProposeDuplicated), Box::new(ForkedTransaction), + Box::new(MissingUncleRequest), ]; specs.into_iter().map(|spec| (spec.name(), spec)).collect() } diff --git a/test/src/specs/relay/get_block_transactions_process.rs b/test/src/specs/relay/get_block_transactions_process.rs new file mode 100644 index 0000000000..65334d3054 --- /dev/null +++ b/test/src/specs/relay/get_block_transactions_process.rs @@ -0,0 +1,77 @@ +use crate::{Net, Spec, TestProtocol}; +use ckb_sync::NetworkProtocol; +use ckb_types::{ + core::UncleBlockView, + packed::{self, RelayMessage}, + prelude::*, +}; + +pub struct MissingUncleRequest; + +impl Spec for MissingUncleRequest { + crate::name!("missing_uncle_request"); + + crate::setup!(protocols: vec![TestProtocol::sync(), TestProtocol::relay()]); + + // Case: Send to node GetBlockTransactions with missing uncle index, node should response BlockTransactions with uncles + fn run(&self, net: &mut Net) { + net.exit_ibd_mode(); + let node = &net.nodes[0]; + net.connect(node); + let (peer_id, _, _) = net.receive(); + + node.generate_block(); + let _ = net.receive(); + + let builder = node.new_block_builder(None, None, None); + let block1 = builder.clone().nonce(0.pack()).build(); + let block2 = builder.clone().nonce(1.pack()).build(); + node.submit_block(&block1.data()); + node.submit_block(&block2.data()); + + let builder = node.new_block_builder(None, None, None); + let block = builder + .clone() + .set_uncles(vec![block2.as_uncle()]) + .nonce(0.pack()) + .build(); + node.submit_block(&block.data()); + + let content = packed::GetBlockTransactions::new_builder() + .block_hash(block.hash()) + .uncle_indexes(vec![0u32].pack()) + .build(); + let message = packed::RelayMessage::new_builder().set(content).build(); + + (0..3).for_each(|_| { + net.receive(); // ignore three new block announce + }); + + net.send( + NetworkProtocol::RELAY.into(), + peer_id, + message.as_slice().into(), + ); + + let (_, _, data) = net.receive(); + let message = RelayMessage::from_slice(&data).unwrap(); + + assert_eq!( + message.to_enum().item_name(), + packed::BlockTransactions::NAME, + "Node should reponse BlockTransactions message", + ); + + if let packed::RelayMessageUnionReader::BlockTransactions(reader) = + message.to_enum().as_reader() + { + let block_transactions = reader.to_entity(); + let received_uncles: Vec = block_transactions + .uncles() + .into_iter() + .map(|uncle| uncle.into_view()) + .collect(); + assert_eq!(received_uncles[0], block2.as_uncle()); + } + } +} diff --git a/test/src/specs/relay/mod.rs b/test/src/specs/relay/mod.rs index 2f47d792f8..a07082d0b6 100644 --- a/test/src/specs/relay/mod.rs +++ b/test/src/specs/relay/mod.rs @@ -1,7 +1,9 @@ mod block_relay; mod compact_block; +mod get_block_transactions_process; mod transaction_relay; pub use block_relay::*; pub use compact_block::*; +pub use get_block_transactions_process::*; pub use transaction_relay::*; From e5e9f7dd30461c5cd85c399f9e81b978e978a6ac Mon Sep 17 00:00:00 2001 From: zhangsoledad <787953403@qq.com> Date: Wed, 9 Oct 2019 17:11:41 +0800 Subject: [PATCH 7/7] test: simple header field json format check --- Cargo.lock | 1 + util/jsonrpc-types/Cargo.toml | 1 + util/jsonrpc-types/src/blockchain.rs | 12 ++++++++++++ 3 files changed, 14 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index 2aa01dce98..a5887986d3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -609,6 +609,7 @@ dependencies = [ "ckb-types 0.23.0-pre", "faster-hex 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-core 10.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "proptest 0.9.4 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.1.7 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/util/jsonrpc-types/Cargo.toml b/util/jsonrpc-types/Cargo.toml index d96937f04e..397f2b5c8b 100644 --- a/util/jsonrpc-types/Cargo.toml +++ b/util/jsonrpc-types/Cargo.toml @@ -16,3 +16,4 @@ jsonrpc-core = "10.1" [dev-dependencies] proptest = "0.9" regex = "1.1" +lazy_static = "1.3" diff --git a/util/jsonrpc-types/src/blockchain.rs b/util/jsonrpc-types/src/blockchain.rs index a51b87fcfd..5f504d557c 100644 --- a/util/jsonrpc-types/src/blockchain.rs +++ b/util/jsonrpc-types/src/blockchain.rs @@ -685,7 +685,9 @@ impl From for BlockReward { mod tests { use super::*; use ckb_types::{bytes::Bytes, core::TransactionBuilder, packed::Byte32}; + use lazy_static::lazy_static; use proptest::{collection::size_range, prelude::*}; + use regex::Regex; fn mock_script(arg: Bytes) -> packed::Script { packed::ScriptBuilder::default() @@ -737,11 +739,21 @@ mod tests { let encoded = serde_json::to_string(&json_block).unwrap(); let decode: BlockView = serde_json::from_str(&encoded).unwrap(); let decode_block: core::BlockView = decode.into(); + header_field_format_check(&encoded); prop_assert_eq!(decode_block.data(), block.data()); prop_assert_eq!(decode_block, block); Ok(()) } + fn header_field_format_check(json: &str) { + lazy_static! { + static ref RE: Regex = Regex::new("\"(version|compact_target|parent_hash|timestamp|number|epoch|transactions_root|proposals_hash|uncles_hash|dao|nonce)\":\"(?P.*?\")").unwrap(); + } + for caps in RE.captures_iter(json) { + assert!(&caps["value"].starts_with("0x")); + } + } + proptest! { #[test] fn test_block_convert(