From 326883ec75a57f5813ba7fec6346145f5161dd0d Mon Sep 17 00:00:00 2001 From: ACassimiro Date: Mon, 16 Sep 2024 12:15:49 -0300 Subject: [PATCH] Allow passing args to the contract's init function (#84) (#87) * Allow passing args to the contract's init function * Contract call tests Co-authored-by: Virgil <25692529+virgil-serbanuta@users.noreply.github.com> --- Makefile | 4 ++- .../main/calls/implementation.md | 33 ++++++++++++++---- mx-rust-semantics/main/glue.md | 1 + mx-rust-semantics/main/representation.md | 6 +++- mx-rust-semantics/setup/mx.md | 3 +- .../targets/contract-testing/configuration.md | 1 + parse-mx-rust-contract-args.sh | 8 +++++ rust-semantics/expression.md | 2 -- rust-semantics/expression/calls.md | 2 +- rust-semantics/helpers.md | 1 + rust-semantics/preprocessing.md | 4 ++- .../{expression => preprocessing}/tools.md | 5 ++- rust-semantics/representation.md | 2 ++ rust-semantics/rust-common-syntax.md | 15 +++----- .../call-endpoint-args.1.args | 0 .../call-endpoint-args.1.run | 34 +++++++++++++++++++ tests/mx-rust-contracts/call-endpoint-args.rs | 27 +++++++++++++++ .../contract-setup-args.1.args | 1 + .../contract-setup-args.1.run | 14 ++++++++ .../mx-rust-contracts/contract-setup-args.rs | 24 +++++++++++++ tests/mx-rust-contracts/contract-setup.1.args | 0 tests/mx-rust-contracts/contract-setup.rs | 2 +- 22 files changed, 164 insertions(+), 25 deletions(-) create mode 100755 parse-mx-rust-contract-args.sh rename rust-semantics/{expression => preprocessing}/tools.md (71%) create mode 100644 tests/mx-rust-contracts/call-endpoint-args.1.args create mode 100644 tests/mx-rust-contracts/call-endpoint-args.1.run create mode 100644 tests/mx-rust-contracts/call-endpoint-args.rs create mode 100644 tests/mx-rust-contracts/contract-setup-args.1.args create mode 100644 tests/mx-rust-contracts/contract-setup-args.1.run create mode 100644 tests/mx-rust-contracts/contract-setup-args.rs create mode 100644 tests/mx-rust-contracts/contract-setup.1.args diff --git a/Makefile b/Makefile index 803b7da..47af25d 100644 --- a/Makefile +++ b/Makefile @@ -191,6 +191,8 @@ $(MX_RUST_CONTRACT_TESTING_OUTPUT_DIR)/%.run.executed.kore: \ --output kore \ --output-file $@.tmp \ -cTEST='$(shell cat $<)' \ - -pTEST=$(CURDIR)/parse-mx-rust-contract-test.sh + -pTEST=$(CURDIR)/parse-mx-rust-contract-test.sh \ + -cARGS='$(shell cat $(patsubst %.run,%.args,$<))' \ + -pARGS=$(CURDIR)/parse-mx-rust-contract-args.sh cat $@.tmp | grep -q "Lbl'-LT-'k'-GT-'{}(dotk{}())" mv -f $@.tmp $@ diff --git a/mx-rust-semantics/main/calls/implementation.md b/mx-rust-semantics/main/calls/implementation.md index f3119ce..6e6445d 100644 --- a/mx-rust-semantics/main/calls/implementation.md +++ b/mx-rust-semantics/main/calls/implementation.md @@ -61,7 +61,8 @@ module MX-RUST-CALLS-IMPLEMENTATION host.mkCall(FunctionName:String) => MxRust#newContractObject(TraitName) - ~> MxRust#partialMethodCall(Endpoint, mxArgsToRustArgs(Args)) + ~> mxArgsToRustArgs(Args, Nfp, .CallParamsList) + ~> MxRust#partialMethodCall(Endpoint) ... @@ -72,18 +73,38 @@ module MX-RUST-CALLS-IMPLEMENTATION => (#token("no#path", "Identifier"):Identifier):TypePath Args:MxValueList + TraitName + Endpoint + _:SelfSort : _ , Nfp:NormalizedFunctionParameterList - rule ptrValue(...) #as SelfValue:Expression - ~> MxRust#partialMethodCall(Method:Identifier, Params:CallParamsList) + rule (ptrValue(...) #as SelfValue:Expression) , Params:CallParamsList + ~> MxRust#partialMethodCall(Method:Identifier) => methodCall(... self: SelfValue, method: Method, params: Params) syntax MxRustInstruction ::= "MxRust#newContractObject" "(" TypePath ")" rule MxRust#newContractObject(P:TypePath) => Rust#newStruct(P, .Map) - syntax MxRustInstruction ::= "MxRust#partialMethodCall" "(" Identifier "," CallParamsList ")" + syntax MxRustInstruction ::= "MxRust#partialMethodCall" "(" Identifier ")" - syntax CallParamsList ::= mxArgsToRustArgs(MxValueList) [function, total] - rule mxArgsToRustArgs(.MxValueList) => .CallParamsList + syntax MxRustInstruction ::= mxArgsToRustArgs + ( MxValueList + , NormalizedFunctionParameterList + , CallParamsList + ) + rule mxArgsToRustArgs(.MxValueList, .NormalizedFunctionParameterList, L:CallParamsList) + => reverse(L, .CallParamsList) + rule (.K => mxValueToRust(T, V)) + ~> mxArgsToRustArgs + ( (V:MxValue , L:MxValueList) => L + , _ : T:Type , Nfp:NormalizedFunctionParameterList => Nfp + , _:CallParamsList + ) + rule (V:PtrValue => .K) + ~> mxArgsToRustArgs + ( _:MxValueList + , _:NormalizedFunctionParameterList + , L:CallParamsList => V, L + ) rule (ptrValue(_, V:Value) => rustValueToMx(V)) ~> endCall diff --git a/mx-rust-semantics/main/glue.md b/mx-rust-semantics/main/glue.md index 137b0d0..e699891 100644 --- a/mx-rust-semantics/main/glue.md +++ b/mx-rust-semantics/main/glue.md @@ -49,6 +49,7 @@ module MX-RUST-GLUE rule V:MxValue ~> mxValueToRust(T:Type) => mxValueToRust(T, V) + rule mxValueToRust(&T => T, _V) rule mxValueToRust(T:Type, mxIntValue(I:Int)) => mxRustNewValue(integerToValue(I, T)) requires diff --git a/mx-rust-semantics/main/representation.md b/mx-rust-semantics/main/representation.md index 0ff2ce9..5de8bc8 100644 --- a/mx-rust-semantics/main/representation.md +++ b/mx-rust-semantics/main/representation.md @@ -8,7 +8,11 @@ module MX-RUST-REPRESENTATION syntax MxRustInstruction ::= "mxRustPreprocessTraits" | mxRustPreprocessMethods(TypePath) | mxRustCreateAccount(String) - | mxRustCreateContract(owner: String, contractAccount: String, code: Crate) + | mxRustCreateContract + ( owner: String + , contractAccount: String + , code: Crate + , args: MxValueList) | mxRustNewValue(ValueOrError) | mxRustEmptyValue(MxRustType) | mxValueToRust(Type) diff --git a/mx-rust-semantics/setup/mx.md b/mx-rust-semantics/setup/mx.md index 1e7c311..75f243b 100644 --- a/mx-rust-semantics/setup/mx.md +++ b/mx-rust-semantics/setup/mx.md @@ -25,6 +25,7 @@ module MX-RUST-SETUP-MX (... owner: Owner:String , contractAccount: Contract:String , code: Code:Crate + , args: Args:MxValueList ) => crateParser(Code) ~> mxRustPreprocessTraits @@ -33,7 +34,7 @@ module MX-RUST-SETUP-MX , newAddress: Contract , egldValue: 0 , gasLimit: 0 - , args: .MxValueList + , args: Args ) // Trying to put the following three rules in one causes this kind of error: diff --git a/mx-rust-semantics/targets/contract-testing/configuration.md b/mx-rust-semantics/targets/contract-testing/configuration.md index 4a66aed..1771cfa 100644 --- a/mx-rust-semantics/targets/contract-testing/configuration.md +++ b/mx-rust-semantics/targets/contract-testing/configuration.md @@ -17,6 +17,7 @@ module COMMON-K-CELL (... owner: "Owner" , contractAccount: "TestContract" , code: $PGM:Crate + , args: $ARGS:MxValueList ) ~> ($TEST:MxRustTest):KItem diff --git a/parse-mx-rust-contract-args.sh b/parse-mx-rust-contract-args.sh new file mode 100755 index 0000000..4dfd2d1 --- /dev/null +++ b/parse-mx-rust-contract-args.sh @@ -0,0 +1,8 @@ +#! /bin/bash + +kast \ + --output kore \ + --definition .build/mx-rust-contract-testing-kompiled \ + --module MX-RUST-SYNTAX \ + --sort MxValueList \ + $1 diff --git a/rust-semantics/expression.md b/rust-semantics/expression.md index ce63ba7..c59585d 100644 --- a/rust-semantics/expression.md +++ b/rust-semantics/expression.md @@ -9,7 +9,6 @@ requires "expression/conditionals.md" requires "expression/literals.md" requires "expression/references.md" requires "expression/struct.md" -requires "expression/tools.md" requires "expression/variables.md" module RUST-EXPRESSION @@ -21,7 +20,6 @@ module RUST-EXPRESSION imports private RUST-EXPRESSION-LITERALS imports private RUST-EXPRESSION-REFERENCES imports private RUST-EXPRESSION-STRUCT - imports private RUST-EXPRESSION-TOOLS imports private RUST-EXPRESSION-VARIABLES imports private RUST-INTEGER-OPERATIONS imports private RUST-BOOL-OPERATIONS diff --git a/rust-semantics/expression/calls.md b/rust-semantics/expression/calls.md index 3c2d535..5f365bf 100644 --- a/rust-semantics/expression/calls.md +++ b/rust-semantics/expression/calls.md @@ -4,7 +4,7 @@ module RUST-EXPRESSION-CALLS imports private COMMON-K-CELL imports private RUST-SHARED-SYNTAX imports private RUST-EXECUTION-CONFIGURATION - imports private RUST-EXPRESSION-TOOLS + imports private RUST-PREPROCESSING-TOOLS imports private RUST-REPRESENTATION imports private RUST-SHARED-SYNTAX diff --git a/rust-semantics/helpers.md b/rust-semantics/helpers.md index 06e54c7..5fa45c6 100644 --- a/rust-semantics/helpers.md +++ b/rust-semantics/helpers.md @@ -16,5 +16,6 @@ module RUST-HELPERS rule isSameType(u64(_), u64) => true rule isSameType(i32(_), i32) => true rule isSameType(u32(_), u32) => true + rule isSameType(struct(T, _), T:Type) => true endmodule ``` diff --git a/rust-semantics/preprocessing.md b/rust-semantics/preprocessing.md index 879f4a7..f12e1f0 100644 --- a/rust-semantics/preprocessing.md +++ b/rust-semantics/preprocessing.md @@ -6,13 +6,15 @@ requires "preprocessing/configuration.md" requires "preprocessing/helpers.md" requires "preprocessing/initialization.md" requires "preprocessing/syntax.md" +requires "preprocessing/tools.md" requires "preprocessing/trait.md" requires "preprocessing/trait-methods.md" module RUST-PREPROCESSING - imports private RUST-CONSTANTS imports private CRATE imports private INITIALIZATION + imports private RUST-CONSTANTS + imports private RUST-PREPROCESSING-TOOLS imports private TRAIT imports private TRAIT-METHODS endmodule diff --git a/rust-semantics/expression/tools.md b/rust-semantics/preprocessing/tools.md similarity index 71% rename from rust-semantics/expression/tools.md rename to rust-semantics/preprocessing/tools.md index c81fdfe..2896052 100644 --- a/rust-semantics/expression/tools.md +++ b/rust-semantics/preprocessing/tools.md @@ -1,6 +1,6 @@ ```k -module RUST-EXPRESSION-TOOLS +module RUST-PREPROCESSING-TOOLS imports private BOOL imports private RUST-REPRESENTATION imports private RUST-SHARED-SYNTAX @@ -10,6 +10,9 @@ module RUST-EXPRESSION-TOOLS rule isValueWithPtr(_:PtrValue) => true rule isValueWithPtr(.CallParamsList) => true rule isValueWithPtr(P:Expression , Ps:CallParamsList) => isValueWithPtr(P) andBool isValueWithPtr(Ps) + + rule reverse(.CallParamsList, L:CallParamsList) => L + rule reverse((P , Ps:CallParamsList => Ps), (L:CallParamsList => P, L)) endmodule ``` \ No newline at end of file diff --git a/rust-semantics/representation.md b/rust-semantics/representation.md index 87c5b7f..e4f9f6b 100644 --- a/rust-semantics/representation.md +++ b/rust-semantics/representation.md @@ -99,6 +99,8 @@ module RUST-REPRESENTATION syntax String ::= IdentifierToString(Identifier) [function, total, hook(STRING.token2string)] + syntax CallParamsList ::= reverse(CallParamsList, CallParamsList) [function, total] + endmodule ``` diff --git a/rust-semantics/rust-common-syntax.md b/rust-semantics/rust-common-syntax.md index b46cab6..d7636ff 100644 --- a/rust-semantics/rust-common-syntax.md +++ b/rust-semantics/rust-common-syntax.md @@ -312,7 +312,6 @@ https://doc.rust-lang.org/reference/items/extern-crates.html | ExpressionWithBlock syntax Expression ::= LiteralExpression - | GroupedExpression | ArrayExpression | AwaitExpression | TupleExpression @@ -331,7 +330,11 @@ https://doc.rust-lang.org/reference/items/extern-crates.html // Several sub-expressions were included directly in Expression // to make it easy to disambiguate based on priority - syntax Expression ::= PathExpression + syntax Expression ::= + // https://doc.rust-lang.org/reference/expressions/grouped-expr.html + "(" Expression ")" [bracket] + + > PathExpression // https://doc.rust-lang.org/reference/expressions/method-call-expr.html > Expression "." PathExprSegment "(" ")" @@ -471,14 +474,6 @@ https://doc.rust-lang.org/reference/items/extern-crates.html syntax TypeCastExpression ::= "TODO: not needed yet, not implementing" -``` - - https://doc.rust-lang.org/reference/expressions/grouped-expr.html - -```k - - syntax GroupedExpression ::= "(" Expression ")" - ``` https://doc.rust-lang.org/reference/expressions/array-expr.html diff --git a/tests/mx-rust-contracts/call-endpoint-args.1.args b/tests/mx-rust-contracts/call-endpoint-args.1.args new file mode 100644 index 0000000..e69de29 diff --git a/tests/mx-rust-contracts/call-endpoint-args.1.run b/tests/mx-rust-contracts/call-endpoint-args.1.run new file mode 100644 index 0000000..0b1f617 --- /dev/null +++ b/tests/mx-rust-contracts/call-endpoint-args.1.run @@ -0,0 +1,34 @@ +setCallee("Owner"); + +push mxListValue(); +push mxStringValue("getMyStorage"); +push mxIntValue(0); +push mxTransfersValue(); +push mxIntValue(0); +push mxStringValue("TestContract"); +call 6 MX#managedExecuteOnDestContext; +check_eq mxIntValue(0); + +push_return_value; +check_eq mxIntValue(0); + +push mxListValue(mxIntValue(8)); +push mxStringValue("setMyStorage"); +push mxIntValue(0); +push mxTransfersValue(); +push mxIntValue(0); +push mxStringValue("TestContract"); +call 6 MX#managedExecuteOnDestContext; +check_eq mxIntValue(0); + +push mxListValue(); +push mxStringValue("getMyStorage"); +push mxIntValue(0); +push mxTransfersValue(); +push mxIntValue(0); +push mxStringValue("TestContract"); +call 6 MX#managedExecuteOnDestContext; +check_eq mxIntValue(0); + +push_return_value; +check_eq mxIntValue(8) diff --git a/tests/mx-rust-contracts/call-endpoint-args.rs b/tests/mx-rust-contracts/call-endpoint-args.rs new file mode 100644 index 0000000..0dcf76a --- /dev/null +++ b/tests/mx-rust-contracts/call-endpoint-args.rs @@ -0,0 +1,27 @@ +#![no_std] + +#[allow(unused_imports)] +use multiversx_sc::imports::*; + +#[multiversx_sc::contract] +pub trait Contract { + #[view(noArg)] + #[storage_mapper("my_value")] + fn my_storage(&self) -> SingleValueMapper; + + #[init] + fn init(&self) {} + + #[upgrade] + fn upgrade(&self) {} + + #[endpoint(setMyStorage)] + fn set_my_storage(&self, value: &BigUint) { + self.my_storage().set(value) + } + + #[endpoint(getMyStorage)] + fn get_my_storage(&self) -> BigUint { + self.my_storage().get() + } +} diff --git a/tests/mx-rust-contracts/contract-setup-args.1.args b/tests/mx-rust-contracts/contract-setup-args.1.args new file mode 100644 index 0000000..aeadbf1 --- /dev/null +++ b/tests/mx-rust-contracts/contract-setup-args.1.args @@ -0,0 +1 @@ +mxIntValue(13) diff --git a/tests/mx-rust-contracts/contract-setup-args.1.run b/tests/mx-rust-contracts/contract-setup-args.1.run new file mode 100644 index 0000000..1a7645c --- /dev/null +++ b/tests/mx-rust-contracts/contract-setup-args.1.run @@ -0,0 +1,14 @@ +setCallee("Owner"); + +push mxListValue(); +push mxStringValue("getMyStorage"); +push mxIntValue(0); +push mxTransfersValue(); +push mxIntValue(0); +push mxStringValue("TestContract"); +call 6 MX#managedExecuteOnDestContext; +check_eq mxIntValue(0); + +push_return_value; +check_eq mxIntValue(13) + diff --git a/tests/mx-rust-contracts/contract-setup-args.rs b/tests/mx-rust-contracts/contract-setup-args.rs new file mode 100644 index 0000000..8843f21 --- /dev/null +++ b/tests/mx-rust-contracts/contract-setup-args.rs @@ -0,0 +1,24 @@ +#![no_std] + +#[allow(unused_imports)] +use multiversx_sc::imports::*; + +#[multiversx_sc::contract] +pub trait Storage { + #[view(noArg)] + #[storage_mapper("my_storage")] + fn my_storage(&self) -> SingleValueMapper; + + #[init] + fn init(&self, value: &BigUint) { + self.my_storage().set_if_empty(value) + } + + #[upgrade] + fn upgrade(&self) {} + + #[endpoint(getMyStorage)] + fn get_my_storage(&self) -> BigUint { + self.my_storage().get() + } +} diff --git a/tests/mx-rust-contracts/contract-setup.1.args b/tests/mx-rust-contracts/contract-setup.1.args new file mode 100644 index 0000000..e69de29 diff --git a/tests/mx-rust-contracts/contract-setup.rs b/tests/mx-rust-contracts/contract-setup.rs index 5483974..7618d15 100644 --- a/tests/mx-rust-contracts/contract-setup.rs +++ b/tests/mx-rust-contracts/contract-setup.rs @@ -6,7 +6,7 @@ use multiversx_sc::imports::*; #[multiversx_sc::contract] pub trait Storage { #[view(noArg)] - #[storage_mapper("no_arg")] + #[storage_mapper("my_value")] fn my_storage(&self) -> SingleValueMapper; #[init]