diff --git a/src/block.rs b/src/block.rs index e725a69f6..b1207ce53 100644 --- a/src/block.rs +++ b/src/block.rs @@ -169,7 +169,7 @@ impl<'x, 'y> OpenBlock<'x, 'y> { /// If valid, it will be executed, and archived together with the receipt. pub fn push_transaction(&mut self, t: Transaction, h: Option) -> Result<&Receipt, Error> { 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) { Ok(x) => { self.block.archive_set.insert(h.unwrap_or_else(||t.hash())); self.block.archive.push(Entry { transaction: t, receipt: x.receipt }); diff --git a/src/common.rs b/src/common.rs index 468a722d7..061d0748a 100644 --- a/src/common.rs +++ b/src/common.rs @@ -8,4 +8,5 @@ pub use builtin::*; pub use header::*; pub use account::*; pub use transaction::*; +pub use log_entry::*; pub use receipt::*; \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index bcf112c10..1b9c055df 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -88,6 +88,7 @@ extern crate ethcore_util as util; pub mod common; pub mod basic_types; pub mod error; +pub mod log_entry; pub mod env_info; pub mod engine; pub mod state; diff --git a/src/log_entry.rs b/src/log_entry.rs new file mode 100644 index 000000000..939d60276 --- /dev/null +++ b/src/log_entry.rs @@ -0,0 +1,62 @@ +use util::*; +use basic_types::LogBloom; + +/// A single log's entry. +pub struct LogEntry { + pub address: Address, + pub topics: Vec, + 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())) + } + + /// Create a new log entry. + pub fn new(address: Address, topics: Vec, data: Bytes) -> LogEntry { + LogEntry { + address: address, + topics: topics, + data: data + } + } + + /// Returns reference to address. + pub fn address(&self) -> &Address { + &self.address + } + + /// Returns reference to topics. + pub fn topics(&self) -> &Vec { + &self.topics + } + + /// Returns reference to data. + pub fn data(&self) -> &Bytes { + &self.data + } +} + +#[cfg(test)] +mod tests { + use util::*; + use super::LogEntry; + + #[test] + fn test_empty_log_bloom() { + let bloom = H2048::from_str("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000").unwrap(); + let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap(); + let log = LogEntry::new(address, vec![], vec![]); + assert_eq!(log.bloom(), bloom); + } +} \ No newline at end of file diff --git a/src/receipt.rs b/src/receipt.rs index 5a188f93d..ef46e0f48 100644 --- a/src/receipt.rs +++ b/src/receipt.rs @@ -1,27 +1,6 @@ use util::*; use basic_types::LogBloom; - -/// A single log's entry. -pub struct LogEntry { - pub address: Address, - pub topics: Vec, - 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())) - } -} +use log_entry::LogEntry; /// Information describing execution of a transaction. pub struct Receipt { diff --git a/src/state.rs b/src/state.rs index 569de13bd..03978fc4e 100644 --- a/src/state.rs +++ b/src/state.rs @@ -134,7 +134,7 @@ impl State { /// Execute a given transaction. /// This will change the state accordingly. - pub fn apply(&mut self, _env_info: &EnvInfo, _engine: &Engine, _t: &Transaction, _is_permanent: bool) -> ApplyResult { + pub fn apply(&mut self, _env_info: &EnvInfo, _engine: &Engine, _t: &Transaction) -> ApplyResult { unimplemented!(); } diff --git a/src/transaction.rs b/src/transaction.rs index d13a728bb..f162bb2c5 100644 --- a/src/transaction.rs +++ b/src/transaction.rs @@ -1,37 +1,33 @@ use util::*; +pub enum Action { + Create, + Call(Address), +} + /// A set of information describing an externally-originating message call /// or contract creation operation. pub struct Transaction { nonce: U256, gas_price: U256, gas: U256, - to: Option
, + action: Action, value: U256, data: Bytes, hash: RefCell>, //TODO: make this private } -impl Transaction { - /// Is this transaction meant to create a contract? - pub fn is_contract_creation(&self) -> bool { - self.to.is_none() - } - - /// Is this transaction meant to send a message? - pub fn is_message_call(&self) -> bool { - !self.is_contract_creation() - } -} - 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); + match self.action { + Action::Create => s.append_empty_data(), + Action::Call(ref to) => s.append(to), + }; s.append(&self.value); s.append(&self.data); } @@ -54,18 +50,19 @@ impl Transaction { pub fn note_dirty(&self) { *self.hash.borrow_mut() = None; } + + /// Returns transaction type. + pub fn action(&self) -> &Action { &self.action } } -impl Encodable for Transaction { - fn encode(&self, encoder: &mut E) where E: Encoder { - encoder.emit_list(| e | { - self.nonce.encode(e); - self.gas_price.encode(e); - self.gas.encode(e); - self.to.encode(e); - self.value.encode(e); - self.data.encode(e); - }) +impl Decodable for Action { + fn decode(decoder: &D) -> Result where D: Decoder { + let rlp = decoder.as_rlp(); + if rlp.is_empty() { + Ok(Action::Create) + } else { + Ok(Action::Call(try!(rlp.as_val()))) + } } } @@ -77,7 +74,7 @@ impl Decodable for Transaction { nonce: try!(Decodable::decode(&d[0])), gas_price: try!(Decodable::decode(&d[1])), gas: try!(Decodable::decode(&d[2])), - to: try!(Decodable::decode(&d[3])), + action: try!(Decodable::decode(&d[3])), value: try!(Decodable::decode(&d[4])), data: try!(Decodable::decode(&d[5])), hash: RefCell::new(None) @@ -86,4 +83,3 @@ impl Decodable for Transaction { Ok(transaction) } } -