From c6d943f2da52393adb99fc018044fb5bb98cd9ed Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Mon, 3 Apr 2017 18:01:47 +0800 Subject: [PATCH 1/2] Problem: Opcode is C-like Solution: Make PUSH, DUP, SWAP, LOG Rust-like to simplify implementation --- src/vm/opcode/code.rs | 251 ++++++++++++++++------------------------- src/vm/opcode/run.rs | 23 +--- src/vm/opcode/usage.rs | 50 +++----- 3 files changed, 117 insertions(+), 207 deletions(-) diff --git a/src/vm/opcode/code.rs b/src/vm/opcode/code.rs index 03ebc692..98a6fbe8 100644 --- a/src/vm/opcode/code.rs +++ b/src/vm/opcode/code.rs @@ -16,18 +16,10 @@ pub enum Opcode { POP, MLOAD, MSTORE, MSTORE8, SLOAD, SSTORE, JUMP, JUMPI, PC, MSIZE, GAS, JUMPDEST, - PUSH1, PUSH2, PUSH3, PUSH4, PUSH5, PUSH6, PUSH7, PUSH8, PUSH9, - PUSH10, PUSH11, PUSH12, PUSH13, PUSH14, PUSH15, PUSH16, PUSH17, - PUSH18, PUSH19, PUSH20, PUSH21, PUSH22, PUSH23, PUSH24, PUSH25, - PUSH26, PUSH27, PUSH28, PUSH29, PUSH30, PUSH31, PUSH32, - - DUP1, DUP2, DUP3, DUP4, DUP5, DUP6, DUP7, DUP8, DUP9, DUP10, - DUP11, DUP12, DUP13, DUP14, DUP15, DUP16, - - SWAP1, SWAP2, SWAP3, SWAP4, SWAP5, SWAP6, SWAP7, SWAP8, SWAP9, - SWAP10, SWAP11, SWAP12, SWAP13, SWAP14, SWAP15, SWAP16, - - LOG0, LOG1, LOG2, LOG3, LOG4, + PUSH(usize), + DUP(usize), + SWAP(usize), + LOG(usize), CREATE, CALL, CALLCODE, RETURN, DELEGATECALL, @@ -98,78 +90,78 @@ impl From for Opcode { 0x5a => Opcode::GAS, 0x5b => Opcode::JUMPDEST, - 0x60 => Opcode::PUSH1, - 0x61 => Opcode::PUSH2, - 0x62 => Opcode::PUSH3, - 0x63 => Opcode::PUSH4, - 0x64 => Opcode::PUSH5, - 0x65 => Opcode::PUSH6, - 0x66 => Opcode::PUSH7, - 0x67 => Opcode::PUSH8, - 0x68 => Opcode::PUSH9, - 0x69 => Opcode::PUSH10, - 0x6a => Opcode::PUSH11, - 0x6b => Opcode::PUSH12, - 0x6c => Opcode::PUSH13, - 0x6d => Opcode::PUSH14, - 0x6e => Opcode::PUSH15, - 0x6f => Opcode::PUSH16, - 0x70 => Opcode::PUSH17, - 0x71 => Opcode::PUSH18, - 0x72 => Opcode::PUSH19, - 0x73 => Opcode::PUSH20, - 0x74 => Opcode::PUSH21, - 0x75 => Opcode::PUSH22, - 0x76 => Opcode::PUSH23, - 0x77 => Opcode::PUSH24, - 0x78 => Opcode::PUSH25, - 0x79 => Opcode::PUSH26, - 0x7a => Opcode::PUSH27, - 0x7b => Opcode::PUSH28, - 0x7c => Opcode::PUSH29, - 0x7d => Opcode::PUSH30, - 0x7e => Opcode::PUSH31, - 0x7f => Opcode::PUSH32, - - 0x80 => Opcode::DUP1, - 0x81 => Opcode::DUP2, - 0x82 => Opcode::DUP3, - 0x83 => Opcode::DUP4, - 0x84 => Opcode::DUP5, - 0x85 => Opcode::DUP6, - 0x86 => Opcode::DUP7, - 0x87 => Opcode::DUP8, - 0x88 => Opcode::DUP9, - 0x89 => Opcode::DUP10, - 0x8a => Opcode::DUP11, - 0x8b => Opcode::DUP12, - 0x8c => Opcode::DUP13, - 0x8d => Opcode::DUP14, - 0x8e => Opcode::DUP15, - 0x8f => Opcode::DUP16, - - 0x90 => Opcode::SWAP1, - 0x91 => Opcode::SWAP2, - 0x92 => Opcode::SWAP3, - 0x93 => Opcode::SWAP4, - 0x94 => Opcode::SWAP5, - 0x95 => Opcode::SWAP6, - 0x96 => Opcode::SWAP7, - 0x97 => Opcode::SWAP8, - 0x98 => Opcode::SWAP9, - 0x99 => Opcode::SWAP10, - 0x9a => Opcode::SWAP11, - 0x9b => Opcode::SWAP12, - 0x9c => Opcode::SWAP13, - 0x9d => Opcode::SWAP14, - 0x9e => Opcode::SWAP15, - 0x9f => Opcode::SWAP16, - - 0xa0 => Opcode::LOG0, - 0xa1 => Opcode::LOG1, - 0xa2 => Opcode::LOG2, - 0xa3 => Opcode::LOG3, - 0xa4 => Opcode::LOG4, + 0x60 => Opcode::PUSH(1), + 0x61 => Opcode::PUSH(2), + 0x62 => Opcode::PUSH(3), + 0x63 => Opcode::PUSH(4), + 0x64 => Opcode::PUSH(5), + 0x65 => Opcode::PUSH(6), + 0x66 => Opcode::PUSH(7), + 0x67 => Opcode::PUSH(8), + 0x68 => Opcode::PUSH(9), + 0x69 => Opcode::PUSH(10), + 0x6a => Opcode::PUSH(11), + 0x6b => Opcode::PUSH(12), + 0x6c => Opcode::PUSH(13), + 0x6d => Opcode::PUSH(14), + 0x6e => Opcode::PUSH(15), + 0x6f => Opcode::PUSH(16), + 0x70 => Opcode::PUSH(17), + 0x71 => Opcode::PUSH(18), + 0x72 => Opcode::PUSH(19), + 0x73 => Opcode::PUSH(20), + 0x74 => Opcode::PUSH(21), + 0x75 => Opcode::PUSH(22), + 0x76 => Opcode::PUSH(23), + 0x77 => Opcode::PUSH(24), + 0x78 => Opcode::PUSH(25), + 0x79 => Opcode::PUSH(26), + 0x7a => Opcode::PUSH(27), + 0x7b => Opcode::PUSH(28), + 0x7c => Opcode::PUSH(29), + 0x7d => Opcode::PUSH(30), + 0x7e => Opcode::PUSH(31), + 0x7f => Opcode::PUSH(32), + + 0x80 => Opcode::DUP(1), + 0x81 => Opcode::DUP(2), + 0x82 => Opcode::DUP(3), + 0x83 => Opcode::DUP(4), + 0x84 => Opcode::DUP(5), + 0x85 => Opcode::DUP(6), + 0x86 => Opcode::DUP(7), + 0x87 => Opcode::DUP(8), + 0x88 => Opcode::DUP(9), + 0x89 => Opcode::DUP(10), + 0x8a => Opcode::DUP(11), + 0x8b => Opcode::DUP(12), + 0x8c => Opcode::DUP(13), + 0x8d => Opcode::DUP(14), + 0x8e => Opcode::DUP(15), + 0x8f => Opcode::DUP(16), + + 0x90 => Opcode::SWAP(1), + 0x91 => Opcode::SWAP(2), + 0x92 => Opcode::SWAP(3), + 0x93 => Opcode::SWAP(4), + 0x94 => Opcode::SWAP(5), + 0x95 => Opcode::SWAP(6), + 0x96 => Opcode::SWAP(7), + 0x97 => Opcode::SWAP(8), + 0x98 => Opcode::SWAP(9), + 0x99 => Opcode::SWAP(10), + 0x9a => Opcode::SWAP(11), + 0x9b => Opcode::SWAP(12), + 0x9c => Opcode::SWAP(13), + 0x9d => Opcode::SWAP(14), + 0x9e => Opcode::SWAP(15), + 0x9f => Opcode::SWAP(16), + + 0xa0 => Opcode::LOG(0), + 0xa1 => Opcode::LOG(1), + 0xa2 => Opcode::LOG(2), + 0xa3 => Opcode::LOG(3), + 0xa4 => Opcode::LOG(4), 0xf0 => Opcode::CREATE, 0xf1 => Opcode::CALL, @@ -247,78 +239,25 @@ impl Into for Opcode { Opcode::GAS => 0x5a, Opcode::JUMPDEST => 0x5b, - Opcode::PUSH1 => 0x60, - Opcode::PUSH2 => 0x61, - Opcode::PUSH3 => 0x62, - Opcode::PUSH4 => 0x63, - Opcode::PUSH5 => 0x64, - Opcode::PUSH6 => 0x65, - Opcode::PUSH7 => 0x66, - Opcode::PUSH8 => 0x67, - Opcode::PUSH9 => 0x68, - Opcode::PUSH10 => 0x69, - Opcode::PUSH11 => 0x6a, - Opcode::PUSH12 => 0x6b, - Opcode::PUSH13 => 0x6c, - Opcode::PUSH14 => 0x6d, - Opcode::PUSH15 => 0x6e, - Opcode::PUSH16 => 0x6f, - Opcode::PUSH17 => 0x70, - Opcode::PUSH18 => 0x71, - Opcode::PUSH19 => 0x72, - Opcode::PUSH20 => 0x73, - Opcode::PUSH21 => 0x74, - Opcode::PUSH22 => 0x75, - Opcode::PUSH23 => 0x76, - Opcode::PUSH24 => 0x77, - Opcode::PUSH25 => 0x78, - Opcode::PUSH26 => 0x79, - Opcode::PUSH27 => 0x7a, - Opcode::PUSH28 => 0x7b, - Opcode::PUSH29 => 0x7c, - Opcode::PUSH30 => 0x7d, - Opcode::PUSH31 => 0x7e, - Opcode::PUSH32 => 0x7f, - - Opcode::DUP1 => 0x80, - Opcode::DUP2 => 0x81, - Opcode::DUP3 => 0x82, - Opcode::DUP4 => 0x83, - Opcode::DUP5 => 0x84, - Opcode::DUP6 => 0x85, - Opcode::DUP7 => 0x86, - Opcode::DUP8 => 0x87, - Opcode::DUP9 => 0x88, - Opcode::DUP10 => 0x89, - Opcode::DUP11 => 0x8a, - Opcode::DUP12 => 0x8b, - Opcode::DUP13 => 0x8c, - Opcode::DUP14 => 0x8d, - Opcode::DUP15 => 0x8e, - Opcode::DUP16 => 0x8f, - - Opcode::SWAP1 => 0x90, - Opcode::SWAP2 => 0x91, - Opcode::SWAP3 => 0x92, - Opcode::SWAP4 => 0x93, - Opcode::SWAP5 => 0x94, - Opcode::SWAP6 => 0x95, - Opcode::SWAP7 => 0x96, - Opcode::SWAP8 => 0x97, - Opcode::SWAP9 => 0x98, - Opcode::SWAP10 => 0x99, - Opcode::SWAP11 => 0x9a, - Opcode::SWAP12 => 0x9b, - Opcode::SWAP13 => 0x9c, - Opcode::SWAP14 => 0x9d, - Opcode::SWAP15 => 0x9e, - Opcode::SWAP16 => 0x9f, - - Opcode::LOG0 => 0xa0, - Opcode::LOG1 => 0xa1, - Opcode::LOG2 => 0xa2, - Opcode::LOG3 => 0xa3, - Opcode::LOG4 => 0xa4, + Opcode::PUSH(v) => { + assert!(v >= 1 && v <= 32); + 0x5f + (v as u8) + }, + + Opcode::DUP(v) => { + assert!(v >= 1 && v <= 16); + 0x7f + (v as u8) + }, + + Opcode::SWAP(v) => { + assert!(v >= 1 && v <= 16); + 0x8f + (v as u8) + }, + + Opcode::LOG(v) => { + assert!(v >= 0 && v <= 4); + 0xa0 + (v as u8) + }, Opcode::CREATE => 0xf0, Opcode::CALL => 0xf1, diff --git a/src/vm/opcode/run.rs b/src/vm/opcode/run.rs index 8bef0742..6f1de403 100644 --- a/src/vm/opcode/run.rs +++ b/src/vm/opcode/run.rs @@ -3,13 +3,6 @@ use vm::{Machine, Memory, Stack, PC}; // TODO: deal with gas limit and other Ethereum-specific things. -fn push(opcode: Opcode, pc: &mut PC, stack: &mut S) { - let code_u8: u8 = opcode.into(); - let count = code_u8 - 0x5f; - let val = pc.read(count as usize); - stack.push(val); -} - impl Opcode { pub fn run(&self, machine: &mut Machine) { let pc = &mut machine.pc; @@ -52,18 +45,10 @@ impl Opcode { // TODO: implement omitted opcodes. - Opcode::PUSH1 | Opcode::PUSH2 | Opcode::PUSH3 | - Opcode::PUSH4 | Opcode::PUSH5 | Opcode::PUSH6 | - Opcode::PUSH7 | Opcode::PUSH8 | Opcode::PUSH9 | - Opcode::PUSH10 | Opcode::PUSH11 | Opcode::PUSH12 | - Opcode::PUSH13 | Opcode::PUSH14 | Opcode::PUSH15 | - Opcode::PUSH16 | Opcode::PUSH17 | Opcode::PUSH18 | - Opcode::PUSH19 | Opcode::PUSH20 | Opcode::PUSH21 | - Opcode::PUSH22 | Opcode::PUSH23 | Opcode::PUSH24 | - Opcode::PUSH25 | Opcode::PUSH26 | Opcode::PUSH27 | - Opcode::PUSH28 | Opcode::PUSH29 | Opcode::PUSH30 | - Opcode::PUSH31 | Opcode::PUSH32 - => push(opcode, pc, stack), + Opcode::PUSH(v) => { + let val = pc.read(v); + stack.push(val); + }, _ => { unimplemented!(); diff --git a/src/vm/opcode/usage.rs b/src/vm/opcode/usage.rs index f79ce25b..459c0fb8 100644 --- a/src/vm/opcode/usage.rs +++ b/src/vm/opcode/usage.rs @@ -53,59 +53,45 @@ impl Opcode { let self_cost: Gas = match opcode { // Unimplemented Opcode::SSTORE | Opcode::EXP | Opcode::CALLDATACOPY | - Opcode::CODECOPY | Opcode::EXTCODECOPY | Opcode::LOG0 | - Opcode::LOG1 | Opcode::LOG2 | Opcode::LOG3 | Opcode::LOG4 | + Opcode::CODECOPY | Opcode::EXTCODECOPY | Opcode::LOG(_) | Opcode::CALL | Opcode::CALLCODE | Opcode::DELEGATECALL | - Opcode::SELFDESTRUCT | Opcode::SHA3 | - Opcode::EXTCODESIZE => unimplemented!(), + Opcode::SELFDESTRUCT | Opcode::SHA3 | Opcode::EXTCODESIZE + => unimplemented!(), Opcode::CREATE => G_CREATE.into(), Opcode::JUMPDEST => G_JUMPDEST.into(), Opcode::SLOAD => G_SLOAD.into(), // W_zero - Opcode::STOP | Opcode::RETURN => G_ZERO.into(), + Opcode::STOP | Opcode::RETURN + => G_ZERO.into(), // W_base Opcode::ADDRESS | Opcode::ORIGIN | Opcode::CALLER | - Opcode::CALLVALUE | Opcode::CALLDATASIZE | Opcode::CODESIZE | - Opcode::GASPRICE | Opcode::COINBASE | Opcode::TIMESTAMP | - Opcode::NUMBER | Opcode::DIFFICULTY | Opcode::GASLIMIT | - Opcode::POP | Opcode::PC | Opcode::MSIZE | - Opcode::GAS => G_BASE.into(), + Opcode::CALLVALUE | Opcode::CALLDATASIZE | + Opcode::CODESIZE | Opcode::GASPRICE | Opcode::COINBASE | + Opcode::TIMESTAMP | Opcode::NUMBER | Opcode::DIFFICULTY | + Opcode::GASLIMIT | Opcode::POP | Opcode::PC | + Opcode::MSIZE | Opcode::GAS + => G_BASE.into(), // W_verylow Opcode::ADD | Opcode::SUB | Opcode::NOT | Opcode::LT | Opcode::GT | Opcode::SLT | Opcode::SGT | Opcode::EQ | Opcode::ISZERO | Opcode::AND | Opcode::OR | Opcode::XOR | Opcode::BYTE | Opcode::CALLDATALOAD | Opcode::MLOAD | - Opcode::MSTORE | Opcode::MSTORE8 | Opcode::PUSH1 | - Opcode::PUSH2 | Opcode::PUSH3 | Opcode::PUSH4 | Opcode::PUSH5 | - Opcode::PUSH6 | Opcode::PUSH7 | Opcode::PUSH8 | - Opcode::PUSH9 | Opcode::PUSH10 | Opcode::PUSH11 | - Opcode::PUSH12 | Opcode::PUSH13 | Opcode::PUSH14 | - Opcode::PUSH15 | Opcode::PUSH16 | Opcode::PUSH17 | - Opcode::PUSH18 | Opcode::PUSH19 | Opcode::PUSH20 | - Opcode::PUSH21 | Opcode::PUSH22 | Opcode::PUSH23 | - Opcode::PUSH24 | Opcode::PUSH25 | Opcode::PUSH26 | - Opcode::PUSH27 | Opcode::PUSH28 | Opcode::PUSH29 | - Opcode::PUSH30 | Opcode::PUSH31 | Opcode::PUSH32 | - Opcode::DUP1 | Opcode::DUP2 | Opcode::DUP3 | Opcode::DUP4 | - Opcode::DUP5 | Opcode::DUP6 | Opcode::DUP7 | Opcode::DUP8 | - Opcode::DUP9 | Opcode::DUP10 | Opcode::DUP11 | Opcode::DUP12 | - Opcode::DUP13 | Opcode::DUP14 | Opcode::DUP15 | Opcode::DUP16 | - Opcode::SWAP1 | Opcode::SWAP2 | Opcode::SWAP3 | - Opcode::SWAP4 | Opcode::SWAP5 | Opcode::SWAP6 | Opcode::SWAP7 | - Opcode::SWAP8 | Opcode::SWAP9 | Opcode::SWAP10 | - Opcode::SWAP11 | Opcode::SWAP12 | Opcode::SWAP13 | - Opcode::SWAP14 | Opcode::SWAP15 | Opcode::SWAP16 => G_VERYLOW.into(), + Opcode::MSTORE | Opcode::MSTORE8 | Opcode::PUSH(_) | + Opcode::DUP(_) | Opcode::SWAP(_) + => G_VERYLOW.into(), // W_low Opcode::MUL | Opcode::DIV | Opcode::SDIV | Opcode::MOD | - Opcode::SMOD | Opcode::SIGNEXTEND => G_LOW.into(), + Opcode::SMOD | Opcode::SIGNEXTEND + => G_LOW.into(), // W_mid - Opcode::ADDMOD | Opcode::MULMOD | Opcode::JUMP => G_MID.into(), + Opcode::ADDMOD | Opcode::MULMOD | Opcode::JUMP + => G_MID.into(), // W_high Opcode::JUMPI => G_HIGH.into(), From 8814ca7777ac36c3accf1ba5d8ae5aff5f4d49b5 Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Mon, 3 Apr 2017 18:09:51 +0800 Subject: [PATCH 2/2] Problem: Issue #1 Solution: (suggestion 1) Using git dependency --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 4ca23370..7db59ba9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,4 +17,4 @@ path = "./src/bin/cli.rs" [dependencies] clap = "2.22" log = "0.3" -u256 = "0.1" \ No newline at end of file +u256 = { git = "https://github.com/sorpaas/u256" } \ No newline at end of file