monolith_height -> monolith_time (until block# is known)
This commit is contained in:
parent
9910fce3e2
commit
70b08a7ca0
|
@ -38,9 +38,9 @@ pub struct BitcoinCashConsensusParams {
|
|||
/// Height of difficulty adjustment hardfork.
|
||||
/// https://reviews.bitcoinabc.org/D601
|
||||
pub difficulty_adjustion_height: u32,
|
||||
/// Height of monolith (aka May 2018) hardfork.
|
||||
/// Time of monolith (aka May 2018) hardfork.
|
||||
/// https://github.com/bitcoincashorg/spec/blob/4fbb0face661e293bcfafe1a2a4744dcca62e50d/may-2018-hardfork.md
|
||||
pub monolith_height: u32,
|
||||
pub monolith_time: u32,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
|
@ -191,9 +191,9 @@ impl ConsensusFork {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn max_block_size(&self, height: u32) -> usize {
|
||||
pub fn max_block_size(&self, height: u32, median_time_past: u32) -> usize {
|
||||
match *self {
|
||||
ConsensusFork::BitcoinCash(ref fork) if height >= fork.monolith_height => 32_000_000,
|
||||
ConsensusFork::BitcoinCash(ref fork) if median_time_past >= fork.monolith_time => 32_000_000,
|
||||
ConsensusFork::BitcoinCash(ref fork) if height >= fork.height => 8_000_000,
|
||||
ConsensusFork::NoFork | ConsensusFork::BitcoinCash(_) => 1_000_000,
|
||||
}
|
||||
|
@ -233,17 +233,17 @@ impl BitcoinCashConsensusParams {
|
|||
Network::Mainnet | Network::Other(_) => BitcoinCashConsensusParams {
|
||||
height: 478559,
|
||||
difficulty_adjustion_height: 504031,
|
||||
monolith_height: ::std::u32::MAX, // TODO: change me + tests
|
||||
monolith_time: 1526400000,
|
||||
},
|
||||
Network::Testnet => BitcoinCashConsensusParams {
|
||||
height: 1155876,
|
||||
difficulty_adjustion_height: 1188697,
|
||||
monolith_height: ::std::u32::MAX, // TODO: change me
|
||||
monolith_time: 1526400000,
|
||||
},
|
||||
Network::Regtest | Network::Unitest => BitcoinCashConsensusParams {
|
||||
height: 0,
|
||||
difficulty_adjustion_height: 0,
|
||||
monolith_height: ::std::u32::MAX, // TODO: change me
|
||||
monolith_time: 1526400000,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ use synchronization_server::{Server, ServerTask};
|
|||
use synchronization_verifier::{TransactionVerificationSink};
|
||||
use primitives::hash::H256;
|
||||
use miner::BlockTemplate;
|
||||
use verification::median_timestamp_inclusive;
|
||||
use synchronization_peers::{TransactionAnnouncementType, BlockAnnouncementType};
|
||||
use types::{PeerIndex, RequestId, StorageRef, MemoryPoolRef, PeersRef, ExecutorRef,
|
||||
ClientRef, ServerRef, SynchronizationStateRef, SyncListenerRef};
|
||||
|
@ -275,11 +276,14 @@ impl<T, U, V> LocalNode<T, U, V> where T: TaskExecutor, U: Server, V: Client {
|
|||
|
||||
/// Get block template for mining
|
||||
pub fn get_block_template(&self) -> BlockTemplate {
|
||||
let height = self.storage.best_block().number;
|
||||
let max_block_size = self.consensus.fork.max_block_size(height);
|
||||
let previous_block_height = self.storage.best_block().number;
|
||||
let previous_block_header = self.storage.block_header(previous_block_height.into()).expect("best block is in db; qed");
|
||||
let median_timestamp = median_timestamp_inclusive(previous_block_header.hash(), self.storage.as_block_header_provider());
|
||||
let new_block_height = previous_block_height + 1;
|
||||
let max_block_size = self.consensus.fork.max_block_size(new_block_height, median_timestamp);
|
||||
let block_assembler = BlockAssembler {
|
||||
max_block_size: max_block_size as u32,
|
||||
max_block_sigops: self.consensus.fork.max_block_sigops(height, max_block_size) as u32,
|
||||
max_block_sigops: self.consensus.fork.max_block_sigops(new_block_height, max_block_size) as u32,
|
||||
};
|
||||
let memory_pool = &*self.memory_pool.read();
|
||||
block_assembler.create_new_block(&self.storage, memory_pool, time::get_time().sec as u32, &self.consensus)
|
||||
|
|
|
@ -27,12 +27,13 @@ impl<'a> BlockAcceptor<'a> {
|
|||
consensus: &'a ConsensusParams,
|
||||
block: CanonBlock<'a>,
|
||||
height: u32,
|
||||
median_time_past: u32,
|
||||
deployments: &'a BlockDeployments<'a>,
|
||||
headers: &'a BlockHeaderProvider,
|
||||
) -> Self {
|
||||
BlockAcceptor {
|
||||
finality: BlockFinality::new(block, height, deployments, headers),
|
||||
serialized_size: BlockSerializedSize::new(block, consensus, deployments, height),
|
||||
serialized_size: BlockSerializedSize::new(block, consensus, deployments, height, median_time_past),
|
||||
coinbase_script: BlockCoinbaseScript::new(block, consensus, height),
|
||||
coinbase_claim: BlockCoinbaseClaim::new(block, store, height),
|
||||
sigops: BlockSigops::new(block, store, consensus, height),
|
||||
|
@ -89,17 +90,19 @@ pub struct BlockSerializedSize<'a> {
|
|||
block: CanonBlock<'a>,
|
||||
consensus: &'a ConsensusParams,
|
||||
height: u32,
|
||||
median_time_past: u32,
|
||||
segwit_active: bool,
|
||||
}
|
||||
|
||||
impl<'a> BlockSerializedSize<'a> {
|
||||
fn new(block: CanonBlock<'a>, consensus: &'a ConsensusParams, deployments: &'a BlockDeployments<'a>, height: u32) -> Self {
|
||||
fn new(block: CanonBlock<'a>, consensus: &'a ConsensusParams, deployments: &'a BlockDeployments<'a>, height: u32, median_time_past: u32) -> Self {
|
||||
let segwit_active = deployments.segwit();
|
||||
|
||||
BlockSerializedSize {
|
||||
block: block,
|
||||
consensus: consensus,
|
||||
height: height,
|
||||
median_time_past: median_time_past,
|
||||
segwit_active: segwit_active,
|
||||
}
|
||||
}
|
||||
|
@ -112,7 +115,7 @@ impl<'a> BlockSerializedSize<'a> {
|
|||
// after SegWit: without witness data, block size should be <= 1_000_000
|
||||
// after BitcoinCash fork: block size is increased to 8_000_000
|
||||
if size < self.consensus.fork.min_block_size(self.height) ||
|
||||
size > self.consensus.fork.max_block_size(self.height) {
|
||||
size > self.consensus.fork.max_block_size(self.height, self.median_time_past) {
|
||||
return Err(Error::Size(size));
|
||||
}
|
||||
|
||||
|
|
|
@ -17,13 +17,13 @@ pub struct ChainAcceptor<'a> {
|
|||
}
|
||||
|
||||
impl<'a> ChainAcceptor<'a> {
|
||||
pub fn new(store: &'a Store, consensus: &'a ConsensusParams, verification_level: VerificationLevel, block: CanonBlock<'a>, height: u32, deployments: &'a BlockDeployments) -> Self {
|
||||
pub fn new(store: &'a Store, consensus: &'a ConsensusParams, verification_level: VerificationLevel, block: CanonBlock<'a>, height: u32, median_time_past: u32, deployments: &'a BlockDeployments) -> Self {
|
||||
trace!(target: "verification", "Block verification {}", block.hash().to_reversed_str());
|
||||
let output_store = DuplexTransactionOutputProvider::new(store.as_transaction_output_provider(), block.raw());
|
||||
let headers = store.as_block_header_provider();
|
||||
|
||||
ChainAcceptor {
|
||||
block: BlockAcceptor::new(store.as_transaction_output_provider(), consensus, block, height, deployments, headers),
|
||||
block: BlockAcceptor::new(store.as_transaction_output_provider(), consensus, block, height, median_time_past, deployments, headers),
|
||||
header: HeaderAcceptor::new(headers, consensus, block.header(), height, deployments),
|
||||
transactions: block.transactions()
|
||||
.into_iter()
|
||||
|
@ -37,6 +37,7 @@ impl<'a> ChainAcceptor<'a> {
|
|||
block.hash(),
|
||||
height,
|
||||
block.header.raw.time,
|
||||
median_time_past,
|
||||
tx_index,
|
||||
deployments,
|
||||
))
|
||||
|
|
|
@ -36,6 +36,7 @@ impl<'a> TransactionAcceptor<'a> {
|
|||
block_hash: &'a H256,
|
||||
height: u32,
|
||||
time: u32,
|
||||
median_time_past: u32,
|
||||
transaction_index: usize,
|
||||
deployments: &'a BlockDeployments<'a>,
|
||||
) -> Self {
|
||||
|
@ -48,7 +49,7 @@ impl<'a> TransactionAcceptor<'a> {
|
|||
overspent: TransactionOverspent::new(transaction, output_store),
|
||||
double_spent: TransactionDoubleSpend::new(transaction, output_store),
|
||||
return_replay_protection: TransactionReturnReplayProtection::new(transaction, consensus, height),
|
||||
eval: TransactionEval::new(transaction, output_store, consensus, verification_level, height, time, deployments),
|
||||
eval: TransactionEval::new(transaction, output_store, consensus, verification_level, height, time, median_time_past, deployments),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -85,11 +86,12 @@ impl<'a> MemoryPoolTransactionAcceptor<'a> {
|
|||
transaction: CanonTransaction<'a>,
|
||||
height: u32,
|
||||
time: u32,
|
||||
median_time_past: u32,
|
||||
deployments: &'a BlockDeployments<'a>,
|
||||
) -> Self {
|
||||
trace!(target: "verification", "Mempool-Tx verification {}", transaction.hash.to_reversed_str());
|
||||
let transaction_index = 0;
|
||||
let max_block_sigops = consensus.fork.max_block_sigops(height, consensus.fork.max_block_size(height));
|
||||
let max_block_sigops = consensus.fork.max_block_sigops(height, consensus.fork.max_block_size(height, median_time_past));
|
||||
MemoryPoolTransactionAcceptor {
|
||||
missing_inputs: TransactionMissingInputs::new(transaction, output_store, transaction_index),
|
||||
maturity: TransactionMaturity::new(transaction, meta_store, height),
|
||||
|
@ -97,7 +99,7 @@ impl<'a> MemoryPoolTransactionAcceptor<'a> {
|
|||
sigops: TransactionSigops::new(transaction, output_store, consensus, max_block_sigops, time),
|
||||
double_spent: TransactionDoubleSpend::new(transaction, output_store),
|
||||
return_replay_protection: TransactionReturnReplayProtection::new(transaction, consensus, height),
|
||||
eval: TransactionEval::new(transaction, output_store, consensus, VerificationLevel::Full, height, time, deployments),
|
||||
eval: TransactionEval::new(transaction, output_store, consensus, VerificationLevel::Full, height, time, median_time_past, deployments),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -303,6 +305,7 @@ impl<'a> TransactionEval<'a> {
|
|||
verification_level: VerificationLevel,
|
||||
height: u32,
|
||||
time: u32,
|
||||
median_timestamp: u32,
|
||||
deployments: &'a BlockDeployments,
|
||||
) -> Self {
|
||||
let verify_p2sh = time >= params.bip16_time;
|
||||
|
@ -313,7 +316,7 @@ impl<'a> TransactionEval<'a> {
|
|||
let verify_locktime = height >= params.bip65_height;
|
||||
let verify_dersig = height >= params.bip66_height;
|
||||
let verify_monolith_opcodes = match params.fork {
|
||||
ConsensusFork::BitcoinCash(ref fork) if height >= fork.monolith_height => true,
|
||||
ConsensusFork::BitcoinCash(ref fork) if median_timestamp >= fork.monolith_time => true,
|
||||
_ => false,
|
||||
};
|
||||
let signature_version = match params.fork {
|
||||
|
|
|
@ -13,6 +13,7 @@ use verify_transaction::MemoryPoolTransactionVerifier;
|
|||
use accept_chain::ChainAcceptor;
|
||||
use accept_transaction::MemoryPoolTransactionAcceptor;
|
||||
use deployments::{Deployments, BlockDeployments};
|
||||
use timestamp::median_timestamp_inclusive;
|
||||
use {Verify, VerificationLevel};
|
||||
|
||||
pub struct BackwardsCompatibleChainVerifier {
|
||||
|
@ -43,6 +44,8 @@ impl BackwardsCompatibleChainVerifier {
|
|||
assert_eq!(Some(self.store.best_block().hash), self.store.block_hash(self.store.best_block().number));
|
||||
let block_origin = self.store.block_origin(&block.header)?;
|
||||
trace!(target: "verification", "verify_block: {:?} best_block: {:?} block_origin: {:?}", block.hash().reversed(), self.store.best_block(), block_origin);
|
||||
|
||||
let median_time_past = median_timestamp_inclusive(block.header.raw.previous_header_hash.clone(), self.store.as_block_header_provider());
|
||||
match block_origin {
|
||||
BlockOrigin::KnownBlock => {
|
||||
// there should be no known blocks at this point
|
||||
|
@ -52,7 +55,8 @@ impl BackwardsCompatibleChainVerifier {
|
|||
let header_provider = self.store.as_store().as_block_header_provider();
|
||||
let deployments = BlockDeployments::new(&self.deployments, block_number, header_provider, &self.consensus);
|
||||
let canon_block = CanonBlock::new(block);
|
||||
let chain_acceptor = ChainAcceptor::new(self.store.as_store(), &self.consensus, verification_level, canon_block, block_number, &deployments);
|
||||
let chain_acceptor = ChainAcceptor::new(self.store.as_store(), &self.consensus, verification_level,
|
||||
canon_block, block_number, median_time_past, &deployments);
|
||||
chain_acceptor.check()?;
|
||||
},
|
||||
BlockOrigin::SideChain(origin) => {
|
||||
|
@ -61,7 +65,8 @@ impl BackwardsCompatibleChainVerifier {
|
|||
let deployments = BlockDeployments::new(&self.deployments, block_number, header_provider, &self.consensus);
|
||||
let fork = self.store.fork(origin)?;
|
||||
let canon_block = CanonBlock::new(block);
|
||||
let chain_acceptor = ChainAcceptor::new(fork.store(), &self.consensus, verification_level, canon_block, block_number, &deployments);
|
||||
let chain_acceptor = ChainAcceptor::new(fork.store(), &self.consensus, verification_level, canon_block,
|
||||
block_number, median_time_past, &deployments);
|
||||
chain_acceptor.check()?;
|
||||
},
|
||||
BlockOrigin::SideChainBecomingCanonChain(origin) => {
|
||||
|
@ -70,7 +75,8 @@ impl BackwardsCompatibleChainVerifier {
|
|||
let deployments = BlockDeployments::new(&self.deployments, block_number, header_provider, &self.consensus);
|
||||
let fork = self.store.fork(origin)?;
|
||||
let canon_block = CanonBlock::new(block);
|
||||
let chain_acceptor = ChainAcceptor::new(fork.store(), &self.consensus, verification_level, canon_block, block_number, &deployments);
|
||||
let chain_acceptor = ChainAcceptor::new(fork.store(), &self.consensus, verification_level, canon_block,
|
||||
block_number, median_time_past, &deployments);
|
||||
chain_acceptor.check()?;
|
||||
},
|
||||
}
|
||||
|
@ -111,6 +117,11 @@ impl BackwardsCompatibleChainVerifier {
|
|||
// now let's do full verification
|
||||
let noop = NoopStore;
|
||||
let output_store = DuplexTransactionOutputProvider::new(prevout_provider, &noop);
|
||||
let previous_block_number = height.checked_sub(1)
|
||||
.expect("height is the height of future block of new tx; genesis block can't be in the future; qed");
|
||||
let previous_block_header = block_header_provider.block_header(previous_block_number.into())
|
||||
.expect("blocks up to height should be in db; qed");
|
||||
let median_time_past = median_timestamp_inclusive(previous_block_header.hash(), block_header_provider);
|
||||
let tx_acceptor = MemoryPoolTransactionAcceptor::new(
|
||||
self.store.as_transaction_meta_provider(),
|
||||
output_store,
|
||||
|
@ -118,6 +129,7 @@ impl BackwardsCompatibleChainVerifier {
|
|||
canon_tx,
|
||||
height,
|
||||
time,
|
||||
median_time_past,
|
||||
&deployments,
|
||||
);
|
||||
tx_acceptor.check()
|
||||
|
|
|
@ -110,7 +110,7 @@ pub use verify_transaction::{TransactionVerifier, MemoryPoolTransactionVerifier}
|
|||
pub use chain_verifier::BackwardsCompatibleChainVerifier;
|
||||
pub use error::{Error, TransactionError};
|
||||
pub use sigops::transaction_sigops;
|
||||
pub use timestamp::median_timestamp;
|
||||
pub use timestamp::{median_timestamp, median_timestamp_inclusive};
|
||||
pub use work::{work_required, is_valid_proof_of_work, is_valid_proof_of_work_hash, block_reward_satoshi};
|
||||
pub use deployments::Deployments;
|
||||
|
||||
|
|
|
@ -217,6 +217,7 @@ mod tests {
|
|||
let uahf_consensus = ConsensusParams::new(Network::Mainnet, ConsensusFork::BitcoinCash(BitcoinCashConsensusParams {
|
||||
height: 1000,
|
||||
difficulty_adjustion_height: 0xffffffff,
|
||||
monolith_time: 0xffffffff,
|
||||
}));
|
||||
let mut header_provider = MemoryBlockHeaderProvider::default();
|
||||
header_provider.insert(BlockHeader {
|
||||
|
@ -269,6 +270,7 @@ mod tests {
|
|||
let uahf_consensus = ConsensusParams::new(Network::Mainnet, ConsensusFork::BitcoinCash(BitcoinCashConsensusParams {
|
||||
height: 1000,
|
||||
difficulty_adjustion_height: 0xffffffff,
|
||||
monolith_time: 0xffffffff,
|
||||
}));
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue