Skip to content

Commit 735cd05

Browse files
committed
Moving Vector tests to vm2-collections-test contract so they will execute against a real execution engine
1 parent 0f8e423 commit 735cd05

File tree

9 files changed

+492
-301
lines changed

9 files changed

+492
-301
lines changed

executor/wasm/tests/collections.rs

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,3 +86,75 @@ fn should_run_test_suite() {
8686
assert!(res.host_error.is_none());
8787
}
8888
}
89+
90+
#[test]
91+
fn inserting_into_non_existing_vec_index_fails() {
92+
let chainspec_config = ChainspecConfig::from_chainspec_path(&*CHAINSPEC_SYMLINK)
93+
.expect("must get chainspec config");
94+
let storage_costs = chainspec_config.storage_costs;
95+
let mint_costs = chainspec_config.system_costs_config.mint_costs().clone();
96+
let auction_costs = chainspec_config.system_costs_config.auction_costs().clone();
97+
let v1_config = EngineConfig::from(chainspec_config.clone());
98+
let execution_engine_v1 = ExecutionEngineV1::new(v1_config);
99+
let wasm_v2_config = *chainspec_config.wasm_config.v2();
100+
let memory_limit = wasm_v2_config.max_memory();
101+
let message_limits = chainspec_config.wasm_config.messages_limits();
102+
let executor_config = ExecutorConfigBuilder::default()
103+
.with_memory_limit(memory_limit)
104+
.with_executor_kind(ExecutorKind::Compiled)
105+
.with_wasm_config(wasm_v2_config)
106+
.with_storage_costs(storage_costs)
107+
.with_mint_costs(mint_costs)
108+
.with_auction_costs(auction_costs)
109+
.with_baseline_motes_amount(chainspec_config.core_config.baseline_motes_amount)
110+
.with_message_limits(message_limits)
111+
.build()
112+
.expect("Should build");
113+
let mut executor = ExecutorV2::new(executor_config, execution_engine_v1);
114+
115+
let (global_state, mut state_root_hash, _tempdir) = make_global_state_with_genesis();
116+
117+
let address_generator = make_address_generator();
118+
119+
let vm2_collections_test = read_wasm("vm2_collections_test.wasm");
120+
121+
let install_request = base_install_request_builder(&chainspec_config)
122+
.with_wasm_bytes(vm2_collections_test.wasm)
123+
.with_bundle_data(vm2_collections_test.meta.expect("should have bundle data"))
124+
.with_shared_address_generator(Arc::clone(&address_generator))
125+
.with_transferred_value(0)
126+
.with_entry_point("new".to_string())
127+
.build()
128+
.expect("should build");
129+
130+
let create_result = run_create_contract(
131+
&mut executor,
132+
&global_state,
133+
state_root_hash,
134+
install_request,
135+
);
136+
137+
let contract_address = *create_result.smart_contract_addr();
138+
state_root_hash = global_state
139+
.commit_effects(state_root_hash, create_result.effects().clone())
140+
.expect("Should commit");
141+
142+
let run_method = base_execute_builder(&chainspec_config)
143+
.with_shared_address_generator(Arc::clone(&address_generator))
144+
.with_transferred_value(0)
145+
.with_execution_kind(ExecutionKind::Stored {
146+
address: contract_address,
147+
entry_point: "test_remove_invalid_index_prepare".to_owned(),
148+
})
149+
.build()
150+
.expect("should build");
151+
let res = run_wasm_session(&mut executor, &global_state, state_root_hash, run_method);
152+
assert!(res.is_ok());
153+
if let Ok(res) = res {
154+
let host_error = res.host_error;
155+
assert!(host_error.is_some());
156+
if let Some(err) = host_error {
157+
println!("XXX {:?}", err);
158+
}
159+
}
160+
}

smart_contracts/contracts/vm2/vm2-collections-test/src/lib.rs

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,17 @@ extern crate alloc;
66
mod iterable_map;
77
mod iterable_set;
88
mod types;
9-
use casper_contract_sdk::prelude::*;
9+
mod vector;
10+
use casper_contract_sdk::{collections::Vector, prelude::*};
1011
use iterable_map::*;
1112

12-
use crate::iterable_set::IterableSetTestData;
13+
use crate::{iterable_set::IterableSetTestData, vector::VectorTestData};
1314

1415
#[casper(contract_state)]
1516
pub struct CollectionsTestContract {
1617
iterable_map_test_data: IterableMapTestData,
1718
iterable_set_test_data: IterableSetTestData,
19+
vector_test_data: VectorTestData,
1820
}
1921

