Skip to content
This repository has been archived by the owner on Nov 6, 2020. It is now read-only.

Commit

Permalink
Merge branch 'master' of github.com:ethcore/parity into filter_create…
Browse files Browse the repository at this point in the history
…_address
  • Loading branch information
debris committed Jul 23, 2016
2 parents b6f01bb + aafb014 commit 221da02
Show file tree
Hide file tree
Showing 11 changed files with 250 additions and 13 deletions.
1 change: 1 addition & 0 deletions ethcore/src/externalities.rs
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,7 @@ impl<'a, T, V> Ext for Externalities<'a, T, V> where T: 'a + Tracer, V: 'a + VMT
self.state.transfer_balance(&address, refund_address, &balance);
}

self.tracer.trace_suicide(address, balance, refund_address.clone(), self.depth + 1);
self.substate.suicides.insert(address);
}

Expand Down
54 changes: 53 additions & 1 deletion ethcore/src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ impl State {
/// Reset the code of account `a` so that it is `code`.
pub fn reset_code(&mut self, a: &Address, code: Bytes) {
self.require_or_from(a, true, || Account::new_contract(0.into(), self.account_start_nonce), |_|{}).reset_code(code);
}
}

/// Execute a given transaction.
/// This will change the state accordingly.
Expand Down Expand Up @@ -1154,6 +1154,58 @@ fn should_trace_failed_subcall_with_subcall_transaction() {
assert_eq!(result.trace, expected_trace);
}

#[test]
fn should_trace_suicide() {
init_log();

let temp = RandomTempPath::new();
let mut state = get_temp_state_in(temp.as_path());

let mut info = EnvInfo::default();
info.gas_limit = 1_000_000.into();
let engine = TestEngine::new(5);

let t = Transaction {
nonce: 0.into(),
gas_price: 0.into(),
gas: 100_000.into(),
action: Action::Call(0xa.into()),
value: 100.into(),
data: vec![],
}.sign(&"".sha3());

state.init_code(&0xa.into(), FromHex::from_hex("73000000000000000000000000000000000000000bff").unwrap());
state.add_balance(&0xa.into(), &50.into());
state.add_balance(t.sender().as_ref().unwrap(), &100.into());
let vm_factory = Default::default();
let result = state.apply(&info, &engine, &vm_factory, &t, true).unwrap();
let expected_trace = Some(Trace {
depth: 0,
action: trace::Action::Call(trace::Call {
from: "9cce34f7ab185c7aba1b7c8140d620b4bda941d6".into(),
to: 0xa.into(),
value: 100.into(),
gas: 79000.into(),
input: vec![],
}),
result: trace::Res::Call(trace::CallResult {
gas_used: 3.into(),
output: vec![]
}),
subs: vec![Trace {
depth: 1,
action: trace::Action::Suicide(trace::Suicide {
address: 0xa.into(),
refund_address: 0xb.into(),
balance: 150.into(),
}),
result: trace::Res::None,
subs: vec![]
}]
});
assert_eq!(result.trace, expected_trace);
}

