From 7bf5118f69b1f36392c8e8865b44892a42af1fc0 Mon Sep 17 00:00:00 2001 From: wborgeaud Date: Thu, 7 Jul 2022 18:46:20 +0200 Subject: [PATCH] Test exp kernel function --- evm/src/cpu/kernel/aggregator.rs | 36 +++++++++++++++++++++++++++++++ evm/src/cpu/kernel/asm/exp.asm | 3 +++ evm/src/cpu/kernel/interpreter.rs | 8 +++---- 3 files changed, 43 insertions(+), 4 deletions(-) diff --git a/evm/src/cpu/kernel/aggregator.rs b/evm/src/cpu/kernel/aggregator.rs index d58208fd..a23e18b8 100644 --- a/evm/src/cpu/kernel/aggregator.rs +++ b/evm/src/cpu/kernel/aggregator.rs @@ -27,6 +27,7 @@ mod tests { use anyhow::Result; use ethereum_types::U256; + use rand::{thread_rng, Rng}; use crate::cpu::kernel::aggregator::combined_kernel; use crate::cpu::kernel::interpreter::run; @@ -43,6 +44,41 @@ mod tests { .map(U256::from_str) .collect::, _>>()?) } + #[test] + fn test_exp() -> Result<()> { + // Make sure we can parse and assemble the entire kernel. + let kernel = combined_kernel(); + let exp = kernel.global_labels["exp"]; + let mut rng = thread_rng(); + let a = U256([0; 4].map(|_| rng.gen())); + let b = U256([0; 4].map(|_| rng.gen())); + + // Random input + let initial_stack = vec![U256::from_str("0xdeadbeef")?, b, a]; + let stack_with_kernel = run(&kernel.code, exp, initial_stack); + let initial_stack = vec![b, a]; + let code = [0xa, 0x63, 0xde, 0xad, 0xbe, 0xef, 0x56]; // EXP, PUSH4 deadbeef, JUMP + let stack_with_opcode = run(&code, 0, initial_stack); + assert_eq!(stack_with_kernel, stack_with_opcode); + + // 0 base + let initial_stack = vec![U256::from_str("0xdeadbeef")?, b, U256::zero()]; + let stack_with_kernel = run(&kernel.code, exp, initial_stack); + let initial_stack = vec![b, U256::zero()]; + let code = [0xa, 0x63, 0xde, 0xad, 0xbe, 0xef, 0x56]; // EXP, PUSH4 deadbeef, JUMP + let stack_with_opcode = run(&code, 0, initial_stack); + assert_eq!(stack_with_kernel, stack_with_opcode); + + // 0 exponent + let initial_stack = vec![U256::from_str("0xdeadbeef")?, U256::zero(), a]; + let stack_with_kernel = run(&kernel.code, exp, initial_stack); + let initial_stack = vec![U256::zero(), a]; + let code = [0xa, 0x63, 0xde, 0xad, 0xbe, 0xef, 0x56]; // EXP, PUSH4 deadbeef, JUMP + let stack_with_opcode = run(&code, 0, initial_stack); + assert_eq!(stack_with_kernel, stack_with_opcode); + + Ok(()) + } #[test] fn test_ec_ops() -> Result<()> { diff --git a/evm/src/cpu/kernel/asm/exp.asm b/evm/src/cpu/kernel/asm/exp.asm index 3e3b0f6f..683e67c3 100644 --- a/evm/src/cpu/kernel/asm/exp.asm +++ b/evm/src/cpu/kernel/asm/exp.asm @@ -10,6 +10,7 @@ /// Note that this correctly handles exp(0, 0) == 1. global exp: + jumpdest // stack: x, e, retdest dup2 // stack: e, x, e, retdest @@ -28,6 +29,7 @@ global exp: jump step_case: + jumpdest // stack: x, e, retdest push recursion_return // stack: recursion_return, x, e, retdest @@ -45,6 +47,7 @@ step_case: // stack: exp, x * x, e / 2, recursion_return, x, e, retdest jump recursion_return: + jumpdest // stack: exp(x * x, e / 2), x, e, retdest push 2 // stack: 2, exp(x * x, e / 2), x, e, retdest diff --git a/evm/src/cpu/kernel/interpreter.rs b/evm/src/cpu/kernel/interpreter.rs index a099a48b..97fb5209 100644 --- a/evm/src/cpu/kernel/interpreter.rs +++ b/evm/src/cpu/kernel/interpreter.rs @@ -127,21 +127,21 @@ impl<'a> Interpreter<'a> { fn run_add(&mut self) { let x = self.pop(); let y = self.pop(); - self.push(x + y); + self.push(x.overflowing_add(y).0); self.incr(1); } fn run_mul(&mut self) { let x = self.pop(); let y = self.pop(); - self.push(x * y); + self.push(x.overflowing_mul(y).0); self.incr(1); } fn run_sub(&mut self) { let x = self.pop(); let y = self.pop(); - self.push(x - y); + self.push(x.overflowing_sub(y).0); self.incr(1); } @@ -180,7 +180,7 @@ impl<'a> Interpreter<'a> { fn run_exp(&mut self) { let x = self.pop(); let y = self.pop(); - self.push(x.pow(y)); + self.push(x.overflowing_pow(y).0); self.incr(1); }