OpenBlock::close() should be complete. No tests yet though.

This commit is contained in:
Gav Wood 2016-01-09 23:47:15 +01:00
parent 9a79a9032d
commit 53fada4f4a
4 changed files with 76 additions and 35 deletions

View File

@ -111,7 +111,7 @@ impl<'engine> OpenBlock<'engine> {
let env_info = self.env_info(); let env_info = self.env_info();
match self.block.state.apply(&env_info, self.engine, &t, true) { match self.block.state.apply(&env_info, self.engine, &t, true) {
Ok(x) => { Ok(x) => {
self.block.archive_set.insert(h.unwrap_or_else(||t.sha3())); self.block.archive_set.insert(h.unwrap_or_else(||t.hash()));
self.block.archive.push(Entry { transaction: t, receipt: x.receipt }); self.block.archive.push(Entry { transaction: t, receipt: x.receipt });
Ok(&self.block.archive.last().unwrap().receipt) Ok(&self.block.archive.last().unwrap().receipt)
} }
@ -122,15 +122,14 @@ impl<'engine> OpenBlock<'engine> {
/// Turn this into a `ClosedBlock`. A BlockChain must be provided in order to figure out the uncles. /// Turn this into a `ClosedBlock`. A BlockChain must be provided in order to figure out the uncles.
pub fn close(self, uncles: Vec<Header>, author: Address, extra_data: Bytes) -> ClosedBlock<'engine> { pub fn close(self, uncles: Vec<Header>, author: Address, extra_data: Bytes) -> ClosedBlock<'engine> {
let mut s = self; let mut s = self;
// populate rest of header.
s.engine.on_close_block(&mut s.block); s.engine.on_close_block(&mut s.block);
s.block.header.author = author; s.block.header.author = author;
// s.header.transactions_root = ...; s.block.header.transactions_root = ordered_trie_root(s.block.archive.iter().map(|ref e| e.transaction.rlp_bytes()).collect());
let uncle_bytes = uncles.iter().fold(RlpStream::new_list(uncles.len()), |mut s, u| {s.append(&u.rlp(Seal::With)); s} ).out(); let uncle_bytes = uncles.iter().fold(RlpStream::new_list(uncles.len()), |mut s, u| {s.append(&u.rlp(Seal::With)); s} ).out();
s.block.header.uncles_hash = uncle_bytes.sha3(); s.block.header.uncles_hash = uncle_bytes.sha3();
s.block.header.extra_data = extra_data; s.block.header.extra_data = extra_data;
s.block.header.state_root = s.block.state.root().clone(); s.block.header.state_root = s.block.state.root().clone();
// s.header.receipts_root = ...; s.block.header.receipts_root = ordered_trie_root(s.block.archive.iter().map(|ref e| e.receipt.rlp_bytes()).collect());
s.block.header.log_bloom = s.block.archive.iter().fold(LogBloom::zero(), |mut b, e| {b |= &e.receipt.log_bloom; b}); s.block.header.log_bloom = s.block.archive.iter().fold(LogBloom::zero(), |mut b, e| {b |= &e.receipt.log_bloom; b});
s.block.header.gas_used = s.block.archive.last().map(|t| t.receipt.gas_used).unwrap_or(U256::from(0)); s.block.header.gas_used = s.block.archive.last().map(|t| t.receipt.gas_used).unwrap_or(U256::from(0));
s.block.header.note_dirty(); s.block.header.note_dirty();
@ -175,12 +174,10 @@ impl IsBlock for SealedBlock {
#[test] #[test]
fn open_block() { fn open_block() {
use spec::*; use spec::*;
use ethereum::*; let engine = Spec::new_test().to_engine().unwrap();
let engine = new_morden().to_engine().unwrap();
let genesis_header = engine.spec().genesis_header(); let genesis_header = engine.spec().genesis_header();
let mut db = OverlayDB::new_temp(); let mut db = OverlayDB::new_temp();
engine.spec().ensure_db_good(&mut db); engine.spec().ensure_db_good(&mut db);
let b = OpenBlock::new(engine.deref(), db, &genesis_header, vec![genesis_header.hash()]); let b = OpenBlock::new(engine.deref(), db, &genesis_header, vec![genesis_header.hash()]);
let b = b.close(vec![], Address::zero(), vec![]); let _ = b.close(vec![], Address::zero(), vec![]);
assert_eq!(b.state().balance(&Address::zero()), U256::from_str("4563918244F40000").unwrap());
} }

View File

@ -27,7 +27,7 @@ pub struct Header {
pub difficulty: U256, pub difficulty: U256,
pub seal: Vec<Bytes>, pub seal: Vec<Bytes>,
pub hash: RefCell<Option<H256>>, //TODO: make this private pub hash: RefCell<Option<H256>>,
} }
pub enum Seal { pub enum Seal {
@ -163,28 +163,6 @@ impl Encodable for Header {
}) })
} }
} }
/*
trait RlpStandard {
fn append(&self, s: &mut RlpStream);
}
impl RlpStandard for Header {
fn append(&self, s: &mut RlpStream) {
s.append_list(13);
s.append(self.parent_hash);
s.append_raw(self.seal[0]);
s.append_standard(self.x);
}
fn populate(&mut self, s: &Rlp) {
}
}
impl RlpStream {
fn append_standard<O>(&mut self, o: &O) where O: RlpStandard {
o.append(self);
}
}
*/
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {

View File

@ -1,10 +1,47 @@
use util::*; use util::*;
use basic_types::LogBloom; use basic_types::LogBloom;
/// A single log's entry.
pub struct LogEntry {
pub address: Address,
pub topics: Vec<H256>,
pub data: Bytes,
}
impl RlpStandard for LogEntry {
fn rlp_append(&self, s: &mut RlpStream) {
s.append_list(3);
s.append(&self.address);
s.append(&self.topics);
s.append(&self.data);
}
}
impl LogEntry {
pub fn bloom(&self) -> LogBloom {
self.topics.iter().fold(LogBloom::from_bloomed(&self.address.sha3()), |b, t| b.with_bloomed(&t.sha3()))
}
}
/// Information describing execution of a transaction. /// Information describing execution of a transaction.
pub struct Receipt { pub struct Receipt {
// TODO
pub state_root: H256, pub state_root: H256,
pub gas_used: U256, pub gas_used: U256,
pub log_bloom: LogBloom, pub log_bloom: LogBloom,
pub logs: Vec<LogEntry>,
}
impl RlpStandard for Receipt {
fn rlp_append(&self, s: &mut RlpStream) {
s.append_list(4);
s.append(&self.state_root);
s.append(&self.gas_used);
s.append(&self.log_bloom);
// TODO: make work:
//s.append(&self.logs);
s.append_list(self.logs.len());
for l in self.logs.iter() {
l.rlp_append(s);
}
}
} }

View File

@ -9,6 +9,8 @@ pub struct Transaction {
to: Option<Address>, to: Option<Address>,
value: U256, value: U256,
data: Bytes, data: Bytes,
hash: RefCell<Option<H256>>, //TODO: make this private
} }
impl Transaction { impl Transaction {
@ -21,10 +23,36 @@ impl Transaction {
pub fn is_message_call(&self) -> bool { pub fn is_message_call(&self) -> bool {
!self.is_contract_creation() !self.is_contract_creation()
} }
}
/// Get the hash of this transaction. impl RlpStandard for Transaction {
pub fn sha3(&self) -> H256 { fn rlp_append(&self, s: &mut RlpStream) {
unimplemented!(); s.append_list(6);
s.append(&self.nonce);
s.append(&self.gas_price);
s.append(&self.gas);
s.append(&self.to);
s.append(&self.value);
s.append(&self.data);
}
}
impl Transaction {
/// Get the hash of this header (sha3 of the RLP).
pub fn hash(&self) -> H256 {
let mut hash = self.hash.borrow_mut();
match &mut *hash {
&mut Some(ref h) => h.clone(),
hash @ &mut None => {
*hash = Some(self.rlp_sha3());
hash.as_ref().unwrap().clone()
}
}
}
/// Note that some fields have changed. Resets the memoised hash.
pub fn note_dirty(&self) {
*self.hash.borrow_mut() = None;
} }
} }
@ -52,6 +80,7 @@ impl Decodable for Transaction {
to: try!(Decodable::decode(&d[3])), to: try!(Decodable::decode(&d[3])),
value: try!(Decodable::decode(&d[4])), value: try!(Decodable::decode(&d[4])),
data: try!(Decodable::decode(&d[5])), data: try!(Decodable::decode(&d[5])),
hash: RefCell::new(None)
}; };
Ok(transaction) Ok(transaction)