Tracing for rewards added. Without tests for now
This commit is contained in:
parent
003eef982b
commit
06862c7dee
@ -92,6 +92,7 @@ pub struct ExecutedBlock {
|
|||||||
transactions_set: HashSet<H256>,
|
transactions_set: HashSet<H256>,
|
||||||
state: State<StateDB>,
|
state: State<StateDB>,
|
||||||
traces: Option<Vec<Vec<FlatTrace>>>,
|
traces: Option<Vec<Vec<FlatTrace>>>,
|
||||||
|
tracing_enabled: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A set of references to `ExecutedBlock` fields that are publicly accessible.
|
/// A set of references to `ExecutedBlock` fields that are publicly accessible.
|
||||||
@ -108,6 +109,8 @@ pub struct BlockRefMut<'a> {
|
|||||||
pub state: &'a mut State<StateDB>,
|
pub state: &'a mut State<StateDB>,
|
||||||
/// Traces.
|
/// Traces.
|
||||||
pub traces: &'a Option<Vec<Vec<FlatTrace>>>,
|
pub traces: &'a Option<Vec<Vec<FlatTrace>>>,
|
||||||
|
/// Tracing enabled flag.
|
||||||
|
pub tracing_enabled: &'a mut bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A set of immutable references to `ExecutedBlock` fields that are publicly accessible.
|
/// A set of immutable references to `ExecutedBlock` fields that are publicly accessible.
|
||||||
@ -124,6 +127,8 @@ pub struct BlockRef<'a> {
|
|||||||
pub state: &'a State<StateDB>,
|
pub state: &'a State<StateDB>,
|
||||||
/// Traces.
|
/// Traces.
|
||||||
pub traces: &'a Option<Vec<Vec<FlatTrace>>>,
|
pub traces: &'a Option<Vec<Vec<FlatTrace>>>,
|
||||||
|
/// Tracing enabled flag.
|
||||||
|
pub tracing_enabled: &'a bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ExecutedBlock {
|
impl ExecutedBlock {
|
||||||
@ -137,6 +142,7 @@ impl ExecutedBlock {
|
|||||||
transactions_set: Default::default(),
|
transactions_set: Default::default(),
|
||||||
state: state,
|
state: state,
|
||||||
traces: if tracing {Some(Vec::new())} else {None},
|
traces: if tracing {Some(Vec::new())} else {None},
|
||||||
|
tracing_enabled: tracing,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -149,6 +155,7 @@ impl ExecutedBlock {
|
|||||||
state: &mut self.state,
|
state: &mut self.state,
|
||||||
receipts: &self.receipts,
|
receipts: &self.receipts,
|
||||||
traces: &self.traces,
|
traces: &self.traces,
|
||||||
|
tracing_enabled: &mut self.tracing_enabled,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -161,6 +168,7 @@ impl ExecutedBlock {
|
|||||||
state: &self.state,
|
state: &self.state,
|
||||||
receipts: &self.receipts,
|
receipts: &self.receipts,
|
||||||
traces: &self.traces,
|
traces: &self.traces,
|
||||||
|
tracing_enabled: &self.tracing_enabled,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -196,6 +204,9 @@ pub trait IsBlock {
|
|||||||
|
|
||||||
/// Get all uncles in this block.
|
/// Get all uncles in this block.
|
||||||
fn uncles(&self) -> &[Header] { &self.block().uncles }
|
fn uncles(&self) -> &[Header] { &self.block().uncles }
|
||||||
|
|
||||||
|
/// Get tracing enabled flag for this block.
|
||||||
|
fn tracing_enabled(&self) -> &bool { &self.block().tracing_enabled }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Trait for a object that has a state database.
|
/// Trait for a object that has a state database.
|
||||||
@ -392,9 +403,16 @@ impl<'x> OpenBlock<'x> {
|
|||||||
|
|
||||||
let unclosed_state = s.block.state.clone();
|
let unclosed_state = s.block.state.clone();
|
||||||
|
|
||||||
if let Err(e) = s.engine.on_close_block(&mut s.block) {
|
match s.engine.on_close_block(&mut s.block) {
|
||||||
warn!("Encountered error on closing the block: {}", e);
|
Ok(outcome) => {
|
||||||
|
let t = outcome.trace;
|
||||||
|
if t.is_some() {
|
||||||
|
s.block.traces.as_mut().map(|traces| traces.push(t.unwrap()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(e) => warn!("Encountered error on closing the block: {}", e),
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Err(e) = s.block.state.commit() {
|
if let Err(e) = s.block.state.commit() {
|
||||||
warn!("Encountered error on state commit: {}", e);
|
warn!("Encountered error on state commit: {}", e);
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,9 @@ use account_provider::AccountProvider;
|
|||||||
use block::*;
|
use block::*;
|
||||||
use builtin::Builtin;
|
use builtin::Builtin;
|
||||||
use client::{Client, EngineClient};
|
use client::{Client, EngineClient};
|
||||||
use engines::{Call, Engine, Seal, EngineError, ConstructedVerifier};
|
use engines::{Call, Engine, Seal, EngineError, ConstructedVerifier, CloseOutcome};
|
||||||
|
use trace::{Tracer, ExecutiveTracer};
|
||||||
|
use types::trace_types::trace::{RewardType};
|
||||||
use error::{Error, TransactionError, BlockError};
|
use error::{Error, TransactionError, BlockError};
|
||||||
use ethjson;
|
use ethjson;
|
||||||
use header::{Header, BlockNumber};
|
use header::{Header, BlockNumber};
|
||||||
@ -543,18 +545,30 @@ impl Engine for AuthorityRound {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Apply the block reward on finalisation of the block.
|
/// Apply the block reward on finalisation of the block.
|
||||||
fn on_close_block(&self, block: &mut ExecutedBlock) -> Result<(), Error> {
|
fn on_close_block(&self, block: &mut ExecutedBlock) -> Result<CloseOutcome, Error> {
|
||||||
let fields = block.fields_mut();
|
let fields = block.fields_mut();
|
||||||
|
let mut tracer = ExecutiveTracer::default();
|
||||||
// Bestow block reward
|
// Bestow block reward
|
||||||
let reward = self.params().block_reward;
|
let reward = self.params().block_reward;
|
||||||
let res = fields.state.add_balance(fields.header.author(), &reward, CleanupMode::NoEmpty)
|
let res = fields.state.add_balance(fields.header.author(), &reward, CleanupMode::NoEmpty)
|
||||||
.map_err(::error::Error::from)
|
.map_err(::error::Error::from)
|
||||||
.and_then(|_| fields.state.commit());
|
.and_then(|_| fields.state.commit());
|
||||||
|
|
||||||
|
// Trace it
|
||||||
|
let block_miner = fields.header.author().clone();
|
||||||
|
tracer.trace_reward(block_miner, self.block_reward, RewardType::Block);
|
||||||
|
|
||||||
// Commit state so that we can actually figure out the state root.
|
// Commit state so that we can actually figure out the state root.
|
||||||
if let Err(ref e) = res {
|
if let Err(ref e) = res {
|
||||||
warn!("Encountered error on closing block: {}", e);
|
warn!("Encountered error on closing block: {}", e);
|
||||||
}
|
}
|
||||||
res
|
match res {
|
||||||
|
Ok(res) => match *fields.tracing_enabled {
|
||||||
|
true => Ok(CloseOutcome{trace: Some(tracer.traces())}),
|
||||||
|
false => Ok(CloseOutcome{trace: None})
|
||||||
|
},
|
||||||
|
Err(e) => Err(e)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check the number of seal fields.
|
/// Check the number of seal fields.
|
||||||
|
@ -48,6 +48,7 @@ use error::Error;
|
|||||||
use evm::Schedule;
|
use evm::Schedule;
|
||||||
use header::{Header, BlockNumber};
|
use header::{Header, BlockNumber};
|
||||||
use receipt::Receipt;
|
use receipt::Receipt;
|
||||||
|
use trace::FlatTrace;
|
||||||
use snapshot::SnapshotComponents;
|
use snapshot::SnapshotComponents;
|
||||||
use spec::CommonParams;
|
use spec::CommonParams;
|
||||||
use transaction::{UnverifiedTransaction, SignedTransaction};
|
use transaction::{UnverifiedTransaction, SignedTransaction};
|
||||||
@ -81,6 +82,13 @@ pub enum EngineError {
|
|||||||
RequiresClient,
|
RequiresClient,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Used to return information about close block operation.
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct CloseOutcome {
|
||||||
|
/// The trace for the closing block, if None if tracing is disabled.
|
||||||
|
pub trace: Option<Vec<FlatTrace>>,
|
||||||
|
}
|
||||||
|
|
||||||
impl fmt::Display for EngineError {
|
impl fmt::Display for EngineError {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
use self::EngineError::*;
|
use self::EngineError::*;
|
||||||
@ -228,8 +236,8 @@ pub trait Engine : Sync + Send {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Block transformation functions, after the transactions.
|
/// Block transformation functions, after the transactions.
|
||||||
fn on_close_block(&self, _block: &mut ExecutedBlock) -> Result<(), Error> {
|
fn on_close_block(&self, _block: &mut ExecutedBlock) -> Result<CloseOutcome, Error> {
|
||||||
Ok(())
|
Ok(CloseOutcome{trace: None})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// None means that it requires external input (e.g. PoW) to seal a block.
|
/// None means that it requires external input (e.g. PoW) to seal a block.
|
||||||
|
@ -37,7 +37,9 @@ use ethkey::{Message, public_to_address, recover, Signature};
|
|||||||
use account_provider::AccountProvider;
|
use account_provider::AccountProvider;
|
||||||
use block::*;
|
use block::*;
|
||||||
use spec::CommonParams;
|
use spec::CommonParams;
|
||||||
use engines::{Engine, Seal, EngineError, ConstructedVerifier};
|
use engines::{Engine, Seal, EngineError, CloseOutcome, ConstructedVerifier};
|
||||||
|
use trace::{Tracer, ExecutiveTracer};
|
||||||
|
use types::trace_types::trace::{RewardType};
|
||||||
use state::CleanupMode;
|
use state::CleanupMode;
|
||||||
use io::IoService;
|
use io::IoService;
|
||||||
use super::signer::EngineSigner;
|
use super::signer::EngineSigner;
|
||||||
@ -538,18 +540,31 @@ impl Engine for Tendermint {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Apply the block reward on finalisation of the block.
|
/// Apply the block reward on finalisation of the block.
|
||||||
fn on_close_block(&self, block: &mut ExecutedBlock) -> Result<(), Error>{
|
fn on_close_block(&self, block: &mut ExecutedBlock) -> Result<CloseOutcome, Error>{
|
||||||
let fields = block.fields_mut();
|
let fields = block.fields_mut();
|
||||||
|
let mut tracer = ExecutiveTracer::default();
|
||||||
// Bestow block reward
|
// Bestow block reward
|
||||||
let reward = self.params().block_reward;
|
let reward = self.params().block_reward;
|
||||||
let res = fields.state.add_balance(fields.header.author(), &reward, CleanupMode::NoEmpty)
|
let res = fields.state.add_balance(fields.header.author(), &reward, CleanupMode::NoEmpty)
|
||||||
.map_err(::error::Error::from)
|
.map_err(::error::Error::from)
|
||||||
.and_then(|_| fields.state.commit());
|
.and_then(|_| fields.state.commit());
|
||||||
|
|
||||||
|
// Trace it
|
||||||
|
let block_miner = fields.header.author().clone();
|
||||||
|
tracer.trace_reward(block_miner, self.block_reward, RewardType::Block);
|
||||||
|
|
||||||
// Commit state so that we can actually figure out the state root.
|
// Commit state so that we can actually figure out the state root.
|
||||||
if let Err(ref e) = res {
|
if let Err(ref e) = res {
|
||||||
warn!("Encountered error on closing block: {}", e);
|
warn!("Encountered error on closing block: {}", e);
|
||||||
}
|
}
|
||||||
res
|
match res {
|
||||||
|
Ok(res) => match *fields.tracing_enabled {
|
||||||
|
true => Ok(CloseOutcome{trace: Some(tracer.traces())}),
|
||||||
|
false => Ok(CloseOutcome{trace: None})
|
||||||
|
},
|
||||||
|
Err(e) => Err(e)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn verify_block_basic(&self, header: &Header, _block: Option<&[u8]>) -> Result<(), Error> {
|
fn verify_block_basic(&self, header: &Header, _block: Option<&[u8]>) -> Result<(), Error> {
|
||||||
|
@ -21,11 +21,13 @@ use block::*;
|
|||||||
use builtin::Builtin;
|
use builtin::Builtin;
|
||||||
use evm::env_info::EnvInfo;
|
use evm::env_info::EnvInfo;
|
||||||
use error::{BlockError, Error, TransactionError};
|
use error::{BlockError, Error, TransactionError};
|
||||||
|
use trace::{Tracer, ExecutiveTracer};
|
||||||
|
use types::trace_types::trace::{RewardType};
|
||||||
use header::{Header, BlockNumber};
|
use header::{Header, BlockNumber};
|
||||||
use state::CleanupMode;
|
use state::CleanupMode;
|
||||||
use spec::CommonParams;
|
use spec::CommonParams;
|
||||||
use transaction::UnverifiedTransaction;
|
use transaction::UnverifiedTransaction;
|
||||||
use engines::{self, Engine};
|
use engines::{self, Engine, CloseOutcome};
|
||||||
use evm::Schedule;
|
use evm::Schedule;
|
||||||
use ethjson;
|
use ethjson;
|
||||||
use rlp::{self, UntrustedRlp};
|
use rlp::{self, UntrustedRlp};
|
||||||
@ -271,40 +273,57 @@ impl Engine for Arc<Ethash> {
|
|||||||
|
|
||||||
/// Apply the block reward on finalisation of the block.
|
/// Apply the block reward on finalisation of the block.
|
||||||
/// This assumes that all uncles are valid uncles (i.e. of at least one generation before the current).
|
/// This assumes that all uncles are valid uncles (i.e. of at least one generation before the current).
|
||||||
fn on_close_block(&self, block: &mut ExecutedBlock) -> Result<(), Error> {
|
fn on_close_block(&self, block: &mut ExecutedBlock) -> Result<CloseOutcome, Error> {
|
||||||
let reward = self.params().block_reward;
|
let reward = self.params().block_reward;
|
||||||
let fields = block.fields_mut();
|
let fields = block.fields_mut();
|
||||||
let eras_rounds = self.ethash_params.ecip1017_era_rounds;
|
let eras_rounds = self.ethash_params.ecip1017_era_rounds;
|
||||||
let (eras, reward) = ecip1017_eras_block_reward(eras_rounds, reward, fields.header.number());
|
let (eras, reward) = ecip1017_eras_block_reward(eras_rounds, reward, fields.header.number());
|
||||||
|
let mut tracer = ExecutiveTracer::default();
|
||||||
|
|
||||||
// Bestow block reward
|
// Bestow block reward
|
||||||
|
let result_block_reward = reward + reward / U256::from(32) * U256::from(fields.uncles.len());
|
||||||
fields.state.add_balance(
|
fields.state.add_balance(
|
||||||
fields.header.author(),
|
fields.header.author(),
|
||||||
&(reward + reward / U256::from(32) * U256::from(fields.uncles.len())),
|
&result_block_reward,
|
||||||
CleanupMode::NoEmpty
|
CleanupMode::NoEmpty
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
// Trace it
|
||||||
|
let block_miner = fields.header.author().clone();
|
||||||
|
tracer.trace_reward(block_miner, result_block_reward, RewardType::Block);
|
||||||
|
|
||||||
// Bestow uncle rewards
|
// Bestow uncle rewards
|
||||||
let current_number = fields.header.number();
|
let current_number = fields.header.number();
|
||||||
for u in fields.uncles.iter() {
|
for u in fields.uncles.iter() {
|
||||||
|
let uncle_miner = u.author().clone();
|
||||||
|
let mut result_uncle_reward: U256 = U256::from(0);
|
||||||
|
|
||||||
if eras == 0 {
|
if eras == 0 {
|
||||||
|
result_uncle_reward = reward * U256::from(8 + u.number() - current_number) / U256::from(8);
|
||||||
fields.state.add_balance(
|
fields.state.add_balance(
|
||||||
u.author(),
|
u.author(),
|
||||||
&(reward * U256::from(8 + u.number() - current_number) / U256::from(8)),
|
&(result_uncle_reward),
|
||||||
CleanupMode::NoEmpty
|
CleanupMode::NoEmpty
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
|
result_uncle_reward = reward / U256::from(32);
|
||||||
fields.state.add_balance(
|
fields.state.add_balance(
|
||||||
u.author(),
|
u.author(),
|
||||||
&(reward / U256::from(32)),
|
&(result_uncle_reward),
|
||||||
CleanupMode::NoEmpty
|
CleanupMode::NoEmpty
|
||||||
)
|
)
|
||||||
}?;
|
}?;
|
||||||
|
|
||||||
|
// Trace uncle rewards
|
||||||
|
tracer.trace_reward(uncle_miner, result_uncle_reward, RewardType::Uncle);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Commit state so that we can actually figure out the state root.
|
// Commit state so that we can actually figure out the state root.
|
||||||
fields.state.commit()?;
|
fields.state.commit()?;
|
||||||
Ok(())
|
match *fields.tracing_enabled {
|
||||||
|
true => Ok(CloseOutcome{trace: Some(tracer.traces())}),
|
||||||
|
false => Ok(CloseOutcome{trace: None})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn verify_block_basic(&self, header: &Header, _block: Option<&[u8]>) -> result::Result<(), Error> {
|
fn verify_block_basic(&self, header: &Header, _block: Option<&[u8]>) -> result::Result<(), Error> {
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
|
|
||||||
use util::{Bytes, Address, U256};
|
use util::{Bytes, Address, U256};
|
||||||
use evm::action_params::ActionParams;
|
use evm::action_params::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};
|
use trace::{Tracer, VMTracer, FlatTrace, TraceError};
|
||||||
|
|
||||||
/// Simple executive tracer. Traces all calls and creates. Ignores delegatecalls.
|
/// Simple executive tracer. Traces all calls and creates. Ignores delegatecalls.
|
||||||
@ -162,6 +162,21 @@ impl Tracer for ExecutiveTracer {
|
|||||||
debug!(target: "trace", "Traced failed suicide {:?}", trace);
|
debug!(target: "trace", "Traced failed suicide {:?}", trace);
|
||||||
self.traces.push(trace);
|
self.traces.push(trace);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn trace_reward(&mut self, miner: Address, value: U256, reward_type: RewardType) {
|
||||||
|
let trace = FlatTrace {
|
||||||
|
subtraces: 0,
|
||||||
|
action: Action::Reward(Reward {
|
||||||
|
miner: miner,
|
||||||
|
value: value,
|
||||||
|
reward_type: reward_type,
|
||||||
|
}),
|
||||||
|
result: Res::None,
|
||||||
|
trace_address: Default::default(),
|
||||||
|
};
|
||||||
|
debug!(target: "trace", "Traced failed reward {:?}", trace);
|
||||||
|
self.traces.push(trace);
|
||||||
|
}
|
||||||
|
|
||||||
fn subtracer(&self) -> Self {
|
fn subtracer(&self) -> Self {
|
||||||
ExecutiveTracer::default()
|
ExecutiveTracer::default()
|
||||||
|
@ -33,7 +33,7 @@ pub use self::localized::LocalizedTrace;
|
|||||||
|
|
||||||
pub use self::types::{filter, flat, localized, trace};
|
pub use self::types::{filter, flat, localized, trace};
|
||||||
pub use self::types::error::Error as TraceError;
|
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::flat::{FlatTrace, FlatTransactionTraces, FlatBlockTraces};
|
||||||
pub use self::types::filter::{Filter, AddressesFilter};
|
pub use self::types::filter::{Filter, AddressesFilter};
|
||||||
|
|
||||||
@ -81,6 +81,9 @@ pub trait Tracer: Send {
|
|||||||
/// Stores suicide info.
|
/// Stores suicide info.
|
||||||
fn trace_suicide(&mut self, address: Address, balance: U256, refund_address: Address);
|
fn trace_suicide(&mut self, address: Address, balance: U256, refund_address: Address);
|
||||||
|
|
||||||
|
/// Stores reward info.
|
||||||
|
fn trace_reward(&mut self, miner: Address, value: U256, reward_type: RewardType);
|
||||||
|
|
||||||
/// Spawn subtracer which will be used to trace deeper levels of execution.
|
/// Spawn subtracer which will be used to trace deeper levels of execution.
|
||||||
fn subtracer(&self) -> Self where Self: Sized;
|
fn subtracer(&self) -> Self where Self: Sized;
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
use util::{Bytes, Address, U256};
|
use util::{Bytes, Address, U256};
|
||||||
use evm::action_params::ActionParams;
|
use evm::action_params::ActionParams;
|
||||||
use trace::{Tracer, VMTracer, FlatTrace, TraceError};
|
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.
|
/// Nonoperative tracer. Does not trace anything.
|
||||||
pub struct NoopTracer;
|
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_suicide(&mut self, _address: Address, _balance: U256, _refund_address: Address) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn trace_reward(&mut self, miner: Address, value: U256, reward_type: RewardType) {
|
||||||
|
}
|
||||||
|
|
||||||
fn subtracer(&self) -> Self {
|
fn subtracer(&self) -> Self {
|
||||||
NoopTracer
|
NoopTracer
|
||||||
}
|
}
|
||||||
|
@ -128,6 +128,10 @@ impl Filter {
|
|||||||
let from_matches = self.from_address.matches(&suicide.address);
|
let from_matches = self.from_address.matches(&suicide.address);
|
||||||
let to_matches = self.to_address.matches(&suicide.refund_address);
|
let to_matches = self.to_address.matches(&suicide.refund_address);
|
||||||
from_matches && to_matches
|
from_matches && to_matches
|
||||||
|
},
|
||||||
|
Action::Reward(ref reward) => {
|
||||||
|
let to_matches = self.to_address.matches(&reward.miner);
|
||||||
|
to_matches
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -218,6 +218,81 @@ impl Create {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Reward type.
|
||||||
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
|
#[cfg_attr(feature = "ipc", binary)]
|
||||||
|
pub enum RewardType {
|
||||||
|
/// None
|
||||||
|
None,
|
||||||
|
/// Block
|
||||||
|
Block,
|
||||||
|
/// Uncle
|
||||||
|
Uncle,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Encodable for RewardType {
|
||||||
|
fn rlp_append(&self, s: &mut RlpStream) {
|
||||||
|
let v = match *self {
|
||||||
|
RewardType::None => 0u32,
|
||||||
|
RewardType::Block => 1,
|
||||||
|
RewardType::Uncle => 2,
|
||||||
|
};
|
||||||
|
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::None,
|
||||||
|
1 => RewardType::Block,
|
||||||
|
2 => 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 {
|
||||||
|
/// Miner's address.
|
||||||
|
pub miner: 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(&self.miner.sha3())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Encodable for Reward {
|
||||||
|
fn rlp_append(&self, s: &mut RlpStream) {
|
||||||
|
s.begin_list(2);
|
||||||
|
s.append(&self.miner);
|
||||||
|
s.append(&self.value);
|
||||||
|
s.append(&self.reward_type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Decodable for Reward {
|
||||||
|
fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> {
|
||||||
|
let res = Reward {
|
||||||
|
miner: rlp.val_at(0)?,
|
||||||
|
value: rlp.val_at(1)?,
|
||||||
|
reward_type: rlp.val_at(2)?,
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(res)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Suicide action.
|
/// Suicide action.
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
#[cfg_attr(feature = "ipc", binary)]
|
#[cfg_attr(feature = "ipc", binary)]
|
||||||
@ -260,7 +335,7 @@ impl Decodable for Suicide {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Description of an action that we trace; will be either a call or a create.
|
/// Description of an action that we trace.
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
#[cfg_attr(feature = "ipc", binary)]
|
#[cfg_attr(feature = "ipc", binary)]
|
||||||
pub enum Action {
|
pub enum Action {
|
||||||
@ -270,6 +345,8 @@ pub enum Action {
|
|||||||
Create(Create),
|
Create(Create),
|
||||||
/// Suicide.
|
/// Suicide.
|
||||||
Suicide(Suicide),
|
Suicide(Suicide),
|
||||||
|
/// Reward
|
||||||
|
Reward(Reward),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Encodable for Action {
|
impl Encodable for Action {
|
||||||
@ -287,7 +364,12 @@ impl Encodable for Action {
|
|||||||
Action::Suicide(ref suicide) => {
|
Action::Suicide(ref suicide) => {
|
||||||
s.append(&2u8);
|
s.append(&2u8);
|
||||||
s.append(suicide);
|
s.append(suicide);
|
||||||
|
},
|
||||||
|
Action::Reward(ref reward) => {
|
||||||
|
s.append(&3u8);
|
||||||
|
s.append(reward);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -299,6 +381,7 @@ impl Decodable for Action {
|
|||||||
0 => rlp.val_at(1).map(Action::Call),
|
0 => rlp.val_at(1).map(Action::Call),
|
||||||
1 => rlp.val_at(1).map(Action::Create),
|
1 => rlp.val_at(1).map(Action::Create),
|
||||||
2 => rlp.val_at(1).map(Action::Suicide),
|
2 => rlp.val_at(1).map(Action::Suicide),
|
||||||
|
3 => rlp.val_at(1).map(Action::Reward),
|
||||||
_ => Err(DecoderError::Custom("Invalid action type.")),
|
_ => Err(DecoderError::Custom("Invalid action type.")),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -311,6 +394,7 @@ impl Action {
|
|||||||
Action::Call(ref call) => call.bloom(),
|
Action::Call(ref call) => call.bloom(),
|
||||||
Action::Create(ref create) => create.bloom(),
|
Action::Create(ref create) => create.bloom(),
|
||||||
Action::Suicide(ref suicide) => suicide.bloom(),
|
Action::Suicide(ref suicide) => suicide.bloom(),
|
||||||
|
Action::Reward(ref reward) => reward.bloom(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -299,6 +299,53 @@ impl From<trace::Call> for Call {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Reward type.
|
||||||
|
#[derive(Debug, Serialize)]
|
||||||
|
pub enum RewardType {
|
||||||
|
/// None
|
||||||
|
#[serde(rename="none")]
|
||||||
|
None,
|
||||||
|
/// Block
|
||||||
|
#[serde(rename="block")]
|
||||||
|
Block,
|
||||||
|
/// Uncle
|
||||||
|
#[serde(rename="uncle")]
|
||||||
|
Uncle,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<trace::RewardType> for RewardType {
|
||||||
|
fn from(c: trace::RewardType) -> Self {
|
||||||
|
match c {
|
||||||
|
trace::RewardType::None => RewardType::None,
|
||||||
|
trace::RewardType::Block => RewardType::Block,
|
||||||
|
trace::RewardType::Uncle => RewardType::Uncle,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Reward action
|
||||||
|
#[derive(Debug, Serialize)]
|
||||||
|
pub struct Reward {
|
||||||
|
/// Miner's address.
|
||||||
|
pub miner: H160,
|
||||||
|
/// Reward amount.
|
||||||
|
pub value: U256,
|
||||||
|
/// Reward type.
|
||||||
|
#[serde(rename="rewardType")]
|
||||||
|
pub reward_type: RewardType,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<trace::Reward> for Reward {
|
||||||
|
fn from(r: trace::Reward) -> Self {
|
||||||
|
Reward {
|
||||||
|
miner: r.miner.into(),
|
||||||
|
value: r.value.into(),
|
||||||
|
reward_type: r.reward_type.into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Suicide
|
/// Suicide
|
||||||
#[derive(Debug, Serialize)]
|
#[derive(Debug, Serialize)]
|
||||||
pub struct Suicide {
|
pub struct Suicide {
|
||||||
@ -330,6 +377,8 @@ pub enum Action {
|
|||||||
Create(Create),
|
Create(Create),
|
||||||
/// Suicide
|
/// Suicide
|
||||||
Suicide(Suicide),
|
Suicide(Suicide),
|
||||||
|
/// Reward
|
||||||
|
Reward(Reward),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<trace::Action> for Action {
|
impl From<trace::Action> for Action {
|
||||||
@ -338,6 +387,7 @@ impl From<trace::Action> for Action {
|
|||||||
trace::Action::Call(call) => Action::Call(call.into()),
|
trace::Action::Call(call) => Action::Call(call.into()),
|
||||||
trace::Action::Create(create) => Action::Create(create.into()),
|
trace::Action::Create(create) => Action::Create(create.into()),
|
||||||
trace::Action::Suicide(suicide) => Action::Suicide(suicide.into()),
|
trace::Action::Suicide(suicide) => Action::Suicide(suicide.into()),
|
||||||
|
trace::Action::Reward(reward) => Action::Reward(reward.into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -449,6 +499,10 @@ impl Serialize for LocalizedTrace {
|
|||||||
struc.serialize_field("type", "suicide")?;
|
struc.serialize_field("type", "suicide")?;
|
||||||
struc.serialize_field("action", suicide)?;
|
struc.serialize_field("action", suicide)?;
|
||||||
},
|
},
|
||||||
|
Action::Reward(ref reward) => {
|
||||||
|
struc.serialize_field("type", "reward")?;
|
||||||
|
struc.serialize_field("action", reward)?;
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
match self.result {
|
match self.result {
|
||||||
@ -516,6 +570,10 @@ impl Serialize for Trace {
|
|||||||
struc.serialize_field("type", "suicide")?;
|
struc.serialize_field("type", "suicide")?;
|
||||||
struc.serialize_field("action", suicide)?;
|
struc.serialize_field("action", suicide)?;
|
||||||
},
|
},
|
||||||
|
Action::Reward(ref reward) => {
|
||||||
|
struc.serialize_field("type", "reward")?;
|
||||||
|
struc.serialize_field("action", reward)?;
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
match self.result {
|
match self.result {
|
||||||
|
Loading…
Reference in New Issue
Block a user