Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.

Commit a22647e

Browse files
committed
Make Trait::Balance: Slicable
1 parent 4d7ceca commit a22647e

File tree

2 files changed

+91
-79
lines changed

2 files changed

+91
-79
lines changed

substrate/runtime/staking/src/contract.rs

Lines changed: 90 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
// TODO: Extract to it's own crate?
2020

2121
use codec::Slicable;
22-
use primitives::traits::As;
2322
use rstd::prelude::*;
2423
use sandbox;
2524
use {AccountDb, Module, OverlayAccountDb, Trait};
@@ -190,15 +189,19 @@ pub(crate) fn execute<'a, 'b: 'a, T: Trait>(
190189
fn ext_transfer<T: Trait>(e: &mut ExecutionExt<T>, args: &[sandbox::TypedValue]) -> Result<sandbox::ReturnValue, sandbox::HostError> {
191190
let transfer_to_ptr = args[0].as_i32().unwrap() as u32;
192191
let transfer_to_len = args[1].as_i32().unwrap() as u32;
193-
let value = args[2].as_i32().unwrap() as u64;
192+
let value_ptr = args[2].as_i32().unwrap() as u32;
193+
let value_len = args[3].as_i32().unwrap() as u32;
194194

195-
// TODO: slicable
196195
let mut transfer_to = Vec::new();
197196
transfer_to.resize(transfer_to_len as usize, 0);
198197
e.memory().get(transfer_to_ptr, &mut transfer_to)?;
199-
let value = T::Balance::sa(value as usize);
200198
let transfer_to = T::AccountId::decode(&mut &transfer_to[..]).unwrap();
201199

200+
let mut value_buf = Vec::new();
201+
value_buf.resize(value_len as usize, 0);
202+
e.memory().get(value_ptr, &mut value_buf)?;
203+
let value = T::Balance::decode(&mut &value_buf[..]).unwrap();
204+
202205
let account = e.account().clone();
203206
if let Some(commit_state) =
204207
Module::<T>::effect_transfer(&account, &transfer_to, value, e.account_db())
@@ -213,10 +216,13 @@ pub(crate) fn execute<'a, 'b: 'a, T: Trait>(
213216
fn ext_create<T: Trait>(e: &mut ExecutionExt<T>, args: &[sandbox::TypedValue]) -> Result<sandbox::ReturnValue, sandbox::HostError> {
214217
let code_ptr = args[0].as_i32().unwrap() as u32;
215218
let code_len = args[1].as_i32().unwrap() as u32;
216-
let value = args[2].as_i32().unwrap() as u32;
219+
let value_ptr = args[2].as_i32().unwrap() as u32;
220+
let value_len = args[3].as_i32().unwrap() as u32;
217221

218-
// TODO: slicable
219-
let value = T::Balance::sa(value as usize);
222+
let mut value_buf = Vec::new();
223+
value_buf.resize(value_len as usize, 0);
224+
e.memory().get(value_ptr, &mut value_buf)?;
225+
let value = T::Balance::decode(&mut &value_buf[..]).unwrap();
220226

221227
let mut code = Vec::new();
222228
code.resize(code_len as usize, 0u8);
@@ -506,30 +512,35 @@ mod tests {
506512
assert_matches!(r, Err(Error::Memory));
507513
}
508514

509-
#[test]
510-
fn contract_transfer() {
511-
let code_transfer = wabt::wat2wasm(
512-
r#"
515+
const CODE_TRANSFER: &str = r#"
513516
(module
514-
;; ext_transfer(transfer_to: u32, transfer_to_len: u32, value: u32)
515-
(import "env" "ext_transfer" (func $ext_transfer (param i32 i32 i32)))
517+
;; ext_transfer(transfer_to: u32, transfer_to_len: u32, value_ptr: u32, value_len: u32)
518+
(import "env" "ext_transfer" (func $ext_transfer (param i32 i32 i32 i32)))
516519
517520
(import "env" "memory" (memory 1 1))
518521
519522
(func (export "call")
520523
(call $ext_transfer
521524
(i32.const 4) ;; Pointer to "Transfer to" address.
522525
(i32.const 8) ;; Length of "Transfer to" address.
523-
(i32.const 6) ;; value to transfer
526+
(i32.const 12) ;; Pointer to the buffer with value to transfer
527+
(i32.const 8) ;; Length of the buffer with value to transfer.
524528
)
525529
)
526530
527531
;; Destination AccountId to transfer the funds.
528532
;; Represented by u64 (8 bytes long) in little endian.
529533
(data (i32.const 4) "\02\00\00\00\00\00\00\00")
534+
535+
;; Amount of value to transfer.
536+
;; Represented by u64 (8 bytes long) in little endian.
537+
(data (i32.const 12) "\06\00\00\00\00\00\00\00")
530538
)
531-
"#,
532-
).unwrap();
539+
"#;
540+
541+
#[test]
542+
fn contract_transfer() {
543+
let code_transfer = wabt::wat2wasm(CODE_TRANSFER).unwrap();
533544

534545
with_externalities(&mut new_test_ext(1, 3, 1, false), || {
535546
<FreeBalance<Test>>::insert(0, 111);
@@ -546,61 +557,55 @@ mod tests {
546557
});
547558
}
548559

549-
fn escaped_bytestring(bytes: &[u8]) -> String {
550-
use std::fmt::Write;
551-
let mut result = String::new();
552-
for b in bytes {
553-
write!(result, "\\{:02x}", b).unwrap();
560+
/// Returns code that uses `ext_create` runtime call.
561+
///
562+
/// Takes bytecode of the contract that needs to be deployed.
563+
fn code_create(child_bytecode: &[u8]) -> String {
564+
/// Convert a byte slice to a string with hex values.
565+
///
566+
/// Each value is preceeded with a `\` character.
567+
fn escaped_bytestring(bytes: &[u8]) -> String {
568+
use std::fmt::Write;
569+
let mut result = String::new();
570+
for b in bytes {
571+
write!(result, "\\{:02x}", b).unwrap();
572+
}
573+
result
554574
}
555-
result
556-
}
557575

558-
#[test]
559-
fn contract_create() {
560-
let code_transfer = wabt::wat2wasm(
561-
r#"
576+
format!(
577+
r#"
562578
(module
563-
;; ext_transfer(transfer_to: u32, transfer_to_len: u32, value: u32)
564-
(import "env" "ext_transfer" (func $ext_transfer (param i32 i32 i32)))
579+
;; ext_create(code_ptr: u32, code_len: u32, value_ptr: u32, value_len: u32)
580+
(import "env" "ext_create" (func $ext_create (param i32 i32 i32 i32)))
565581
566582
(import "env" "memory" (memory 1 1))
567583
568584
(func (export "call")
569-
(call $ext_transfer
570-
(i32.const 4) ;; Pointer to "Transfer to" address.
571-
(i32.const 8) ;; Length of "Transfer to" address.
572-
(i32.const 6) ;; value to transfer
585+
(call $ext_create
586+
(i32.const 12) ;; Pointer to `code`
587+
(i32.const {code_len}) ;; Length of `code`
588+
(i32.const 4) ;; Pointer to the buffer with value to transfer
589+
(i32.const 8) ;; Length of the buffer with value to transfer
573590
)
574591
)
592+
;; Amount of value to transfer.
593+
;; Represented by u64 (8 bytes long) in little endian.
594+
(data (i32.const 4) "\03\00\00\00\00\00\00\00")
575595
576-
;; Destination AccountId to transfer the funds.
577-
;; Represented by u64 (8 bytes long) in little endian.
578-
(data (i32.const 4) "\02\00\00\00\00\00\00\00")
596+
;; Embedded wasm code.
597+
(data (i32.const 12) "{escaped_bytecode}")
579598
)
580-
"#,
581-
).unwrap();
582-
583-
let code_create = wabt::wat2wasm(format!(
584-
r#"
585-
(module
586-
;; ext_create(code_ptr: u32, code_len: u32, value: u32)
587-
(import "env" "ext_create" (func $ext_create (param i32 i32 i32)))
588-
589-
(import "env" "memory" (memory 1 1))
599+
"#,
600+
escaped_bytecode = escaped_bytestring(&child_bytecode),
601+
code_len = child_bytecode.len(),
602+
)
603+
}
590604

591-
(func (export "call")
592-
(call $ext_create
593-
(i32.const 4) ;; Pointer to `code`
594-
(i32.const {code_length}) ;; Length of `code`
595-
(i32.const 3) ;; Value to transfer
596-
)
597-
)
598-
(data (i32.const 4) "{escaped_code_transfer}")
599-
)
600-
"#,
601-
escaped_code_transfer = escaped_bytestring(&code_transfer),
602-
code_length = code_transfer.len(),
603-
)).unwrap();
605+
#[test]
606+
fn contract_create() {
607+
let code_transfer = wabt::wat2wasm(CODE_TRANSFER).unwrap();
608+
let code_create = wabt::wat2wasm(&code_create(&code_transfer)).unwrap();
604609

605610
with_externalities(&mut new_test_ext(1, 3, 1, false), || {
606611
<FreeBalance<Test>>::insert(0, 111);
@@ -620,9 +625,10 @@ mod tests {
620625
});
621626
}
622627

623-
#[test]
624-
fn contract_adder() {
625-
let code_adder = wabt::wat2wasm(r#"
628+
/// This code a value from the storage, increment it's first byte
629+
/// and then stores it back in the storage.
630+
const CODE_ADDER: &str =
631+
r#"
626632
(module
627633
;; ext_set_storage(location_ptr: i32, value_non_null: bool, value_ptr: i32)
628634
(import "env" "ext_set_storage" (func $ext_set_storage (param i32 i32 i32)))
@@ -652,10 +658,14 @@ mod tests {
652658
)
653659
)
654660
655-
;; Location of storage to put the data. 32 bytes.
661+
;; Location of storage to load/store the data. 32 bytes.
656662
(data (i32.const 4) "\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01")
657663
)
658-
"#).unwrap();
664+
"#;
665+
666+
#[test]
667+
fn contract_adder() {
668+
let code_adder = wabt::wat2wasm(CODE_ADDER).unwrap();
659669

660670
with_externalities(&mut new_test_ext(1, 3, 1, false), || {
661671
<FreeBalance<Test>>::insert(0, 111);
@@ -681,12 +691,10 @@ mod tests {
681691
});
682692
}
683693

684-
#[test]
685-
fn contract_out_of_gas() {
686-
// This code should make 100_000 iterations so it should
687-
// consume more than 100_000 units of gas.
688-
let code_loop = wabt::wat2wasm(
689-
r#"
694+
// This code should make 100_000 iterations so it should
695+
// consume more than 100_000 units of gas.
696+
const CODE_LOOP: &str =
697+
r#"
690698
(module
691699
(func (export "call")
692700
(local $i i32)
@@ -710,8 +718,11 @@ mod tests {
710718
end
711719
)
712720
)
713-
"#,
714-
).unwrap();
721+
"#;
722+
723+
#[test]
724+
fn contract_out_of_gas() {
725+
let code_loop = wabt::wat2wasm(CODE_LOOP).unwrap();
715726

716727
with_externalities(&mut new_test_ext(1, 3, 1, false), || {
717728
// Set initial balances.
@@ -730,10 +741,8 @@ mod tests {
730741
});
731742
}
732743

733-
#[test]
734-
fn contract_internal_mem() {
735-
let code_mem = wabt::wat2wasm(
736-
r#"
744+
const CODE_MEM: &str =
745+
r#"
737746
(module
738747
;; Internal memory is not allowed.
739748
(memory 1 1)
@@ -742,8 +751,11 @@ mod tests {
742751
nop
743752
)
744753
)
745-
"#,
746-
).unwrap();
754+
"#;
755+
756+
#[test]
757+
fn contract_internal_mem() {
758+
let code_mem = wabt::wat2wasm(CODE_MEM).unwrap();
747759

748760
with_externalities(&mut new_test_ext(1, 3, 1, false), || {
749761
// Set initial balances.

substrate/runtime/staking/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ impl<Hashing, AccountId> ContractAddressFor<AccountId> for Hashing where
9292

9393
pub trait Trait: system::Trait + session::Trait {
9494
/// The balance of an account.
95-
type Balance: Parameter + SimpleArithmetic + Default + Copy;
95+
type Balance: Parameter + SimpleArithmetic + Slicable + Default + Copy;
9696
type DetermineContractAddress: ContractAddressFor<Self::AccountId>;
9797
}
9898

0 commit comments

Comments
 (0)