segwit: sigops check
This commit is contained in:
parent
abbffb49bb
commit
e84e0a57df
|
@ -11,7 +11,8 @@ pub const BITCOIN_CASH_FORK_BLOCK: u32 = 478559; // https://blockchair.com/bitco
|
||||||
pub mod segwit {
|
pub mod segwit {
|
||||||
/// The maximum allowed weight for a block, see BIP 141 (network rule)
|
/// The maximum allowed weight for a block, see BIP 141 (network rule)
|
||||||
pub const MAX_BLOCK_WEIGHT: usize = 4_000_000;
|
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.
|
/// Witness scale factor.
|
||||||
pub const WITNESS_SCALE_FACTOR: usize = 4;
|
pub const WITNESS_SCALE_FACTOR: usize = 4;
|
||||||
}
|
}
|
||||||
|
@ -217,6 +218,18 @@ impl ConsensusFork {
|
||||||
ConsensusFork::NoFork | ConsensusFork::SegWit2x(_) | ConsensusFork::BitcoinCash(_) => 20_000,
|
ConsensusFork::NoFork | ConsensusFork::SegWit2x(_) | ConsensusFork::BitcoinCash(_) => 20_000,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn check_block_sigops(&self, sigops: usize, height: u32, block_size: usize, deployments: &Deployments) -> bool {
|
||||||
|
match *self {
|
||||||
|
// 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 =>
|
||||||
|
sigops <= 20_000 * (max(block_size, 1_000_000) / 1_000_000),
|
||||||
|
ConsensusFork::NoFork | ConsensusFork::SegWit2x(_) if deployments.is_active("segwit") =>
|
||||||
|
sigops * segwit::WITNESS_SCALE_FACTOR <= segwit::MAX_BLOCK_SIGOPS_COST,
|
||||||
|
ConsensusFork::NoFork | ConsensusFork::SegWit2x(_) | ConsensusFork::BitcoinCash(_) =>
|
||||||
|
sigops <= 20_000,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
|
@ -110,11 +110,14 @@ impl<'a> BlockSerializedSize<'a> {
|
||||||
|
|
||||||
let is_segwit_active = self.deployments.is_active("segwit");
|
let is_segwit_active = self.deployments.is_active("segwit");
|
||||||
if is_segwit_active {
|
if is_segwit_active {
|
||||||
// TODO: block.vtx.size() * WITNESS_SCALE_FACTOR > MAX_BLOCK_WEIGHT
|
if self.block.transactions.len() * segwit::WITNESS_SCALE_FACTOR > segwit::MAX_BLOCK_WEIGHT {
|
||||||
|
return Err(Error::Weight);
|
||||||
|
}
|
||||||
|
|
||||||
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 * (segwit::WITNESS_SCALE_FACTOR - 1) + size_with_witness;
|
||||||
if weight > segwit::MAX_BLOCK_WEIGHT {
|
if weight > segwit::MAX_BLOCK_WEIGHT {
|
||||||
return Err(Error::Weight(weight));
|
return Err(Error::Weight);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -37,7 +37,7 @@ pub enum Error {
|
||||||
/// Block size is invalid
|
/// Block size is invalid
|
||||||
Size(usize),
|
Size(usize),
|
||||||
/// Block weight is invalid
|
/// Block weight is invalid
|
||||||
Weight(usize),
|
Weight,
|
||||||
/// Block transactions are not final.
|
/// Block transactions are not final.
|
||||||
NonFinalBlock,
|
NonFinalBlock,
|
||||||
/// Old version block.
|
/// Old version block.
|
||||||
|
|
Loading…
Reference in New Issue