Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: use epoch as the basic maturity unit #1646

Merged
merged 2 commits into from
Sep 26, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
2 changes: 1 addition & 1 deletion error/src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ macro_rules! assert_error_eq {
assert_eq!(
Into::<$crate::Error>::into($left).to_string(),
Into::<$crate::Error>::into($right).to_string(),
$($arg)+,
$($arg)+
);
}
}
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