blockchain generator
This commit is contained in:
parent
72f4dfdd7a
commit
ab9fddf6b2
@ -766,19 +766,24 @@ mod tests {
|
||||
use std::str::FromStr;
|
||||
use rustc_serialize::hex::FromHex;
|
||||
use util::hash::*;
|
||||
use util::sha3::Hashable;
|
||||
use blockchain::{BlockProvider, BlockChain, BlockChainConfig};
|
||||
use tests::helpers::*;
|
||||
use devtools::*;
|
||||
use blockchain::helpers::generators::ChainGenerator;
|
||||
use views::BlockView;
|
||||
|
||||
#[test]
|
||||
fn valid_tests_extra32() {
|
||||
let genesis = "f901fcf901f7a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0925002c3260b44e44c3edebad1cc442142b03020209df1ab8bb86752edbd2cd7a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000080832fefd8808454c98c8142a0363659b251bf8b819179874c8cce7b9b983d7f3704cbb58a3b334431f7032871889032d09c281e1236c0c0".from_hex().unwrap();
|
||||
fn basic_blockchain_insert() {
|
||||
let mut canon_chain = ChainGenerator::default();
|
||||
let genesis = canon_chain.next().unwrap();
|
||||
let first = canon_chain.next().unwrap();
|
||||
let genesis_hash = BlockView::new(&genesis).header_view().sha3();
|
||||
let first_hash = BlockView::new(&first).header_view().sha3();
|
||||
|
||||
let temp = RandomTempPath::new();
|
||||
let bc = BlockChain::new(BlockChainConfig::default(), &genesis, temp.as_path());
|
||||
|
||||
let genesis_hash = H256::from_str("3caa2203f3d7c136c0295ed128a7d31cea520b1ca5e27afe17d0853331798942").unwrap();
|
||||
|
||||
assert_eq!(bc.genesis_hash(), genesis_hash.clone());
|
||||
assert_eq!(bc.best_block_number(), 0);
|
||||
assert_eq!(bc.best_block_hash(), genesis_hash.clone());
|
||||
@ -786,12 +791,8 @@ mod tests {
|
||||
assert_eq!(bc.block_hash(1), None);
|
||||
assert_eq!(bc.block_details(&genesis_hash).unwrap().children, vec![]);
|
||||
|
||||
let first = "f90285f90219a03caa2203f3d7c136c0295ed128a7d31cea520b1ca5e27afe17d0853331798942a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0bac6177a79e910c98d86ec31a09ae37ac2de15b754fd7bed1ba52362c49416bfa0d45893a296c1490a978e0bd321b5f2635d8280365c1fe9f693d65f233e791344a0c7778a7376099ee2e5c455791c1885b5c361b95713fddcbe32d97fd01334d296b90100000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000400000000000000000000000000000000000000000000000000000008302000001832fefd882560b845627cb99a00102030405060708091011121314151617181920212223242526272829303132a08ccb2837fb2923bd97e8f2d08ea32012d6e34be018c73e49a0f98843e8f47d5d88e53be49fec01012ef866f864800a82c35094095e7baea6a6c7c4c2dfeb977efac326af552d8785012a05f200801ba0cb088b8d2ff76a7b2c6616c9d02fb6b7a501afbf8b69d7180b09928a1b80b5e4a06448fe7476c606582039bb72a9f6f4b4fad18507b8dfbd00eebbe151cc573cd2c0".from_hex().unwrap();
|
||||
|
||||
bc.insert_block(&first, vec![]);
|
||||
|
||||
let first_hash = H256::from_str("a940e5af7d146b3b917c953a82e1966b906dace3a4e355b5b0a4560190357ea1").unwrap();
|
||||
|
||||
assert_eq!(bc.block_hash(0), Some(genesis_hash.clone()));
|
||||
assert_eq!(bc.best_block_number(), 1);
|
||||
assert_eq!(bc.best_block_hash(), first_hash.clone());
|
||||
@ -1043,4 +1044,6 @@ mod tests {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
138
ethcore/src/blockchain/helpers/generators.rs
Normal file
138
ethcore/src/blockchain/helpers/generators.rs
Normal file
@ -0,0 +1,138 @@
|
||||
use util::rlp::*;
|
||||
use util::hash::{H256, H2048};
|
||||
use util::uint::{U256};
|
||||
use util::bytes::Bytes;
|
||||
use header::{BlockNumber, Header};
|
||||
use transaction::SignedTransaction;
|
||||
|
||||
/// Chain iterator interface.
|
||||
pub trait ChainIterator: Iterator {
|
||||
/// Should be called to create a fork of current iterator.
|
||||
/// Blocks generated by fork will have lower difficulty than current chain.
|
||||
fn fork(&mut self) -> Self;
|
||||
/// Should be called to create new block with given bloom.
|
||||
fn next_with_bloom(&mut self, bloom: H2048) -> Option<Self::Item>;
|
||||
}
|
||||
|
||||
/// Helper structure, used for encoding blocks.
|
||||
#[derive(Default)]
|
||||
struct Block {
|
||||
header: Header,
|
||||
transactions: Vec<SignedTransaction>,
|
||||
uncles: Vec<Header>
|
||||
}
|
||||
|
||||
impl Encodable for Block {
|
||||
fn rlp_append(&self, s: &mut RlpStream) {
|
||||
s.begin_list(3);
|
||||
s.append(&self.header);
|
||||
s.append(&self.transactions);
|
||||
s.append(&self.uncles);
|
||||
}
|
||||
}
|
||||
|
||||
/// Blockchain generator.
|
||||
pub struct ChainGenerator {
|
||||
/// Next block number.
|
||||
number: BlockNumber,
|
||||
/// Next block parent hash.
|
||||
parent_hash: H256,
|
||||
/// Next block difficulty.
|
||||
difficulty: U256,
|
||||
/// Number of forks of current block.
|
||||
number_of_forks: usize,
|
||||
}
|
||||
|
||||
impl ChainGenerator {
|
||||
fn prepare_block(&self) -> Block {
|
||||
let mut block = Block::default();
|
||||
block.header.parent_hash = self.parent_hash.clone();
|
||||
block.header.number = self.number;
|
||||
block.header.difficulty = self.difficulty;
|
||||
block
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for ChainGenerator {
|
||||
fn default() -> Self {
|
||||
ChainGenerator {
|
||||
number: 0,
|
||||
parent_hash: H256::default(),
|
||||
difficulty: U256::from(1000),
|
||||
number_of_forks: 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Iterator for ChainGenerator {
|
||||
type Item = Bytes;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
let block = self.prepare_block();
|
||||
self.number += 1;
|
||||
self.parent_hash = block.header.hash();
|
||||
self.number_of_forks = 0;
|
||||
Some(encode(&block).to_vec())
|
||||
}
|
||||
}
|
||||
|
||||
impl ChainIterator for ChainGenerator {
|
||||
fn fork(&mut self) -> Self {
|
||||
self.number_of_forks += 1;
|
||||
ChainGenerator {
|
||||
number: self.number,
|
||||
parent_hash: self.parent_hash.clone(),
|
||||
difficulty: self.difficulty - U256::from(self.number_of_forks),
|
||||
number_of_forks: 0
|
||||
}
|
||||
}
|
||||
|
||||
fn next_with_bloom(&mut self, bloom: H2048) -> Option<Self::Item> {
|
||||
let mut block = self.prepare_block();
|
||||
block.header.log_bloom = bloom;
|
||||
self.number += 1;
|
||||
self.parent_hash = block.header.hash();
|
||||
self.number_of_forks = 0;
|
||||
Some(encode(&block).to_vec())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use util::hash::H256;
|
||||
use util::sha3::Hashable;
|
||||
use views::BlockView;
|
||||
use super::{ChainIterator, ChainGenerator};
|
||||
|
||||
#[test]
|
||||
fn canon_chain_generator() {
|
||||
let mut canon_chain = ChainGenerator::default();
|
||||
|
||||
let genesis_rlp = canon_chain.next().unwrap();
|
||||
let genesis = BlockView::new(&genesis_rlp);
|
||||
|
||||
assert_eq!(genesis.header_view().parent_hash(), H256::default());
|
||||
assert_eq!(genesis.header_view().number(), 0);
|
||||
|
||||
let b1_rlp = canon_chain.next().unwrap();
|
||||
let b1 = BlockView::new(&b1_rlp);
|
||||
|
||||
assert_eq!(b1.header_view().parent_hash(), genesis.header_view().sha3());
|
||||
assert_eq!(b1.header_view().number(), 1);
|
||||
|
||||
let mut fork_chain = canon_chain.fork();
|
||||
|
||||
let b2_rlp_fork = fork_chain.next().unwrap();
|
||||
let b2_fork = BlockView::new(&b2_rlp_fork);
|
||||
|
||||
assert_eq!(b2_fork.header_view().parent_hash(), b1.header_view().sha3());
|
||||
assert_eq!(b2_fork.header_view().number(), 2);
|
||||
|
||||
let b2_rlp = canon_chain.next().unwrap();
|
||||
let b2 = BlockView::new(&b2_rlp);
|
||||
|
||||
assert_eq!(b2.header_view().parent_hash(), b1.header_view().sha3());
|
||||
assert_eq!(b2.header_view().number(), 2);
|
||||
assert!(b2.header_view().difficulty() > b2_fork.header_view().difficulty());
|
||||
}
|
||||
}
|
3
ethcore/src/blockchain/helpers/mod.rs
Normal file
3
ethcore/src/blockchain/helpers/mod.rs
Normal file
@ -0,0 +1,3 @@
|
||||
pub mod generators;
|
||||
|
||||
//pub use self::blockchain_builder::BlockChainBuilder;
|
@ -23,6 +23,8 @@ mod bloom_indexer;
|
||||
mod cache;
|
||||
mod tree_route;
|
||||
mod update;
|
||||
#[cfg(test)]
|
||||
mod helpers;
|
||||
|
||||
pub use self::blockchain::{BlockProvider, BlockChain, BlockChainConfig};
|
||||
pub use self::cache::CacheSize;
|
||||
|
Loading…
Reference in New Issue
Block a user