fixed suicide refund address

This commit is contained in:
debris 2016-01-13 16:16:21 +01:00
parent 87eb66183c
commit d7adf95189
6 changed files with 28 additions and 10 deletions

View File

@ -127,6 +127,12 @@ impl ContextHandle {
unsafe { std::slice::from_raw_parts(self.data_handle.call_data, self.data_handle.call_data_size as usize) } unsafe { std::slice::from_raw_parts(self.data_handle.call_data, self.data_handle.call_data_size as usize) }
} }
/// Returns address to which funds should be transfered after suicide.
pub fn suicide_refund_address(&self) -> JitI256 {
// evmjit reuses data_handle address field to store suicide address
self.data_handle.address
}
/// Returns gas left. /// Returns gas left.
pub fn gas_left(&self) -> u64 { pub fn gas_left(&self) -> u64 {
self.data_handle.gas as u64 self.data_handle.gas as u64

View File

@ -51,7 +51,8 @@ pub trait Ext {
fn ret(&mut self, gas: u64, data: &[u8]) -> Result<u64, Error>; fn ret(&mut self, gas: u64, data: &[u8]) -> Result<u64, Error>;
/// Should be called when contract commits suicide. /// Should be called when contract commits suicide.
fn suicide(&mut self); /// Address to which funds should be refunded.
fn suicide(&mut self, refund_address: &Address);
/// Returns schedule. /// Returns schedule.
fn schedule(&self) -> &Schedule; fn schedule(&self) -> &Schedule;

View File

@ -347,8 +347,7 @@ impl evm::Evm for JitEvm {
evmjit::ReturnCode::Stop => Ok(U256::from(context.gas_left())), evmjit::ReturnCode::Stop => Ok(U256::from(context.gas_left())),
evmjit::ReturnCode::Return => ext.ret(context.gas_left(), context.output_data()).map(|gas_left| U256::from(gas_left)), evmjit::ReturnCode::Return => ext.ret(context.gas_left(), context.output_data()).map(|gas_left| U256::from(gas_left)),
evmjit::ReturnCode::Suicide => { evmjit::ReturnCode::Suicide => {
// what if there is a suicide and we run out of gas just after? ext.suicide(&Address::from_jit(&context.suicide_refund_address()));
ext.suicide();
Ok(U256::from(context.gas_left())) Ok(U256::from(context.gas_left()))
}, },
evmjit::ReturnCode::OutOfGas => Err(evm::Error::OutOfGas), evmjit::ReturnCode::OutOfGas => Err(evm::Error::OutOfGas),

View File

@ -72,7 +72,7 @@ impl Ext for FakeExt {
unimplemented!(); unimplemented!();
} }
fn suicide(&mut self) { fn suicide(&mut self, refund_address: &Address) {
unimplemented!(); unimplemented!();
} }

View File

@ -457,8 +457,10 @@ impl<'a> Ext for Externalities<'a> {
self.substate.logs.push(LogEntry::new(address, topics, data)); self.substate.logs.push(LogEntry::new(address, topics, data));
} }
fn suicide(&mut self) { fn suicide(&mut self, refund_address: &Address) {
let address = self.params.address.clone(); let address = self.params.address.clone();
let balance = self.balance(&address);
self.state.transfer_balance(&address, refund_address, &balance);
self.substate.suicides.insert(address); self.substate.suicides.insert(address);
} }

View File

@ -139,8 +139,8 @@ impl<'a> Ext for TestExt<'a> {
self.ext.ret(gas, data) self.ext.ret(gas, data)
} }
fn suicide(&mut self) { fn suicide(&mut self, refund_address: &Address) {
self.ext.suicide() self.ext.suicide(refund_address)
} }
fn schedule(&self) -> &Schedule { fn schedule(&self) -> &Schedule {
@ -227,10 +227,20 @@ fn do_json_test(json_data: &[u8]) -> Vec<String> {
match res { match res {
Err(_) => fail_unless(out_of_gas, "didn't expect to run out of gas."), Err(_) => fail_unless(out_of_gas, "didn't expect to run out of gas."),
Ok(gas_left) => { Ok(gas_left) => {
println!("name: {}, gas_left : {:?}, expected: {:?}", name, gas_left, u256_from_json(&test["gas"])); //println!("name: {}, gas_left : {:?}, expected: {:?}", name, gas_left, u256_from_json(&test["gas"]));
fail_unless(!out_of_gas, "expected to run out of gas."); fail_unless(!out_of_gas, "expected to run out of gas.");
fail_unless(gas_left == u256_from_json(&test["gas"]), "gas_left is incorrect"); fail_unless(gas_left == u256_from_json(&test["gas"]), "gas_left is incorrect");
fail_unless(output == bytes_from_json(&test["out"]), "output is incorrect"); fail_unless(output == bytes_from_json(&test["out"]), "output is incorrect");
test.find("post").map(|pre| for (addr, s) in pre.as_object().unwrap() {
let address = address_from_str(addr);
//let balance = u256_from_json(&s["balance"]);
fail_unless(state.code(&address) == Some(bytes_from_json(&s["code"])), "code is incorrect");
fail_unless(state.balance(&address) == u256_from_json(&s["balance"]), "balance is incorrect");
});
} }
} }
} }
@ -247,11 +257,11 @@ fn do_json_test(json_data: &[u8]) -> Vec<String> {
declare_test!{ExecutiveTests_vmArithmeticTest, "VMTests/vmArithmeticTest"} declare_test!{ExecutiveTests_vmArithmeticTest, "VMTests/vmArithmeticTest"}
declare_test!{ExecutiveTests_vmBitwiseLogicOperationTest, "VMTests/vmBitwiseLogicOperationTest"} declare_test!{ExecutiveTests_vmBitwiseLogicOperationTest, "VMTests/vmBitwiseLogicOperationTest"}
// this one crashes with some vm internal error. Separately they pass. // this one crashes with some vm internal error. Separately they pass.
//declare_test!{ExecutiveTests_vmBlockInfoTest, "VMTests/vmBlockInfoTest"} declare_test_ignore!{ExecutiveTests_vmBlockInfoTest, "VMTests/vmBlockInfoTest"}
declare_test!{ExecutiveTests_vmEnvironmentalInfoTest, "VMTests/vmEnvironmentalInfoTest"} declare_test!{ExecutiveTests_vmEnvironmentalInfoTest, "VMTests/vmEnvironmentalInfoTest"}
declare_test!{ExecutiveTests_vmIOandFlowOperationsTest, "VMTests/vmIOandFlowOperationsTest"} declare_test!{ExecutiveTests_vmIOandFlowOperationsTest, "VMTests/vmIOandFlowOperationsTest"}
// this one take way too long. // this one take way too long.
//declare_test!{ExecutiveTests_vmInputLimits, "VMTests/vmInputLimits"} declare_test_ignore!{ExecutiveTests_vmInputLimits, "VMTests/vmInputLimits"}
declare_test!{ExecutiveTests_vmLogTest, "VMTests/vmLogTest"} declare_test!{ExecutiveTests_vmLogTest, "VMTests/vmLogTest"}
declare_test!{ExecutiveTests_vmPerformanceTest, "VMTests/vmPerformanceTest"} declare_test!{ExecutiveTests_vmPerformanceTest, "VMTests/vmPerformanceTest"}
declare_test!{ExecutiveTests_vmPushDupSwapTest, "VMTests/vmPushDupSwapTest"} declare_test!{ExecutiveTests_vmPushDupSwapTest, "VMTests/vmPushDupSwapTest"}