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();
match self.block.state.apply(&env_info, self.engine, &t, true) {
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 });
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.
pub fn close(self, uncles: Vec<Header>, author: Address, extra_data: Bytes) -> ClosedBlock<'engine> {
let mut s = self;
// populate rest of header.
s.engine.on_close_block(&mut s.block);
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();
s.block.header.uncles_hash = uncle_bytes.sha3();
s.block.header.extra_data = extra_data;
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.gas_used = s.block.archive.last().map(|t| t.receipt.gas_used).unwrap_or(U256::from(0));
s.block.header.note_dirty();
@ -175,12 +174,10 @@ impl IsBlock for SealedBlock {
#[test]
fn open_block() {
use spec::*;
use ethereum::*;
let engine = new_morden().to_engine().unwrap();
let engine = Spec::new_test().to_engine().unwrap();
let genesis_header = engine.spec().genesis_header();
let mut db = OverlayDB::new_temp();
engine.spec().ensure_db_good(&mut db);
let b = OpenBlock::new(engine.deref(), db, &genesis_header, vec![genesis_header.hash()]);
let b = b.close(vec![], Address::zero(), vec![]);
assert_eq!(b.state().balance(&Address::zero()), U256::from_str("4563918244F40000").unwrap());
let _ = b.close(vec![], Address::zero(), vec![]);
}

View File

@ -27,7 +27,7 @@ pub struct Header {
pub difficulty: U256,
pub seal: Vec<Bytes>,
pub hash: RefCell<Option<H256>>, //TODO: make this private
pub hash: RefCell<Option<H256>>,
}
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)]
mod tests {

View File

@ -1,10 +1,47 @@
use util::*;
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.
pub struct Receipt {
// TODO
pub state_root: H256,
pub gas_used: U256,
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>,
value: U256,
data: Bytes,
hash: RefCell<Option<H256>>, //TODO: make this private
}
impl Transaction {
@ -21,10 +23,36 @@ impl Transaction {
pub fn is_message_call(&self) -> bool {
!self.is_contract_creation()
}
}
/// Get the hash of this transaction.
pub fn sha3(&self) -> H256 {
unimplemented!();
impl RlpStandard for Transaction {
fn rlp_append(&self, s: &mut RlpStream) {
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])),
value: try!(Decodable::decode(&d[4])),
data: try!(Decodable::decode(&d[5])),
hash: RefCell::new(None)
};
Ok(transaction)