#[test]
fn code_from_database() {
let a = Address::zero();
Expand Down
16 changes: 15 additions & 1 deletion ethcore/src/trace/executive_tracer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
use util::{Bytes, Address, U256};
use action_params::ActionParams;
use trace::trace::{Trace, Call, Create, Action, Res, CreateResult, CallResult, VMTrace, VMOperation, VMExecutedOperation, MemoryDiff, StorageDiff};
use trace::trace::{Trace, Call, Create, Action, Res, CreateResult, CallResult, VMTrace, VMOperation, VMExecutedOperation, MemoryDiff, StorageDiff, Suicide};
use trace::{Tracer, VMTracer};

/// Simple executive tracer. Traces all calls and creates. Ignores delegatecalls.
Expand Down Expand Up @@ -97,6 +97,20 @@ impl Tracer for ExecutiveTracer {
self.traces.push(trace);
}

fn trace_suicide(&mut self, address: Address, balance: U256, refund_address: Address, depth: usize) {
let trace = Trace {
depth: depth,
subs: vec![],
action: Action::Suicide(Suicide {
address: address,
refund_address: refund_address,
balance: balance,
}),
result: Res::None,
};
self.traces.push(trace);
}

fn subtracer(&self) -> Self {
ExecutiveTracer::default()
}
Expand Down
3 changes: 3 additions & 0 deletions ethcore/src/trace/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,9 @@ pub trait Tracer: Send {
/// Stores failed create trace.
fn trace_failed_create(&mut self, create: Option<Create>, depth: usize, subs: Vec<Trace>);

/// Stores suicide info.
fn trace_suicide(&mut self, address: Address, balance: U256, refund_address: Address, depth: usize);

/// Spawn subtracer which will be used to trace deeper levels of execution.
fn subtracer(&self) -> Self where Self: Sized;

Expand Down
3 changes: 3 additions & 0 deletions ethcore/src/trace/noop_tracer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ impl Tracer for NoopTracer {
assert!(create.is_none(), "self.prepare_trace_create().is_none(): so we can't be tracing: qed");
}

fn trace_suicide(&mut self, _address: Address, _balance: U256, _refund_address: Address, _depth: usize) {
}

fn subtracer(&self) -> Self {
NoopTracer
}
Expand Down
28 changes: 26 additions & 2 deletions ethcore/src/types/trace_types/filter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,11 @@ impl Filter {
let from_matches = self.from_address.matches(&create.from);
let to_matches = self.to_address.matches_all();
from_matches && to_matches
},
Action::Suicide(ref suicide) => {
let from_matches = self.from_address.matches(&suicide.address);
let to_matches = self.to_address.matches(&suicide.refund_address);
from_matches && to_matches
}
};

Expand All @@ -132,9 +137,9 @@ impl Filter {

#[cfg(test)]
mod tests {
use util::{FixedHash, Address, U256};
use util::{FixedHash, Address};
use util::sha3::Hashable;
use trace::trace::{Action, Call, Res, Create, CreateResult};
use trace::trace::{Action, Call, Res, Create, CreateResult, Suicide};
use trace::flat::FlatTrace;
use trace::{Filter, AddressesFilter};
use basic_types::LogBloom;
Expand Down Expand Up @@ -317,5 +322,24 @@ mod tests {
assert!(f4.matches(&trace));
assert!(f5.matches(&trace));
assert!(!f6.matches(&trace));

let trace = FlatTrace {
action: Action::Suicide(Suicide {
address: 1.into(),
refund_address: 2.into(),
balance: 3.into(),
}),
result: Res::None,
trace_address: vec![],
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));
}
}
74 changes: 72 additions & 2 deletions ethcore/src/types/trace_types/trace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -212,13 +212,57 @@ impl Create {
}
}

/// Suicide action.
#[derive(Debug, Clone, PartialEq, Binary)]
pub struct Suicide {
/// Suicided address.
pub address: Address,
/// Suicided contract heir.
pub refund_address: Address,
/// Balance of the contract just before suicide.
pub balance: U256,
}

impl Suicide {
/// Return suicide action bloom.
pub fn bloom(&self) -> LogBloom {
LogBloom::from_bloomed(&self.address.sha3())
.with_bloomed(&self.refund_address.sha3())
}
}

impl Encodable for Suicide {
fn rlp_append(&self, s: &mut RlpStream) {
s.begin_list(3);
s.append(&self.address);
s.append(&self.refund_address);
s.append(&self.balance);
}
}

impl Decodable for Suicide {
fn decode<D>(decoder: &D) -> Result<Self, DecoderError> where D: Decoder {
let d = decoder.as_rlp();
let res = Suicide {
address: try!(d.val_at(0)),
refund_address: try!(d.val_at(1)),
balance: try!(d.val_at(3)),
};

Ok(res)
}
}


/// Description of an action that we trace; will be either a call or a create.
#[derive(Debug, Clone, PartialEq, Binary)]
pub enum Action {
/// It's a call action.
Call(Call),
/// It's a create action.
Create(Create),
/// Suicide.
Suicide(Suicide),
}

impl Encodable for Action {
Expand All @@ -232,6 +276,10 @@ impl Encodable for Action {
Action::Create(ref create) => {
s.append(&1u8);
s.append(create);
},
Action::Suicide(ref suicide) => {
s.append(&2u8);
s.append(suicide);
}
}
}
Expand All @@ -244,6 +292,7 @@ impl Decodable for Action {
match action_type {
0 => d.val_at(1).map(Action::Call),
1 => d.val_at(1).map(Action::Create),
2 => d.val_at(2).map(Action::Suicide),
_ => Err(DecoderError::Custom("Invalid action type.")),
}
}
Expand All @@ -255,6 +304,7 @@ impl Action {
match *self {
Action::Call(ref call) => call.bloom(),
Action::Create(ref create) => create.bloom(),
Action::Suicide(ref suicide) => suicide.bloom(),
}
}
}
Expand All @@ -270,6 +320,8 @@ pub enum Res {
FailedCall,
/// Failed create.
FailedCreate,
/// None
None,
}

