First test.

This commit is contained in:
Gav Wood 2016-03-19 21:02:44 +01:00
parent 2d55e08b41
commit a2fc006ee5
4 changed files with 87 additions and 9 deletions

View File

@ -440,8 +440,8 @@ mod tests {
// TODO: just test state root. // TODO: just test state root.
} }
evm_test!{test_create_contract: test_create_contract_jit, test_create_contract_int} evm_test!{test_create_contract_out_of_depth: test_create_contract_out_of_depth_jit, test_create_contract_out_of_depth_int}
fn test_create_contract(factory: Factory) { fn test_create_contract_out_of_depth(factory: Factory) {
// code: // code:
// //
// 7c 601080600c6000396000f3006000355415600957005b60203560003555 - push 29 bytes? // 7c 601080600c6000396000f3006000355415600957005b60203560003555 - push 29 bytes?
@ -494,6 +494,83 @@ mod tests {
assert_eq!(substate.contracts_created.len(), 0); assert_eq!(substate.contracts_created.len(), 0);
} }
evm_test!{test_create_contract: test_create_contract_jit, test_create_contract_int}
fn test_create_contract(factory: Factory) {
// code:
//
// 7c 601080600c6000396000f3006000355415600957005b60203560003555 - push 29 bytes?
// 60 00 - push 0
// 52
// 60 1d - push 29
// 60 03 - push 3
// 60 17 - push 17
// f0 - create
// 60 00 - push 0
// 55 sstore
//
// other code:
//
// 60 10 - push 16
// 80 - duplicate first stack item
// 60 0c - push 12
// 60 00 - push 0
// 39 - copy current code to memory
// 60 00 - push 0
// f3 - return
let code = "7c601080600c6000396000f3006000355415600957005b60203560003555600052601d60036017f0600055".from_hex().unwrap();
let sender = Address::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap();
let address = contract_address(&sender, &U256::zero());
// TODO: add tests for 'callcreate'
//let next_address = contract_address(&address, &U256::zero());
let mut params = ActionParams::default();
params.address = address.clone();
params.sender = sender.clone();
params.origin = sender.clone();
params.gas = U256::from(100_000);
params.code = Some(code.clone());
params.value = ActionValue::Transfer(U256::from(100));
let mut state_result = get_temp_state();
let mut state = state_result.reference_mut();
state.add_balance(&sender, &U256::from(100));
let info = EnvInfo::default();
let engine = TestEngine::new(5, factory);
let mut substate = Substate::new(true);
let gas_left = {
let mut ex = Executive::new(&mut state, &info, &engine);
let output = BytesRef::Fixed(&mut[0u8;0]);
ex.call(params, &mut substate, output).unwrap()
};
println!("trace: {:?}", substate.subtraces);
let expected_trace = Some(vec![ Trace {
depth: 0,
action: TraceAction::Call(TraceCall {
from: x!("cd1722f3947def4cf144679da39c4c32bdc35681"),
to: x!("b010143a42d5980c7e5ef0e4a4416dc098a4fed3"),
value: x!(100),
gas: x!(100000),
input: vec![],
result: Some((x!(55248), vec![]))
}),
subs: vec![Trace {
depth: 1,
action: TraceAction::Create(TraceCreate {
from: x!("b010143a42d5980c7e5ef0e4a4416dc098a4fed3"),
value: x!(23),
gas: x!(67979),
init: vec![96, 16, 128, 96, 12, 96, 0, 57, 96, 0, 243, 0, 96, 0, 53, 84, 21, 96, 9, 87, 0, 91, 96, 32, 53, 96, 0, 53, 85],
result: Some((x!(3224), x!("c6d80f262ae5e0f164e5fde365044d7ada2bfa34"), vec![96, 0, 53, 84, 21, 96, 9, 87, 0, 91, 96, 32, 53, 96, 0, 53])),
}),
subs: vec![]
}]
} ]);
assert_eq!(substate.subtraces, expected_trace);
assert_eq!(gas_left, U256::from(44_752));
}
evm_test!{test_create_contract_value_too_high: test_create_contract_value_too_high_jit, test_create_contract_value_too_high_int} evm_test!{test_create_contract_value_too_high: test_create_contract_value_too_high_jit, test_create_contract_value_too_high_int}
fn test_create_contract_value_too_high(factory: Factory) { fn test_create_contract_value_too_high(factory: Factory) {
// code: // code:

View File

@ -197,6 +197,7 @@ impl<'a> Ext for Externalities<'a> {
match self.output { match self.output {
OutputPolicy::Return(BytesRef::Fixed(ref mut slice), ref mut copy) => { OutputPolicy::Return(BytesRef::Fixed(ref mut slice), ref mut copy) => {
handle_copy(copy); handle_copy(copy);
let len = cmp::min(slice.len(), data.len()); let len = cmp::min(slice.len(), data.len());
unsafe { unsafe {
ptr::copy(data.as_ptr(), slice.as_mut_ptr(), len); ptr::copy(data.as_ptr(), slice.as_mut_ptr(), len);
@ -205,6 +206,7 @@ impl<'a> Ext for Externalities<'a> {
}, },
OutputPolicy::Return(BytesRef::Flexible(ref mut vec), ref mut copy) => { OutputPolicy::Return(BytesRef::Flexible(ref mut vec), ref mut copy) => {
handle_copy(copy); handle_copy(copy);
vec.clear(); vec.clear();
vec.reserve(data.len()); vec.reserve(data.len());
unsafe { unsafe {
@ -230,8 +232,7 @@ impl<'a> Ext for Externalities<'a> {
ptr::copy(data.as_ptr(), code.as_mut_ptr(), data.len()); ptr::copy(data.as_ptr(), code.as_mut_ptr(), data.len());
code.set_len(data.len()); code.set_len(data.len());
} }
let address = &self.origin_info.address; self.state.init_code(&self.origin_info.address, code);
self.state.init_code(address, code);
Ok(*gas - return_cost) Ok(*gas - return_cost)
} }
} }

View File

@ -84,7 +84,7 @@ impl TraceAction {
from: p.sender.clone(), from: p.sender.clone(),
value: match p.value { ActionValue::Transfer(ref x) | ActionValue::Apparent(ref x) => x.clone() }, value: match p.value { ActionValue::Transfer(ref x) | ActionValue::Apparent(ref x) => x.clone() },
gas: p.gas.clone(), gas: p.gas.clone(),
init: p.data.clone().unwrap_or(vec![]), init: p.code.clone().unwrap_or(vec![]),
result: None, result: None,
}) })
} }

View File

@ -18,7 +18,7 @@
use common::*; use common::*;
/// Description of a _call_ action, either a `CALL` operation or a message transction. /// Description of a _call_ action, either a `CALL` operation or a message transction.
#[derive(Debug, Clone)] #[derive(Debug, Clone, PartialEq)]
pub struct TraceCall { pub struct TraceCall {
/// The sending account. /// The sending account.
pub from: Address, pub from: Address,
@ -35,7 +35,7 @@ pub struct TraceCall {
} }
/// Description of a _create_ action, either a `CREATE` operation or a create transction. /// Description of a _create_ action, either a `CREATE` operation or a create transction.
#[derive(Debug, Clone)] #[derive(Debug, Clone, PartialEq)]
pub struct TraceCreate { pub struct TraceCreate {
/// The address of the creator. /// The address of the creator.
pub from: Address, pub from: Address,
@ -52,7 +52,7 @@ pub struct TraceCreate {
} }
/// Description of an action that we trace; will be either a call or a create. /// Description of an action that we trace; will be either a call or a create.
#[derive(Debug, Clone)] #[derive(Debug, Clone, PartialEq)]
pub enum TraceAction { pub enum TraceAction {
/// Action isn't yet known. /// Action isn't yet known.
Unknown, Unknown,
@ -62,7 +62,7 @@ pub enum TraceAction {
Create(TraceCreate), Create(TraceCreate),
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone, PartialEq)]
/// A trace; includes a description of the action being traced and sub traces of each interior action. /// A trace; includes a description of the action being traced and sub traces of each interior action.
pub struct Trace { pub struct Trace {
/// The number of EVM execution environments active when this action happened; 0 if it's /// The number of EVM execution environments active when this action happened; 0 if it's