mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-13 18:41:05 +00:00
Ditch the input buffer (#2911)
* Pass input data via the scratch buffer. Remove calls to ext_input_*. * Fix tests and docs * Bump the version. * Remove ext_input_* from COMPLEXITY.md * Return back the length check and add more comments * Update the documentation of the scratch buffer. * Fix a silly mistake.
This commit is contained in:
@@ -527,8 +527,8 @@ const CODE_SET_RENT: &str = r#"
|
||||
(import "env" "ext_dispatch_call" (func $ext_dispatch_call (param i32 i32)))
|
||||
(import "env" "ext_set_storage" (func $ext_set_storage (param i32 i32 i32 i32)))
|
||||
(import "env" "ext_set_rent_allowance" (func $ext_set_rent_allowance (param i32 i32)))
|
||||
(import "env" "ext_input_size" (func $ext_input_size (result i32)))
|
||||
(import "env" "ext_input_copy" (func $ext_input_copy (param i32 i32 i32)))
|
||||
(import "env" "ext_scratch_size" (func $ext_scratch_size (result i32)))
|
||||
(import "env" "ext_scratch_copy" (func $ext_scratch_copy (param i32 i32 i32)))
|
||||
(import "env" "memory" (memory 1 1))
|
||||
|
||||
;; insert a value of 4 bytes into storage
|
||||
@@ -575,7 +575,7 @@ const CODE_SET_RENT: &str = r#"
|
||||
(func (export "call")
|
||||
(local $input_size i32)
|
||||
(set_local $input_size
|
||||
(call $ext_input_size)
|
||||
(call $ext_scratch_size)
|
||||
)
|
||||
(block $IF_ELSE
|
||||
(block $IF_2
|
||||
@@ -602,16 +602,16 @@ const CODE_SET_RENT: &str = r#"
|
||||
;; Set call set_rent_allowance with input
|
||||
(func (export "deploy")
|
||||
(local $input_size i32)
|
||||
(set_local $input_size
|
||||
(call $ext_scratch_size)
|
||||
)
|
||||
(call $ext_set_storage
|
||||
(i32.const 0)
|
||||
(i32.const 1)
|
||||
(i32.const 0)
|
||||
(i32.const 4)
|
||||
)
|
||||
(set_local $input_size
|
||||
(call $ext_input_size)
|
||||
)
|
||||
(call $ext_input_copy
|
||||
(call $ext_scratch_copy
|
||||
(i32.const 0)
|
||||
(i32.const 0)
|
||||
(get_local $input_size)
|
||||
@@ -631,7 +631,7 @@ const CODE_SET_RENT: &str = r#"
|
||||
"#;
|
||||
|
||||
// Use test_hash_and_code test to get the actual hash if the code changed.
|
||||
const HASH_SET_RENT: [u8; 32] = hex!("21d6b1d59aa6038fcad632488e9026893a1bbb48581774c771b8f24320697f05");
|
||||
const HASH_SET_RENT: [u8; 32] = hex!("69aedfb4f6c1c398e97f8a5204de0f95ad5e7dc3540960beab11a86c569fbfcf");
|
||||
|
||||
/// Input data for each call in set_rent code
|
||||
mod call {
|
||||
@@ -1041,8 +1041,12 @@ const CODE_RESTORATION: &str = r#"
|
||||
|
||||
(func (export "call")
|
||||
(call $ext_dispatch_call
|
||||
(i32.const 200) ;; Pointer to the start of encoded call buffer
|
||||
(i32.const 115) ;; Length of the buffer
|
||||
;; Pointer to the start of the encoded call buffer
|
||||
(i32.const 200)
|
||||
;; The length of the encoded call buffer.
|
||||
;;
|
||||
;; NB: This is required to keep in sync with the values in `restoration`.
|
||||
(i32.const 115)
|
||||
)
|
||||
)
|
||||
(func (export "deploy")
|
||||
@@ -1069,16 +1073,17 @@ const CODE_RESTORATION: &str = r#"
|
||||
;; ACL
|
||||
(data (i32.const 100) "\01")
|
||||
|
||||
;; Call
|
||||
(data (i32.const 200) "\01\05\02\00\00\00\00\00\00\00\21\d6\b1\d5\9a\a6\03\8f\ca\d6\32\48\8e\90"
|
||||
"\26\89\3a\1b\bb\48\58\17\74\c7\71\b8\f2\43\20\69\7f\05\32\00\00\00\00\00\00\00\08\01\00\00"
|
||||
"\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\01"
|
||||
"\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00"
|
||||
"\00"
|
||||
;; Serialized version of `T::Call` that encodes a call to `restore_to` function. For more
|
||||
;; details check out the `ENCODED_CALL_LITERAL`.
|
||||
(data (i32.const 200)
|
||||
"\01\05\02\00\00\00\00\00\00\00\69\ae\df\b4\f6\c1\c3\98\e9\7f\8a\52\04\de\0f\95\ad\5e\7d\c3"
|
||||
"\54\09\60\be\ab\11\a8\6c\56\9f\bf\cf\32\00\00\00\00\00\00\00\08\01\00\00\00\00\00\00\00\00"
|
||||
"\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\01\00\00\00\00\00\00"
|
||||
"\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00"
|
||||
)
|
||||
)
|
||||
"#;
|
||||
const HASH_RESTORATION: [u8; 32] = hex!("b393bfa8de97b02f08ba1580b46100a80c9489a97c8d870691c9ff7236b29bc7");
|
||||
const HASH_RESTORATION: [u8; 32] = hex!("02988182efba70fe605031f5c55bfa59e47f72c0a4707f22b6b74fffbf7803dc");
|
||||
|
||||
#[test]
|
||||
fn restorations_dirty_storage_and_different_storage() {
|
||||
@@ -1116,12 +1121,25 @@ fn restoration(test_different_storage: bool, test_restore_to_with_dirty_storage:
|
||||
vec![acl_key, acl_key],
|
||||
))));
|
||||
|
||||
let literal = "0105020000000000000021d6b1d59aa6038fcad632488e9026893a1bbb48581774c771b8f243206\
|
||||
97f053200000000000000080100000000000000000000000000000000000000000000000000000000000000010\
|
||||
0000000000000000000000000000000000000000000000000000000000000";
|
||||
|
||||
assert_eq!(encoded, literal);
|
||||
assert_eq!(115, hex::decode(literal).unwrap().len());
|
||||
// `ENCODED_CALL_LITERAL` is encoded `T::Call` represented as a byte array. There is an exact
|
||||
// same copy of this (modulo hex notation differences) in `CODE_RESTORATION`.
|
||||
//
|
||||
// When this assert is triggered make sure that you update the literals here and in
|
||||
// `CODE_RESTORATION`. Hopefully, we switch to automatical injection of the code.
|
||||
const ENCODED_CALL_LITERAL: &str =
|
||||
"0105020000000000000069aedfb4f6c1c398e97f8a5204de0f95ad5e7dc3540960beab11a86c569fbfcf320000\
|
||||
0000000000080100000000000000000000000000000000000000000000000000000000000000010000000000000\
|
||||
0000000000000000000000000000000000000000000000000";
|
||||
assert_eq!(
|
||||
encoded,
|
||||
ENCODED_CALL_LITERAL,
|
||||
"The literal was changed and requires updating here and in `CODE_RESTORATION`",
|
||||
);
|
||||
assert_eq!(
|
||||
hex::decode(ENCODED_CALL_LITERAL).unwrap().len(),
|
||||
115,
|
||||
"The size of the literal was changed and requires updating in `CODE_RESTORATION`",
|
||||
);
|
||||
|
||||
let restoration_wasm = wabt::wat2wasm(CODE_RESTORATION).unwrap();
|
||||
let set_rent_wasm = wabt::wat2wasm(CODE_SET_RENT).unwrap();
|
||||
@@ -1153,14 +1171,18 @@ fn restoration(test_different_storage: bool, test_restore_to_with_dirty_storage:
|
||||
},
|
||||
]);
|
||||
|
||||
// Create an account with address `BOB` with code `HASH_SET_RENT`.
|
||||
// The input parameter sets the rent allowance to 0.
|
||||
assert_ok!(Contract::create(
|
||||
Origin::signed(ALICE),
|
||||
30_000,
|
||||
100_000, HASH_SET_RENT.into(),
|
||||
100_000,
|
||||
HASH_SET_RENT.into(),
|
||||
<Test as balances::Trait>::Balance::from(0u32).encode()
|
||||
));
|
||||
|
||||
// Check creation
|
||||
// Check if `BOB` was created successfully and that the rent allowance is
|
||||
// set to 0.
|
||||
let bob_contract = ContractInfoOf::<Test>::get(BOB).unwrap().get_alive().unwrap();
|
||||
assert_eq!(bob_contract.rent_allowance, 0);
|
||||
|
||||
@@ -1172,36 +1194,49 @@ fn restoration(test_different_storage: bool, test_restore_to_with_dirty_storage:
|
||||
);
|
||||
}
|
||||
|
||||
// Advance 4 blocks
|
||||
// Advance 4 blocks, to the 5th.
|
||||
System::initialize(&5, &[0u8; 32].into(), &[0u8; 32].into(), &Default::default());
|
||||
|
||||
// Trigger rent through call
|
||||
// Call `BOB`, which makes it pay rent. Since the rent allowance is set to 0
|
||||
// we expect that it will get removed leaving tombstone.
|
||||
assert_ok!(Contract::call(Origin::signed(ALICE), BOB, 0, 100_000, call::null()));
|
||||
assert!(ContractInfoOf::<Test>::get(BOB).unwrap().get_tombstone().is_some());
|
||||
|
||||
/// Create another account with the address `DJANGO` with `CODE_RESTORATION`.
|
||||
///
|
||||
/// Note that we can't use `ALICE` for creating `DJANGO` so we create yet another
|
||||
/// account `CHARLIE` and create `DJANGO` with it.
|
||||
Balances::deposit_creating(&CHARLIE, 1_000_000);
|
||||
assert_ok!(Contract::create(
|
||||
Origin::signed(CHARLIE),
|
||||
30_000,
|
||||
100_000, HASH_RESTORATION.into(),
|
||||
100_000,
|
||||
HASH_RESTORATION.into(),
|
||||
<Test as balances::Trait>::Balance::from(0u32).encode()
|
||||
));
|
||||
|
||||
// Before performing a call to `DJANGO` save its original trie id.
|
||||
let django_trie_id = ContractInfoOf::<Test>::get(DJANGO).unwrap()
|
||||
.get_alive().unwrap().trie_id;
|
||||
|
||||
if !test_restore_to_with_dirty_storage {
|
||||
// Advance 1 blocks
|
||||
// Advance 1 block, to the 6th.
|
||||
System::initialize(&6, &[0u8; 32].into(), &[0u8; 32].into(), &Default::default());
|
||||
}
|
||||
|
||||
// Perform a call to `DJANGO`. This should either perform restoration successfully or
|
||||
// fail depending on the test parameters.
|
||||
assert_ok!(Contract::call(
|
||||
Origin::signed(ALICE),
|
||||
DJANGO, 0, 100_000,
|
||||
DJANGO,
|
||||
0,
|
||||
100_000,
|
||||
vec![],
|
||||
));
|
||||
|
||||
if test_different_storage || test_restore_to_with_dirty_storage {
|
||||
// Parametrization of the test imply restoration failure. Check that `DJANGO` aka
|
||||
// restoration contract is still in place and also that `BOB` doesn't exist.
|
||||
assert!(ContractInfoOf::<Test>::get(BOB).unwrap().get_tombstone().is_some());
|
||||
let django_contract = ContractInfoOf::<Test>::get(DJANGO).unwrap()
|
||||
.get_alive().unwrap();
|
||||
@@ -1209,6 +1244,8 @@ fn restoration(test_different_storage: bool, test_restore_to_with_dirty_storage:
|
||||
assert_eq!(django_contract.trie_id, django_trie_id);
|
||||
assert_eq!(django_contract.deduct_block, System::block_number());
|
||||
} else {
|
||||
// Here we expect that the restoration is succeeded. Check that the restoration
|
||||
// contract `DJANGO` ceased to exist and that `BOB` returned back.
|
||||
let bob_contract = ContractInfoOf::<Test>::get(BOB).unwrap()
|
||||
.get_alive().unwrap();
|
||||
assert_eq!(bob_contract.rent_allowance, 50);
|
||||
|
||||
Reference in New Issue
Block a user