Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Preprocess contracts #152

Merged
merged 2 commits into from
Oct 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 55 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,11 @@ UKM_NO_CONTRACT_TESTING_OUTPUT_DIR ::= .build/ukm-no-contract/output
UKM_NO_CONTRACT_TESTING_INPUTS ::= $(wildcard $(UKM_NO_CONTRACT_TESTING_INPUT_DIR)/*.run)
UKM_NO_CONTRACT_TESTING_OUTPUTS ::= $(patsubst $(UKM_NO_CONTRACT_TESTING_INPUT_DIR)/%,$(UKM_NO_CONTRACT_TESTING_OUTPUT_DIR)/%.executed.kore,$(UKM_NO_CONTRACT_TESTING_INPUTS))

UKM_WITH_CONTRACT_TESTING_INPUT_DIR ::= tests/ukm-with-contract
UKM_WITH_CONTRACT_TESTING_OUTPUT_DIR ::= .build/ukm-with-contract/output
UKM_WITH_CONTRACT_TESTING_INPUTS ::= $(wildcard $(UKM_WITH_CONTRACT_TESTING_INPUT_DIR)/*.run)
UKM_WITH_CONTRACT_TESTING_OUTPUTS ::= $(patsubst $(UKM_WITH_CONTRACT_TESTING_INPUT_DIR)/%,$(UKM_WITH_CONTRACT_TESTING_OUTPUT_DIR)/%.executed.kore,$(UKM_WITH_CONTRACT_TESTING_INPUTS))

.PHONY: clean build build-legacy test test-legacy syntax-test preprocessing-test execution-test mx-test mx-rust-test mx-rust-contract-test mx-rust-two-contracts-test demos-test ukm-no-contracts-test

all: build test
Expand Down Expand Up @@ -127,6 +132,8 @@ demos-test: $(DEMOS_TESTING_OUTPUTS)

ukm-no-contracts-test: $(UKM_NO_CONTRACT_TESTING_OUTPUTS)

ukm-with-contracts-test: $(UKM_WITH_CONTRACT_TESTING_OUTPUTS)

$(RUST_PREPROCESSING_TIMESTAMP): $(RUST_SEMANTICS_FILES)
# Workaround for https://github.com/runtimeverification/k/issues/4141
-rm -r $(RUST_PREPROCESSING_KOMPILED)
Expand Down Expand Up @@ -424,3 +431,51 @@ $(UKM_NO_CONTRACT_TESTING_OUTPUT_DIR)/%.run.executed.kore: \
-pTEST=$(CURDIR)/parsers/test-ukm-testing-execution.sh
cat $@.tmp | grep -q "Lbl'-LT-'k'-GT-'{}(dotk{}())"
mv -f $@.tmp $@


# TODO: Add $(shell echo "$<" | sed 's/\.[^.]*.run$$//').rs
# as a dependency
$(UKM_WITH_CONTRACT_TESTING_OUTPUT_DIR)/%.run.executed.kore: \
$(UKM_WITH_CONTRACT_TESTING_INPUT_DIR)/%.run \
$(UKM_CONTRACTS_TESTING_INPUT_DIR)/bytes_hooks.rs \
$(UKM_CONTRACTS_TESTING_INPUT_DIR)/ukm.rs \
$(UKM_TESTING_TIMESTAMP) \
$(wildcard parsers/inc-*.sh) \
parsers/crates-ukm-testing-execution.sh \
parsers/test-ukm-testing-execution.sh
mkdir -p $(UKM_WITH_CONTRACT_TESTING_OUTPUT_DIR)

echo "<(<" > $@.in.tmp
echo "::bytes_hooks" >> $@.in.tmp
echo "<|>" >> $@.in.tmp
cat $(UKM_CONTRACTS_TESTING_INPUT_DIR)/bytes_hooks.rs >> $@.in.tmp
echo ">)>" >> $@.in.tmp

echo "<(<" >> $@.in.tmp
echo "::state_hooks" >> $@.in.tmp
echo "<|>" >> $@.in.tmp
cat $(UKM_CONTRACTS_TESTING_INPUT_DIR)/state_hooks.rs >> $@.in.tmp
echo ">)>" >> $@.in.tmp

echo "<(<" >> $@.in.tmp
echo "::ukm" >> $@.in.tmp
echo "<|>" >> $@.in.tmp
cat $(UKM_CONTRACTS_TESTING_INPUT_DIR)/ukm.rs >> $@.in.tmp
echo ">)>" >> $@.in.tmp

echo "<(<" >> $@.in.tmp
echo "$<" | sed 's%^.*/%%' | sed 's/\..*//' | sed 's/^/::/' >> $@.in.tmp
echo "<|>" >> $@.in.tmp
cat "$(shell echo "$<" | sed 's/\.[^.]*.run$$//').rs" >> $@.in.tmp
echo ">)>" >> $@.in.tmp

krun \
$@.in.tmp \
--parser $(CURDIR)/parsers/crates-ukm-testing-execution.sh \
--definition $(UKM_TESTING_KOMPILED) \
--output kore \
--output-file $@.tmp \
-cTEST='$(shell cat $<)' \
-pTEST=$(CURDIR)/parsers/test-ukm-testing-execution.sh
cat $@.tmp | grep -q "Lbl'-LT-'k'-GT-'{}(dotk{}())"
mv -f $@.tmp $@
2 changes: 1 addition & 1 deletion mx-rust-semantics/main/preprocessing/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ module MX-RUST-PREPROCESSED-CONTRACT-TRAIT-CONFIGURATION
imports RUST-SHARED-SYNTAX

configuration
<mx-rust-contract-trait> (#token("no#path", "Identifier"):Identifier):TypePath </mx-rust-contract-trait> // String to Identifier
<mx-rust-contract-trait> (#token("no#path", "Identifier"):Identifier):TypePath </mx-rust-contract-trait>
endmodule

module MX-RUST-PREPROCESSED-PROXIES-CONFIGURATION
Expand Down
20 changes: 15 additions & 5 deletions rust-semantics/error.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ module RUST-ERROR-SYNTAX

syntax ValueListOrError ::= concat(ValueOrError, ValueListOrError) [function, total]
syntax PtrListOrError ::= concat(Ptr, PtrListOrError) [function, total]
syntax StringOrError ::= concat(StringOrError, StringOrError) [function, total]
syntax NonEmptyStatementsOrError ::= concat(NonEmptyStatementsOrError, NonEmptyStatementsOrError) [function, total]
syntax PtrValueOrError ::= wrapPtrValueOrError(Ptr, ValueOrError) [function, total]
syntax TypePathOrError ::= doubleColonOrError(TypePathSegmentsOrError) [function, total]
syntax TypePathOrError ::= injectOrError(TypePathSegmentsOrError) [function, total]
Expand All @@ -22,10 +24,18 @@ module RUST-ERROR
rule concat(V:Value, L:ValueList) => V , L
rule concat(_:Value, E:SemanticsError) => E
rule concat(E:SemanticsError, _:ValueListOrError) => E
rule concat(E:ValueOrError, L:ValueListOrError)
=> error("unexpected branch (concat(ValueOrError, ValueListOrError))", ListItem(E) ListItem(L))

rule concat(S1:String:StringOrError, S2:String:StringOrError) => S1 +String S2
rule concat(_:String:StringOrError, E:SemanticsError:StringOrError) => E
rule concat(E:SemanticsError:StringOrError, _:StringOrError) => E
rule concat(S1:StringOrError, S2:StringOrError)
=> error("concat(StringOrError, StringOrError): Unknown error", ListItem(S1) ListItem(S2))
[owise]

rule concat(S1:NonEmptyStatements, S2:NonEmptyStatements) => concatNonEmptyStatements(S1, S2)
rule concat(_:NonEmptyStatements, E:SemanticsError) => E
rule concat(E:SemanticsError, _:NonEmptyStatementsOrError) => E

rule wrapPtrValueOrError(P:Ptr, V:Value) => ptrValue(P, V)
rule wrapPtrValueOrError(_:Ptr, E:SemanticsError) => E

Expand All @@ -38,9 +48,9 @@ module RUST-ERROR
rule concat(_:TypePathSegment, E) => E
rule concat(S:TypePathSegment, Ss:TypePathSegments) => S :: Ss

rule andOrError(_:ExpressionOrError, E:SemanticsError) => E
rule andOrError(E:SemanticsError, _:Expression) => E
rule andOrError(E1:Expression, E2:Expression) => E1 && E2
rule andOrError(_:ExpressionOrError, e(E:SemanticsError)) => e(E)
rule andOrError(e(E:SemanticsError), v(_:Expression)) => e(E)
rule andOrError(v(E1:Expression), v(E2:Expression)) => v(E1 && E2)

rule tupleOrError(L:ValueList) => tuple(L)
rule tupleOrError(E:SemanticsError) => E
Expand Down
20 changes: 11 additions & 9 deletions rust-semantics/expression/comparisons.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,26 +23,28 @@ module RUST-EXPRESSION-STRUCT-COMPARISONS
rule (ptrValue(_, struct(StructName:TypePath, FirstFields:Map))
== ptrValue(_, struct(StructName, SecondFields:Map))
):Expression
=> allPtrEquality
( listToPtrList(values(FirstFields))
, listToPtrList(values(SecondFields))
=> unwrap
( allPtrEquality
( listToPtrList(values(FirstFields))
, listToPtrList(values(SecondFields))
)
)
[owise]

syntax ExpressionOrError ::= allPtrEquality(PtrListOrError, PtrListOrError)
[function, total]

rule allPtrEquality(E:SemanticsError, _:PtrListOrError) => E
rule allPtrEquality(_:PtrList, E:SemanticsError) => E
rule allPtrEquality(E:SemanticsError, _:PtrListOrError) => e(E)
rule allPtrEquality(_:PtrList, E:SemanticsError) => e(E)

rule allPtrEquality(.PtrList, .PtrList) => true
rule allPtrEquality(.PtrList, .PtrList) => v(true)
rule allPtrEquality((P:Ptr , Ps:PtrList), (Q:Ptr , Qs:PtrList))
=> andOrError(P == Q , allPtrEquality(Ps, Qs))
=> andOrError(v(P == Q) , allPtrEquality(Ps, Qs))

rule allPtrEquality(.PtrList, (_:Ptr , _:PtrList) #as Ps:PtrList)
=> error("allPtrEquality: Second list too long", ListItem(Ps))
=> e(error("allPtrEquality: Second list too long", ListItem(Ps)))
rule allPtrEquality((_:Ptr , _:PtrList) #as Ps:PtrList, .PtrList)
=> error("zip(PtrList): First list too long", ListItem(Ps))
=> e(error("zip(PtrList): First list too long", ListItem(Ps)))

endmodule

Expand Down
4 changes: 2 additions & 2 deletions rust-semantics/expression/struct.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,9 @@ module RUST-EXPRESSION-STRUCT
rule <k>
fromStructExpressionWithAssignmentsBuildFieldsMap(
Name:TypePath,
((FieldName:Identifier : LE:Expression):StructExprField, RS):StructExprFields,
((FieldName:Identifier : Le:Expression):StructExprField, RS):StructExprFields,
FieldsMap:Map)
=> LE ~> FieldName ~> fromStructExpressionWithAssignmentsBuildFieldsMap(Name, RS, FieldsMap)
=> Le ~> FieldName ~> fromStructExpressionWithAssignmentsBuildFieldsMap(Name, RS, FieldsMap)
...
</k>

Expand Down
3 changes: 3 additions & 0 deletions rust-semantics/helpers.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,5 +42,8 @@ module RUST-HELPERS
rule isSignedInt(u128) => true
rule isSignedInt(&T => T)

rule concatNonEmptyStatements(.NonEmptyStatements, S:NonEmptyStatements) => S
rule concatNonEmptyStatements(S:Statement Ss1:NonEmptyStatements, Ss2:NonEmptyStatements)
=> S concatNonEmptyStatements(Ss1, Ss2)
endmodule
```
8 changes: 3 additions & 5 deletions rust-semantics/preprocessing/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ module RUST-PREPROCESSING-CONFIGURATION
imports private RUST-REPRESENTATION
imports private RUST-SHARED-SYNTAX

syntax Identifier ::= "my_identifier" [token]

configuration
<preprocessed>
<constants>
Expand All @@ -17,7 +15,7 @@ module RUST-PREPROCESSING-CONFIGURATION
<struct-list> .List </struct-list>
<structs>
<struct multiplicity="*" type="Map">
<struct-path> my_identifier:TypePath </struct-path>
<struct-path> #token("not#initialized", "Identifier"):Identifier:TypePath </struct-path>
<field-list> .List </field-list> // List of Identifier
<fields>
<field multiplicity="*" type="Map">
Expand All @@ -30,14 +28,14 @@ module RUST-PREPROCESSING-CONFIGURATION
<trait-list> .List </trait-list> // List of TypePath
<traits>
<trait multiplicity="*" type="Map">
<trait-path> my_identifier:TypePath </trait-path>
<trait-path> #token("not#initialized", "Identifier"):Identifier:TypePath </trait-path>
<trait-attributes> `emptyOuterAttributes`(.KList):OuterAttributes </trait-attributes>
<method-list> .List </method-list> // List of Identifier
</trait>
</traits>
<methods>
<method multiplicity="*" type="Map">
<method-name> my_identifier:PathInExpression </method-name>
<method-name> #token("not#initialized", "Identifier"):Identifier:PathInExpression </method-name>
<method-params> .NormalizedFunctionParameterList </method-params>
<method-return-type> ():Type </method-return-type>
<method-implementation> empty:FunctionBodyRepresentation </method-implementation>
Expand Down
11 changes: 10 additions & 1 deletion rust-semantics/representation.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,10 @@ module RUST-REPRESENTATION
syntax MapOrError ::= Map | SemanticsError

syntax Expression ::= Ptr
syntax ExpressionOrError ::= Expression | SemanticsError
syntax ExpressionOrError ::= v(Expression) | e(SemanticsError)
Copy link
Member Author

@virgil-serbanuta virgil-serbanuta Oct 10, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change is needed because of a K crash that does not make sense, and which looks like this:

(NoSuchElementException: key not found: inj{SortExpressionOrError{}, SortKItem{}})

These seem to be triggered by random changes in the code, not related in any way to the ExpressionOrError sort. Anyway, using explicit constructors seems to make the error go away (it may also be that this is another random code change that makes the error go away for no good reason).

syntax KItem ::= unwrap(ExpressionOrError) [function, total]
rule unwrap(v(E:Expression)) => E
rule unwrap(e(E:SemanticsError)) => E

syntax NormalizedFunctionParameterListOrError ::= NormalizedFunctionParameterList | SemanticsError

Expand Down Expand Up @@ -129,7 +132,10 @@ module RUST-REPRESENTATION
syntax IntOrError ::= valueToInteger(Value) [function, total]
syntax ValueOrError ::= integerToValue(Int, Type) [function, total]

syntax StringOrError ::= String | SemanticsError

syntax String ::= IdentifierToString(Identifier) [function, total, hook(STRING.token2string)]
syntax Identifier ::= StringToIdentifier(String) [function, total, hook(STRING.string2token)]

syntax CallParamsList ::= reverse(CallParamsList, CallParamsList) [function, total]

Expand Down Expand Up @@ -175,6 +181,9 @@ module RUST-REPRESENTATION

syntax TypePath ::= append(MaybeTypePath, Identifier) [function, total]

syntax NonEmptyStatementsOrError ::= NonEmptyStatements | SemanticsError
syntax NonEmptyStatements ::= concatNonEmptyStatements(NonEmptyStatements, NonEmptyStatements) [function, total]

endmodule

```
4 changes: 2 additions & 2 deletions rust-semantics/rust-common-syntax.md
Original file line number Diff line number Diff line change
Expand Up @@ -197,8 +197,8 @@ https://doc.rust-lang.org/reference/items/extern-crates.html
syntax Struct ::= StructStruct | TupleStruct
syntax TupleStruct ::= "TODO: not needed yet, not implementing"
syntax StructStruct ::= "struct" Identifier MaybeGenericParams MaybeWhereClause "{" MaybeStructFields "}"
syntax MaybeStructFields ::= "" | StructFields
syntax StructFields ::= List{StructField, ","}
syntax MaybeStructFields ::= "" | StructFields | StructFields ","
syntax StructFields ::= NeList{StructField, ","}
syntax StructField ::= OuterAttributes MaybeVisibility Identifier ":" Type //TODO: Outerfields and visibility for
//struct fields is not yet supported.

Expand Down
1 change: 1 addition & 0 deletions rust-semantics/test/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ module RUST-EXECUTION-TEST-CONFIGURATION
configuration
<rust-test>
<test-stack> .List </test-stack>
<mocks> .Map </mocks>
</rust-test>
endmodule

Expand Down
12 changes: 12 additions & 0 deletions rust-semantics/test/execution.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ module RUST-EXECUTION-TEST-PARSING-SYNTAX
| "return_value_to_arg"
| "check_eq" Expression [strict]
| "push" Expression [strict]
syntax KItem ::= mock(KItem, K)
endmodule

module RUST-EXECUTION-TEST
Expand Down Expand Up @@ -92,6 +93,17 @@ module RUST-EXECUTION-TEST
<values> VALUES:Map => VALUES[NVI <- V] </values>
<next-value-id> NVI:Int => NVI +Int 1 </next-value-id>

syntax KItem ::= wrappedK(K)
syntax Mockable

rule
<k> mock(Mocked:Mockable, Result:K) => .K ... </k>
<mocks> M:Map => M[Mocked <- wrappedK(Result)] </mocks>

rule
<k> (Mocked:Mockable => Result) ...</k>
<mocks> Mocked |-> wrappedK(Result:K) ...</mocks>
[priority(10)]
endmodule

```
2 changes: 1 addition & 1 deletion tests/ukm-contracts/bytes_hooks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ extern "C" {
fn append_u64(bytes_id: u64, value: u64) -> u64;
fn append_u32(bytes_id: u64, value: u32) -> u64;
fn append_u16(bytes_id: u64, value: u16) -> u64;
fn append_u7(bytes_id: u64, value: u8) -> u64;
fn append_u8(bytes_id: u64, value: u8) -> u64;
fn append_str(bytes_id: u64, value: &str) -> u64;

fn decode_u128(bytes_id: u64) -> (u64, u128);
Expand Down
4 changes: 4 additions & 0 deletions tests/ukm-contracts/state_hooks.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
extern "C" {
fn setStatus(status: u64);
fn setOutput(bytes_id: u64);
}
2 changes: 1 addition & 1 deletion tests/ukm-contracts/ukm.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#![no_std]

// TODO: Support structs and figure out the content of MessageResult
struct MessageResult { }
struct MessageResult { gas: u64 }

pub const EVMC_REJECTED: u64 = 0_u64;
pub const EVMC_INTERNAL_ERROR: u64 = 1_u64;
Expand Down
23 changes: 23 additions & 0 deletions tests/ukm-with-contract/endpoints.1.run
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
call :: bytes_hooks :: empty;
return_value_to_arg;
push "myEndpoint(Uint64)";
call :: bytes_hooks :: append_str;
return_value_to_arg;
push 123_u64;
call :: bytes_hooks :: append_u64;
return_value;
mock CallData;

call_contract 12345;
return_value;
check_eq ();

push_status;
check_eq 2;

output_to_arg;
call :: endpoints :: decode_single_u64;
return_value;

check_eq 126_u64

23 changes: 23 additions & 0 deletions tests/ukm-with-contract/endpoints.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#![no_std]

#[allow(unused_imports)]
use ukm::*;

#[ukm::contract]
pub trait Endpoints {
#[init]
fn init(&self) {}

#[endpoint(myEndpoint)]
fn endpoint(&self, value: u64) -> u64 {
value + 3_u64
}
}

fn decode_single_u64(bytes_id: u64) -> u64 {
let (remaining_id, value) = :: bytes_hooks :: decode_u64(bytes_id);
if :: bytes_hooks :: length(remaining_id) > 0_u32 {
fail();
};
value
}
13 changes: 13 additions & 0 deletions ukm-semantics/main/common-tools.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
```k

module UKM-COMMON-TOOLS-SYNTAX
syntax Identifier ::= "dispatcherMethodIdentifier" [function, total]
endmodule

module UKM-COMMON-TOOLS
imports private UKM-COMMON-TOOLS-SYNTAX

rule dispatcherMethodIdentifier => #token("ukm#dispatch#method", "Identifier")
endmodule

```
3 changes: 3 additions & 0 deletions ukm-semantics/main/configuration.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
```k
requires "hooks/bytes.md"
requires "hooks/state.md"
module UKM-CONFIGURATION
imports UKM-HOOKS-BYTES-CONFIGURATION
imports UKM-HOOKS-STATE-CONFIGURATION
configuration
<ukm>
<ukm-bytes/>
<ukm-state/>
</ukm>
endmodule
Expand Down
Loading
Loading