diff --git a/package/version b/package/version index 7906299..7e72641 100644 --- a/package/version +++ b/package/version @@ -1 +1 @@ -0.1.21 +0.1.22 diff --git a/pyproject.toml b/pyproject.toml index 998bcb2..456af4c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api" [tool.poetry] name = "ksoroban" -version = "0.1.21" +version = "0.1.22" description = "K tooling for the Soroban platform" authors = [ "Runtime Verification, Inc. ", diff --git a/src/ksoroban/kdist/soroban-semantics/cheatcodes.md b/src/ksoroban/kdist/soroban-semantics/cheatcodes.md index 9e80ee1..7a23d1d 100644 --- a/src/ksoroban/kdist/soroban-semantics/cheatcodes.md +++ b/src/ksoroban/kdist/soroban-semantics/cheatcodes.md @@ -3,15 +3,25 @@ ```k requires "host/hostfuns.md" +requires "kasmer.md" module CHEATCODES imports HOSTFUNS + imports KASMER-SYNTAX-COMMON // TODO: Add a check to ensure these host functions are only called from a Kasmer test contract. - // extern "C" { - // fn kasmer_set_ledger_sequence(x : u64); - // } +``` + +## kasmer_set_ledger_sequence + +```rust + extern "C" { + fn kasmer_set_ledger_sequence(x : u64); + } +``` + +```k rule [kasmer-set-ledger-sequence]: hostCall ( "env" , "kasmer_set_ledger_sequence" , [ i64 .ValTypes ] -> [ .ValTypes ] ) => toSmall(Void) @@ -22,6 +32,49 @@ module CHEATCODES _ => getMajor(HostVal(NEW_SEQ_NUM)) requires getTag(HostVal(NEW_SEQ_NUM)) ==Int getTag(U32(0)) // check `NEW_SEQ_NUM` is a U32 +``` + +## kasmer_create_contract + +```rust +extern "C" { + fn kasmer_create_contract(addr_val: u64, hash_val: u64) -> u64; +} + +fn create_contract(env: &Env, addr: &Bytes, hash: &Bytes) -> Address { + unsafe { + let res = kasmer_create_contract(addr.as_val().get_payload(), hash.as_val().get_payload()); + Address::from_val(env, &Val::from_payload(res)) + } +} +``` + +```k + rule [kasmer-create-contract]: + hostCall ( "env" , "kasmer_create_contract" , [ i64 i64 .ValTypes ] -> [ i64 .ValTypes ] ) + => loadObject(HostVal(HASH)) + ~> loadObject(HostVal(ADDR)) + ~> kasmerCreateContract + ... + + + 0 |-> < i64 > ADDR // ScBytes HostVal + 1 |-> < i64 > HASH // ScBytes HostVal + + + syntax InternalInstr ::= "kasmerCreateContract" [symbol(kasmerCreateContract)] + // -------------------------------------------------------------------------------- + rule [kasmerCreateContract]: + kasmerCreateContract + => #waitCommands + ~> allocObject(ScAddress(Contract(ADDR))) + ~> returnHostVal + ... + + (.K => deployContract(CONTRACT, Contract(ADDR), HASH)) ... + ScBytes(ADDR) : ScBytes(HASH) : S => S + CONTRACT + endmodule ``` \ No newline at end of file diff --git a/src/ksoroban/kdist/soroban-semantics/configuration.md b/src/ksoroban/kdist/soroban-semantics/configuration.md index cac07a7..0748778 100644 --- a/src/ksoroban/kdist/soroban-semantics/configuration.md +++ b/src/ksoroban/kdist/soroban-semantics/configuration.md @@ -15,7 +15,7 @@ module CONFIG Contract(.Bytes) - Account(.Bytes) + Account(.Bytes):Address .WasmString .List diff --git a/src/ksoroban/kdist/soroban-semantics/data.md b/src/ksoroban/kdist/soroban-semantics/data.md index db87512..1fc742b 100644 --- a/src/ksoroban/kdist/soroban-semantics/data.md +++ b/src/ksoroban/kdist/soroban-semantics/data.md @@ -53,7 +53,7 @@ various contexts: syntax ScVal ::= SCBool(Bool) [symbol(SCVal:Bool)] | "Void" [symbol(SCVal:Void)] - | Error(ErrorType, Int) [symbol(SCVal:Error)] + | Error(ErrorType, Int) [symbol(SCVal:Error)] | U32(Int) [symbol(SCVal:U32)] | I32(Int) [symbol(SCVal:I32)] | U64(Int) [symbol(SCVal:U64)] @@ -63,6 +63,7 @@ various contexts: | ScMap(Map) [symbol(SCVal:Map)] // Map | ScAddress(Address) [symbol(SCVal:Address)] | Symbol(String) [symbol(SCVal:Symbol)] + | ScBytes(Bytes) [symbol(SCVal:Bytes)] syntax Address ::= AccountId | ContractId syntax AccountId ::= Account(Bytes) [symbol(AccountId)] @@ -158,7 +159,7 @@ module HOST-OBJECT rule getTag(ScAddress(_)) => 77 rule getTag(Symbol(BS)) => 14 requires lengthString(BS) <=Int 9 rule getTag(Symbol(BS)) => 74 requires lengthString(BS) >Int 9 - + rule getTag(ScBytes(_)) => 72 // 64-bit integers that fit in 56 bits syntax Int ::= "#maxU64small" [macro] diff --git a/src/ksoroban/kdist/soroban-semantics/host/address.md b/src/ksoroban/kdist/soroban-semantics/host/address.md new file mode 100644 index 0000000..cff577e --- /dev/null +++ b/src/ksoroban/kdist/soroban-semantics/host/address.md @@ -0,0 +1,32 @@ +# ADDRESS + +```k +requires "../configuration.md" +requires "../switch.md" +requires "../wasm-ops.md" +requires "integer.md" + +module HOST-ADDRESS + imports CONFIG-OPERATIONS + imports WASM-OPERATIONS + imports HOST-INTEGER + imports SWITCH-SYNTAX + +``` + +## require_auth + +```k + // TODO This is just a placeholder, as the auth system is out of scope for now. + // This function needs to be properly implemented to handle the authorization. + rule [hostfun-require-auth]: + hostCall ( "a" , "0" , [ i64 .ValTypes ] -> [ i64 .ValTypes ] ) + => toSmall(Void) + ... + + + 0 |-> < i64 > _ // Address + + +endmodule +``` \ No newline at end of file diff --git a/src/ksoroban/kdist/soroban-semantics/host/buffer.md b/src/ksoroban/kdist/soroban-semantics/host/buffer.md new file mode 100644 index 0000000..f797750 --- /dev/null +++ b/src/ksoroban/kdist/soroban-semantics/host/buffer.md @@ -0,0 +1,69 @@ +# Buffer + +```k +requires "../configuration.md" +requires "../switch.md" +requires "../wasm-ops.md" +requires "integer.md" + +module HOST-BUFFER + imports CONFIG-OPERATIONS + imports WASM-OPERATIONS + imports HOST-INTEGER + imports SWITCH-SYNTAX + +``` + +## bytes_new_from_linear_memory + +```k + rule [hostfun-bytes-new-from-linear-memory]: + hostCall ( "b" , "3" , [ i64 i64 .ValTypes ] -> [ i64 .ValTypes ] ) + => #memLoad(getMajor(HostVal(LM_POS)), getMajor(HostVal(LEN))) + ~> bytesNewFromLinearMemory + ... + + + 0 |-> < i64 > LM_POS // U32 + 1 |-> < i64 > LEN // U32 + + requires fromSmallValid(HostVal(LM_POS)) + andBool fromSmallValid(HostVal(LEN)) + + syntax InternalInstr ::= "bytesNewFromLinearMemory" [symbol(bytesNewFromLinearMemory)] + // --------------------------------------------------------------------------------- + rule [bytesNewFromLinearMemory]: + bytesNewFromLinearMemory + => allocObject(ScBytes(BS)) + ~> returnHostVal + ... + + BS:Bytes : S => S + +``` + +## bytes_len + +```k + + rule [hostfun-bytes-len]: + hostCall ( "b" , "8" , [ i64 .ValTypes ] -> [ i64 .ValTypes ] ) + => loadObject(HostVal(BYTES)) + ~> bytesLen + ... + + + 0 |-> < i64 > BYTES // Bytes HostVal + + + syntax InternalInstr ::= "bytesLen" [symbol(bytesLen)] + // --------------------------------------------------------------------------------- + rule [bytesLen]: + bytesLen + => toSmall(U32(lengthBytes(BS))) + ... + + ScBytes(BS) : S => S + +endmodule +``` \ No newline at end of file diff --git a/src/ksoroban/kdist/soroban-semantics/host/call.md b/src/ksoroban/kdist/soroban-semantics/host/call.md new file mode 100644 index 0000000..57ff194 --- /dev/null +++ b/src/ksoroban/kdist/soroban-semantics/host/call.md @@ -0,0 +1,64 @@ +# Call + +```k +requires "../configuration.md" +requires "../switch.md" +requires "../soroban.md" +requires "integer.md" + +module HOST-CALL + imports CONFIG-OPERATIONS + imports SOROBAN-SYNTAX + imports HOST-INTEGER + imports SWITCH-SYNTAX + +``` + +## call + +```k + // TODO Check reentry + rule [hostfun-require-auth]: + hostCall ( "d" , "_" , [ i64 i64 i64 .ValTypes ] -> [ i64 .ValTypes ] ) + => loadObject(HostVal(ARGS)) + ~> loadObject(HostVal(FUNC)) + ~> loadObject(HostVal(ADDR)) + ~> call + ... + + + 0 |-> < i64 > ADDR // Address + 1 |-> < i64 > FUNC // Symbol + 2 |-> < i64 > ARGS // Vec + + + syntax InternalInstr ::= "call" [symbol(call)] + // ------------------------------------------ + rule [call]: + call + => #waitCommands + ~> returnCallResult + ... + + ScAddress(TO) : Symbol(FUNC) : ScVec(ARGS) : S => S + FROM + (.K => callContract(FROM, TO, FUNC, ARGS)) ... + + + syntax InternalInstr ::= "returnCallResult" [symbol(returnCallResult)] + // ------------------------------------------------------------------------ + rule [returnCallResult-error]: + returnCallResult => trap ... + Error(_,_) : _ + + rule [returnCallResult]: + returnCallResult + => allocObject(RES) + ~> returnHostVal + ... + + RES:ScVal : S => S + [owise] + +endmodule +``` \ No newline at end of file diff --git a/src/ksoroban/kdist/soroban-semantics/host/context.md b/src/ksoroban/kdist/soroban-semantics/host/context.md index e417fea..8790500 100644 --- a/src/ksoroban/kdist/soroban-semantics/host/context.md +++ b/src/ksoroban/kdist/soroban-semantics/host/context.md @@ -48,5 +48,19 @@ Return the current ledger sequence number as `U32`. andBool getTag(HostVal(ERR)) ==Int 3 andBool Int2ErrorType(getMinor(HostVal(ERR))) =/=K ErrContract +``` + +## get_current_contract_address + +```k + rule [hostfun-get-current-contract-address]: + hostCall ( "x" , "7" , [ .ValTypes ] -> [ i64 .ValTypes ] ) + => allocObject(ScAddress(CONTRACT)) + ~> returnHostVal + ... + + .Map + CONTRACT + endmodule ``` \ No newline at end of file diff --git a/src/ksoroban/kdist/soroban-semantics/host/hostfuns.md b/src/ksoroban/kdist/soroban-semantics/host/hostfuns.md index 5702f25..0aaacbc 100644 --- a/src/ksoroban/kdist/soroban-semantics/host/hostfuns.md +++ b/src/ksoroban/kdist/soroban-semantics/host/hostfuns.md @@ -1,5 +1,8 @@ ```k +requires "address.md" +requires "buffer.md" +requires "call.md" requires "context.md" requires "integer.md" requires "ledger.md" @@ -8,6 +11,9 @@ requires "symbol.md" requires "vector.md" module HOSTFUNS + imports HOST-ADDRESS + imports HOST-BUFFER + imports HOST-CALL imports HOST-CONTEXT imports HOST-INTEGER imports HOST-LEDGER diff --git a/src/ksoroban/kdist/soroban-semantics/soroban.md b/src/ksoroban/kdist/soroban-semantics/soroban.md index 100275e..731252f 100644 --- a/src/ksoroban/kdist/soroban-semantics/soroban.md +++ b/src/ksoroban/kdist/soroban-semantics/soroban.md @@ -6,6 +6,10 @@ requires "switch.md" requires "host/hostfuns.md" module SOROBAN-SYNTAX + imports HOST-OBJECT-SYNTAX + + syntax InternalCmd ::= callContract ( Address, ContractId, String, List ) [symbol(callContractString), function, total] + endmodule @@ -20,8 +24,7 @@ module SOROBAN ```k - syntax InternalCmd ::= callContract ( Address, ContractId, String, List ) [symbol(callContractString), function, total] - | callContract ( Address, ContractId, WasmString, List ) [symbol(callContractWasmString)] + syntax InternalCmd ::= callContract ( Address, ContractId, WasmString, List ) [symbol(callContractWasmString)] | callContractAux ( Address, ContractId, WasmString, List ) [symbol(callContractAux)] // ------------------------------------------------------------------------------------- rule callContract(FROM, TO, FUNCNAME:String, ARGS) diff --git a/src/tests/integration/data/bytes.wast b/src/tests/integration/data/bytes.wast new file mode 100644 index 0000000..700c9d2 --- /dev/null +++ b/src/tests/integration/data/bytes.wast @@ -0,0 +1,202 @@ + +setExitCode(1) + +uploadWasm( b"test-wasm", +;; #![no_std] +;; use soroban_sdk::{contract, contractimpl, Env, Bytes}; +;; +;; #[contract] +;; pub struct IncrementContract; +;; +;; #[contractimpl] +;; impl IncrementContract { +;; pub fn get_len(_env: Env, bs: Bytes) -> u32 { +;; bs.len() +;; } +;; +;; pub fn encode_u64(env: Env, x: u64) -> Bytes { +;; Bytes::from_array(&env, &x.to_be_bytes()) +;; } +;; } +(module $soroban_increment_contract.wasm + (type (;0;) (func (param i64) (result i64))) + (type (;1;) (func (param i64 i64) (result i64))) + (type (;2;) (func)) + (import "b" "8" (func $_ZN17soroban_env_guest5guest3buf9bytes_len17h05a915be159e6975E (type 0))) + (import "i" "0" (func $_ZN17soroban_env_guest5guest3int10obj_to_u6417hb6825d7c3a487396E (type 0))) + (import "b" "3" (func $_ZN17soroban_env_guest5guest3buf28bytes_new_from_linear_memory17hd0615159a54bda25E (type 1))) + (func $get_len (type 0) (param i64) (result i64) + block ;; label = @1 + local.get 0 + i64.const 255 + i64.and + i64.const 72 + i64.eq + br_if 0 (;@1;) + unreachable + unreachable + end + local.get 0 + call $_ZN17soroban_env_guest5guest3buf9bytes_len17h05a915be159e6975E + i64.const -4294967296 + i64.and + i64.const 4 + i64.or) + (func $encode_u64 (type 0) (param i64) (result i64) + (local i32 i32) + global.get $__stack_pointer + i32.const 16 + i32.sub + local.tee 1 + global.set $__stack_pointer + block ;; label = @1 + block ;; label = @2 + local.get 0 + i32.wrap_i64 + i32.const 255 + i32.and + local.tee 2 + i32.const 64 + i32.eq + br_if 0 (;@2;) + block ;; label = @3 + local.get 2 + i32.const 6 + i32.ne + br_if 0 (;@3;) + local.get 0 + i64.const 8 + i64.shr_u + local.set 0 + br 2 (;@1;) + end + unreachable + unreachable + end + local.get 0 + call $_ZN17soroban_env_guest5guest3int10obj_to_u6417hb6825d7c3a487396E + local.set 0 + end + local.get 1 + local.get 0 + i64.const 56 + i64.shl + local.get 0 + i64.const 65280 + i64.and + i64.const 40 + i64.shl + i64.or + local.get 0 + i64.const 16711680 + i64.and + i64.const 24 + i64.shl + local.get 0 + i64.const 4278190080 + i64.and + i64.const 8 + i64.shl + i64.or + i64.or + local.get 0 + i64.const 8 + i64.shr_u + i64.const 4278190080 + i64.and + local.get 0 + i64.const 24 + i64.shr_u + i64.const 16711680 + i64.and + i64.or + local.get 0 + i64.const 40 + i64.shr_u + i64.const 65280 + i64.and + local.get 0 + i64.const 56 + i64.shr_u + i64.or + i64.or + i64.or + i64.store offset=8 + local.get 1 + i32.const 8 + i32.add + i64.extend_i32_u + i64.const 32 + i64.shl + i64.const 4 + i64.or + i64.const 34359738372 + call $_ZN17soroban_env_guest5guest3buf28bytes_new_from_linear_memory17hd0615159a54bda25E + local.set 0 + local.get 1 + i32.const 16 + i32.add + global.set $__stack_pointer + local.get 0) + (func $_ (type 2)) + (memory (;0;) 16) + (global $__stack_pointer (mut i32) (i32.const 1048576)) + (global (;1;) i32 (i32.const 1048576)) + (global (;2;) i32 (i32.const 1048576)) + (export "memory" (memory 0)) + (export "get_len" (func $get_len)) + (export "encode_u64" (func $encode_u64)) + (export "_" (func $_)) + (export "__data_end" (global 1)) + (export "__heap_base" (global 2))) +) + +setAccount(Account(b"test-account"), 9876543210) + +deployContract( + Account(b"test-account"), + Contract(b"test-sc"), + b"test-wasm" +) + +callTx( + Account(b"test-caller"), + Contract(b"test-sc"), + "get_len", + ListItem(ScBytes(b"1234")), + U32(4) +) + +callTx( + Account(b"test-caller"), + Contract(b"test-sc"), + "get_len", + ListItem(ScBytes(b"")), + U32(0) +) + +callTx( + Account(b"test-caller"), + Contract(b"test-sc"), + "encode_u64", + ListItem(U64(0)), + ScBytes(b"\x00\x00\x00\x00\x00\x00\x00\x00") +) + +callTx( + Account(b"test-caller"), + Contract(b"test-sc"), + "encode_u64", + ListItem(U64(123)), + ScBytes(b"\x00\x00\x00\x00\x00\x00\x00\x7b") +) + +callTx( + Account(b"test-caller"), + Contract(b"test-sc"), + "encode_u64", + ListItem(U64(12379813812177893520)), + ScBytes(b"\xab\xcd\xef\x12\x34\x56\x78\x90") +) + +setExitCode(0) \ No newline at end of file diff --git a/src/tests/integration/data/call_add.wast b/src/tests/integration/data/call_add.wast new file mode 100644 index 0000000..2b3d438 --- /dev/null +++ b/src/tests/integration/data/call_add.wast @@ -0,0 +1,343 @@ + +setExitCode(1) + +uploadWasm( b"test-wasm", +;; #![no_std] +;; use soroban_sdk::{contract, contractimpl, Address, Env}; +;; +;; #[contract] +;; pub struct IncrementContract; +;; +;; #[contractimpl] +;; impl IncrementContract { +;; pub fn add(_env: Env, x: u32, y: u32) -> u32 { +;; x + y +;; } +;; pub fn call_other(env: Env, addr: Address, x: u32, y: u32) -> u32 { +;; let client = IncrementContractClient::new(&env, &addr); +;; client.add(&x, &y) +;; } +;; } +(module $soroban_increment_contract.wasm + (type (;0;) (func (param i64 i64) (result i64))) + (type (;1;) (func (param i64 i64 i64) (result i64))) + (type (;2;) (func)) + (type (;3;) (func (param i32))) + (import "b" "j" (func $_ZN17soroban_env_guest5guest3buf29symbol_new_from_linear_memory17h35ac7f14f9817888E (type 0))) + (import "v" "g" (func $_ZN17soroban_env_guest5guest3vec26vec_new_from_linear_memory17h70c58232833beea9E (type 0))) + (import "d" "_" (func $_ZN17soroban_env_guest5guest4call4call17hb799ec77dfde2c11E (type 1))) + (func $add (type 0) (param i64 i64) (result i64) + (local i32 i32) + block ;; label = @1 + block ;; label = @2 + local.get 0 + i64.const 255 + i64.and + i64.const 4 + i64.ne + br_if 0 (;@2;) + local.get 1 + i64.const 255 + i64.and + i64.const 4 + i64.ne + br_if 0 (;@2;) + local.get 0 + i64.const 32 + i64.shr_u + i32.wrap_i64 + local.tee 2 + local.get 1 + i64.const 32 + i64.shr_u + i32.wrap_i64 + i32.add + local.tee 3 + local.get 2 + i32.lt_u + br_if 1 (;@1;) + local.get 3 + i64.extend_i32_u + i64.const 32 + i64.shl + i64.const 4 + i64.or + return + end + unreachable + unreachable + end + call $_ZN4core9panicking11panic_const24panic_const_add_overflow17hde776086e9d58b0fE + unreachable) + (func $_ZN4core9panicking11panic_const24panic_const_add_overflow17hde776086e9d58b0fE (type 2) + call $_ZN4core9panicking9panic_fmt17h5c7ce52813e94bcdE + unreachable) + (func $call_other (type 1) (param i64 i64 i64) (result i64) + (local i32 i64 i32 i32 i32) + global.get $__stack_pointer + i32.const 32 + i32.sub + local.tee 3 + global.set $__stack_pointer + block ;; label = @1 + local.get 0 + i64.const 255 + i64.and + i64.const 77 + i64.ne + br_if 0 (;@1;) + local.get 1 + i64.const 255 + i64.and + i64.const 4 + i64.ne + br_if 0 (;@1;) + local.get 2 + i64.const 255 + i64.and + i64.const 4 + i64.ne + br_if 0 (;@1;) + i64.const 0 + local.set 4 + i32.const -3 + local.set 5 + block ;; label = @2 + block ;; label = @3 + block ;; label = @4 + loop ;; label = @5 + local.get 5 + i32.eqz + br_if 1 (;@4;) + i32.const 1 + local.set 6 + block ;; label = @6 + local.get 5 + i32.const 1048579 + i32.add + i32.load8_u + local.tee 7 + i32.const 95 + i32.eq + br_if 0 (;@6;) + block ;; label = @7 + local.get 7 + i32.const -48 + i32.add + i32.const 255 + i32.and + i32.const 10 + i32.lt_u + br_if 0 (;@7;) + block ;; label = @8 + local.get 7 + i32.const -65 + i32.add + i32.const 255 + i32.and + i32.const 26 + i32.lt_u + br_if 0 (;@8;) + local.get 7 + i32.const -97 + i32.add + i32.const 255 + i32.and + i32.const 25 + i32.gt_u + br_if 5 (;@3;) + local.get 7 + i32.const -59 + i32.add + local.set 6 + br 2 (;@6;) + end + local.get 7 + i32.const -53 + i32.add + local.set 6 + br 1 (;@6;) + end + local.get 7 + i32.const -46 + i32.add + local.set 6 + end + local.get 4 + i64.const 6 + i64.shl + local.get 6 + i64.extend_i32_u + i64.const 255 + i64.and + i64.or + local.set 4 + local.get 5 + i32.const 1 + i32.add + local.set 5 + br 0 (;@5;) + end + end + local.get 4 + i64.const 8 + i64.shl + i64.const 14 + i64.or + local.set 4 + br 1 (;@2;) + end + i32.const 1048576 + i64.extend_i32_u + i64.const 32 + i64.shl + i64.const 4 + i64.or + i64.const 12884901892 + call $_ZN17soroban_env_guest5guest3buf29symbol_new_from_linear_memory17h35ac7f14f9817888E + local.set 4 + end + local.get 3 + local.get 2 + i64.const -4294967292 + i64.and + i64.store offset=8 + local.get 3 + local.get 1 + i64.const -4294967292 + i64.and + i64.store + i32.const 0 + local.set 5 + block ;; label = @2 + loop ;; label = @3 + block ;; label = @4 + local.get 5 + i32.const 16 + i32.ne + br_if 0 (;@4;) + i32.const 0 + local.set 5 + block ;; label = @5 + loop ;; label = @6 + local.get 5 + i32.const 16 + i32.eq + br_if 1 (;@5;) + local.get 3 + i32.const 16 + i32.add + local.get 5 + i32.add + local.get 3 + local.get 5 + i32.add + i64.load + i64.store + local.get 5 + i32.const 8 + i32.add + local.set 5 + br 0 (;@6;) + end + end + local.get 0 + local.get 4 + local.get 3 + i32.const 16 + i32.add + i64.extend_i32_u + i64.const 32 + i64.shl + i64.const 4 + i64.or + i64.const 8589934596 + call $_ZN17soroban_env_guest5guest3vec26vec_new_from_linear_memory17h70c58232833beea9E + call $_ZN17soroban_env_guest5guest4call4call17hb799ec77dfde2c11E + local.tee 4 + i64.const 255 + i64.and + i64.const 4 + i64.ne + br_if 2 (;@2;) + local.get 3 + i32.const 32 + i32.add + global.set $__stack_pointer + local.get 4 + i64.const -4294967292 + i64.and + return + end + local.get 3 + i32.const 16 + i32.add + local.get 5 + i32.add + i64.const 2 + i64.store + local.get 5 + i32.const 8 + i32.add + local.set 5 + br 0 (;@3;) + end + end + local.get 3 + i32.const 16 + i32.add + call $_ZN4core6result13unwrap_failed17h4ed86702351a3017E + unreachable + end + unreachable + unreachable) + (func $_ZN4core6result13unwrap_failed17h4ed86702351a3017E (type 3) (param i32) + call $_ZN4core9panicking9panic_fmt17h5c7ce52813e94bcdE + unreachable) + (func $_ZN4core9panicking9panic_fmt17h5c7ce52813e94bcdE (type 2) + unreachable + unreachable) + (func $_ (type 2)) + (memory (;0;) 17) + (global $__stack_pointer (mut i32) (i32.const 1048576)) + (global (;1;) i32 (i32.const 1048579)) + (global (;2;) i32 (i32.const 1048592)) + (export "memory" (memory 0)) + (export "add" (func $add)) + (export "call_other" (func $call_other)) + (export "_" (func $_)) + (export "__data_end" (global 1)) + (export "__heap_base" (global 2)) + (data $.rodata (i32.const 1048576) "add")) +) + +setAccount(Account(b"test-account"), 9876543210) + +;; let c1 = env.register_contract(None, IncrementContract); +;; let c2 = env.register_contract(None, IncrementContract); + +deployContract( + Account(b"test-account"), + Contract(b"test-sc-1"), + b"test-wasm" +) + +deployContract( + Account(b"test-account"), + Contract(b"test-sc-2"), + b"test-wasm" +) + +;; let client = IncrementContractClient::new(&env, &c1); +;; assert_eq!(client.call_other(&c2, &3, &5), 8); + +callTx( + Account(b"test-caller"), + Contract(b"test-sc-1"), + "call_other", + ListItem(ScAddress(Contract(b"test-sc-2"))) ListItem(U32(3)) ListItem(U32(5)), + U32(8) +) + + +setExitCode(0) \ No newline at end of file diff --git a/src/tests/integration/data/cheat_create_contract.wast b/src/tests/integration/data/cheat_create_contract.wast new file mode 100644 index 0000000..ddfa3e9 --- /dev/null +++ b/src/tests/integration/data/cheat_create_contract.wast @@ -0,0 +1,88 @@ + +setExitCode(1) + +uploadWasm( b"test-wasm", +;; #![no_std] +;; use soroban_sdk::{contract, contractimpl, Address, Bytes, Env, FromVal, Val}; +;; +;; extern "C" { +;; fn kasmer_create_contract(addr_val: u64, hash_val: u64) -> u64; +;; } +;; +;; fn create_contract(env: &Env, addr: &Bytes, hash: &Bytes) -> Address { +;; unsafe { +;; let res = kasmer_create_contract(addr.as_val().get_payload(), hash.as_val().get_payload()); +;; Address::from_val(env, &Val::from_payload(res)) +;; } +;; } +;; +;; #[contract] +;; pub struct IncrementContract; +;; +;; #[contractimpl] +;; impl IncrementContract { +;; pub fn create_contract(env: Env, addr: Bytes, hash: Bytes) -> Address { +;; create_contract(&env, &addr, &hash) +;; } +;; } +(module $soroban_increment_contract.wasm + (type (;0;) (func (param i64 i64) (result i64))) + (type (;1;) (func)) + (import "env" "kasmer_create_contract" (func $kasmer_create_contract (type 0))) + (func $create_contract (type 0) (param i64 i64) (result i64) + block ;; label = @1 + local.get 0 + i64.const 255 + i64.and + i64.const 72 + i64.ne + br_if 0 (;@1;) + local.get 1 + i64.const 255 + i64.and + i64.const 72 + i64.ne + br_if 0 (;@1;) + local.get 0 + local.get 1 + call $kasmer_create_contract + local.tee 0 + i64.const 255 + i64.and + i64.const 77 + i64.ne + br_if 0 (;@1;) + local.get 0 + return + end + unreachable + unreachable) + (func $_ (type 1)) + (memory (;0;) 16) + (global $__stack_pointer (mut i32) (i32.const 1048576)) + (global (;1;) i32 (i32.const 1048576)) + (global (;2;) i32 (i32.const 1048576)) + (export "memory" (memory 0)) + (export "create_contract" (func $create_contract)) + (export "_" (func $_)) + (export "__data_end" (global 1)) + (export "__heap_base" (global 2))) +) + +setAccount(Account(b"test-account"), 9876543210) + +deployContract( + Account(b"test-account"), + Contract(b"test-ctr"), + b"test-wasm" +) + +callTx( + Account(b"test-caller"), + Contract(b"test-ctr"), + "create_contract", + ListItem(ScBytes(b"child-ctr")) ListItem(ScBytes(b"test-wasm")), + ScAddress(Contract(b"child-ctr")) +) + +setExitCode(0) \ No newline at end of file diff --git a/src/tests/integration/data/get_contract_address.wast b/src/tests/integration/data/get_contract_address.wast new file mode 100644 index 0000000..c834eb6 --- /dev/null +++ b/src/tests/integration/data/get_contract_address.wast @@ -0,0 +1,51 @@ + +setExitCode(1) + +uploadWasm( b"test-wasm", +;; #![no_std] +;; use soroban_sdk::{contract, contractimpl, Address, Env}; +;; +;; #[contract] +;; pub struct IncrementContract; +;; +;; #[contractimpl] +;; impl IncrementContract { +;; pub fn get_address(env: Env) -> Address { +;; env.current_contract_address() +;; } +;; } +(module $soroban_increment_contract.wasm + (type (;0;) (func (result i64))) + (type (;1;) (func)) + (import "x" "7" (func $_ZN17soroban_env_guest5guest7context28get_current_contract_address17hd0d5b3707078d502E (type 0))) + (func $get_address (type 0) (result i64) + call $_ZN17soroban_env_guest5guest7context28get_current_contract_address17hd0d5b3707078d502E) + (func $_ (type 1)) + (memory (;0;) 16) + (global $__stack_pointer (mut i32) (i32.const 1048576)) + (global (;1;) i32 (i32.const 1048576)) + (global (;2;) i32 (i32.const 1048576)) + (export "memory" (memory 0)) + (export "get_address" (func $get_address)) + (export "_" (func $_)) + (export "__data_end" (global 1)) + (export "__heap_base" (global 2))) +) + +setAccount(Account(b"test-account"), 9876543210) + +deployContract( + Account(b"test-account"), + Contract(b"test-sc"), + b"test-wasm" +) + +callTx( + Account(b"test-caller"), + Contract(b"test-sc"), + "get_address", + .List, + ScAddress(Contract(b"test-sc")) +) + +setExitCode(0) \ No newline at end of file diff --git a/src/tests/integration/data/require_auth.wast b/src/tests/integration/data/require_auth.wast new file mode 100644 index 0000000..b34958f --- /dev/null +++ b/src/tests/integration/data/require_auth.wast @@ -0,0 +1,57 @@ + +setExitCode(1) + +uploadWasm( b"test-wasm", +;; #![no_std] +;; use soroban_sdk::{contract, contractimpl, Env}; +;; +;; #[contract] +;; pub struct IncrementContract; +;; +;; #[contractimpl] +;; impl IncrementContract { +;; pub fn require_auth(env: Env) { +;; let a = env.current_contract_address(); +;; a.require_auth(); +;; } +;; } +(module $soroban_increment_contract.wasm + (type (;0;) (func (result i64))) + (type (;1;) (func (param i64) (result i64))) + (type (;2;) (func)) + (import "x" "7" (func $_ZN17soroban_env_guest5guest7context28get_current_contract_address17hd0d5b3707078d502E (type 0))) + (import "a" "0" (func $_ZN17soroban_env_guest5guest7address12require_auth17hd692125619c6dd23E (type 1))) + (func $require_auth (type 0) (result i64) + call $_ZN17soroban_env_guest5guest7context28get_current_contract_address17hd0d5b3707078d502E + call $_ZN17soroban_env_guest5guest7address12require_auth17hd692125619c6dd23E + drop + i64.const 2) + (func $_ (type 2)) + (memory (;0;) 16) + (global $__stack_pointer (mut i32) (i32.const 1048576)) + (global (;1;) i32 (i32.const 1048576)) + (global (;2;) i32 (i32.const 1048576)) + (export "memory" (memory 0)) + (export "require_auth" (func $require_auth)) + (export "_" (func $_)) + (export "__data_end" (global 1)) + (export "__heap_base" (global 2))) +) + +setAccount(Account(b"test-account"), 9876543210) + +deployContract( + Account(b"test-account"), + Contract(b"test-sc"), + b"test-wasm" +) + +callTx( + Account(b"test-caller"), + Contract(b"test-sc"), + "require_auth", + .List, + Void +) + +setExitCode(0) \ No newline at end of file