segwit2x: get rid of hardcoded SegWit constants
This commit is contained in:
parent
07e5064755
commit
4f9811fe6f
|
@ -7,16 +7,6 @@ pub const SEGWIT2X_FORK_BLOCK: u32 = 0xFFFFFFFF; // not known (yet?)
|
||||||
/// First block of BitcoinCash fork.
|
/// First block of BitcoinCash fork.
|
||||||
pub const BITCOIN_CASH_FORK_BLOCK: u32 = 478559; // https://blockchair.com/bitcoin-cash/block/478559
|
pub const BITCOIN_CASH_FORK_BLOCK: u32 = 478559; // https://blockchair.com/bitcoin-cash/block/478559
|
||||||
|
|
||||||
/// Segwit-related constants.
|
|
||||||
pub mod segwit {
|
|
||||||
/// The maximum allowed weight for a block, see BIP 141 (network rule).
|
|
||||||
pub const MAX_BLOCK_WEIGHT: usize = 4_000_000;
|
|
||||||
/// The maximum allowed number of signature check operations in a block (network rule).
|
|
||||||
pub const MAX_BLOCK_SIGOPS_COST: usize = 80_000;
|
|
||||||
/// Witness scale factor.
|
|
||||||
pub const WITNESS_SCALE_FACTOR: usize = 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
/// Parameters that influence chain consensus.
|
/// Parameters that influence chain consensus.
|
||||||
pub struct ConsensusParams {
|
pub struct ConsensusParams {
|
||||||
|
@ -57,6 +47,7 @@ pub enum ConsensusFork {
|
||||||
/// Technical specification:
|
/// Technical specification:
|
||||||
/// Segregated Witness (Consensus layer) - https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki
|
/// Segregated Witness (Consensus layer) - https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki
|
||||||
/// Block size increase to 2MB - https://github.com/bitcoin/bips/blob/master/bip-0102.mediawiki
|
/// Block size increase to 2MB - https://github.com/bitcoin/bips/blob/master/bip-0102.mediawiki
|
||||||
|
/// Readiness checklist - https://segwit2x.github.io/segwit2x-announce.html
|
||||||
SegWit2x(u32),
|
SegWit2x(u32),
|
||||||
/// Bitcoin Cash (aka UAHF).
|
/// Bitcoin Cash (aka UAHF).
|
||||||
/// `u32` is height of the first block, for which new consensus rules are applied.
|
/// `u32` is height of the first block, for which new consensus rules are applied.
|
||||||
|
@ -171,6 +162,11 @@ impl ConsensusFork {
|
||||||
160_000
|
160_000
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Witness scale factor (equal among all forks)
|
||||||
|
pub fn witness_scale_factor() -> usize {
|
||||||
|
4
|
||||||
|
}
|
||||||
|
|
||||||
pub fn max_transaction_size(&self) -> usize {
|
pub fn max_transaction_size(&self) -> usize {
|
||||||
// BitcoinCash: according to REQ-5: max size of tx is still 1_000_000
|
// BitcoinCash: according to REQ-5: max size of tx is still 1_000_000
|
||||||
// SegWit: size * 4 <= 4_000_000 ===> max size of tx is still 1_000_000
|
// SegWit: size * 4 <= 4_000_000 ===> max size of tx is still 1_000_000
|
||||||
|
@ -198,6 +194,8 @@ impl ConsensusFork {
|
||||||
// according to REQ-5: max_block_sigops = 20000 * ceil((max(blocksize_bytes, 1000000) / 1000000))
|
// according to REQ-5: max_block_sigops = 20000 * ceil((max(blocksize_bytes, 1000000) / 1000000))
|
||||||
ConsensusFork::BitcoinCash(fork_height) if height >= fork_height && block_size > 1_000_000 =>
|
ConsensusFork::BitcoinCash(fork_height) if height >= fork_height && block_size > 1_000_000 =>
|
||||||
20_000 * (max(block_size, 1_000_000) / 1_000_000),
|
20_000 * (max(block_size, 1_000_000) / 1_000_000),
|
||||||
|
ConsensusFork::SegWit2x(fork_height) if height >= fork_height =>
|
||||||
|
40_000,
|
||||||
ConsensusFork::NoFork | ConsensusFork::SegWit2x(_) | ConsensusFork::BitcoinCash(_) => 20_000,
|
ConsensusFork::NoFork | ConsensusFork::SegWit2x(_) | ConsensusFork::BitcoinCash(_) => 20_000,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -205,9 +203,22 @@ impl ConsensusFork {
|
||||||
pub fn max_block_sigops_cost(&self, height: u32, block_size: usize) -> usize {
|
pub fn max_block_sigops_cost(&self, height: u32, block_size: usize) -> usize {
|
||||||
match *self {
|
match *self {
|
||||||
ConsensusFork::BitcoinCash(_) =>
|
ConsensusFork::BitcoinCash(_) =>
|
||||||
self.max_block_sigops(height, block_size) * segwit::WITNESS_SCALE_FACTOR,
|
self.max_block_sigops(height, block_size) * Self::witness_scale_factor(),
|
||||||
|
ConsensusFork::SegWit2x(fork_height) if height >= fork_height =>
|
||||||
|
160_000,
|
||||||
ConsensusFork::NoFork | ConsensusFork::SegWit2x(_) =>
|
ConsensusFork::NoFork | ConsensusFork::SegWit2x(_) =>
|
||||||
segwit::MAX_BLOCK_SIGOPS_COST,
|
80_000,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn max_block_weight(&self, height: u32) -> usize {
|
||||||
|
match *self {
|
||||||
|
ConsensusFork::SegWit2x(fork_height) if height >= fork_height =>
|
||||||
|
8_000_000,
|
||||||
|
ConsensusFork::NoFork | ConsensusFork::SegWit2x(_) =>
|
||||||
|
4_000_000,
|
||||||
|
ConsensusFork::BitcoinCash(_) =>
|
||||||
|
unreachable!("BitcoinCash has no SegWit; weight is only checked with SegWit activated; qed"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -272,8 +283,8 @@ mod tests {
|
||||||
fn test_consensus_fork_max_block_sigops() {
|
fn test_consensus_fork_max_block_sigops() {
|
||||||
assert_eq!(ConsensusFork::NoFork.max_block_sigops(0, 1_000_000), 20_000);
|
assert_eq!(ConsensusFork::NoFork.max_block_sigops(0, 1_000_000), 20_000);
|
||||||
assert_eq!(ConsensusFork::SegWit2x(100).max_block_sigops(0, 1_000_000), 20_000);
|
assert_eq!(ConsensusFork::SegWit2x(100).max_block_sigops(0, 1_000_000), 20_000);
|
||||||
assert_eq!(ConsensusFork::SegWit2x(100).max_block_sigops(100, 2_000_000), 20_000);
|
assert_eq!(ConsensusFork::SegWit2x(100).max_block_sigops(100, 2_000_000), 40_000);
|
||||||
assert_eq!(ConsensusFork::SegWit2x(100).max_block_sigops(200, 3_000_000), 20_000);
|
assert_eq!(ConsensusFork::SegWit2x(100).max_block_sigops(200, 3_000_000), 40_000);
|
||||||
assert_eq!(ConsensusFork::BitcoinCash(100).max_block_sigops(0, 1_000_000), 20_000);
|
assert_eq!(ConsensusFork::BitcoinCash(100).max_block_sigops(0, 1_000_000), 20_000);
|
||||||
assert_eq!(ConsensusFork::BitcoinCash(100).max_block_sigops(100, 2_000_000), 40_000);
|
assert_eq!(ConsensusFork::BitcoinCash(100).max_block_sigops(100, 2_000_000), 40_000);
|
||||||
assert_eq!(ConsensusFork::BitcoinCash(100).max_block_sigops(200, 3_000_000), 60_000);
|
assert_eq!(ConsensusFork::BitcoinCash(100).max_block_sigops(200, 3_000_000), 60_000);
|
||||||
|
|
|
@ -8,7 +8,7 @@ mod magic;
|
||||||
|
|
||||||
pub use primitives::{hash, compact};
|
pub use primitives::{hash, compact};
|
||||||
|
|
||||||
pub use consensus::{ConsensusParams, ConsensusFork, SEGWIT2X_FORK_BLOCK, BITCOIN_CASH_FORK_BLOCK, segwit};
|
pub use consensus::{ConsensusParams, ConsensusFork, SEGWIT2X_FORK_BLOCK, BITCOIN_CASH_FORK_BLOCK};
|
||||||
pub use deployments::Deployment;
|
pub use deployments::Deployment;
|
||||||
pub use magic::Magic;
|
pub use magic::Magic;
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use network::{ConsensusParams, segwit};
|
use network::{ConsensusParams, ConsensusFork};
|
||||||
use crypto::dhash256;
|
use crypto::dhash256;
|
||||||
use db::{TransactionOutputProvider, BlockHeaderProvider};
|
use db::{TransactionOutputProvider, BlockHeaderProvider};
|
||||||
use script;
|
use script;
|
||||||
|
@ -113,8 +113,8 @@ impl<'a> BlockSerializedSize<'a> {
|
||||||
|
|
||||||
if self.segwit_active {
|
if self.segwit_active {
|
||||||
let size_with_witness = self.block.size_with_witness();
|
let size_with_witness = self.block.size_with_witness();
|
||||||
let weight = size * (segwit::WITNESS_SCALE_FACTOR - 1) + size_with_witness;
|
let weight = size * (ConsensusFork::witness_scale_factor() - 1) + size_with_witness;
|
||||||
if weight > segwit::MAX_BLOCK_WEIGHT {
|
if weight > self.consensus.fork.max_block_weight(self.height) {
|
||||||
return Err(Error::Weight);
|
return Err(Error::Weight);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
// TODO: excess clones
|
use network::ConsensusFork;
|
||||||
use network::segwit;
|
|
||||||
use chain::Transaction;
|
use chain::Transaction;
|
||||||
use db::TransactionOutputProvider;
|
use db::TransactionOutputProvider;
|
||||||
use script::{Script, ScriptWitness};
|
use script::{Script, ScriptWitness};
|
||||||
|
@ -47,7 +46,7 @@ pub fn transaction_sigops_cost(
|
||||||
store: &TransactionOutputProvider,
|
store: &TransactionOutputProvider,
|
||||||
sigops: usize,
|
sigops: usize,
|
||||||
) -> usize {
|
) -> usize {
|
||||||
let sigops_cost = sigops * segwit::WITNESS_SCALE_FACTOR;
|
let sigops_cost = sigops * ConsensusFork::witness_scale_factor();
|
||||||
let witness_sigops_cost: usize = transaction.inputs.iter()
|
let witness_sigops_cost: usize = transaction.inputs.iter()
|
||||||
.map(|input| store.transaction_output(&input.previous_output, usize::max_value())
|
.map(|input| store.transaction_output(&input.previous_output, usize::max_value())
|
||||||
.map(|output| witness_sigops(&Script::new(input.script_sig.clone()), &Script::new(output.script_pubkey.clone()), &input.script_witness,))
|
.map(|output| witness_sigops(&Script::new(input.script_sig.clone()), &Script::new(output.script_pubkey.clone()), &input.script_witness,))
|
||||||
|
|
Loading…
Reference in New Issue