executive output uses BytesRef
This commit is contained in:
parent
5f7a81a468
commit
87eb66183c
@ -160,7 +160,9 @@ impl<'a> Executive<'a> {
|
||||
code: self.state.code(address).unwrap_or(vec![]),
|
||||
data: t.data.clone(),
|
||||
};
|
||||
self.call(¶ms, &mut substate, &mut [])
|
||||
// TODO: move output upstream
|
||||
let mut out = vec![];
|
||||
self.call(¶ms, &mut substate, BytesRef::Flexible(&mut out))
|
||||
}
|
||||
};
|
||||
|
||||
@ -172,7 +174,7 @@ impl<'a> Executive<'a> {
|
||||
/// NOTE. It does not finalize the transaction (doesn't do refunds, nor suicides).
|
||||
/// Modifies the substate and the output.
|
||||
/// Returns either gas_left or `evm::Error`.
|
||||
pub fn call(&mut self, params: &ActionParams, substate: &mut Substate, output: &mut [u8]) -> evm::Result {
|
||||
pub fn call(&mut self, params: &ActionParams, substate: &mut Substate, mut output: BytesRef) -> evm::Result {
|
||||
// at first, transfer value to destination
|
||||
self.state.transfer_balance(¶ms.sender, ¶ms.address, ¶ms.value);
|
||||
|
||||
@ -181,7 +183,7 @@ impl<'a> Executive<'a> {
|
||||
let cost = self.engine.cost_of_builtin(¶ms.address, ¶ms.data);
|
||||
match cost <= params.gas {
|
||||
true => {
|
||||
self.engine.execute_builtin(¶ms.address, ¶ms.data, output);
|
||||
self.engine.execute_builtin(¶ms.address, ¶ms.data, &mut output);
|
||||
Ok(params.gas - cost)
|
||||
},
|
||||
false => Err(evm::Error::OutOfGas)
|
||||
@ -270,7 +272,7 @@ impl<'a> Executive<'a> {
|
||||
pub enum OutputPolicy<'a> {
|
||||
/// Return reference to fixed sized output.
|
||||
/// Used for message calls.
|
||||
Return(&'a mut [u8]),
|
||||
Return(BytesRef<'a>),
|
||||
/// Init new contract as soon as `RETURN` is called.
|
||||
InitContract
|
||||
}
|
||||
@ -405,7 +407,7 @@ impl<'a> Ext for Externalities<'a> {
|
||||
};
|
||||
|
||||
let mut ex = Executive::from_parent(self.state, self.info, self.engine, self.depth);
|
||||
ex.call(¶ms, self.substate, output).map(|gas_left| {
|
||||
ex.call(¶ms, self.substate, BytesRef::Fixed(output)).map(|gas_left| {
|
||||
gas + gas_left.low_u64()
|
||||
})
|
||||
}
|
||||
@ -416,11 +418,18 @@ impl<'a> Ext for Externalities<'a> {
|
||||
|
||||
fn ret(&mut self, gas: u64, data: &[u8]) -> Result<u64, evm::Error> {
|
||||
match &mut self.output {
|
||||
&mut OutputPolicy::Return(ref mut slice) => unsafe {
|
||||
&mut OutputPolicy::Return(BytesRef::Fixed(ref mut slice)) => unsafe {
|
||||
let len = cmp::min(slice.len(), data.len());
|
||||
ptr::copy(data.as_ptr(), slice.as_mut_ptr(), len);
|
||||
Ok(gas)
|
||||
},
|
||||
&mut OutputPolicy::Return(BytesRef::Flexible(ref mut vec)) => unsafe {
|
||||
vec.clear();
|
||||
vec.reserve(data.len());
|
||||
ptr::copy(data.as_ptr(), vec.as_mut_ptr(), data.len());
|
||||
vec.set_len(data.len());
|
||||
Ok(gas)
|
||||
},
|
||||
&mut OutputPolicy::InitContract => {
|
||||
let return_cost = data.len() as u64 * self.schedule.create_data_gas as u64;
|
||||
if return_cost > gas {
|
||||
@ -743,7 +752,7 @@ mod tests {
|
||||
|
||||
let gas_left = {
|
||||
let mut ex = Executive::new(&mut state, &info, &engine);
|
||||
ex.call(¶ms, &mut substate, &mut []).unwrap()
|
||||
ex.call(¶ms, &mut substate, BytesRef::Fixed(&mut [])).unwrap()
|
||||
};
|
||||
|
||||
assert_eq!(gas_left, U256::from(73_237));
|
||||
@ -785,7 +794,7 @@ mod tests {
|
||||
|
||||
let gas_left = {
|
||||
let mut ex = Executive::new(&mut state, &info, &engine);
|
||||
ex.call(¶ms, &mut substate, &mut []).unwrap()
|
||||
ex.call(¶ms, &mut substate, BytesRef::Fixed(&mut [])).unwrap()
|
||||
};
|
||||
|
||||
assert_eq!(gas_left, U256::from(59_870));
|
||||
|
@ -213,10 +213,11 @@ fn do_json_test(json_data: &[u8]) -> Vec<String> {
|
||||
}).is_none();
|
||||
|
||||
let mut substate = Substate::new();
|
||||
let mut output = vec![];
|
||||
|
||||
// execute
|
||||
let res = {
|
||||
let ex = Externalities::new(&mut state, &info, &engine, 0, ¶ms, &mut substate, OutputPolicy::Return(&mut []));
|
||||
let ex = Externalities::new(&mut state, &info, &engine, 0, ¶ms, &mut substate, OutputPolicy::Return(BytesRef::Flexible(&mut output)));
|
||||
let mut test_ext = TestExt::new(ex);
|
||||
let evm = Factory::create();
|
||||
evm.exec(¶ms, &mut test_ext)
|
||||
@ -226,9 +227,10 @@ fn do_json_test(json_data: &[u8]) -> Vec<String> {
|
||||
match res {
|
||||
Err(_) => fail_unless(out_of_gas, "didn't expect to run out of gas."),
|
||||
Ok(gas_left) => {
|
||||
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(gas_left == u256_from_json(&test["gas"]), "gas_left is incorrect");
|
||||
println!("name: {}, gas_left : {:?}, expected: {:?}", name, gas_left, u256_from_json(&test["gas"]));
|
||||
fail_unless(output == bytes_from_json(&test["out"]), "output is incorrect");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user