Merge branch 'master' into keccak_fn

This commit is contained in:
debris
2017-08-31 11:53:26 +02:00
55 changed files with 704 additions and 120 deletions

View File

@@ -20,7 +20,8 @@ use std::collections::{HashMap, VecDeque};
use std::sync::Arc;
use bloomchain::{Number, Config as BloomConfig};
use bloomchain::group::{BloomGroupDatabase, BloomGroupChain, GroupPosition, BloomGroup};
use util::{H256, H264, KeyValueDB, DBTransaction, RwLock, HeapSizeOf};
use heapsize::HeapSizeOf;
use util::{H256, H264, KeyValueDB, DBTransaction, RwLock};
use header::BlockNumber;
use trace::{LocalizedTrace, Config, Filter, Database as TraceDatabase, ImportRequest, DatabaseExtras};
use db::{self, Key, Writable, Readable, CacheUpdatePolicy};
@@ -215,8 +216,11 @@ impl<T> TraceDB<T> where T: DatabaseExtras {
block_number: BlockNumber,
tx_number: usize
) -> Vec<LocalizedTrace> {
let tx_hash = self.extras.transaction_hash(block_number, tx_number)
.expect("Expected to find transaction hash. Database is probably corrupted");
let (trace_tx_number, trace_tx_hash) = match self.extras.transaction_hash(block_number, tx_number) {
Some(hash) => (Some(tx_number), Some(hash.clone())),
//None means trace without transaction (reward)
None => (None, None),
};
let flat_traces: Vec<FlatTrace> = traces.into();
flat_traces.into_iter()
@@ -227,8 +231,8 @@ impl<T> TraceDB<T> where T: DatabaseExtras {
result: trace.result,
subtraces: trace.subtraces,
trace_address: trace.trace_address.into_iter().collect(),
transaction_number: tx_number,
transaction_hash: tx_hash.clone(),
transaction_number: trace_tx_number,
transaction_hash: trace_tx_hash,
block_number: block_number,
block_hash: block_hash
}),
@@ -321,8 +325,8 @@ impl<T> TraceDatabase for TraceDB<T> where T: DatabaseExtras {
result: trace.result,
subtraces: trace.subtraces,
trace_address: trace.trace_address.into_iter().collect(),
transaction_number: tx_position,
transaction_hash: tx_hash,
transaction_number: Some(tx_position),
transaction_hash: Some(tx_hash),
block_number: block_number,
block_hash: block_hash,
}
@@ -345,8 +349,8 @@ impl<T> TraceDatabase for TraceDB<T> where T: DatabaseExtras {
result: trace.result,
subtraces: trace.subtraces,
trace_address: trace.trace_address.into_iter().collect(),
transaction_number: tx_position,
transaction_hash: tx_hash.clone(),
transaction_number: Some(tx_position),
transaction_hash: Some(tx_hash.clone()),
block_number: block_number,
block_hash: block_hash
})
@@ -363,8 +367,11 @@ impl<T> TraceDatabase for TraceDB<T> where T: DatabaseExtras {
.map(Into::<Vec<FlatTrace>>::into)
.enumerate()
.flat_map(|(tx_position, traces)| {
let tx_hash = self.extras.transaction_hash(block_number, tx_position)
.expect("Expected to find transaction hash. Database is probably corrupted");
let (trace_tx_number, trace_tx_hash) = match self.extras.transaction_hash(block_number, tx_position) {
Some(hash) => (Some(tx_position), Some(hash.clone())),
//None means trace without transaction (reward)
None => (None, None),
};
traces.into_iter()
.map(|trace| LocalizedTrace {
@@ -372,8 +379,8 @@ impl<T> TraceDatabase for TraceDB<T> where T: DatabaseExtras {
result: trace.result,
subtraces: trace.subtraces,
trace_address: trace.trace_address.into_iter().collect(),
transaction_number: tx_position,
transaction_hash: tx_hash.clone(),
transaction_number: trace_tx_number,
transaction_hash: trace_tx_hash,
block_number: block_number,
block_hash: block_hash,
})
@@ -543,8 +550,8 @@ mod tests {
result: Res::FailedCall(TraceError::OutOfGas),
trace_address: vec![],
subtraces: 0,
transaction_number: 0,
transaction_hash: tx_hash,
transaction_number: Some(0),
transaction_hash: Some(tx_hash),
block_number: block_number,
block_hash: block_hash,
}

View File

@@ -18,7 +18,7 @@
use util::{Bytes, Address, U256};
use vm::ActionParams;
use trace::trace::{Call, Create, Action, Res, CreateResult, CallResult, VMTrace, VMOperation, VMExecutedOperation, MemoryDiff, StorageDiff, Suicide};
use trace::trace::{Call, Create, Action, Res, CreateResult, CallResult, VMTrace, VMOperation, VMExecutedOperation, MemoryDiff, StorageDiff, Suicide, Reward, RewardType};
use trace::{Tracer, VMTracer, FlatTrace, TraceError};
/// Simple executive tracer. Traces all calls and creates. Ignores delegatecalls.
@@ -151,15 +151,22 @@ impl Tracer for ExecutiveTracer {
fn trace_suicide(&mut self, address: Address, balance: U256, refund_address: Address) {
let trace = FlatTrace {
subtraces: 0,
action: Action::Suicide(Suicide {
address: address,
refund_address: refund_address,
balance: balance,
}),
action: Action::Suicide(Suicide { address, refund_address, balance } ),
result: Res::None,
trace_address: Default::default(),
};
debug!(target: "trace", "Traced failed suicide {:?}", trace);
debug!(target: "trace", "Traced suicide {:?}", trace);
self.traces.push(trace);
}
fn trace_reward(&mut self, author: Address, value: U256, reward_type: RewardType) {
let trace = FlatTrace {
subtraces: 0,
action: Action::Reward(Reward { author, value, reward_type } ),
result: Res::None,
trace_address: Default::default(),
};
debug!(target: "trace", "Traced reward {:?}", trace);
self.traces.push(trace);
}

View File

@@ -33,7 +33,7 @@ pub use self::localized::LocalizedTrace;
pub use self::types::{filter, flat, localized, trace};
pub use self::types::error::Error as TraceError;
pub use self::types::trace::{VMTrace, VMOperation, VMExecutedOperation, MemoryDiff, StorageDiff};
pub use self::types::trace::{VMTrace, VMOperation, VMExecutedOperation, MemoryDiff, StorageDiff, RewardType};
pub use self::types::flat::{FlatTrace, FlatTransactionTraces, FlatBlockTraces};
pub use self::types::filter::{Filter, AddressesFilter};
@@ -81,6 +81,9 @@ pub trait Tracer: Send {
/// Stores suicide info.
fn trace_suicide(&mut self, address: Address, balance: U256, refund_address: Address);
/// Stores reward info.
fn trace_reward(&mut self, author: Address, value: U256, reward_type: RewardType);
/// Spawn subtracer which will be used to trace deeper levels of execution.
fn subtracer(&self) -> Self where Self: Sized;

View File

@@ -19,7 +19,7 @@
use util::{Bytes, Address, U256};
use vm::ActionParams;
use trace::{Tracer, VMTracer, FlatTrace, TraceError};
use trace::trace::{Call, Create, VMTrace};
use trace::trace::{Call, Create, VMTrace, RewardType};
/// Nonoperative tracer. Does not trace anything.
pub struct NoopTracer;
@@ -58,6 +58,9 @@ impl Tracer for NoopTracer {
fn trace_suicide(&mut self, _address: Address, _balance: U256, _refund_address: Address) {
}
fn trace_reward(&mut self, _: Address, _: U256, _: RewardType) {
}
fn subtracer(&self) -> Self {
NoopTracer
}

View File

@@ -113,7 +113,7 @@ impl Filter {
let from_matches = self.from_address.matches(&call.from);
let to_matches = self.to_address.matches(&call.to);
from_matches && to_matches
}
},
Action::Create(ref create) => {
let from_matches = self.from_address.matches(&create.from);
@@ -128,7 +128,10 @@ impl Filter {
let from_matches = self.from_address.matches(&suicide.address);
let to_matches = self.to_address.matches(&suicide.refund_address);
from_matches && to_matches
}
},
Action::Reward(ref reward) => {
self.to_address.matches(&reward.author)
},
}
}
}
@@ -138,9 +141,9 @@ mod tests {
use util::Address;
use hash::keccak;
use bloomable::Bloomable;
use trace::trace::{Action, Call, Res, Create, CreateResult, Suicide};
use trace::trace::{Action, Call, Res, Create, CreateResult, Suicide, Reward};
use trace::flat::FlatTrace;
use trace::{Filter, AddressesFilter, TraceError};
use trace::{Filter, AddressesFilter, TraceError, RewardType};
use evm::CallType;
#[test]
@@ -341,5 +344,24 @@ mod tests {
assert!(f4.matches(&trace));
assert!(f5.matches(&trace));
assert!(!f6.matches(&trace));
let trace = FlatTrace {
action: Action::Reward(Reward {
author: 2.into(),
value: 100.into(),
reward_type: RewardType::Block,
}),
result: Res::None,
trace_address: vec![].into_iter().collect(),
subtraces: 0
};
assert!(f0.matches(&trace));
assert!(f1.matches(&trace));
assert!(f2.matches(&trace));
assert!(f3.matches(&trace));
assert!(f4.matches(&trace));
assert!(f5.matches(&trace));
assert!(!f6.matches(&trace));
}
}

View File

@@ -18,7 +18,7 @@
use std::collections::VecDeque;
use rlp::*;
use util::HeapSizeOf;
use heapsize::HeapSizeOf;
use basic_types::LogBloom;
use super::trace::{Action, Res};
@@ -138,8 +138,9 @@ impl Into<Vec<FlatTransactionTraces>> for FlatBlockTraces {
mod tests {
use rlp::*;
use super::{FlatBlockTraces, FlatTransactionTraces, FlatTrace};
use trace::trace::{Action, Res, CallResult, Call, Suicide};
use trace::trace::{Action, Res, CallResult, Call, Suicide, Reward};
use evm::CallType;
use trace::RewardType;
#[test]
fn encode_flat_transaction_traces() {
@@ -214,9 +215,32 @@ mod tests {
subtraces: 0,
};
let flat_trace3 = FlatTrace {
action: Action::Reward(Reward {
author: "412fda7643b37d436cb40628f6dbbb80a07267ed".parse().unwrap(),
value: 10.into(),
reward_type: RewardType::Uncle,
}),
result: Res::None,
trace_address: vec![0].into_iter().collect(),
subtraces: 0,
};
let flat_trace4 = FlatTrace {
action: Action::Reward(Reward {
author: "412fda7643b37d436cb40628f6dbbb80a07267ed".parse().unwrap(),
value: 10.into(),
reward_type: RewardType::Block,
}),
result: Res::None,
trace_address: vec![0].into_iter().collect(),
subtraces: 0,
};
let block_traces = FlatBlockTraces(vec![
FlatTransactionTraces(vec![flat_trace]),
FlatTransactionTraces(vec![flat_trace1, flat_trace2])
FlatTransactionTraces(vec![flat_trace1, flat_trace2]),
FlatTransactionTraces(vec![flat_trace3, flat_trace4])
]);
let encoded = ::rlp::encode(&block_traces);

View File

@@ -34,9 +34,9 @@ pub struct LocalizedTrace {
/// [index in root, index in first CALL, index in second CALL, ...]
pub trace_address: Vec<usize>,
/// Transaction number within the block.
pub transaction_number: usize,
pub transaction_number: Option<usize>,
/// Signed transaction hash.
pub transaction_hash: H256,
pub transaction_hash: Option<H256>,
/// Block number.
pub block_number: BlockNumber,
/// Block hash.

View File

@@ -128,6 +128,77 @@ impl Create {
}
}
/// Reward type.
#[derive(Debug, PartialEq, Clone)]
#[cfg_attr(feature = "ipc", binary)]
pub enum RewardType {
/// Block
Block,
/// Uncle
Uncle,
}
impl Encodable for RewardType {
fn rlp_append(&self, s: &mut RlpStream) {
let v = match *self {
RewardType::Block => 0u32,
RewardType::Uncle => 1,
};
Encodable::rlp_append(&v, s);
}
}
impl Decodable for RewardType {
fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> {
rlp.as_val().and_then(|v| Ok(match v {
0u32 => RewardType::Block,
1 => RewardType::Uncle,
_ => return Err(DecoderError::Custom("Invalid value of RewardType item")),
}))
}
}
/// Reward action
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "ipc", binary)]
pub struct Reward {
/// Author's address.
pub author: Address,
/// Reward amount.
pub value: U256,
/// Reward type.
pub reward_type: RewardType,
}
impl Reward {
/// Return reward action bloom.
pub fn bloom(&self) -> LogBloom {
LogBloom::from_bloomed(&keccak(&self.author))
}
}
impl Encodable for Reward {
fn rlp_append(&self, s: &mut RlpStream) {
s.begin_list(3);
s.append(&self.author);
s.append(&self.value);
s.append(&self.reward_type);
}
}
impl Decodable for Reward {
fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> {
let res = Reward {
author: rlp.val_at(0)?,
value: rlp.val_at(1)?,
reward_type: rlp.val_at(2)?,
};
Ok(res)
}
}
/// Suicide action.
#[derive(Debug, Clone, PartialEq, RlpEncodable, RlpDecodable)]
#[cfg_attr(feature = "ipc", binary)]
@@ -158,6 +229,8 @@ pub enum Action {
Create(Create),
/// Suicide.
Suicide(Suicide),
/// Reward
Reward(Reward),
}
impl Encodable for Action {
@@ -175,7 +248,12 @@ impl Encodable for Action {
Action::Suicide(ref suicide) => {
s.append(&2u8);
s.append(suicide);
},
Action::Reward(ref reward) => {
s.append(&3u8);
s.append(reward);
}
}
}
}
@@ -187,6 +265,7 @@ impl Decodable for Action {
0 => rlp.val_at(1).map(Action::Call),
1 => rlp.val_at(1).map(Action::Create),
2 => rlp.val_at(1).map(Action::Suicide),
3 => rlp.val_at(1).map(Action::Reward),
_ => Err(DecoderError::Custom("Invalid action type.")),
}
}
@@ -199,6 +278,7 @@ impl Action {
Action::Call(ref call) => call.bloom(),
Action::Create(ref create) => create.bloom(),
Action::Suicide(ref suicide) => suicide.bloom(),
Action::Reward(ref reward) => reward.bloom(),
}
}
}