Skip to content

Commit 11e36de

Browse files
authored
Compilance fix 5 (#221)
* Fix issues with SUICIDE testing and retval/retbuf * Fix gas cost calculation related to address access cost * Revert "Fix gas cost calculation related to address access cost" This reverts commit 5406dab. * Fix issue with call stipend * Enable more jsontests
1 parent fc97fb7 commit 11e36de

File tree

14 files changed

+100
-59
lines changed

14 files changed

+100
-59
lines changed

.github/workflows/rust.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,12 @@ jobs:
3636
- name: Run tests
3737
run: |
3838
cargo run --release --verbose -p jsontests -- \
39+
jsontests/res/ethtests/GeneralStateTests/stCodeCopyTest/ \
3940
jsontests/res/ethtests/GeneralStateTests/stExample/ \
4041
jsontests/res/ethtests/GeneralStateTests/stSLoadTest/ \
4142
jsontests/res/ethtests/GeneralStateTests/VMTests/vmArithmeticTest/ \
4243
jsontests/res/ethtests/GeneralStateTests/VMTests/vmBitwiseLogicOperation/ \
4344
jsontests/res/ethtests/GeneralStateTests/VMTests/vmIOandFlowOperations/ \
44-
jsontests/res/ethtests/GeneralStateTests/VMTests/vmLogTest/
45+
jsontests/res/ethtests/GeneralStateTests/VMTests/vmLogTest/ \
46+
jsontests/res/ethtests/GeneralStateTests/VMTests/vmTests/
4547

interpreter/src/eval/misc.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,7 @@ pub fn ret<S, Tr>(state: &mut Machine<S>) -> Control<Tr> {
207207
pop_u256!(state, start, len);
208208
try_or_fail!(state.memory.resize_offset(start, len));
209209
state.memory.resize_to_range(start..(start + len));
210+
state.memory.swap_and_clear(&mut state.retval);
210211
Control::Exit(ExitSucceed::Returned.into())
211212
}
212213

@@ -215,5 +216,6 @@ pub fn revert<S, Tr>(state: &mut Machine<S>) -> Control<Tr> {
215216
pop_u256!(state, start, len);
216217
try_or_fail!(state.memory.resize_offset(start, len));
217218
state.memory.resize_to_range(start..(start + len));
219+
state.memory.swap_and_clear(&mut state.retval);
218220
Control::Exit(ExitError::Reverted.into())
219221
}

interpreter/src/eval/system.rs

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use super::Control;
22
use crate::{
33
ExitException, ExitFatal, ExitSucceed, Log, Machine, RuntimeBackend, RuntimeEnvironment,
4-
RuntimeState,
4+
RuntimeState, Transfer,
55
};
66
use alloc::vec::Vec;
77
use primitive_types::{H256, U256};
@@ -47,7 +47,7 @@ pub fn balance<S: AsRef<RuntimeState>, H: RuntimeEnvironment + RuntimeBackend, T
4747
handler: &mut H,
4848
) -> Control<Tr> {
4949
pop!(machine, address);
50-
try_or_fail!(handler.mark_hot(address.into(), None));
50+
handler.mark_hot(address.into(), None);
5151
push_u256!(machine, handler.balance(address.into()));
5252

5353
Control::Continue
@@ -127,7 +127,7 @@ pub fn extcodesize<S: AsRef<RuntimeState>, H: RuntimeEnvironment + RuntimeBacken
127127
handler: &mut H,
128128
) -> Control<Tr> {
129129
pop!(machine, address);
130-
try_or_fail!(handler.mark_hot(address.into(), None));
130+
handler.mark_hot(address.into(), None);
131131
let code_size = handler.code_size(address.into());
132132
push_u256!(machine, code_size);
133133

@@ -139,7 +139,7 @@ pub fn extcodehash<S: AsRef<RuntimeState>, H: RuntimeEnvironment + RuntimeBacken
139139
handler: &mut H,
140140
) -> Control<Tr> {
141141
pop!(machine, address);
142-
try_or_fail!(handler.mark_hot(address.into(), None));
142+
handler.mark_hot(address.into(), None);
143143
let code_hash = handler.code_hash(address.into());
144144
push!(machine, code_hash);
145145

@@ -153,7 +153,7 @@ pub fn extcodecopy<S: AsRef<RuntimeState>, H: RuntimeEnvironment + RuntimeBacken
153153
pop!(machine, address);
154154
pop_u256!(machine, memory_offset, code_offset, len);
155155

156-
try_or_fail!(handler.mark_hot(address.into(), None));
156+
handler.mark_hot(address.into(), None);
157157
try_or_fail!(machine.memory.resize_offset(memory_offset, len));
158158

159159
let code = handler.code(address.into());
@@ -265,7 +265,7 @@ pub fn sload<S: AsRef<RuntimeState>, H: RuntimeEnvironment + RuntimeBackend, Tr>
265265
handler: &mut H,
266266
) -> Control<Tr> {
267267
pop!(machine, index);
268-
try_or_fail!(handler.mark_hot(machine.state.as_ref().context.address, Some(index)));
268+
handler.mark_hot(machine.state.as_ref().context.address, Some(index));
269269
let value = handler.storage(machine.state.as_ref().context.address, index);
270270
push!(machine, value);
271271

@@ -277,7 +277,7 @@ pub fn sstore<S: AsRef<RuntimeState>, H: RuntimeEnvironment + RuntimeBackend, Tr
277277
handler: &mut H,
278278
) -> Control<Tr> {
279279
pop!(machine, index, value);
280-
try_or_fail!(handler.mark_hot(machine.state.as_ref().context.address, Some(index)));
280+
handler.mark_hot(machine.state.as_ref().context.address, Some(index));
281281

282282
match handler.set_storage(machine.state.as_ref().context.address, index, value) {
283283
Ok(()) => Control::Continue,
@@ -335,12 +335,23 @@ pub fn suicide<S: AsRef<RuntimeState>, H: RuntimeEnvironment + RuntimeBackend, T
335335
machine: &mut Machine<S>,
336336
handler: &mut H,
337337
) -> Control<Tr> {
338-
pop!(machine, target);
338+
let address = machine.state.as_ref().context.address;
339339

340-
match handler.mark_delete(machine.state.as_ref().context.address, target.into()) {
341-
Ok(()) => (),
342-
Err(e) => return Control::Exit(e.into()),
343-
}
340+
match machine.stack.perform_pop1_push0(|target| {
341+
let balance = handler.balance(address);
342+
343+
handler.transfer(Transfer {
344+
source: address,
345+
target: (*target).into(),
346+
value: balance,
347+
})?;
344348

345-
Control::Exit(ExitSucceed::Suicided.into())
349+
handler.mark_delete(address);
350+
handler.reset_balance(address);
351+
352+
Ok(((), ()))
353+
}) {
354+
Ok(()) => Control::Exit(ExitSucceed::Suicided.into()),
355+
Err(e) => Control::Exit(Err(e)),
356+
}
346357
}

interpreter/src/lib.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@ pub struct Machine<S> {
4040
position: usize,
4141
/// Code validity maps.
4242
valids: Valids,
43+
/// Return value. Note the difference between `retbuf`.
44+
/// A `retval` holds what's returned by the current machine, with `RETURN` or `REVERT` opcode.
45+
/// A `retbuf` holds the buffer of returned value by sub-calls.
46+
pub retval: Vec<u8>,
4347
/// Memory.
4448
pub memory: Memory,
4549
/// Stack.
@@ -69,6 +73,7 @@ impl<S> Machine<S> {
6973
code,
7074
position: 0,
7175
valids,
76+
retval: Vec::new(),
7277
memory: Memory::new(memory_limit),
7378
stack: Stack::new(stack_limit),
7479
state,
@@ -93,11 +98,6 @@ impl<S> Machine<S> {
9398
self.position = self.code.len();
9499
}
95100

96-
/// Return value of the machine.
97-
pub fn into_retbuf(self) -> Vec<u8> {
98-
self.memory.into_data()
99-
}
100-
101101
/// Inspect the machine's next opcode and current stack.
102102
pub fn inspect(&self) -> Option<(Opcode, &Stack)> {
103103
self.code

interpreter/src/memory.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::{ExitException, ExitFatal};
22
use alloc::vec::Vec;
3-
use core::cmp::min;
43
use core::ops::{BitAnd, Not, Range};
4+
use core::{cmp::min, mem};
55
use primitive_types::U256;
66

77
/// A sequencial memory. It uses Rust's `Vec` for internal
@@ -48,9 +48,10 @@ impl Memory {
4848
&self.data
4949
}
5050

51-
/// Into the full data.
52-
pub fn into_data(self) -> Vec<u8> {
53-
self.data
51+
pub(crate) fn swap_and_clear(&mut self, other: &mut Vec<u8>) {
52+
mem::swap(&mut self.data, other);
53+
self.data = Vec::new();
54+
self.effective_len = U256::zero();
5455
}
5556

5657
/// Resize the memory, making it cover the memory region of `offset..(offset

interpreter/src/runtime.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -133,13 +133,13 @@ pub trait RuntimeBackend: RuntimeBaseBackend {
133133
}
134134

135135
/// Mark an address or (address, index) pair as hot.
136-
fn mark_hot(&mut self, address: H160, index: Option<H256>) -> Result<(), ExitError>;
136+
fn mark_hot(&mut self, address: H160, index: Option<H256>);
137137
/// Set storage value of address at index.
138138
fn set_storage(&mut self, address: H160, index: H256, value: H256) -> Result<(), ExitError>;
139139
/// Create a log owned by address with given topics and data.
140140
fn log(&mut self, log: Log) -> Result<(), ExitError>;
141-
/// Mark an address to be deleted, with funds transferred to target.
142-
fn mark_delete(&mut self, address: H160, target: H160) -> Result<(), ExitError>;
141+
/// Mark an address to be deleted.
142+
fn mark_delete(&mut self, address: H160);
143143
/// Fully delete storages of an account.
144144
fn reset_storage(&mut self, address: H160);
145145
/// Set code of an account.

interpreter/tests/performance.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ macro_rules! ret_test {
1515
vm.run(&mut (), &ETABLE),
1616
Capture::Exit(Ok(ExitSucceed::Returned.into()))
1717
);
18-
assert_eq!(vm.into_retbuf(), hex::decode($ret).unwrap());
18+
assert_eq!(vm.retval, hex::decode($ret).unwrap());
1919
}
2020
};
2121
}

interpreter/tests/usability.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ fn etable_wrap() {
2525
let mut vm = Machine::new(Rc::new(code), Rc::new(data), 1024, 10000, ());
2626
let result = vm.run(&mut (), &wrapped_etable);
2727
assert_eq!(result, Capture::Exit(Ok(ExitSucceed::Returned.into())));
28-
assert_eq!(vm.into_retbuf(), hex::decode(&RET1).unwrap());
28+
assert_eq!(vm.retval, hex::decode(&RET1).unwrap());
2929
}
3030

3131
#[test]
@@ -125,7 +125,7 @@ impl<'a> RuntimeBackend for UnimplementedHandler {
125125
unimplemented!()
126126
}
127127

128-
fn mark_hot(&mut self, _address: H160, _index: Option<H256>) -> Result<(), ExitError> {
128+
fn mark_hot(&mut self, _address: H160, _index: Option<H256>) {
129129
unimplemented!()
130130
}
131131

@@ -135,7 +135,7 @@ impl<'a> RuntimeBackend for UnimplementedHandler {
135135
fn log(&mut self, _log: Log) -> Result<(), ExitError> {
136136
unimplemented!()
137137
}
138-
fn mark_delete(&mut self, _address: H160, _target: H160) -> Result<(), ExitError> {
138+
fn mark_delete(&mut self, _address: H160) {
139139
unimplemented!()
140140
}
141141

@@ -194,5 +194,5 @@ fn etable_runtime() {
194194

195195
let res = vm.run(&mut handler, &RUNTIME_ETABLE).exit().unwrap();
196196
assert_eq!(res, Ok(ExitSucceed::Returned.into()));
197-
assert_eq!(vm.into_retbuf(), hex::decode(&RET1).unwrap());
197+
assert_eq!(vm.retval, hex::decode(&RET1).unwrap());
198198
}

jsontests/src/run.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ pub fn run_test(_filename: &str, _test_name: &str, test: Test, debug: bool) -> R
9494
&invoker,
9595
&etable,
9696
);
97+
run_backend.layers[0].clear_pending();
9798

9899
// Step
99100
if debug {
@@ -116,6 +117,7 @@ pub fn run_test(_filename: &str, _test_name: &str, test: Test, debug: bool) -> R
116117
break result;
117118
}
118119
});
120+
step_backend.layers[0].clear_pending();
119121
}
120122

