Skip to content

Commit

Permalink
add unit tests for stackOnlyOp opcode (privacy-scaling-explorations#939)
Browse files Browse the repository at this point in the history
* add unit tests for stackOnlyOp opcode(privacy-scaling-explorations#939)

* Add rest needed stack-only opcode unit tests

* Add some mock var

Co-authored-by: Carlos Pérez <[email protected]>
Co-authored-by: aguzmant103 <[email protected]>
  • Loading branch information
3 people authored Dec 21, 2022
1 parent 0b8f7de commit 82e6c87
Show file tree
Hide file tree
Showing 3 changed files with 260 additions and 26 deletions.
272 changes: 250 additions & 22 deletions bus-mapping/src/evm/opcodes/stackonlyop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,9 @@ mod stackonlyop_tests {
};
use itertools::Itertools;
use mock::test_ctx::{helpers::*, TestContext};
use mock::{MOCK_BASEFEE, MOCK_DIFFICULTY, MOCK_GASLIMIT};
use pretty_assertions::assert_eq;
use std::ops::{BitOr, BitXor};

fn stack_only_opcode_impl<const N_POP: usize, const N_PUSH: usize>(
opcode: OpcodeId,
Expand Down Expand Up @@ -107,35 +109,57 @@ mod stackonlyop_tests {
}

#[test]
fn not_opcode_impl() {
stack_only_opcode_impl::<1, 1>(
OpcodeId::NOT,
fn sdiv_opcode_impl() {
stack_only_opcode_impl::<2, 1>(
OpcodeId::SDIV,
bytecode! {
PUSH32(word!("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"))
NOT
PUSH1(0x80u64)
PUSH1(0x60u64)
SDIV
STOP
},
vec![
StackOp::new(1, StackAddress(1022), Word::from(0x60)),
StackOp::new(1, StackAddress(1023), Word::from(0x80)),
],
vec![StackOp::new(
1,
StackAddress(1023),
word!("0x000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"),
Word::from(0x60) / Word::from(0x80),
)],
);
}

#[test]
fn mod_opcode_impl() {
stack_only_opcode_impl::<2, 1>(
OpcodeId::MOD,
bytecode! {
PUSH1(0x80u64)
PUSH1(0x60u64)
MOD
STOP
},
vec![
StackOp::new(1, StackAddress(1022), Word::from(0x60)),
StackOp::new(1, StackAddress(1023), Word::from(0x80)),
],
vec![StackOp::new(
1,
StackAddress(1023),
word!("0xfffefdfcfbfaf9f8f7f6f5f4f3f2f1f0efeeedecebeae9e8e7e6e5e4e3e2e1e0"),
Word::from(0x60) % Word::from(0x80),
)],
);
}

#[test]
fn add_opcode_impl() {
fn smod_opcode_impl() {
stack_only_opcode_impl::<2, 1>(
OpcodeId::ADD,
OpcodeId::SMOD,
bytecode! {
PUSH1(0x80u64)
PUSH1(0x60u64)
ADD
SMOD
STOP
},
vec![
Expand All @@ -145,28 +169,232 @@ mod stackonlyop_tests {
vec![StackOp::new(
1,
StackAddress(1023),
Word::from(0x60) + Word::from(0x80),
Word::from(0x60) % Word::from(0x80),
)],
);
}

fn lt_opcode_impl(a: usize, b: usize, result: usize) {
stack_only_opcode_impl::<2, 1>(
OpcodeId::LT,
bytecode! {
PUSH1(b)
PUSH1(a)
LT
STOP
},
vec![
StackOp::new(1, StackAddress(1022), Word::from(a)),
StackOp::new(1, StackAddress(1023), Word::from(b)),
],
vec![StackOp::new(1, StackAddress(1023), Word::from(result))],
);
}

#[test]
fn test_lt_opcode() {
lt_opcode_impl(0x01, 0x02, 0x01);
lt_opcode_impl(0x01, 0x01, 0x00);
lt_opcode_impl(0x02, 0x01, 0x00);
}

fn gt_opcode_impl(a: usize, b: usize, result: usize) {
stack_only_opcode_impl::<2, 1>(
OpcodeId::GT,
bytecode! {
PUSH1(b)
PUSH1(a)
GT
STOP
},
vec![
StackOp::new(1, StackAddress(1022), Word::from(a)),
StackOp::new(1, StackAddress(1023), Word::from(b)),
],
vec![StackOp::new(1, StackAddress(1023), Word::from(result))],
);
}
#[test]
fn addmod_opcode_impl() {
stack_only_opcode_impl::<3, 1>(
OpcodeId::ADDMOD,
fn test_gt_opcode() {
gt_opcode_impl(0x01, 0x02, 0x00);
gt_opcode_impl(0x01, 0x01, 0x00);
gt_opcode_impl(0x02, 0x01, 0x01);
}

fn slt_opcode_impl(a: usize, b: usize, result: usize) {
stack_only_opcode_impl::<2, 1>(
OpcodeId::SLT,
bytecode! {
PUSH3(0xbcdef)
PUSH3(0x6789a)
PUSH3(0x12345)
ADDMOD
PUSH1(b)
PUSH1(a)
SLT
STOP
},
vec![
StackOp::new(1, StackAddress(1021), Word::from(0x12345)),
StackOp::new(1, StackAddress(1022), Word::from(0x6789a)),
StackOp::new(1, StackAddress(1023), Word::from(0xbcdef)),
StackOp::new(1, StackAddress(1022), Word::from(a)),
StackOp::new(1, StackAddress(1023), Word::from(b)),
],
vec![StackOp::new(1, StackAddress(1023), Word::from(0x79bdf))],
vec![StackOp::new(1, StackAddress(1023), Word::from(result))],
);
}

#[test]
fn test_slt_opcode() {
slt_opcode_impl(0x01, 0x02, 0x01);
slt_opcode_impl(0x01, 0x01, 0x00);
slt_opcode_impl(0x02, 0x01, 0x00);
}

fn sgt_opcode_impl(a: usize, b: usize, result: usize) {
stack_only_opcode_impl::<2, 1>(
OpcodeId::SGT,
bytecode! {
PUSH1(b)
PUSH1(a)
SGT
STOP
},
vec![
StackOp::new(1, StackAddress(1022), Word::from(a)),
StackOp::new(1, StackAddress(1023), Word::from(b)),
],
vec![StackOp::new(1, StackAddress(1023), Word::from(result))],
);
}
#[test]
fn test_sgt_opcode() {
sgt_opcode_impl(0x01, 0x02, 0x00);
sgt_opcode_impl(0x01, 0x01, 0x00);
sgt_opcode_impl(0x02, 0x01, 0x01);
}

fn and_opcode_impl(a: usize, b: usize, result: usize) {
stack_only_opcode_impl::<2, 1>(
OpcodeId::AND,
bytecode! {
PUSH1(b)
PUSH1(a)
AND
STOP
},
vec![
StackOp::new(1, StackAddress(1022), Word::from(a)),
StackOp::new(1, StackAddress(1023), Word::from(b)),
],
vec![StackOp::new(1, StackAddress(1023), Word::from(result))],
);
}
#[test]
fn test_and_operate() {
and_opcode_impl(0x01, 0x01, 0x01);
and_opcode_impl(0x01, 0x00, 0x00);
and_opcode_impl(0x00, 0x00, 0x00);
}

fn or_opcode_impl(a: usize, b: usize, result: usize) {
stack_only_opcode_impl::<2, 1>(
OpcodeId::OR,
bytecode! {
PUSH1(b)
PUSH1(a)
OR
STOP
},
vec![
StackOp::new(1, StackAddress(1022), Word::from(a)),
StackOp::new(1, StackAddress(1023), Word::from(b)),
],
vec![StackOp::new(1, StackAddress(1023), Word::from(result))],
);
}
#[test]
fn test_or_operate() {
or_opcode_impl(0x01, 0x01, 0x01.bitor(0x01) as usize);
or_opcode_impl(0x00, 0x01, 0x00.bitor(0x01) as usize);
or_opcode_impl(0x00, 0x00, 0x00.bitor(0x00) as usize);
}

fn xor_opcode_impl(a: usize, b: usize, result: usize) {
stack_only_opcode_impl::<2, 1>(
OpcodeId::XOR,
bytecode! {
PUSH1(b)
PUSH1(a)
XOR
STOP
},
vec![
StackOp::new(1, StackAddress(1022), Word::from(a)),
StackOp::new(1, StackAddress(1023), Word::from(b)),
],
vec![StackOp::new(1, StackAddress(1023), Word::from(result))],
);
}
#[test]
fn test_xor_operate() {
xor_opcode_impl(0x01, 0x01, 0x01.bitxor(0x01) as usize);
xor_opcode_impl(0x01, 0x00, 0x00.bitxor(0x01) as usize);
xor_opcode_impl(0x00, 0x00, 0x00.bitxor(0x00) as usize);
}

#[test]
fn not_opcode_impl() {
stack_only_opcode_impl::<1, 1>(
OpcodeId::NOT,
bytecode! {
PUSH32(word!("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"))
NOT
STOP
},
vec![StackOp::new(
1,
StackAddress(1023),
word!("0x000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"),
)],
vec![StackOp::new(
1,
StackAddress(1023),
word!("0xfffefdfcfbfaf9f8f7f6f5f4f3f2f1f0efeeedecebeae9e8e7e6e5e4e3e2e1e0"),
)],
);
}

#[test]
fn difficulty_opcode_impl() {
stack_only_opcode_impl::<0, 1>(
OpcodeId::DIFFICULTY,
bytecode! {
DIFFICULTY
STOP
},
vec![],
vec![StackOp::new(1, StackAddress(1023), *MOCK_DIFFICULTY)],
);
}

#[test]
fn gas_limit_opcode_impl() {
stack_only_opcode_impl::<0, 1>(
OpcodeId::GASLIMIT,
bytecode! {
GASLIMIT
STOP
},
vec![],
vec![StackOp::new(1, StackAddress(1023), *MOCK_GASLIMIT)],
);
}

#[test]
fn basefee_opcode_impl() {
stack_only_opcode_impl::<0, 1>(
OpcodeId::BASEFEE,
bytecode! {
BASEFEE
STOP
},
vec![],
vec![StackOp::new(1, StackAddress(1023), *MOCK_BASEFEE)],
);
}
}
8 changes: 4 additions & 4 deletions mock/src/block.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Mock Block definition and builder related methods.
use crate::{MockTransaction, MOCK_CHAIN_ID};
use crate::{MockTransaction, MOCK_BASEFEE, MOCK_CHAIN_ID, MOCK_DIFFICULTY, MOCK_GASLIMIT};
use eth_types::{Address, Block, Bytes, Hash, Transaction, Word, H64, U64};
use ethers_core::types::Bloom;
use ethers_core::types::OtherFields;
Expand Down Expand Up @@ -50,12 +50,12 @@ impl Default for MockBlock {
receipts_root: Hash::zero(),
number: U64([0u64]),
gas_used: Word::zero(),
gas_limit: Word::from(0x2386f26fc10000u64),
base_fee_per_gas: Word::zero(),
gas_limit: *MOCK_GASLIMIT,
base_fee_per_gas: *MOCK_BASEFEE,
extra_data: Bytes::default(),
logs_bloom: None,
timestamp: Word::from(123456789u64),
difficulty: Word::from(0x200000u64),
difficulty: *MOCK_DIFFICULTY,
total_difficulty: Word::zero(),
seal_fields: Vec::new(),
uncles: Vec::new(),
Expand Down
6 changes: 6 additions & 0 deletions mock/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,14 @@ lazy_static! {
address!("0x00000000000000000000000000000000c014ba5e");
/// Mock gasprice value
pub static ref MOCK_GASPRICE: Word = Word::from(1u8);
/// Mock BASEFEE value
pub static ref MOCK_BASEFEE: Word = Word::zero();
/// Mock GASLIMIT value
pub static ref MOCK_GASLIMIT: Word = Word::from(0x2386f26fc10000u64);
/// Mock chain ID value
pub static ref MOCK_CHAIN_ID: Word = Word::from(1338u64);
/// Mock DIFFICULTY value
pub static ref MOCK_DIFFICULTY: Word = Word::from(0x200000u64);
/// Mock accounts loaded with ETH to use for test cases.
pub static ref MOCK_ACCOUNTS: Vec<Address> = vec![
address!("0x000000000000000000000000000000000cafe111"),
Expand Down

0 comments on commit 82e6c87

Please sign in to comment.