impl Encodable for Res {
Expand All @@ -292,6 +344,10 @@ impl Encodable for Res {
Res::FailedCreate => {
s.begin_list(1);
s.append(&3u8);
},
Res::None => {
s.begin_list(1);
s.append(&4u8);
}
}
}
Expand All @@ -306,6 +362,7 @@ impl Decodable for Res {
1 => d.val_at(1).map(Res::Create),
2 => Ok(Res::FailedCall),
3 => Ok(Res::FailedCreate),
4 => Ok(Res::None),
_ => Err(DecoderError::Custom("Invalid result type.")),
}
}
Expand All @@ -316,7 +373,7 @@ impl Res {
pub fn bloom(&self) -> LogBloom {
match *self {
Res::Create(ref create) => create.bloom(),
Res::Call(_) | Res::FailedCall | Res::FailedCreate => Default::default(),
Res::Call(_) | Res::FailedCall | Res::FailedCreate | Res::None => Default::default(),
}
}
}
Expand Down Expand Up @@ -535,7 +592,7 @@ mod tests {
use util::{Address, U256, FixedHash};
use util::rlp::{encode, decode};
use util::sha3::Hashable;
use trace::trace::{Call, CallResult, Create, Res, Action, Trace, CreateResult};
use trace::trace::{Call, CallResult, Create, Res, Action, Trace, Suicide, CreateResult};

#[test]
fn traces_rlp() {
Expand Down Expand Up @@ -598,6 +655,16 @@ mod tests {
code: vec![],
address: 15.into(),
}),
},
Trace {
depth: 3,
action: Action::Suicide(Suicide {
address: 101.into(),
refund_address: 102.into(),
balance: 0.into(),
}),
subs: vec![],
result: Res::None,
}
],
result: Res::Call(CallResult {
Expand All @@ -614,5 +681,8 @@ mod tests {
assert!(!bloom.contains_bloomed(&Address::from(20).sha3()));
assert!(bloom.contains_bloomed(&Address::from(6).sha3()));
assert!(bloom.contains_bloomed(&Address::from(15).sha3()));
assert!(bloom.contains_bloomed(&Address::from(101).sha3()));
assert!(bloom.contains_bloomed(&Address::from(102).sha3()));
assert!(!bloom.contains_bloomed(&Address::from(103).sha3()));
}
}
35 changes: 33 additions & 2 deletions parity/configuration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -562,8 +562,15 @@ impl Configuration {
}

pub fn signer_enabled(&self) -> bool {
(self.args.flag_unlock.is_none() && !self.args.flag_no_signer) ||
self.args.flag_force_signer
if self.args.flag_force_signer {
return true;
}

let signer_disabled = self.args.flag_unlock.is_some() ||
self.args.flag_geth ||
self.args.flag_no_signer;

return !signer_disabled;
}

pub fn log_settings(&self) -> LogSettings {
Expand Down Expand Up @@ -660,5 +667,29 @@ mod tests {
assert_eq!(conf2.rpc_hosts(), None);
assert_eq!(conf3.rpc_hosts(), Some(vec!["ethcore.io".into(), "something.io".into()]));
}

#[test]
fn should_disable_signer_in_geth_compat() {
// given

// when
let conf0 = parse(&["parity", "--geth"]);
let conf1 = parse(&["parity", "--geth", "--force-signer"]);

// then
assert_eq!(conf0.signer_enabled(), false);
assert_eq!(conf1.signer_enabled(), true);
}

#[test]
fn should_disable_signer_when_account_is_unlocked() {
// given

// when
let conf0 = parse(&["parity", "--unlock", "0x0"]);

// then
assert_eq!(conf0.signer_enabled(), false);
}
}

4 changes: 2 additions & 2 deletions rpc/src/v1/impls/eth_signing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ use ethcore::account_provider::AccountProvider;
use v1::helpers::{SigningQueue, ConfirmationPromise, ConfirmationResult, ConfirmationsQueue, TransactionRequest as TRequest};
use v1::traits::EthSigning;
use v1::types::{TransactionRequest, H160 as RpcH160, H256 as RpcH256, H520 as RpcH520, U256 as RpcU256};
use v1::impls::{default_gas_price, sign_and_dispatch};
use v1::impls::{default_gas_price, sign_and_dispatch, transaction_rejected_error};

fn fill_optional_fields<C, M>(request: &mut TRequest, client: &C, miner: &M)
where C: MiningBlockChainClient, M: MinerService {
Expand Down Expand Up @@ -129,7 +129,7 @@ impl<C, M> EthSigning for EthSigningQueueClient<C, M>
let res = match pending.get(&id) {
Some(ref promise) => match promise.result() {
ConfirmationResult::Waiting => { return Ok(Value::Null); }
ConfirmationResult::Rejected => to_value(&RpcH256::default()),
ConfirmationResult::Rejected => Err(transaction_rejected_error()),
ConfirmationResult::Confirmed(rpc_response) => rpc_response,
},
_ => { return Err(Error::invalid_params()); }
Expand Down
Loading

0 comments on commit 221da02

Please sign in to comment.