121123
let state_root = crate::hash::state_root(&run_backend);

src/backend/in_memory.rs

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use crate::{
44
};
55
use alloc::collections::{BTreeMap, BTreeSet};
66
use primitive_types::{H160, H256, U256};
7+
use std::mem;
78

89
#[derive(Clone, Debug)]
910
pub struct InMemoryEnvironment {
@@ -30,7 +31,6 @@ pub struct InMemoryAccount {
3031
#[derive(Clone, Debug)]
3132
pub struct InMemorySuicideInfo {
3233
pub address: H160,
33-
pub target: H160,
3434
}
3535

3636
#[derive(Clone, Debug)]
@@ -41,6 +41,18 @@ pub struct InMemoryLayer {
4141
pub hots: BTreeSet<(H160, Option<H256>)>,
4242
}
4343

44+
impl InMemoryLayer {
45+
pub fn clear_pending(&mut self) {
46+
self.hots.clear();
47+
48+
let mut suicides = Vec::new();
49+
mem::swap(&mut suicides, &mut self.suicides);
50+
for suicide in suicides {
51+
self.state.remove(&suicide.address);
52+
}
53+
}
54+
}
55+
4456
#[derive(Clone, Debug)]
4557
pub struct InMemoryBackend {
4658
pub environment: InMemoryEnvironment,
@@ -168,9 +180,8 @@ impl RuntimeBackend for InMemoryBackend {
168180
!self.current_layer().hots.contains(&(address, index))
169181
}
170182

171-
fn mark_hot(&mut self, address: H160, index: Option<H256>) -> Result<(), ExitError> {
183+
fn mark_hot(&mut self, address: H160, index: Option<H256>) {
172184
self.current_layer_mut().hots.insert((address, index));
173-
Ok(())
174185
}
175186

176187
fn set_storage(&mut self, address: H160, index: H256, value: H256) -> Result<(), ExitError> {
@@ -189,11 +200,10 @@ impl RuntimeBackend for InMemoryBackend {
189200
Ok(())
190201
}
191202

192-
fn mark_delete(&mut self, address: H160, target: H160) -> Result<(), ExitError> {
203+
fn mark_delete(&mut self, address: H160) {
193204
self.current_layer_mut()
194205
.suicides
195-
.push(InMemorySuicideInfo { address, target });
196-
Ok(())
206+
.push(InMemorySuicideInfo { address });
197207
}
198208

199209
fn reset_storage(&mut self, address: H160) {

0 commit comments

Comments
 (0)