some block builder routines

This commit is contained in:
NikVolf 2016-10-28 00:13:44 +03:00
parent e250d49001
commit 1ef314eb11
3 changed files with 222 additions and 0 deletions

204
test-data/src/block.rs Normal file
View File

@ -0,0 +1,204 @@
//! Block builder
use chain;
use primitives::hash::H256;
use invoke::{Invoke, Identity};
pub struct BlockBuilder<F=Identity> {
callback: F,
header: Option<chain::BlockHeader>,
transactions: Vec<chain::Transaction>,
}
impl BlockBuilder {
pub fn new() -> Self {
BlockBuilder::with_callback(Identity)
}
}
impl<F> BlockBuilder<F> where F: Invoke<chain::Block> {
pub fn with_callback(callback: F) -> Self {
BlockBuilder {
callback: callback,
header: None,
transactions: Vec::new(),
}
}
pub fn with_header(mut self, header: chain::BlockHeader) -> Self {
self.header = Some(header);
self
}
pub fn with_transaction(mut self, transaction: chain::Transaction) -> Self {
self.transactions.push(transaction);
self
}
pub fn with_transactions<I>(mut self, txs: I) -> Self
where I: IntoIterator<Item=chain::Transaction>
{
self.transactions.extend(txs);
self
}
pub fn with_raw(mut self, raw: &'static str) -> Self {
let raw_block: chain::Block = raw.into();
self.transactions = raw_block.transactions.to_vec();
self.header = Some(raw_block.header().clone());
self
}
pub fn header(self) -> BlockHeaderBuilder<Self> {
BlockHeaderBuilder::with_callback(self)
}
pub fn transaction(self) -> TransactionBuilder<Self> {
TransactionBuilder::with_callback(self)
}
pub fn build(self) -> F::Result {
self.callback.invoke(
chain::Block::new(
self.header.unwrap(),
self.transactions,
)
)
}
}
impl<F> Invoke<chain::BlockHeader> for BlockBuilder<F>
where F: Invoke<chain::Block>
{
type Result = Self;
fn invoke(self, header: chain::BlockHeader) -> Self {
self.with_header(header)
}
}
impl<F> Invoke<chain::Transaction> for BlockBuilder<F>
where F: Invoke<chain::Block>
{
type Result = Self;
fn invoke(self, tx: chain::Transaction) -> Self {
self.with_transaction(tx)
}
}
pub struct BlockHeaderBuilder<F=Identity> {
callback: F,
time: u32,
parent: H256,
nonce: u32,
nbits: u32,
version: u32,
merkle_root: H256,
}
impl<F> BlockHeaderBuilder<F> where F: Invoke<chain::BlockHeader> {
pub fn with_callback(callback: F) -> Self {
BlockHeaderBuilder {
callback: callback,
time: 0,
nonce: 0,
merkle_root: H256::from(0),
parent: H256::from(0),
nbits: 0,
version: 1,
}
}
pub fn parent(mut self, parent: H256) -> Self {
self.parent = parent;
self
}
pub fn time(mut self, time: u32) -> Self {
self.time = time;
self
}
pub fn merkle_root(mut self, merkle_root: H256) -> Self {
self.merkle_root = merkle_root;
self
}
pub fn nbits(mut self, nbits: u32) -> Self {
self.nbits = nbits;
self
}
pub fn nonce(mut self, nonce: u32) -> Self {
self.nonce = nonce;
self
}
pub fn build(self) -> F::Result {
self.callback.invoke(
chain::BlockHeader {
time: self.time,
previous_header_hash: self.parent,
nbits: self.nbits,
nonce: self.nonce,
merkle_root_hash: self.merkle_root,
version: self.version,
}
)
}
}
pub struct TransactionBuilder<F=Identity> {
callback: F,
version: i32,
lock_time: u32,
inputs: Vec<chain::TransactionInput>,
outputs: Vec<chain::TransactionOutput>,
}
impl<F> TransactionBuilder<F> where F: Invoke<chain::Transaction> {
fn with_callback(callback: F) -> Self {
TransactionBuilder {
callback: callback,
version: 1,
lock_time: 0,
inputs: Vec::new(),
outputs: Vec::new(),
}
}
pub fn lock_time(mut self, time: u32) -> Self {
self.lock_time = time;
self
}
pub fn build(self) -> F::Result {
self.callback.invoke(
chain::Transaction {
lock_time: self.lock_time,
version: self.version,
inputs: self.inputs,
outputs: self.outputs,
}
)
}
}
pub fn block_builder() -> BlockBuilder { BlockBuilder::new() }
#[test]
fn example1() {
let block = BlockBuilder::new().header().time(1000).build().build();
assert_eq!(block.header().time, 1000);
}
#[test]
fn example2() {
let block = BlockBuilder::new()
.header().build()
.transaction().lock_time(100500).build()
.build();
assert_eq!(block.transactions().len(), 1);
}

15
test-data/src/invoke.rs Normal file
View File

@ -0,0 +1,15 @@
//! invoke helper
pub trait Invoke<A> {
type Result;
fn invoke(self, arg: A) -> Self::Result;
}
pub struct Identity;
impl<A> Invoke<A> for Identity {
type Result = A;
fn invoke(self, arg: A) -> A { arg }
}

View File

@ -7,8 +7,11 @@ extern crate serialization as ser;
use chain::Block;
pub mod chain_builder;
pub mod block;
pub mod invoke;
pub use chain_builder::{ChainBuilder, TransactionBuilder};
pub use block::block_builder;
pub fn block1() -> Block {
let block: Block = "01000000ba8b9cda965dd8e536670f9ddec10e53aab14b20bacad27b9137190000000000190760b278fe7b8565fda3b968b918d5fd997f993b23674c0af3b6fde300b38f33a5914ce6ed5b1b01e32f570201000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0704e6ed5b1b014effffffff0100f2052a01000000434104b68a50eaa0287eff855189f949c1c6e5f58b37c88231373d8a59809cbae83059cc6469d65c665ccfd1cfeb75c6e8e19413bba7fbff9bc762419a76d87b16086eac000000000100000001a6b97044d03da79c005b20ea9c0e1a6d9dc12d9f7b91a5911c9030a439eed8f5000000004948304502206e21798a42fae0e854281abd38bacd1aeed3ee3738d9e1446618c4571d1090db022100e2ac980643b0b82c0e88ffdfec6b64e3e6ba35e7ba5fdd7d5d6cc8d25c6b241501ffffffff0100f2052a010000001976a914404371705fa9bd789a2fcd52d2c580b65d35549d88ac00000000".into();