age & coinbase
This commit is contained in:
parent
a5fb6e757f
commit
903d2b8878
|
@ -611,6 +611,7 @@ dependencies = [
|
|||
"primitives 0.1.0",
|
||||
"serialization 0.1.0",
|
||||
"test-data 0.1.0",
|
||||
"time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
|
@ -245,6 +245,11 @@ impl Transaction {
|
|||
pub fn outputs(&self) -> &[TransactionOutput] {
|
||||
&self.outputs
|
||||
}
|
||||
|
||||
pub fn is_coinbase(&self) -> bool {
|
||||
if self.inputs.len() != 1 { return false; }
|
||||
self.inputs[0].previous_output.hash.is_zero() && self.inputs[0].previous_output.index == 0xffffffff
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
|
@ -124,6 +124,11 @@ macro_rules! impl_hash {
|
|||
pub fn size() -> usize {
|
||||
$size
|
||||
}
|
||||
|
||||
pub fn is_zero(&self) -> bool {
|
||||
for b in self.0.iter() { if *b != 0 { return false; } }
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,3 +13,5 @@ parking_lot = "0.3"
|
|||
linked-hash-map = "0.3"
|
||||
test-data = { path = "../test-data" }
|
||||
byteorder = "0.5"
|
||||
time = "0.1"
|
||||
|
||||
|
|
|
@ -8,6 +8,8 @@ use super::{Verify, VerificationResult, Chain, Error};
|
|||
use primitives::hash::H256;
|
||||
use byteorder::{LittleEndian, BigEndian, ByteOrder};
|
||||
|
||||
const BLOCK_MAX_FUTURE: i64 = 2 * 60 * 60; // 2 hours
|
||||
|
||||
pub struct ChainVerifier {
|
||||
store: Arc<db::Store>,
|
||||
}
|
||||
|
@ -55,6 +57,10 @@ fn check_nbits(hash: &H256, n_bits: u32) -> bool {
|
|||
return true;
|
||||
}
|
||||
|
||||
fn age(protocol_time: u32) -> i64 {
|
||||
::time::get_time().sec - protocol_time as i64
|
||||
}
|
||||
|
||||
impl Verify for ChainVerifier {
|
||||
fn verify(&self, block: &chain::Block) -> VerificationResult {
|
||||
let hash = block.hash();
|
||||
|
@ -69,6 +75,16 @@ impl Verify for ChainVerifier {
|
|||
return Err(Error::Pow);
|
||||
}
|
||||
|
||||
// check if block timestamp is not far in the future
|
||||
if age(block.header().time) < -BLOCK_MAX_FUTURE {
|
||||
return Err(Error::Timestamp);
|
||||
}
|
||||
|
||||
// check first transaction is a coinbase transaction
|
||||
if !block.transactions()[0].is_coinbase() {
|
||||
return Err(Error::Coinbase)
|
||||
}
|
||||
|
||||
let parent = match self.store.block(BlockRef::Hash(block.header().previous_header_hash.clone())) {
|
||||
Some(b) => b,
|
||||
None => { return Ok(Chain::Orphan); }
|
||||
|
|
|
@ -7,6 +7,7 @@ extern crate serialization;
|
|||
extern crate parking_lot;
|
||||
extern crate linked_hash_map;
|
||||
extern crate byteorder;
|
||||
extern crate time;
|
||||
|
||||
#[cfg(test)]
|
||||
extern crate ethcore_devtools as devtools;
|
||||
|
|
Loading…
Reference in New Issue