Skip to content

Commit

Permalink
feat: use epoch as the basic maturity unit
Browse files Browse the repository at this point in the history
  • Loading branch information
yangby-cryptape committed Sep 25, 2019
1 parent 253274d commit e1799c2
Show file tree
Hide file tree
Showing 19 changed files with 238 additions and 165 deletions.
6 changes: 3 additions & 3 deletions benches/benches/benchmarks/overall.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ use ckb_tx_pool::BlockAssemblerConfig;
use ckb_types::{
bytes::Bytes,
core::{
capacity_bytes, BlockBuilder, BlockView, Capacity, ScriptHashType, TransactionBuilder,
TransactionView,
capacity_bytes, BlockBuilder, BlockView, Capacity, EpochNumberWithFraction, ScriptHashType,
TransactionBuilder, TransactionView,
},
packed::{Block, CellDep, CellInput, CellOutput, Header, OutPoint},
prelude::*,
Expand Down Expand Up @@ -73,7 +73,7 @@ pub fn setup_chain(txs_size: usize) -> (Shared, ChainController) {
.build();

let mut consensus = ConsensusBuilder::default()
.cellbase_maturity(0)
.cellbase_maturity(EpochNumberWithFraction::new(0, 0, 1))
.genesis_block(genesis_block)
.build();
consensus.tx_proposal_window = ProposalWindow(1, 10);
Expand Down
8 changes: 4 additions & 4 deletions benches/benches/benchmarks/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ use ckb_types::{
core::{
capacity_bytes,
cell::{resolve_transaction, OverlayCellProvider, TransactionsProvider},
BlockBuilder, BlockView, Capacity, HeaderView, ScriptHashType, TransactionBuilder,
TransactionView,
BlockBuilder, BlockView, Capacity, EpochNumberWithFraction, HeaderView, ScriptHashType,
TransactionBuilder, TransactionView,
},
h160, h256,
packed::{Byte32, CellDep, CellInput, CellOutput, OutPoint, ProposalShortId, Script},
Expand Down Expand Up @@ -66,7 +66,7 @@ pub fn new_always_success_chain(txs_size: usize, chains_num: usize) -> Chains {
.build();

let mut consensus = ConsensusBuilder::default()
.cellbase_maturity(0)
.cellbase_maturity(EpochNumberWithFraction::new(0, 0, 1))
.genesis_block(genesis_block)
.build();
consensus.tx_proposal_window = ProposalWindow(1, 10);
Expand Down Expand Up @@ -271,7 +271,7 @@ pub fn new_secp_chain(txs_size: usize, chains_num: usize) -> Chains {
.build();

let mut consensus = ConsensusBuilder::default()
.cellbase_maturity(0)
.cellbase_maturity(EpochNumberWithFraction::new(0, 0, 1))
.genesis_block(genesis_block)
.build();
consensus.tx_proposal_window = ProposalWindow(1, 10);
Expand Down
6 changes: 3 additions & 3 deletions chain/src/tests/reward.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ use ckb_types::prelude::*;
use ckb_types::{
bytes::Bytes,
core::{
capacity_bytes, BlockBuilder, BlockView, Capacity, HeaderView, ScriptHashType,
TransactionBuilder, TransactionView, UncleBlockView,
capacity_bytes, BlockBuilder, BlockView, Capacity, EpochNumberWithFraction, HeaderView,
ScriptHashType, TransactionBuilder, TransactionView, UncleBlockView,
},
packed::{
self, CellDep, CellInput, CellOutputBuilder, OutPoint, ProposalShortId, Script,
Expand Down Expand Up @@ -142,7 +142,7 @@ fn finalize_reward() {
.build();

let consensus = ConsensusBuilder::default()
.cellbase_maturity(0)
.cellbase_maturity(EpochNumberWithFraction::new(0, 0, 1))
.genesis_block(genesis_block)
.build();

Expand Down
5 changes: 3 additions & 2 deletions chain/src/tests/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ use ckb_types::{
core::{
capacity_bytes,
cell::{resolve_transaction, OverlayCellProvider, TransactionsProvider},
BlockBuilder, BlockView, Capacity, HeaderView, TransactionBuilder, TransactionView,
BlockBuilder, BlockView, Capacity, EpochNumberWithFraction, HeaderView, TransactionBuilder,
TransactionView,
},
packed::{self, Byte32, CellDep, CellInput, CellOutputBuilder, OutPoint},
U256,
Expand Down Expand Up @@ -49,7 +50,7 @@ pub(crate) fn start_chain(consensus: Option<Consensus>) -> (ChainController, Sha
.transaction(tx)
.build();
ConsensusBuilder::default()
.cellbase_maturity(0)
.cellbase_maturity(EpochNumberWithFraction::new(0, 0, 1))
.genesis_block(genesis_block)
.build()
});
Expand Down
6 changes: 3 additions & 3 deletions rpc/src/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ use ckb_sync::{SyncSharedState, Synchronizer};
use ckb_test_chain_utils::{always_success_cell, always_success_cellbase};
use ckb_types::{
core::{
capacity_bytes, cell::resolve_transaction, BlockBuilder, BlockView, Capacity, HeaderView,
TransactionBuilder, TransactionView,
capacity_bytes, cell::resolve_transaction, BlockBuilder, BlockView, Capacity,
EpochNumberWithFraction, HeaderView, TransactionBuilder, TransactionView,
},
h256,
packed::{AlertBuilder, CellDep, CellInput, CellOutputBuilder, OutPoint, RawAlertBuilder},
Expand Down Expand Up @@ -81,7 +81,7 @@ fn always_success_consensus() -> Consensus {
ConsensusBuilder::default()
.genesis_block(genesis)
.epoch_reward(Capacity::shannons(EPOCH_REWARD))
.cellbase_maturity(CELLBASE_MATURITY)
.cellbase_maturity(EpochNumberWithFraction::from_full_value(CELLBASE_MATURITY))
.build()
}

Expand Down
19 changes: 10 additions & 9 deletions spec/src/consensus.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ use ckb_resource::Resource;
use ckb_types::{
constants::BLOCK_VERSION,
core::{
BlockBuilder, BlockNumber, BlockView, Capacity, Cycle, EpochExt, HeaderView, Ratio,
TransactionBuilder, TransactionView, Version,
BlockBuilder, BlockNumber, BlockView, Capacity, Cycle, EpochExt, EpochNumberWithFraction,
HeaderView, Ratio, TransactionBuilder, TransactionView, Version,
},
h160,
packed::{Byte32, CellInput, Script},
Expand All @@ -28,10 +28,11 @@ pub(crate) const DEFAULT_SECONDARY_EPOCH_REWARD: Capacity = Capacity::shannons(6
pub(crate) const DEFAULT_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);
// Cellbase outputs are "locked" and require 4 * MAX_EPOCH_LENGTH(1800) confirmations(approximately 16 hours)
// before they mature sufficiently to be spendable,
// Cellbase outputs are "locked" and require 4 epoch confirmations (approximately 16 hours) before
// they mature sufficiently to be spendable,
// This is to reduce the risk of later txs being reversed if a chain reorganization occurs.
pub(crate) const CELLBASE_MATURITY: BlockNumber = 4 * MAX_EPOCH_LENGTH;
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;

Expand Down Expand Up @@ -117,7 +118,7 @@ pub struct ConsensusBuilder {
tx_proposal_window: ProposalWindow,
proposer_reward_ratio: Ratio,
pow: Pow,
cellbase_maturity: BlockNumber,
cellbase_maturity: EpochNumberWithFraction,
median_time_block_count: usize,
max_block_cycles: Cycle,
max_block_bytes: u64,
Expand Down Expand Up @@ -366,7 +367,7 @@ impl ConsensusBuilder {
}

#[must_use]
pub fn cellbase_maturity(mut self, cellbase_maturity: BlockNumber) -> Self {
pub fn cellbase_maturity(mut self, cellbase_maturity: EpochNumberWithFraction) -> Self {
self.cellbase_maturity = cellbase_maturity;
self
}
Expand Down Expand Up @@ -411,7 +412,7 @@ pub struct Consensus {
// For each input, if the referenced output transaction is cellbase,
// it must have at least `cellbase_maturity` confirmations;
// else reject this transaction.
pub cellbase_maturity: BlockNumber,
pub cellbase_maturity: EpochNumberWithFraction,
// This parameter indicates the count of past blocks used in the median time calculation
pub median_time_block_count: usize,
// Maximum cycles that all the scripts in all the commit transactions can take
Expand Down Expand Up @@ -514,7 +515,7 @@ impl Consensus {
self.pow.engine()
}

pub fn cellbase_maturity(&self) -> BlockNumber {
pub fn cellbase_maturity(&self) -> EpochNumberWithFraction {
self.cellbase_maturity
}

Expand Down
12 changes: 7 additions & 5 deletions spec/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ use ckb_types::{
bytes::Bytes,
constants::TYPE_ID_CODE_HASH,
core::{
capacity_bytes, BlockBuilder, BlockNumber, BlockView, Capacity, Cycle, EpochExt, Ratio,
ScriptHashType, TransactionBuilder, TransactionView,
capacity_bytes, BlockBuilder, BlockView, Capacity, Cycle, EpochExt,
EpochNumberWithFraction, Ratio, ScriptHashType, TransactionBuilder, TransactionView,
},
h256, packed,
prelude::*,
Expand Down Expand Up @@ -66,7 +66,7 @@ pub struct Params {
pub epoch_reward: Capacity,
pub secondary_epoch_reward: Capacity,
pub max_block_cycles: Cycle,
pub cellbase_maturity: BlockNumber,
pub cellbase_maturity: u64,
}

impl Default for Params {
Expand All @@ -79,7 +79,7 @@ impl Default for Params {
epoch_reward: DEFAULT_EPOCH_REWARD,
secondary_epoch_reward: DEFAULT_SECONDARY_EPOCH_REWARD,
max_block_cycles: MAX_BLOCK_CYCLES,
cellbase_maturity: CELLBASE_MATURITY,
cellbase_maturity: CELLBASE_MATURITY.full_value(),
}
}
}
Expand Down Expand Up @@ -222,7 +222,9 @@ impl ChainSpec {
let consensus =
ConsensusBuilder::new(genesis_block, self.params.epoch_reward, genesis_epoch_ext)
.id(self.name.clone())
.cellbase_maturity(self.params.cellbase_maturity)
.cellbase_maturity(EpochNumberWithFraction::from_full_value(
self.params.cellbase_maturity,
))
.secondary_epoch_reward(self.params.secondary_epoch_reward)
.max_block_cycles(self.params.max_block_cycles)
.pow(self.pow.clone())
Expand Down
6 changes: 3 additions & 3 deletions sync/src/relayer/tests/helper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ use ckb_types::prelude::*;
use ckb_types::{
bytes::Bytes,
core::{
capacity_bytes, BlockBuilder, BlockNumber, Capacity, HeaderBuilder, HeaderView,
TransactionBuilder, TransactionView,
capacity_bytes, BlockBuilder, BlockNumber, Capacity, EpochNumberWithFraction,
HeaderBuilder, HeaderView, TransactionBuilder, TransactionView,
},
packed::{
CellDep, CellInput, CellOutputBuilder, IndexTransaction, IndexTransactionBuilder, OutPoint,
Expand Down Expand Up @@ -110,7 +110,7 @@ pub(crate) fn build_chain(tip: BlockNumber) -> (Relayer, OutPoint) {
.build();
let consensus = ConsensusBuilder::default()
.genesis_block(genesis)
.cellbase_maturity(0)
.cellbase_maturity(EpochNumberWithFraction::new(0, 0, 1))
.build();
SharedBuilder::default()
.consensus(consensus)
Expand Down
4 changes: 2 additions & 2 deletions sync/src/tests/synchronizer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use ckb_test_chain_utils::always_success_cell;
use ckb_types::prelude::*;
use ckb_types::{
bytes::Bytes,
core::{cell::resolve_transaction, BlockBuilder, TransactionBuilder},
core::{cell::resolve_transaction, BlockBuilder, EpochNumberWithFraction, TransactionBuilder},
packed::{self, CellInput, CellOutputBuilder, OutPoint},
U256,
};
Expand Down Expand Up @@ -96,7 +96,7 @@ fn setup_node(height: u64) -> (TestNode, Shared) {

let consensus = ConsensusBuilder::default()
.genesis_block(block.clone())
.cellbase_maturity(0)
.cellbase_maturity(EpochNumberWithFraction::new(0, 0, 1))
.build();
let (shared, table) = SharedBuilder::default()
.consensus(consensus)
Expand Down
70 changes: 54 additions & 16 deletions test/src/specs/tx_pool/reference_header_maturity.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
use crate::utils::assert_send_transaction_fail;
use crate::{utils::is_committed, Net, Spec, DEFAULT_TX_PROPOSAL_WINDOW};
use ckb_chain_spec::ChainSpec;
use ckb_types::core::BlockNumber;
use ckb_types::core::EpochNumberWithFraction;
use log::info;

const MATURITY: BlockNumber = 5;
const CELLBASE_MATURITY_VALUE: u64 = 3;

pub struct ReferenceHeaderMaturity;

Expand All @@ -18,8 +18,29 @@ impl Spec for ReferenceHeaderMaturity {
node.generate_block();
info!("Use generated block's cellbase as tx input");
let base_block = node.get_tip_block();
info!("Ensure cellbase is matured");
node.generate_blocks(5);

let cellbase_maturity = EpochNumberWithFraction::from_full_value(CELLBASE_MATURITY_VALUE);

{
info!("Ensure cellbase is matured");
let base_epoch = base_block.epoch();
let threshold = cellbase_maturity.to_rational() + base_epoch.to_rational();
loop {
let tip_block = node.get_tip_block();
let tip_epoch = tip_block.epoch();
let current = tip_epoch.to_rational();
if current < threshold {
if tip_epoch.number() < base_epoch.number() + cellbase_maturity.number() {
let remained_blocks_in_epoch = tip_epoch.length() - tip_epoch.index();
node.generate_blocks(remained_blocks_in_epoch as usize);
} else {
node.generate_block();
}
} else {
break;
}
}
}

info!("Reference tip block's header to test for maturity");
let tip_block = node.get_tip_block();
Expand All @@ -31,21 +52,38 @@ impl Spec for ReferenceHeaderMaturity {
.header_dep(tip_block.hash())
.build();

(0..MATURITY).for_each(|i| {
info!("Tx is not matured in N + {} block", i);
assert_send_transaction_fail(node, &tx, "ImmatureHeader");
node.generate_block();
});
{
let base_epoch = tip_block.epoch();
let threshold = cellbase_maturity.to_rational() + base_epoch.to_rational();
loop {
let tip_block = node.get_tip_block();
let tip_epoch = tip_block.epoch();
let current = tip_epoch.to_rational();
if current < threshold {
info!(
"Tx is not matured in {} block (epoch = {})",
tip_block.number(),
tip_block.epoch()
);
assert_send_transaction_fail(node, &tx, "ImmatureHeader");
} else {
break;
}
if tip_epoch.number() < base_epoch.number() + cellbase_maturity.number() {
let remained_blocks_in_epoch = tip_epoch.length() - tip_epoch.index();
node.generate_blocks(remained_blocks_in_epoch as usize);
} else {
node.generate_block();
}
}
}

info!("Tx will be added to pending pool in N + {} block", MATURITY,);
info!("Tx will be added to pending pool");
let tx_hash = node.rpc_client().send_transaction(tx.clone().data().into());
assert_eq!(tx_hash, tx.hash());
node.assert_tx_pool_size(1, 0);

info!(
"Tx will be added to proposed pool in N + {} block",
MATURITY
);
info!("Tx will be added to proposed pool");
(0..DEFAULT_TX_PROPOSAL_WINDOW.0).for_each(|_| {
node.generate_block();
});
Expand All @@ -54,7 +92,7 @@ impl Spec for ReferenceHeaderMaturity {
node.generate_block();
node.assert_tx_pool_size(0, 0);

info!("Tx will be eventually accepted on chain",);
info!("Tx will be eventually accepted on chain");
node.generate_blocks(5);
let tx_status = node
.rpc_client()
Expand All @@ -69,7 +107,7 @@ impl Spec for ReferenceHeaderMaturity {

fn modify_chain_spec(&self) -> Box<dyn Fn(&mut ChainSpec) -> ()> {
Box::new(|spec_config| {
spec_config.params.cellbase_maturity = MATURITY;
spec_config.params.cellbase_maturity = CELLBASE_MATURITY_VALUE;
})
}
}
Loading

0 comments on commit e1799c2

Please sign in to comment.