2022
impl Default for CollectionsTestContract {
@@ -27,14 +29,24 @@ impl Default for CollectionsTestContract {
2729
impl CollectionsTestContract {
2830
#[casper(constructor)]
2931
pub fn new() -> Self {
32+
let iterable_map_test_data = IterableMapTestData::new();
33+
let iterable_set_test_data = IterableSetTestData::new();
34+
let vector_test_data = VectorTestData::new();
3035
Self {
31-
iterable_map_test_data: IterableMapTestData::new(),
32-
iterable_set_test_data: IterableSetTestData::new(),
36+
iterable_map_test_data,
37+
iterable_set_test_data,
38+
vector_test_data,
3339
}
3440
}
3541

3642
pub(crate) fn assertions(&mut self) {
37-
//self.iterable_map_test_data.do_assertions();
43+
self.iterable_map_test_data.do_assertions();
3844
self.iterable_set_test_data.do_assertions();
45+
self.vector_test_data.do_assertions();
46+
}
47+
48+
pub(crate) fn vector_insert_out_of_bounds_panics(&mut self) {
49+
let mut vec = Vector::<u64>::new("vector_insert_out_of_bounds");
50+
vec.insert(1, 1);
3951
}
4052
}

smart_contracts/contracts/vm2/vm2-collections-test/src/types.rs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,35 @@ impl CasperABI for TestKey {
4646
}
4747
}
4848

49+
#[derive(BorshSerialize, BorshDeserialize, PartialEq, Debug)]
50+
pub(crate) struct VectorTestStruct {
51+
pub(crate) field: u64,
52+
}
53+
54+
impl IterableMapHash for VectorTestStruct {}
55+
56+
impl TypeUid for VectorTestStruct {
57+
const UID: Uid = Uid::from_name("VectorTestStruct");
58+
}
59+
60+
impl CLTyped for VectorTestStruct {
61+
fn cl_type() -> CLType {
62+
CLType::Any
63+
}
64+
}
65+
66+
#[cfg(all(not(target_arch = "wasm32")))]
67+
impl CasperABI for VectorTestStruct {
68+
fn definition() -> casper_contract_sdk::abi::Definition {
69+
Definition::Struct {
70+
items: vec![StructField {
71+
name: "field1".into(),
72+
decl: casper_executor_wasm_common::type_uid::of::<u64>().into(),
73+
}],
74+
}
75+
}
76+
}
77+
4978
#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, PartialEq)]
5079
pub(crate) struct TestStruct {
5180
pub(crate) field1: u64,
Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
use core::{panic, ptr::NonNull};
2+
3+
use alloc::{vec, vec::Vec};
4+
use casper_contract_sdk::{
5+
casper,
6+
collections::{compute_prefix_bytes_for_index, Vector},
7+
types::HashAlgorithm,
8+
};
9+
use casper_executor_wasm_common::{
10+
keyspace::{CollectionAddrInner, ContextAddr, Keyspace},
11+
CollectionTypeTag,
12+
};
13+
use const_fnv1a_hash::fnv1a_hash_str_64;
14+
15+
use crate::types::VectorTestStruct;
16+
17+
fn get_vec_elements_from_storage(prefix: &str) -> Vec<u64> {
18+
let mut values = Vec::new();
19+
for idx in 0..64 {
20+
let prefix_bytes = compute_prefix_bytes_for_index(prefix, idx);
21+
let collection_prefix = fnv1a_hash_str_64(prefix).to_le_bytes();
22+
let addr = CollectionAddrInner::new(
23+
*casper::get_callee().address(),
24+
CollectionTypeTag::Vector,
25+
collection_prefix,
26+
casper::generic_hash(&prefix_bytes, HashAlgorithm::Blake2b).unwrap(),
27+
);
28+
29+
let mut value: [u8; 8] = [0; 8];
30+
let result = casper::read(Keyspace::Context(ContextAddr::from(addr)), |size| {
31+
assert_eq!(size, 8);
32+
NonNull::new(value.as_mut_ptr())
33+
})
34+
.unwrap();
35+
36+
if result.is_some() {
37+
values.push(u64::from_le_bytes(value));
38+
}
39+
}
40+
values
41+
}
42+
43+
pub(crate) fn should_not_panic_with_empty_assert(vec: &mut Vector<u64>) {
44+
assert_eq!(vec.len(), 0);
45+
assert_eq!(vec.remove(0), None);
46+
vec.retain(|_| false);
47+
let _ = vec.binary_search(&123);
48+
let v: Vec<u64> = vec.iter().collect();
49+
assert_eq!(v, Vec::<u64>::new())
50+
}
51+
52+
pub(crate) fn should_retain_assert(vec: &mut Vector<u64>) {
53+
let vec: Vec<_> = vec.iter().collect();
54+
assert_eq!(vec, vec![2, 4]);
55+
}
56+
57+
pub(crate) fn test_vec_assert(vec: &mut Vector<u64>) {
58+
assert_eq!(vec.remove(5), Some(334));
59+
assert_eq!(vec.remove(55), None);
60+
61+
let mut iter = vec.iter();
62+
assert_eq!(iter.next(), Some(41));
63+
assert_eq!(iter.next(), Some(43));
64+
assert_eq!(iter.next(), Some(42));
65+
assert_eq!(iter.next(), Some(111));
66+
assert_eq!(iter.next(), Some(222));
67+
assert_eq!(iter.next(), Some(333));
68+
assert_eq!(iter.next(), None);
69+
70+
{
71+
let ser = borsh::to_vec(vec).unwrap();
72+
let deser: Vector<u64> = borsh::from_slice(&ser).unwrap();
73+
let mut iter = deser.iter();
74+
assert_eq!(iter.next(), Some(41));
75+
assert_eq!(iter.next(), Some(43));
76+
assert_eq!(iter.next(), Some(42));
77+
assert_eq!(iter.next(), Some(111));
78+
assert_eq!(iter.next(), Some(222));
79+
assert_eq!(iter.next(), Some(333));
80+
assert_eq!(iter.next(), None);
81+
}
82+
83+
assert_eq!(
84+
get_vec_elements_from_storage("test_vec"),
85+
vec![41, 43, 42, 111, 222, 333]
86+
);
87+
88+
let vec2 = Vector::<u64>::new("test1");
89+
assert_eq!(vec2.get(0), None);
90+
91+
assert_eq!(get_vec_elements_from_storage("test1"), Vec::<u64>::new());
92+
}
93+
94+
pub(crate) fn test_pop_assert(vec: &mut Vector<u64>) {
95+
assert_eq!(vec.pop(), Some(2));
96+
assert_eq!(vec.len(), 1);
97+
assert_eq!(vec.pop(), Some(1));
98+
assert!(vec.is_empty());
99+
100+
assert_eq!(get_vec_elements_from_storage("test_pop"), Vec::<u64>::new());
101+
}
102+
103+
pub(crate) fn test_contains_assert(vec: &mut Vector<u64>) {
104+
assert!(vec.contains(&1));
105+
assert!(vec.contains(&2));
106+
assert!(!vec.contains(&3));
107+
vec.remove(0);
108+
assert!(!vec.contains(&1));
109+
assert_eq!(
110+
get_vec_elements_from_storage("test_contains_prepare"),
111+
vec![2]
112+
);
113+
}
114+
115+
pub(crate) fn test_clear_assert(vec: &mut Vector<u64>) {
116+
vec.clear();
117+
assert_eq!(vec.len(), 0);
118+
assert!(vec.is_empty());
119+
assert_eq!(vec.get(0), None);
120+
vec.push(3);
121+
assert_eq!(vec.get(0), Some(3));
122+
123+
assert_eq!(get_vec_elements_from_storage("test_clear"), vec![3]);
124+
}
125+
126+
pub(crate) fn test_binary_search_assert(vec: &mut Vector<u64>) {
127+
assert_eq!(vec.binary_search(&3), Ok(2));
128+
assert_eq!(vec.binary_search(&0), Err(0));
129+
assert_eq!(vec.binary_search(&6), Err(5));
130+
}
131+
132+
pub(crate) fn test_swap_remove_assert(vec: &mut Vector<u64>) {
133+
assert_eq!(vec.iter().collect::<Vec<_>>(), vec![1, 4]);
134+
assert_eq!(
135+
get_vec_elements_from_storage("test_swap_remove"),
136+
vec![1, 4]
137+
);
138+
}
139+
140+
pub(crate) fn test_insert_at_len_assert(vec: &mut Vector<u64>) {
141+
assert_eq!(vec.iter().collect::<Vec<_>>(), vec![1, 2]);
142+
assert_eq!(
143+
get_vec_elements_from_storage("test_insert_at_len"),
144+
vec![1, 2]
145+
);
146+
}
147+
148+
pub(crate) fn test_struct_elements_assert(vec: &mut Vector<VectorTestStruct>) {
149+
assert_eq!(vec.get(1), Some(VectorTestStruct { field: 2 }));
150+
assert_eq!(vec.len(), 2);
151+
}
152+
153+
pub(crate) fn test_multiple_operations_assert(vec: &mut Vector<u64>) {
154+
vec.push(1);
155+
vec.insert(0, 2);
156+
vec.push(3);
157+
assert_eq!(vec.iter().collect::<Vec<_>>(), vec![2, 1, 3]);
158+
assert_eq!(vec.swap_remove(0), Some(2));
159+
assert_eq!(vec.iter().collect::<Vec<_>>(), vec![3, 1]);
160+
assert_eq!(vec.pop(), Some(1));
161+
assert_eq!(vec.get(0), Some(3));
162+
vec.clear();
163+
assert!(vec.is_empty());
164+
165+
assert_eq!(
166+
get_vec_elements_from_storage("test_multiple_operations"),
167+
Vec::<u64>::new()
168+
);
169+
}
170+
171+
pub(crate) fn test_remove_invalid_index_assert(vec: &mut Vector<u64>) {
172+
assert_eq!(vec.remove(1), None);
173+
assert_eq!(vec.remove(0), Some(1));
174+
assert_eq!(vec.remove(0), None);
175+
}

0 commit comments

Comments
 (0)