use essential_types::Word;
use essential_vm::{
asm::{self, Op},
types::{convert::word_4_from_u8_32, ContentAddress},
GasLimit, Vm,
};
use util::*;
mod util;
#[test]
fn state_read_3_42s() {
let access = test_access();
let state = State::new(vec![(
access.this_solution().predicate_to_solve.contract.clone(),
vec![
(vec![0, 0, 0, 0], vec![42]),
(vec![0, 0, 0, 1], vec![42]),
(vec![0, 0, 0, 2], vec![42]),
],
)]);
let mut vm = Vm::default();
let num_keys = 3;
let num_words = 3;
let mem_len = num_keys * 2 + num_words;
let ops = &[
asm::Stack::Push(mem_len).into(),
asm::Memory::Alloc.into(),
asm::Stack::Push(0).into(), asm::Stack::Push(0).into(), asm::Stack::Push(0).into(), asm::Stack::Push(0).into(), asm::Stack::Push(4).into(), asm::Stack::Push(num_keys).into(),
asm::Stack::Push(0).into(), asm::Op::StateRead(asm::StateRead::KeyRange),
asm::TotalControlFlow::Halt.into(),
];
vm.exec_ops(
ops,
access.clone(),
&state,
&|_: &Op| 1,
GasLimit::UNLIMITED,
)
.unwrap();
assert_eq!(vm.memory[..].len(), mem_len as usize);
assert_eq!(&vm.memory[..], &[6, 1, 7, 1, 8, 1, 42, 42, 42]);
}
#[test]
fn state_read_some_none_some() {
let access = test_access();
let state = State::new(vec![(
access.this_solution().predicate_to_solve.contract.clone(),
vec![(vec![0, 0, 0, 0], vec![42]), (vec![0, 0, 0, 2], vec![42])],
)]);
let mut vm = Vm::default();
let num_keys = 3;
let num_words = 2;
let mem_len = num_keys * 2 + num_words;
let ops = &[
asm::Stack::Push(mem_len).into(),
asm::Memory::Alloc.into(),
asm::Stack::Push(0).into(), asm::Stack::Push(0).into(), asm::Stack::Push(0).into(), asm::Stack::Push(0).into(), asm::Stack::Push(4).into(), asm::Stack::Push(num_keys).into(),
asm::Stack::Push(0).into(), asm::Op::StateRead(asm::StateRead::KeyRange),
asm::TotalControlFlow::Halt.into(),
];
vm.exec_ops(
ops,
access.clone(),
&state,
&|_: &Op| 1,
GasLimit::UNLIMITED,
)
.unwrap();
assert_eq!(vm.memory[..].len(), mem_len as usize);
assert_eq!(&vm.memory[..], &[6, 1, 7, 0, 7, 1, 42, 42]);
}
#[test]
fn state_read_ext() {
let ext_contract_addr = ContentAddress([0x12; 32]);
let state = State::new(vec![(
ext_contract_addr.clone(),
vec![
(vec![1, 2, 3, 4], vec![40]),
(vec![1, 2, 3, 5], vec![41]),
(vec![1, 2, 3, 6], vec![42]),
],
)]);
let mut vm = Vm::default();
let num_keys = 3;
let num_words = 3;
let mem_len = num_keys * 2 + num_words;
let [addr0, addr1, addr2, addr3] = word_4_from_u8_32(ext_contract_addr.0);
let ops = &[
asm::Stack::Push(mem_len).into(),
asm::Memory::Alloc.into(),
asm::Stack::Push(addr0).into(),
asm::Stack::Push(addr1).into(),
asm::Stack::Push(addr2).into(),
asm::Stack::Push(addr3).into(),
asm::Stack::Push(1).into(), asm::Stack::Push(2).into(), asm::Stack::Push(3).into(), asm::Stack::Push(4).into(), asm::Stack::Push(4).into(), asm::Stack::Push(num_keys).into(),
asm::Stack::Push(0).into(), asm::Op::StateRead(asm::StateRead::KeyRangeExtern),
asm::TotalControlFlow::Halt.into(),
];
vm.exec_ops(
ops,
test_access().clone(),
&state,
&|_: &Op| 1,
GasLimit::UNLIMITED,
)
.unwrap();
assert_eq!(vm.memory[..].len(), mem_len as usize);
assert_eq!(&vm.memory[..], &[6, 1, 7, 1, 8, 1, 40, 41, 42]);
}
#[test]
fn state_read_ext_nones() {
let ext_contract_addr = ContentAddress([0x12; 32]);
let state = State::new(vec![(ext_contract_addr.clone(), vec![])]);
let mut vm = Vm::default();
let num_keys = 3;
let num_words = 0;
let mem_len = num_keys * 2 + num_words;
let [addr0, addr1, addr2, addr3] = word_4_from_u8_32(ext_contract_addr.0);
let ops = &[
asm::Stack::Push(mem_len).into(),
asm::Memory::Alloc.into(),
asm::Stack::Push(addr0).into(),
asm::Stack::Push(addr1).into(),
asm::Stack::Push(addr2).into(),
asm::Stack::Push(addr3).into(),
asm::Stack::Push(1).into(), asm::Stack::Push(2).into(), asm::Stack::Push(3).into(), asm::Stack::Push(4).into(), asm::Stack::Push(4).into(), asm::Stack::Push(num_keys).into(),
asm::Stack::Push(0).into(), asm::Op::StateRead(asm::StateRead::KeyRangeExtern),
asm::TotalControlFlow::Halt.into(),
];
vm.exec_ops(
ops,
test_access().clone(),
&state,
&|_: &Op| 1,
GasLimit::UNLIMITED,
)
.unwrap();
assert_eq!(vm.memory[..].len(), mem_len as usize);
assert_eq!(&vm.memory[..], &[6, 0, 6, 0, 6, 0]);
}
#[test]
fn state_read_various_size_values() {
let access = test_access();
let state = State::new(vec![(
access.this_solution().predicate_to_solve.contract.clone(),
vec![
(vec![0, 0, 0, 0], vec![0; 2]),
(vec![0, 0, 0, 1], vec![1; 22]),
(vec![0, 0, 0, 2], vec![2; 14]),
(vec![0, 0, 0, 4], vec![4; 12]),
],
)]);
let mut vm = Vm::default();
let num_keys = 5;
let num_words = 2 + 22 + 14 + 12;
let mem_len = num_keys * 2 + num_words;
let ops = &[
asm::Stack::Push(mem_len).into(),
asm::Memory::Alloc.into(),
asm::Stack::Push(0).into(), asm::Stack::Push(0).into(), asm::Stack::Push(0).into(), asm::Stack::Push(0).into(), asm::Stack::Push(4).into(), asm::Stack::Push(num_keys).into(),
asm::Stack::Push(0).into(), asm::Op::StateRead(asm::StateRead::KeyRange),
asm::TotalControlFlow::Halt.into(),
];
vm.exec_ops(
ops,
access.clone(),
&state,
&|_: &Op| 1,
GasLimit::UNLIMITED,
)
.unwrap();
assert_eq!(vm.memory[..].len(), mem_len as usize);
let mut expected = vec![10, 2, 12, 22, 34, 14, 48, 0, 48, 12]; expected.append(&mut vec![0; 2]);
expected.append(&mut vec![1; 22]);
expected.append(&mut vec![2; 14]);
expected.append(&mut vec![4; 12]);
assert_eq!(Vec::from(vm.memory), expected);
}
#[test]
fn state_read_various_key_sizes() {
let access = test_access();
let kv_pairs = vec![
(vec![0], vec![0; 2]),
(vec![0, 1], vec![7; 6]),
(vec![1], vec![1; 22]),
(vec![0, 0, 0, 0, 0, 2], vec![2; 14]),
(vec![4; 1000], vec![4; 12]),
];
let state = State::new(vec![(
access.this_solution().predicate_to_solve.contract.clone(),
kv_pairs.clone(),
)]);
let mut vm = Vm::default();
let mem_len =
((5 * 2) + kv_pairs[0].1.len() + kv_pairs[2].1.len() + kv_pairs[3].1.len()) as Word;
let krng2_mem_addr = ((3 * 2) + kv_pairs[0].1.len() + kv_pairs[2].1.len()) as Word;
let ops = &[
asm::Stack::Push(mem_len).into(),
asm::Memory::Alloc.into(),
asm::Stack::Push(0).into(), asm::Stack::Push(1).into(), asm::Stack::Push(3).into(), asm::Stack::Push(0).into(), asm::Op::StateRead(asm::StateRead::KeyRange),
asm::Stack::Push(0).into(),
asm::Stack::Push(0).into(),
asm::Stack::Push(0).into(),
asm::Stack::Push(0).into(),
asm::Stack::Push(0).into(),
asm::Stack::Push(2).into(),
asm::Stack::Push(6).into(), asm::Stack::Push(2).into(), asm::Stack::Push(krng2_mem_addr).into(), asm::StateRead::KeyRange.into(),
asm::TotalControlFlow::Halt.into(),
];
vm.exec_ops(
ops,
access.clone(),
&state,
&|_: &Op| 1,
GasLimit::UNLIMITED,
)
.unwrap();
let mut expected = vec![6, 2, 8, 22, 30, 0];
expected.append(&mut vec![0; 2]);
expected.append(&mut vec![1; 22]);
let addr = expected.len() as Word + 2 * 2;
expected.append(&mut vec![addr, 14, addr + 14, 0]);
expected.append(&mut vec![2; 14]);
assert_eq!(&vm.memory[..], &expected[..]);
}