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

Commit 58fde98

Browse files
authored
Update Simple Subroutines to the latest spec (#11731)
1 parent f8cbdad commit 58fde98

File tree

11 files changed

+56
-24
lines changed

11 files changed

+56
-24
lines changed

.gitmodules

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[submodule "ethcore/res/ethereum/tests"]
22
path = ethcore/res/ethereum/tests
33
url = https://github.com/ethereum/tests.git
4-
branch = v7.0.0
4+
branch = develop
55
[submodule "ethcore/res/wasm-tests"]
66
path = ethcore/res/wasm-tests
77
url = https://github.com/openethereum/wasm-tests

ethcore/evm/src/instructions.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -321,11 +321,11 @@ enum_with_from_u8! {
321321
LOG4 = 0xa4,
322322

323323
#[doc = "Marks the entry point to a subroutine."]
324-
BEGINSUB = 0xb2,
325-
#[doc = "Jumps to a defined BEGINSUB subroutine."]
326-
JUMPSUB = 0xb3,
324+
BEGINSUB = 0x5c,
327325
#[doc = "Returns from a subroutine."]
328-
RETURNSUB = 0xb7,
326+
RETURNSUB = 0x5d,
327+
#[doc = "Jumps to a defined BEGINSUB subroutine."]
328+
JUMPSUB = 0x5e,
329329

330330
#[doc = "create a new account with associated code"]
331331
CREATE = 0xf0,
@@ -593,8 +593,8 @@ lazy_static! {
593593
arr[LOG3 as usize] = Some(InstructionInfo::new("LOG3", 5, 0, GasPriceTier::Special));
594594
arr[LOG4 as usize] = Some(InstructionInfo::new("LOG4", 6, 0, GasPriceTier::Special));
595595
arr[BEGINSUB as usize] = Some(InstructionInfo::new("BEGINSUB", 0, 0, GasPriceTier::Base));
596-
arr[JUMPSUB as usize] = Some(InstructionInfo::new("JUMPSUB", 1, 0, GasPriceTier::Low));
597-
arr[RETURNSUB as usize] = Some(InstructionInfo::new("RETURNSUB", 0, 0, GasPriceTier::VeryLow));
596+
arr[JUMPSUB as usize] = Some(InstructionInfo::new("JUMPSUB", 1, 0, GasPriceTier::High));
597+
arr[RETURNSUB as usize] = Some(InstructionInfo::new("RETURNSUB", 0, 0, GasPriceTier::Low));
598598
arr[CREATE as usize] = Some(InstructionInfo::new("CREATE", 3, 1, GasPriceTier::Special));
599599
arr[CALL as usize] = Some(InstructionInfo::new("CALL", 7, 1, GasPriceTier::Special));
600600
arr[CALLCODE as usize] = Some(InstructionInfo::new("CALLCODE", 7, 1, GasPriceTier::Special));

ethcore/evm/src/interpreter/mod.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ const TWO_POW_248: U256 = U256([0, 0, 0, 0x100000000000000]); //0x1 00000000 000
6464

6565
/// Maximal subroutine stack size as specified in
6666
/// https://eips.ethereum.org/EIPS/eip-2315.
67-
pub const MAX_SUB_STACK_SIZE : usize = 1024;
67+
pub const MAX_SUB_STACK_SIZE : usize = 1023;
6868

6969
/// Abstraction over raw vector of Bytes. Easier state management of PC.
7070
struct CodeReader {
@@ -432,7 +432,7 @@ impl<Cost: CostType> Interpreter<Cost> {
432432
Err(e) => return InterpreterResult::Done(Err(e))
433433
};
434434
self.return_stack.push(self.reader.position);
435-
self.reader.position = pos;
435+
self.reader.position = pos + 1;
436436
},
437437
InstructionResult::ReturnFromSubroutine(pos) => {
438438
self.reader.position = pos;
@@ -553,7 +553,7 @@ impl<Cost: CostType> Interpreter<Cost> {
553553
// ignore
554554
},
555555
instructions::BEGINSUB => {
556-
// ignore
556+
return Err(vm::Error::InvalidSubEntry);
557557
},
558558
instructions::JUMPSUB => {
559559
if self.return_stack.len() >= MAX_SUB_STACK_SIZE {

ethcore/evm/src/interpreter/shared_cache.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ fn test_find_sub_entrypoints() {
160160
// given
161161

162162
// see https://eips.ethereum.org/EIPS/eip-2315 for disassembly
163-
let code = hex!("6800000000000000000cb300b26011b3b7b2b7");
163+
let code = hex!("6800000000000000000c5e005c60115e5d5c5d");
164164

165165
// when
166166
let cache_item = SharedCache::find_jump_and_sub_destinations(&code);
@@ -180,7 +180,7 @@ fn test_find_jump_and_sub_allowing_unknown_opcodes() {
180180
// 0000 5B JUMPDEST
181181
// 0001 CC ???
182182
// 0002 B2 BEGINSUB
183-
let code = hex!("5BCCB2");
183+
let code = hex!("5BCC5C");
184184

185185
// when
186186
let cache_item = SharedCache::find_jump_and_sub_destinations(&code);

ethcore/evm/src/tests.rs

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -790,10 +790,10 @@ fn test_jumps(factory: super::Factory) {
790790
evm_test!{test_subs_simple: test_subs_simple_int}
791791
fn test_subs_simple(factory: super::Factory) {
792792
// as defined in https://eips.ethereum.org/EIPS/eip-2315
793-
let code = hex!("6004b300b2b7").to_vec();
793+
let code = hex!("60045e005c5d").to_vec();
794794

795795
let mut params = ActionParams::default();
796-
params.gas = U256::from(13);
796+
params.gas = U256::from(18);
797797
params.code = Some(Arc::new(code));
798798
let mut ext = FakeExt::new_berlin();
799799

@@ -808,10 +808,10 @@ fn test_subs_simple(factory: super::Factory) {
808808
evm_test!{test_subs_two_levels: test_subs_two_levels_int}
809809
fn test_subs_two_levels(factory: super::Factory) {
810810
// as defined in https://eips.ethereum.org/EIPS/eip-2315
811-
let code = hex!("6800000000000000000cb300b26011b3b7b2b7").to_vec();
811+
let code = hex!("6800000000000000000c5e005c60115e5d5c5d").to_vec();
812812

813813
let mut params = ActionParams::default();
814-
params.gas = U256::from(26);
814+
params.gas = U256::from(36);
815815
params.code = Some(Arc::new(code));
816816
let mut ext = FakeExt::new_berlin();
817817

@@ -826,7 +826,7 @@ fn test_subs_two_levels(factory: super::Factory) {
826826
evm_test!{test_subs_invalid_jump: test_subs_invalid_jump_int}
827827
fn test_subs_invalid_jump(factory: super::Factory) {
828828
// as defined in https://eips.ethereum.org/EIPS/eip-2315
829-
let code = hex!("6801000000000000000cb300b26011b3b7b2b7").to_vec();
829+
let code = hex!("6801000000000000000c5e005c60115e5d5c5d").to_vec();
830830

831831
let mut params = ActionParams::default();
832832
params.gas = U256::from(24);
@@ -845,7 +845,7 @@ fn test_subs_invalid_jump(factory: super::Factory) {
845845
evm_test!{test_subs_shallow_return_stack: test_subs_shallow_return_stack_int}
846846
fn test_subs_shallow_return_stack(factory: super::Factory) {
847847
// as defined in https://eips.ethereum.org/EIPS/eip-2315
848-
let code = hex!("b75858").to_vec();
848+
let code = hex!("5d5858").to_vec();
849849

850850
let mut params = ActionParams::default();
851851
params.gas = U256::from(24);
@@ -865,7 +865,9 @@ evm_test!{test_subs_substack_limit: test_subs_substack_limit_int}
865865
fn test_subs_substack_limit(factory: super::Factory) {
866866

867867
// PUSH <recursion_limit>
868+
// JUMP :a
868869
// :s BEGINSUB
870+
// :a JUMPDEST
869871
// DUP1
870872
// JUMPI :c
871873
// STOP
@@ -875,7 +877,7 @@ fn test_subs_substack_limit(factory: super::Factory) {
875877
// SUB
876878
// JUMPSUB :s
877879

878-
let mut code = hex!("610400b280600957005b600190036003b3").to_vec();
880+
let mut code = hex!("6104006007565c5b80600d57005b6001900360065e").to_vec();
879881
code[1..3].copy_from_slice(&(MAX_SUB_STACK_SIZE as u16).to_be_bytes()[..]);
880882

881883
let mut params = ActionParams::default();
@@ -888,12 +890,12 @@ fn test_subs_substack_limit(factory: super::Factory) {
888890
test_finalize(vm.exec(&mut ext).ok().unwrap()).unwrap()
889891
};
890892

891-
assert_eq!(gas_left, U256::from(963_115));
893+
assert_eq!(gas_left, U256::from(959_049));
892894
}
893895

894896
evm_test!{test_subs_substack_out: test_subs_substack_out_int}
895897
fn test_subs_substack_out(factory: super::Factory) {
896-
let mut code = hex!("610400b280600957005b600190036003b3").to_vec();
898+
let mut code = hex!("6104006007565c5b80600d57005b6001900360065e").to_vec();
897899
code[1..3].copy_from_slice(&((MAX_SUB_STACK_SIZE+1) as u16).to_be_bytes()[..]);
898900

899901
let mut params = ActionParams::default();
@@ -912,10 +914,10 @@ fn test_subs_substack_out(factory: super::Factory) {
912914

913915
evm_test!{test_subs_sub_at_end: test_subs_sub_at_end_int}
914916
fn test_subs_sub_at_end(factory: super::Factory) {
915-
let code = hex!("600556b2b75b6003b3").to_vec();
917+
let code = hex!("6005565c5d5b60035e").to_vec();
916918

917919
let mut params = ActionParams::default();
918-
params.gas = U256::from(25);
920+
params.gas = U256::from(30);
919921
params.code = Some(Arc::new(code));
920922
let mut ext = FakeExt::new_berlin();
921923

@@ -927,6 +929,24 @@ fn test_subs_sub_at_end(factory: super::Factory) {
927929
assert_eq!(gas_left, U256::from(0));
928930
}
929931

932+
evm_test!{test_subs_walk_into_subroutine: test_subs_walk_into_subroutine_int}
933+
fn test_subs_walk_into_subroutine(factory: super::Factory) {
934+
let code = hex!("5c5d00").to_vec();
935+
936+
let mut params = ActionParams::default();
937+
params.gas = U256::from(100);
938+
params.code = Some(Arc::new(code));
939+
let mut ext = FakeExt::new_berlin();
940+
941+
let current = {
942+
let vm = factory.create(params, ext.schedule(), ext.depth());
943+
test_finalize(vm.exec(&mut ext).ok().unwrap())
944+
};
945+
946+
let expected = Result::Err(vm::Error::InvalidSubEntry);
947+
assert_eq!(current, expected);
948+
}
949+
930950
evm_test!{test_calls: test_calls_int}
931951
fn test_calls(factory: super::Factory) {
932952
let code = hex!("600054602d57600160005560006000600060006050610998610100f160006000600060006050610998610100f25b").to_vec();

ethcore/machine/src/executive.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,7 @@ impl<'a> CallCreateExecutive<'a> {
359359
| Err(vm::Error::Reverted)
360360
| Err(vm::Error::SubStackUnderflow {..})
361361
| Err(vm::Error::OutOfSubStack {..})
362+
| Err(vm::Error::InvalidSubEntry)
362363
| Ok(FinalizationResult { apply_state: false, .. }) => {
363364
if let Some(addr) = UNPRUNABLE_PRECOMPILE_ADDRESS {
364365
if un_substate.touched.contains(&addr) {

ethcore/res/ethereum/tests

Submodule tests updated 6088 files

ethcore/src/json_tests/chain.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,7 @@ mod block_tests {
304304
declare_test!{BlockchainTests_GeneralStateTest_stSStoreTest, "BlockchainTests/GeneralStateTests/stSStoreTest/"}
305305
declare_test!{BlockchainTests_GeneralStateTest_stStackTests, "BlockchainTests/GeneralStateTests/stStackTests/"}
306306
declare_test!{BlockchainTests_GeneralStateTest_stStaticCall, "BlockchainTests/GeneralStateTests/stStaticCall/"}
307+
declare_test!{BlockchainTests_GeneralStateTest_stSubroutine, "BlockchainTests/GeneralStateTests/stSubroutine/"}
307308
declare_test!{BlockchainTests_GeneralStateTest_stSystemOperationsTest, "BlockchainTests/GeneralStateTests/stSystemOperationsTest/"}
308309
declare_test!{BlockchainTests_GeneralStateTest_stTimeConsuming, "BlockchainTests/GeneralStateTests/stTimeConsuming/"}
309310
declare_test!{BlockchainTests_GeneralStateTest_stTransactionTest, "BlockchainTests/GeneralStateTests/stTransactionTest/"}

ethcore/src/json_tests/state.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,7 @@ mod state_tests {
175175
declare_test!{GeneralStateTest_stSStoreTest, "GeneralStateTests/stSStoreTest/"}
176176
declare_test!{GeneralStateTest_stStackTests, "GeneralStateTests/stStackTests/"}
177177
declare_test!{GeneralStateTest_stStaticCall, "GeneralStateTests/stStaticCall/"}
178+
declare_test!{GeneralStateTest_stSubroutine, "GeneralStateTests/stSubroutine/"}
178179
declare_test!{GeneralStateTest_stSystemOperationsTest, "GeneralStateTests/stSystemOperationsTest/"}
179180
declare_test!{GeneralStateTest_stTimeConsuming, "GeneralStateTests/stTimeConsuming/"}
180181
declare_test!{GeneralStateTest_stTransactionTest, "GeneralStateTests/stTransactionTest/"}

ethcore/trace/src/types/error.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ pub enum Error {
3838
SubStackUnderflow,
3939
/// When execution would exceed defined subroutine Stack Limit
4040
OutOfSubStack,
41+
/// When the code walks into a subroutine, that is not allowed
42+
InvalidSubEntry,
4143
/// When builtin contract failed on input data
4244
BuiltIn,
4345
/// Returned on evm internal error. Should never be ignored during development.
@@ -61,6 +63,7 @@ impl<'a> From<&'a VmError> for Error {
6163
VmError::BadInstruction { .. } => Error::BadInstruction,
6264
VmError::StackUnderflow { .. } => Error::StackUnderflow,
6365
VmError::OutOfStack { .. } => Error::OutOfStack,
66+
VmError::InvalidSubEntry { .. } => Error::InvalidSubEntry,
6467
VmError::BuiltIn { .. } => Error::BuiltIn,
6568
VmError::Wasm { .. } => Error::Wasm,
6669
VmError::Internal(_) => Error::Internal,
@@ -88,6 +91,7 @@ impl fmt::Display for Error {
8891
BadInstruction => "Bad instruction",
8992
StackUnderflow => "Stack underflow",
9093
OutOfStack => "Out of stack",
94+
InvalidSubEntry => "Invalid subroutine entry",
9195
BuiltIn => "Built-in failed",
9296
Wasm => "Wasm runtime error",
9397
Internal => "Internal error",
@@ -118,6 +122,7 @@ impl Encodable for Error {
118122
Reverted => 10,
119123
SubStackUnderflow => 11,
120124
OutOfSubStack => 12,
125+
InvalidSubEntry => 13,
121126
};
122127

123128
s.append_internal(&value);
@@ -142,6 +147,7 @@ impl Decodable for Error {
142147
10 => Ok(Reverted),
143148
11 => Ok(SubStackUnderflow),
144149
12 => Ok(OutOfSubStack),
150+
13 => Ok(InvalidSubEntry),
145151
_ => Err(DecoderError::Custom("Invalid error type")),
146152
}
147153
}

0 commit comments

Comments
 (0)