From 2b7c3657cdd97be3a0c23e700057f34381bb8b2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20M=C3=BCller?= Date: Thu, 31 Aug 2023 15:29:40 -0700 Subject: [PATCH 01/39] add support for dictionary types --- runtime/sema/gen/main.go | 17 +++++++++++++++++ runtime/sema/gen/testdata/fields.cdc | 3 +++ runtime/sema/gen/testdata/fields.golden.go | 19 +++++++++++++++++++ 3 files changed, 39 insertions(+) diff --git a/runtime/sema/gen/main.go b/runtime/sema/gen/main.go index 9e07ce5530..6b48943801 100644 --- a/runtime/sema/gen/main.go +++ b/runtime/sema/gen/main.go @@ -783,6 +783,23 @@ func typeExpr(t ast.Type, typeParams map[string]string) dst.Expr { }, } + case *ast.DictionaryType: + keyType := typeExpr(t.KeyType, typeParams) + valueType := typeExpr(t.ValueType, typeParams) + return &dst.UnaryExpr{ + Op: token.AND, + X: &dst.CompositeLit{ + Type: &dst.Ident{ + Name: "DictionaryType", + Path: semaPath, + }, + Elts: []dst.Expr{ + goKeyValue("KeyType", keyType), + goKeyValue("ValueType", valueType), + }, + }, + } + case *ast.FunctionType: return functionTypeExpr(t, nil, nil, typeParams) diff --git a/runtime/sema/gen/testdata/fields.cdc b/runtime/sema/gen/testdata/fields.cdc index 667f50b712..1cf74e4f96 100644 --- a/runtime/sema/gen/testdata/fields.cdc +++ b/runtime/sema/gen/testdata/fields.cdc @@ -14,6 +14,9 @@ access(all) struct Test { /// This is a test constant-sized integer array. access(all) let testConstInts: [UInt64; 2] + /// This is a test integer dictionary. + access(all) let testIntDict: {UInt64: Bool} + /// This is a test parameterized-type field. access(all) let testParam: Foo diff --git a/runtime/sema/gen/testdata/fields.golden.go b/runtime/sema/gen/testdata/fields.golden.go index 9fdabd602e..f4af42f973 100644 --- a/runtime/sema/gen/testdata/fields.golden.go +++ b/runtime/sema/gen/testdata/fields.golden.go @@ -71,6 +71,17 @@ const TestTypeTestConstIntsFieldDocString = ` This is a test constant-sized integer array. ` +const TestTypeTestIntDictFieldName = "testIntDict" + +var TestTypeTestIntDictFieldType = &DictionaryType{ + KeyType: UInt64Type, + ValueType: BoolType, +} + +const TestTypeTestIntDictFieldDocString = ` +This is a test integer dictionary. +` + const TestTypeTestParamFieldName = "testParam" var TestTypeTestParamFieldType = MustInstantiate( @@ -186,6 +197,14 @@ func init() { TestTypeTestConstIntsFieldType, TestTypeTestConstIntsFieldDocString, ), + NewUnmeteredFieldMember( + t, + PrimitiveAccess(ast.AccessAll), + ast.VariableKindConstant, + TestTypeTestIntDictFieldName, + TestTypeTestIntDictFieldType, + TestTypeTestIntDictFieldDocString, + ), NewUnmeteredFieldMember( t, PrimitiveAccess(ast.AccessAll), From 9fdfb4d9e119dc554df2ca4e1e1f450b1e959d27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20M=C3=BCller?= Date: Fri, 1 Sep 2023 09:54:55 -0700 Subject: [PATCH 02/39] update wasmtime --- go.mod | 2 +- go.sum | 4 ++-- vm/vm.go | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/go.mod b/go.mod index f629d739fd..8adeb56bbb 100644 --- a/go.mod +++ b/go.mod @@ -31,7 +31,7 @@ require ( require ( github.com/SaveTheRbtz/mph v0.1.2 - github.com/bytecodealliance/wasmtime-go/v7 v7.0.0 + github.com/bytecodealliance/wasmtime-go/v12 v12.0.0 github.com/k0kubun/pp v3.0.1+incompatible github.com/k0kubun/pp/v3 v3.2.0 github.com/logrusorgru/aurora/v4 v4.0.0 diff --git a/go.sum b/go.sum index e9a6d1ec46..a9e272b7b5 100644 --- a/go.sum +++ b/go.sum @@ -2,8 +2,8 @@ github.com/SaveTheRbtz/mph v0.1.2 h1:5l3W496Up+7BNOVJQnJhzcGBh+wWfxWdmPUAkx3WmaM github.com/SaveTheRbtz/mph v0.1.2/go.mod h1:V4+WtKQPe2+dEA5os1WnGsEB0NR9qgqqgIiSt73+sT4= github.com/bits-and-blooms/bitset v1.2.2 h1:J5gbX05GpMdBjCvQ9MteIg2KKDExr7DrgK+Yc15FvIk= github.com/bits-and-blooms/bitset v1.2.2/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= -github.com/bytecodealliance/wasmtime-go/v7 v7.0.0 h1:/rBNjgFju2HCZnkPb1eL+W4GBwP8DMbaQu7i+GR9DH4= -github.com/bytecodealliance/wasmtime-go/v7 v7.0.0/go.mod h1:bu6fic7trDt20w+LMooX7j3fsOwv4/ln6j8gAdP6vmA= +github.com/bytecodealliance/wasmtime-go/v12 v12.0.0 h1:Wga02UaZXYF3p0LIeL5xFp09/RI7UhjfT2uB0mLrwlw= +github.com/bytecodealliance/wasmtime-go/v12 v12.0.0/go.mod h1:a3PRoftJxxUzkQvgjC6sv7pKyJJK0ZsFVmH+eeEKQC4= github.com/c-bata/go-prompt v0.2.5 h1:3zg6PecEywxNn0xiqcXHD96fkbxghD+gdB2tbsYfl+Y= github.com/c-bata/go-prompt v0.2.5/go.mod h1:vFnjEGDIIA/Lib7giyE4E9c50Lvl8j0S+7FVlAwDAVw= github.com/dave/dst v0.27.2 h1:4Y5VFTkhGLC1oddtNwuxxe36pnyLxMFXT51FOzH8Ekc= diff --git a/vm/vm.go b/vm/vm.go index f96cadc8d0..8ed9f63340 100644 --- a/vm/vm.go +++ b/vm/vm.go @@ -27,7 +27,7 @@ import ( "C" - "github.com/bytecodealliance/wasmtime-go/v7" + "github.com/bytecodealliance/wasmtime-go/v12" "github.com/onflow/cadence/runtime/interpreter" ) From cbc1eceb4dd0cb6e557d2a23ee29348832ccc352 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20M=C3=BCller?= Date: Fri, 1 Sep 2023 10:19:36 -0700 Subject: [PATCH 03/39] improve encodeArgs helper --- runtime/account_test.go | 8 ++--- runtime/crypto_test.go | 10 +++--- runtime/ft_test.go | 12 +++---- .../imported_values_memory_metering_test.go | 8 ++--- runtime/rlp_test.go | 8 ++--- runtime/runtime_memory_metering_test.go | 34 +++++++++---------- runtime/runtime_test.go | 4 +-- runtime/validation_test.go | 8 ++--- 8 files changed, 46 insertions(+), 46 deletions(-) diff --git a/runtime/account_test.go b/runtime/account_test.go index b4bfa6d0b0..031cf88afd 100644 --- a/runtime/account_test.go +++ b/runtime/account_test.go @@ -496,7 +496,7 @@ func TestRuntimeAuthAccountKeysAdd(t *testing.T) { err := rt.ExecuteTransaction( Script{ Source: []byte(code), - Arguments: encodeArgs([]cadence.Value{pubKey}), + Arguments: encodeArgs(pubKey), }, Context{ Location: nextTransactionLocation(), @@ -1059,7 +1059,7 @@ func addPublicKeyValidation(runtimeInterface *testRuntimeInterface, returnError } } -func encodeArgs(argValues []cadence.Value) [][]byte { +func encodeArgs(argValues ...cadence.Value) [][]byte { args := make([][]byte, len(argValues)) for i, arg := range argValues { var err error @@ -1082,7 +1082,7 @@ func (test accountKeyTestCase) executeTransaction( runtimeInterface *testRuntimeInterface, location Location, ) error { - args := encodeArgs(test.args) + args := encodeArgs(test.args...) err := runtime.ExecuteTransaction( Script{ @@ -1102,7 +1102,7 @@ func (test accountKeyTestCase) executeScript( runtimeInterface *testRuntimeInterface, ) (cadence.Value, error) { - args := encodeArgs(test.args) + args := encodeArgs(test.args...) value, err := runtime.ExecuteScript( Script{ diff --git a/runtime/crypto_test.go b/runtime/crypto_test.go index 74ef69f200..757a47955e 100644 --- a/runtime/crypto_test.go +++ b/runtime/crypto_test.go @@ -351,7 +351,7 @@ func TestRuntimeSignatureAlgorithmImport(t *testing.T) { value, err := runtime.ExecuteScript( Script{ Source: []byte(script), - Arguments: encodeArgs([]cadence.Value{ + Arguments: encodeArgs( cadence.NewEnum([]cadence.Value{ cadence.UInt8(algo.RawValue()), }).WithType(&cadence.EnumType{ @@ -364,7 +364,7 @@ func TestRuntimeSignatureAlgorithmImport(t *testing.T) { }, }, }), - }), + ), }, Context{ Interface: runtimeInterface, @@ -433,7 +433,7 @@ func TestRuntimeHashAlgorithmImport(t *testing.T) { value, err := runtime.ExecuteScript( Script{ Source: []byte(script), - Arguments: encodeArgs([]cadence.Value{ + Arguments: encodeArgs( cadence.NewEnum([]cadence.Value{ cadence.UInt8(algo.RawValue()), }).WithType(&cadence.EnumType{ @@ -446,7 +446,7 @@ func TestRuntimeHashAlgorithmImport(t *testing.T) { }, }, }), - }), + ), }, Context{ Interface: runtimeInterface, @@ -810,7 +810,7 @@ func TestRuntimeTraversingMerkleProof(t *testing.T) { _, err := runtime.ExecuteScript( Script{ Source: script, - Arguments: encodeArgs([]cadence.Value{rootHash, address, accountProof}), + Arguments: encodeArgs(rootHash, address, accountProof), }, Context{ Interface: runtimeInterface, diff --git a/runtime/ft_test.go b/runtime/ft_test.go index a8ffbde2c2..822be68adc 100644 --- a/runtime/ft_test.go +++ b/runtime/ft_test.go @@ -617,10 +617,10 @@ func BenchmarkRuntimeFungibleTokenTransfer(b *testing.B) { err = runtime.ExecuteTransaction( Script{ Source: []byte(realMintFlowTokenTransaction), - Arguments: encodeArgs([]cadence.Value{ + Arguments: encodeArgs( cadence.Address(senderAddress), mintAmount, - }), + ), }, Context{ Interface: runtimeInterface, @@ -645,10 +645,10 @@ func BenchmarkRuntimeFungibleTokenTransfer(b *testing.B) { err = runtime.ExecuteTransaction( Script{ Source: []byte(realFlowTokenTransferTransaction), - Arguments: encodeArgs([]cadence.Value{ + Arguments: encodeArgs( sendAmount, cadence.Address(receiverAddress), - }), + ), }, Context{ Interface: runtimeInterface, @@ -675,9 +675,9 @@ func BenchmarkRuntimeFungibleTokenTransfer(b *testing.B) { result, err := runtime.ExecuteScript( Script{ Source: []byte(realFlowTokenBalanceScript), - Arguments: encodeArgs([]cadence.Value{ + Arguments: encodeArgs( cadence.Address(address), - }), + ), }, Context{ Interface: runtimeInterface, diff --git a/runtime/imported_values_memory_metering_test.go b/runtime/imported_values_memory_metering_test.go index 3418fe15f9..a8418c6816 100644 --- a/runtime/imported_values_memory_metering_test.go +++ b/runtime/imported_values_memory_metering_test.go @@ -56,7 +56,7 @@ func TestRuntimeImportedValueMemoryMetering(t *testing.T) { _, err := runtime.ExecuteScript( Script{ Source: script, - Arguments: encodeArgs(args), + Arguments: encodeArgs(args...), }, Context{ Interface: runtimeInterface, @@ -508,9 +508,9 @@ func TestRuntimeImportedValueMemoryMeteringForSimpleTypes(t *testing.T) { _, err := runtime.ExecuteScript( Script{ Source: script, - Arguments: encodeArgs([]cadence.Value{ + Arguments: encodeArgs( test.TypeInstance, - }), + ), }, Context{ Interface: runtimeInterface, @@ -583,7 +583,7 @@ func TestRuntimeScriptDecodedLocationMetering(t *testing.T) { _, err := runtime.ExecuteScript( Script{ Source: script, - Arguments: encodeArgs([]cadence.Value{value}), + Arguments: encodeArgs(value), }, Context{ Interface: runtimeInterface, diff --git a/runtime/rlp_test.go b/runtime/rlp_test.go index c4789e7bfa..1c9f7cc6b4 100644 --- a/runtime/rlp_test.go +++ b/runtime/rlp_test.go @@ -136,14 +136,14 @@ func TestRuntimeRLPDecodeString(t *testing.T) { result, err := runtime.ExecuteScript( Script{ Source: script, - Arguments: encodeArgs([]cadence.Value{ + Arguments: encodeArgs( cadence.Array{ ArrayType: &cadence.VariableSizedArrayType{ ElementType: cadence.UInt8Type, }, Values: test.input, }, - }), + ), }, Context{ Interface: runtimeInterface, @@ -295,14 +295,14 @@ func TestRuntimeRLPDecodeList(t *testing.T) { result, err := runtime.ExecuteScript( Script{ Source: script, - Arguments: encodeArgs([]cadence.Value{ + Arguments: encodeArgs( cadence.Array{ ArrayType: &cadence.VariableSizedArrayType{ ElementType: cadence.UInt8Type, }, Values: test.input, }, - }), + ), }, Context{ Interface: runtimeInterface, diff --git a/runtime/runtime_memory_metering_test.go b/runtime/runtime_memory_metering_test.go index 9ec4886c76..9534a8324a 100644 --- a/runtime/runtime_memory_metering_test.go +++ b/runtime/runtime_memory_metering_test.go @@ -228,9 +228,9 @@ func TestRuntimeCadenceValueAndTypeMetering(t *testing.T) { _, err := runtime.ExecuteScript( Script{ Source: []byte(script), - Arguments: encodeArgs([]cadence.Value{ + Arguments: encodeArgs( cadence.NewInt(12), - }), + ), }, Context{ Interface: runtimeInterface, @@ -271,9 +271,9 @@ func TestRuntimeCadenceValueAndTypeMetering(t *testing.T) { _, err := runtime.ExecuteScript( Script{ Source: []byte(script), - Arguments: encodeArgs([]cadence.Value{ + Arguments: encodeArgs( largeInt, - }), + ), }, Context{ Interface: runtimeInterface, @@ -307,9 +307,9 @@ func TestRuntimeCadenceValueAndTypeMetering(t *testing.T) { _, err := runtime.ExecuteScript( Script{ Source: []byte(script), - Arguments: encodeArgs([]cadence.Value{ + Arguments: encodeArgs( cadence.NewInt8(12), - }), + ), }, Context{ Interface: runtimeInterface, @@ -343,9 +343,9 @@ func TestRuntimeCadenceValueAndTypeMetering(t *testing.T) { _, err := runtime.ExecuteScript( Script{ Source: []byte(script), - Arguments: encodeArgs([]cadence.Value{ + Arguments: encodeArgs( cadence.NewInt16(12), - }), + ), }, Context{ Interface: runtimeInterface, @@ -379,9 +379,9 @@ func TestRuntimeCadenceValueAndTypeMetering(t *testing.T) { _, err := runtime.ExecuteScript( Script{ Source: []byte(script), - Arguments: encodeArgs([]cadence.Value{ + Arguments: encodeArgs( cadence.NewInt32(12), - }), + ), }, Context{ Interface: runtimeInterface, @@ -415,9 +415,9 @@ func TestRuntimeCadenceValueAndTypeMetering(t *testing.T) { _, err := runtime.ExecuteScript( Script{ Source: []byte(script), - Arguments: encodeArgs([]cadence.Value{ + Arguments: encodeArgs( cadence.NewInt64(12), - }), + ), }, Context{ Interface: runtimeInterface, @@ -451,9 +451,9 @@ func TestRuntimeCadenceValueAndTypeMetering(t *testing.T) { _, err := runtime.ExecuteScript( Script{ Source: []byte(script), - Arguments: encodeArgs([]cadence.Value{ + Arguments: encodeArgs( cadence.NewInt128(12), - }), + ), }, Context{ Interface: runtimeInterface, @@ -487,9 +487,9 @@ func TestRuntimeCadenceValueAndTypeMetering(t *testing.T) { _, err := runtime.ExecuteScript( Script{ Source: []byte(script), - Arguments: encodeArgs([]cadence.Value{ + Arguments: encodeArgs( cadence.NewInt256(12), - }), + ), }, Context{ Interface: runtimeInterface, @@ -989,7 +989,7 @@ func TestRuntimeMemoryMeteringErrors(t *testing.T) { _, err := runtime.ExecuteScript( Script{ Source: script, - Arguments: encodeArgs(args), + Arguments: encodeArgs(args...), }, Context{ Interface: runtimeInterface(meter), diff --git a/runtime/runtime_test.go b/runtime/runtime_test.go index 305cc21b01..eb6fbf1149 100644 --- a/runtime/runtime_test.go +++ b/runtime/runtime_test.go @@ -8075,9 +8075,9 @@ func TestRuntimeAccountTypeEquality(t *testing.T) { result, err := rt.ExecuteScript( Script{ Source: script, - Arguments: encodeArgs([]cadence.Value{ + Arguments: encodeArgs( cadence.Address(common.MustBytesToAddress([]byte{0x1})), - }), + ), }, Context{ Interface: runtimeInterface, diff --git a/runtime/validation_test.go b/runtime/validation_test.go index d9f10a73bb..e32591729a 100644 --- a/runtime/validation_test.go +++ b/runtime/validation_test.go @@ -66,7 +66,7 @@ func TestRuntimeArgumentImportMissingType(t *testing.T) { err := runtime.ExecuteTransaction( Script{ Source: script, - Arguments: encodeArgs([]cadence.Value{ + Arguments: encodeArgs( cadence.Struct{}. WithType(&cadence.StructType{ Location: common.AddressLocation{ @@ -75,7 +75,7 @@ func TestRuntimeArgumentImportMissingType(t *testing.T) { }, QualifiedIdentifier: "Foo.Bar", }), - }), + ), }, Context{ Interface: runtimeInterface, @@ -116,7 +116,7 @@ func TestRuntimeArgumentImportMissingType(t *testing.T) { _, err := runtime.ExecuteScript( Script{ Source: script, - Arguments: encodeArgs([]cadence.Value{ + Arguments: encodeArgs( cadence.Struct{}. WithType(&cadence.StructType{ Location: common.AddressLocation{ @@ -125,7 +125,7 @@ func TestRuntimeArgumentImportMissingType(t *testing.T) { }, QualifiedIdentifier: "Foo.Bar", }), - }), + ), }, Context{ Interface: runtimeInterface, From a780497851fb20b94830dadab10c133721eb0e22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20M=C3=BCller?= Date: Fri, 1 Sep 2023 10:27:13 -0700 Subject: [PATCH 04/39] add the start of a WebAssembly contract allow instantiating a module without imports and allow access to function exports --- runtime/cmd/cmd.go | 4 + runtime/environment.go | 4 + runtime/interface.go | 2 + runtime/runtime_test.go | 9 ++ runtime/stdlib/builtin.go | 2 + runtime/stdlib/webassembly.cdc | 23 +++ runtime/stdlib/webassembly.gen.go | 178 +++++++++++++++++++++ runtime/stdlib/webassembly.go | 219 +++++++++++++++++++++++++ runtime/webassembly_test.go | 257 ++++++++++++++++++++++++++++++ 9 files changed, 698 insertions(+) create mode 100644 runtime/stdlib/webassembly.cdc create mode 100644 runtime/stdlib/webassembly.gen.go create mode 100644 runtime/stdlib/webassembly.go create mode 100644 runtime/webassembly_test.go diff --git a/runtime/cmd/cmd.go b/runtime/cmd/cmd.go index d674d9f6f0..43d4152617 100644 --- a/runtime/cmd/cmd.go +++ b/runtime/cmd/cmd.go @@ -402,6 +402,10 @@ func (*StandardLibraryHandler) BLSAggregateSignatures(_ [][]byte) ([]byte, error return nil, goerrors.New("crypto functionality is not available in this environment") } +func (*StandardLibraryHandler) CompileWebAssembly(_ []byte) (stdlib.WebAssemblyModule, error) { + return nil, goerrors.New("WebAssembly functionality is not available in this environment") +} + func (h *StandardLibraryHandler) NewOnEventEmittedHandler() interpreter.OnEventEmittedFunc { return func( inter *interpreter.Interpreter, diff --git a/runtime/environment.go b/runtime/environment.go index d32ca5ec58..742b8df23a 100644 --- a/runtime/environment.go +++ b/runtime/environment.go @@ -681,6 +681,10 @@ func (e *interpreterEnvironment) Hash(data []byte, tag string, algorithm sema.Ha return e.runtimeInterface.Hash(data, tag, algorithm) } +func (e *interpreterEnvironment) CompileWebAssembly(bytes []byte) (stdlib.WebAssemblyModule, error) { + return e.runtimeInterface.CompileWebAssembly(bytes) +} + func (e *interpreterEnvironment) DecodeArgument(argument []byte, argumentType cadence.Type) (cadence.Value, error) { return e.runtimeInterface.DecodeArgument(argument, argumentType) } diff --git a/runtime/interface.go b/runtime/interface.go index 7f39261d4a..59ec6e3bb7 100644 --- a/runtime/interface.go +++ b/runtime/interface.go @@ -27,6 +27,7 @@ import ( "github.com/onflow/cadence" "github.com/onflow/cadence/runtime/common" "github.com/onflow/cadence/runtime/interpreter" + "github.com/onflow/cadence/runtime/stdlib" ) type Interface interface { @@ -143,6 +144,7 @@ type Interface interface { ) // GenerateAccountID generates a new, *non-zero*, unique ID for the given account. GenerateAccountID(address common.Address) (uint64, error) + CompileWebAssembly(bytes []byte) (stdlib.WebAssemblyModule, error) } type MeterInterface interface { diff --git a/runtime/runtime_test.go b/runtime/runtime_test.go index eb6fbf1149..a196cc460f 100644 --- a/runtime/runtime_test.go +++ b/runtime/runtime_test.go @@ -227,6 +227,7 @@ type testRuntimeInterface struct { interactionUsed func() (uint64, error) updatedContractCode bool generateAccountID func(address common.Address) (uint64, error) + compileWebAssembly func(bytes []byte) (stdlib.WebAssemblyModule, error) uuid uint64 accountIDs map[common.Address]uint64 @@ -618,6 +619,14 @@ func (i *testRuntimeInterface) BLSAggregatePublicKeys(keys []*stdlib.PublicKey) return i.blsAggregatePublicKeys(keys) } +func (i *testRuntimeInterface) CompileWebAssembly(bytes []byte) (stdlib.WebAssemblyModule, error) { + if i.compileWebAssembly == nil { + return nil, nil + } + + return i.compileWebAssembly(bytes) +} + func (i *testRuntimeInterface) GetAccountContractNames(address Address) ([]string, error) { if i.getAccountContractNames == nil { return []string{}, nil diff --git a/runtime/stdlib/builtin.go b/runtime/stdlib/builtin.go index d462a5f83d..038001b9c9 100644 --- a/runtime/stdlib/builtin.go +++ b/runtime/stdlib/builtin.go @@ -34,6 +34,7 @@ type StandardLibraryHandler interface { BLSPublicKeyAggregator BLSSignatureAggregator Hasher + WebAssemblyContractHandler } func DefaultStandardLibraryValues(handler StandardLibraryHandler) []StandardLibraryValue { @@ -51,6 +52,7 @@ func DefaultStandardLibraryValues(handler StandardLibraryHandler) []StandardLibr NewPublicKeyConstructor(handler, handler, handler), NewBLSContract(nil, handler), NewHashAlgorithmConstructor(handler), + NewWebAssemblyContract(nil, handler), } } diff --git a/runtime/stdlib/webassembly.cdc b/runtime/stdlib/webassembly.cdc new file mode 100644 index 0000000000..773bc68c56 --- /dev/null +++ b/runtime/stdlib/webassembly.cdc @@ -0,0 +1,23 @@ +access(all) +contract WebAssembly { + + /// Compile WebAssembly binary code into a Module + /// and instantiate it with the given imports. + access(all) + view fun compileAndInstantiate(bytes: [UInt8]): &WebAssembly.InstantiatedSource + + access(all) + struct InstantiatedSource { + + /// The instance. + access(all) + let instance: &WebAssembly.Instance + } + + struct Instance { + + /// Get the exported value. + access(all) + view fun getExport(name: String): T + } +} diff --git a/runtime/stdlib/webassembly.gen.go b/runtime/stdlib/webassembly.gen.go new file mode 100644 index 0000000000..3317c83c53 --- /dev/null +++ b/runtime/stdlib/webassembly.gen.go @@ -0,0 +1,178 @@ +// Code generated from webassembly.cdc. DO NOT EDIT. +/* + * Cadence - The resource-oriented smart contract programming language + * + * Copyright Dapper Labs, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package stdlib + +import ( + "github.com/onflow/cadence/runtime/ast" + "github.com/onflow/cadence/runtime/common" + "github.com/onflow/cadence/runtime/sema" +) + +const WebAssemblyTypeCompileAndInstantiateFunctionName = "compileAndInstantiate" + +var WebAssemblyTypeCompileAndInstantiateFunctionType = &sema.FunctionType{ + Purity: sema.FunctionPurityView, + Parameters: []sema.Parameter{ + { + Identifier: "bytes", + TypeAnnotation: sema.NewTypeAnnotation(&sema.VariableSizedType{ + Type: UInt8Type, + }), + }, + }, + ReturnTypeAnnotation: sema.NewTypeAnnotation( + &sema.ReferenceType{ + Type: WebAssembly_InstantiatedSourceType, + Authorization: sema.UnauthorizedAccess, + }, + ), +} + +const WebAssemblyTypeCompileAndInstantiateFunctionDocString = ` +Compile WebAssembly binary code into a Module +and instantiate it with the given imports. +` + +const WebAssembly_InstantiatedSourceTypeInstanceFieldName = "instance" + +var WebAssembly_InstantiatedSourceTypeInstanceFieldType = &sema.ReferenceType{ + Type: WebAssembly_InstanceType, + Authorization: sema.UnauthorizedAccess, +} + +const WebAssembly_InstantiatedSourceTypeInstanceFieldDocString = ` +The instance. +` + +const WebAssembly_InstantiatedSourceTypeName = "InstantiatedSource" + +var WebAssembly_InstantiatedSourceType = func() *sema.CompositeType { + var t = &sema.CompositeType{ + Identifier: WebAssembly_InstantiatedSourceTypeName, + Kind: common.CompositeKindStructure, + ImportableBuiltin: false, + HasComputedMembers: true, + } + + return t +}() + +func init() { + var members = []*sema.Member{ + sema.NewUnmeteredFieldMember( + WebAssembly_InstantiatedSourceType, + sema.PrimitiveAccess(ast.AccessAll), + ast.VariableKindConstant, + WebAssembly_InstantiatedSourceTypeInstanceFieldName, + WebAssembly_InstantiatedSourceTypeInstanceFieldType, + WebAssembly_InstantiatedSourceTypeInstanceFieldDocString, + ), + } + + WebAssembly_InstantiatedSourceType.Members = sema.MembersAsMap(members) + WebAssembly_InstantiatedSourceType.Fields = sema.MembersFieldNames(members) +} + +const WebAssembly_InstanceTypeGetExportFunctionName = "getExport" + +var WebAssembly_InstanceTypeGetExportFunctionTypeParameterT = &sema.TypeParameter{ + Name: "T", + TypeBound: AnyStructType, +} + +var WebAssembly_InstanceTypeGetExportFunctionType = &sema.FunctionType{ + Purity: sema.FunctionPurityView, + TypeParameters: []*sema.TypeParameter{ + WebAssembly_InstanceTypeGetExportFunctionTypeParameterT, + }, + Parameters: []sema.Parameter{ + { + Identifier: "name", + TypeAnnotation: sema.NewTypeAnnotation(StringType), + }, + }, + ReturnTypeAnnotation: sema.NewTypeAnnotation( + &sema.GenericType{ + TypeParameter: WebAssembly_InstanceTypeGetExportFunctionTypeParameterT, + }, + ), +} + +const WebAssembly_InstanceTypeGetExportFunctionDocString = ` +Get the exported value. +` + +const WebAssembly_InstanceTypeName = "Instance" + +var WebAssembly_InstanceType = func() *sema.CompositeType { + var t = &sema.CompositeType{ + Identifier: WebAssembly_InstanceTypeName, + Kind: common.CompositeKindStructure, + ImportableBuiltin: false, + HasComputedMembers: true, + } + + return t +}() + +func init() { + var members = []*sema.Member{ + sema.NewUnmeteredFunctionMember( + WebAssembly_InstanceType, + sema.PrimitiveAccess(ast.AccessAll), + WebAssembly_InstanceTypeGetExportFunctionName, + WebAssembly_InstanceTypeGetExportFunctionType, + WebAssembly_InstanceTypeGetExportFunctionDocString, + ), + } + + WebAssembly_InstanceType.Members = sema.MembersAsMap(members) + WebAssembly_InstanceType.Fields = sema.MembersFieldNames(members) +} + +const WebAssemblyTypeName = "WebAssembly" + +var WebAssemblyType = func() *sema.CompositeType { + var t = &sema.CompositeType{ + Identifier: WebAssemblyTypeName, + Kind: common.CompositeKindContract, + ImportableBuiltin: false, + HasComputedMembers: true, + } + + t.SetNestedType(WebAssembly_InstantiatedSourceTypeName, WebAssembly_InstantiatedSourceType) + t.SetNestedType(WebAssembly_InstanceTypeName, WebAssembly_InstanceType) + return t +}() + +func init() { + var members = []*sema.Member{ + sema.NewUnmeteredFunctionMember( + WebAssemblyType, + sema.PrimitiveAccess(ast.AccessAll), + WebAssemblyTypeCompileAndInstantiateFunctionName, + WebAssemblyTypeCompileAndInstantiateFunctionType, + WebAssemblyTypeCompileAndInstantiateFunctionDocString, + ), + } + + WebAssemblyType.Members = sema.MembersAsMap(members) + WebAssemblyType.Fields = sema.MembersFieldNames(members) +} diff --git a/runtime/stdlib/webassembly.go b/runtime/stdlib/webassembly.go new file mode 100644 index 0000000000..73b9a3961f --- /dev/null +++ b/runtime/stdlib/webassembly.go @@ -0,0 +1,219 @@ +/* + * Cadence - The resource-oriented smart contract programming language + * + * Copyright Dapper Labs, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package stdlib + +import ( + "github.com/onflow/cadence/runtime/common" + "github.com/onflow/cadence/runtime/errors" + "github.com/onflow/cadence/runtime/interpreter" + "github.com/onflow/cadence/runtime/sema" +) + +//go:generate go run ../sema/gen -p stdlib webassembly.cdc webassembly.gen.go + +var AnyStructType = sema.AnyStructType +var StringType = sema.StringType + +func newWebAssemblyCompileAndInstantiateFunction( + gauge common.MemoryGauge, + handler WebAssemblyContractHandler, +) *interpreter.HostFunctionValue { + return interpreter.NewHostFunctionValue( + gauge, + WebAssemblyTypeCompileAndInstantiateFunctionType, + func(invocation interpreter.Invocation) interpreter.Value { + inter := invocation.Interpreter + locationRange := invocation.LocationRange + + bytesValue := invocation.Arguments[0] + bytes, err := interpreter.ByteArrayValueToByteSlice(inter, bytesValue, locationRange) + if err != nil { + panic(err) + } + + module, err := handler.CompileWebAssembly(bytes) + if err != nil { + panic(err) + } + + instance, err := module.InstantiateWebAssemblyModule(gauge) + if err != nil { + panic(err) + } + + instanceValue := NewWebAssemblyInstanceValue(gauge, instance) + instanceReferenceValue := interpreter.NewEphemeralReferenceValue( + gauge, + interpreter.UnauthorizedAccess, + instanceValue, + WebAssembly_InstanceType, + ) + + instantiatedSourceValue := NewWebAssemblyInstantiatedSourceValue(gauge, instanceReferenceValue) + return interpreter.NewEphemeralReferenceValue( + gauge, + interpreter.UnauthorizedAccess, + instantiatedSourceValue, + WebAssembly_InstantiatedSourceType, + ) + }, + ) +} + +func newWebAssemblyInstanceGetExportFunction( + gauge common.MemoryGauge, + instance WebAssemblyInstance, +) *interpreter.HostFunctionValue { + return interpreter.NewHostFunctionValue( + gauge, + WebAssembly_InstanceTypeGetExportFunctionType, + func(invocation interpreter.Invocation) interpreter.Value { + inter := invocation.Interpreter + locationRange := invocation.LocationRange + + // Name + nameValue, ok := invocation.Arguments[0].(*interpreter.StringValue) + if !ok { + panic(errors.NewUnreachableError()) + } + name := nameValue.Str + + // Type + typeParameterPair := invocation.TypeParameterTypes.Oldest() + if typeParameterPair == nil { + panic(errors.NewUnreachableError()) + } + ty := typeParameterPair.Value + + // Get and check export + export, err := instance.GetExport(inter, name) + if err != nil { + panic(err) + } + if export == nil { + panic(errors.NewDefaultUserError( + "WebAssembly module does not have an export with name '%s'", + name, + )) + } + + if !sema.IsSubType(export.Type, ty) { + panic(interpreter.TypeMismatchError{ + ExpectedType: ty, + ActualType: export.Type, + LocationRange: locationRange, + }) + } + + return export.Value + }, + ) +} + +var webAssembly_InstanceStaticType = interpreter.ConvertSemaCompositeTypeToStaticCompositeType( + nil, + WebAssembly_InstanceType, +) + +func NewWebAssemblyInstanceValue( + gauge common.MemoryGauge, + instance WebAssemblyInstance, +) *interpreter.SimpleCompositeValue { + return interpreter.NewSimpleCompositeValue( + gauge, + WebAssembly_InstanceType.ID(), + webAssembly_InstanceStaticType, + WebAssembly_InstanceType.Fields, + map[string]interpreter.Value{ + WebAssembly_InstanceTypeGetExportFunctionName: newWebAssemblyInstanceGetExportFunction(gauge, instance), + }, + nil, + nil, + nil, + ) +} + +var webAssembly_InstantiatedSourceStaticType = interpreter.ConvertSemaCompositeTypeToStaticCompositeType( + nil, + WebAssembly_InstantiatedSourceType, +) + +func NewWebAssemblyInstantiatedSourceValue( + gauge common.MemoryGauge, + instanceValue interpreter.Value, +) *interpreter.SimpleCompositeValue { + return interpreter.NewSimpleCompositeValue( + gauge, + WebAssembly_InstantiatedSourceType.ID(), + webAssembly_InstantiatedSourceStaticType, + WebAssembly_InstantiatedSourceType.Fields, + map[string]interpreter.Value{ + WebAssembly_InstantiatedSourceTypeInstanceFieldName: instanceValue, + }, + nil, + nil, + nil, + ) +} + +type WebAssemblyModule interface { + InstantiateWebAssemblyModule(gauge common.MemoryGauge) (WebAssemblyInstance, error) +} + +type WebAssemblyInstance interface { + GetExport(gauge common.MemoryGauge, name string) (*WebAssemblyExport, error) +} + +type WebAssemblyExport struct { + Type sema.Type + Value interpreter.Value +} + +type WebAssemblyContractHandler interface { + CompileWebAssembly(bytes []byte) (WebAssemblyModule, error) +} + +var WebAssemblyTypeStaticType = interpreter.ConvertSemaToStaticType(nil, WebAssemblyType) + +func NewWebAssemblyContract( + gauge common.MemoryGauge, + handler WebAssemblyContractHandler, +) StandardLibraryValue { + webAssemblyContractFields := map[string]interpreter.Value{ + WebAssemblyTypeCompileAndInstantiateFunctionName: newWebAssemblyCompileAndInstantiateFunction(gauge, handler), + } + + webAssemblyContractValue := interpreter.NewSimpleCompositeValue( + gauge, + WebAssemblyType.ID(), + WebAssemblyTypeStaticType, + nil, + webAssemblyContractFields, + nil, + nil, + nil, + ) + + return StandardLibraryValue{ + Name: WebAssemblyTypeName, + Type: WebAssemblyType, + Value: webAssemblyContractValue, + Kind: common.DeclarationKindContract, + } +} diff --git a/runtime/webassembly_test.go b/runtime/webassembly_test.go new file mode 100644 index 0000000000..275802c1be --- /dev/null +++ b/runtime/webassembly_test.go @@ -0,0 +1,257 @@ +/* + * Cadence - The resource-oriented smart contract programming language + * + * Copyright Dapper Labs, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package runtime + +import ( + "fmt" + "testing" + + "github.com/bytecodealliance/wasmtime-go/v12" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/onflow/cadence" + "github.com/onflow/cadence/encoding/json" + "github.com/onflow/cadence/runtime/common" + "github.com/onflow/cadence/runtime/errors" + "github.com/onflow/cadence/runtime/interpreter" + "github.com/onflow/cadence/runtime/sema" + "github.com/onflow/cadence/runtime/stdlib" +) + +type WasmtimeModule struct { + Module *wasmtime.Module + Store *wasmtime.Store +} + +var _ stdlib.WebAssemblyModule = WasmtimeModule{} + +func (m WasmtimeModule) InstantiateWebAssemblyModule(_ common.MemoryGauge) (stdlib.WebAssemblyInstance, error) { + instance, err := wasmtime.NewInstance(m.Store, m.Module, nil) + if err != nil { + return nil, err + } + return WasmtimeInstance{ + Instance: instance, + Store: m.Store, + }, nil +} + +type WasmtimeInstance struct { + Instance *wasmtime.Instance + Store *wasmtime.Store +} + +var _ stdlib.WebAssemblyInstance = WasmtimeInstance{} + +func wasmtimeValKindToSemaType(valKind wasmtime.ValKind) sema.Type { + switch valKind { + case wasmtime.KindI32: + return sema.Int32Type + + case wasmtime.KindI64: + return sema.Int64Type + + default: + return nil + } +} + +func (i WasmtimeInstance) GetExport(gauge common.MemoryGauge, name string) (*stdlib.WebAssemblyExport, error) { + extern := i.Instance.GetExport(i.Store, name) + if extern == nil { + return nil, nil + } + + if function := extern.Func(); function != nil { + return newWasmtimeFunctionWebAssemblyExport(gauge, function, i.Store) + } + + return nil, fmt.Errorf("unsupported export") +} + +func newWasmtimeFunctionWebAssemblyExport( + gauge common.MemoryGauge, + function *wasmtime.Func, + store *wasmtime.Store, +) ( + *stdlib.WebAssemblyExport, + error, +) { + funcType := function.Type(store) + + functionType := &sema.FunctionType{} + + // Parameters + + for _, paramType := range funcType.Params() { + paramKind := paramType.Kind() + parameterType := wasmtimeValKindToSemaType(paramKind) + if parameterType == nil { + return nil, fmt.Errorf( + "unsupported export: function with unsupported parameter type '%s'", + paramKind, + ) + } + functionType.Parameters = append( + functionType.Parameters, + sema.Parameter{ + TypeAnnotation: sema.NewTypeAnnotation(parameterType), + }, + ) + } + + // Result + + results := funcType.Results() + switch len(results) { + case 0: + break + + case 1: + result := results[0] + resultKind := result.Kind() + returnType := wasmtimeValKindToSemaType(resultKind) + if returnType == nil { + return nil, fmt.Errorf( + "unsupported export: function with unsupported result type '%s'", + resultKind, + ) + } + functionType.ReturnTypeAnnotation = sema.NewTypeAnnotation(returnType) + + default: + return nil, fmt.Errorf("unsupported export: function has more than one result") + } + + hostFunctionValue := interpreter.NewHostFunctionValue( + gauge, + functionType, + func(invocation interpreter.Invocation) interpreter.Value { + arguments := invocation.Arguments + + convertedArguments := make([]any, 0, len(arguments)) + + for i, argument := range arguments { + ty := functionType.Parameters[i].TypeAnnotation.Type + + var convertedArgument any + + switch ty { + case sema.Int32Type: + convertedArgument = int32(argument.(interpreter.Int32Value)) + + case sema.Int64Type: + convertedArgument = argument.(interpreter.Int64Value) + + default: + panic(errors.NewUnreachableError()) + } + + convertedArguments = append(convertedArguments, convertedArgument) + } + + result, err := function.Call(store, convertedArguments...) + if err != nil { + panic(err) + } + + switch result := result.(type) { + case int32: + return interpreter.Int32Value(result) + + case int64: + return interpreter.Int64Value(result) + + default: + panic(errors.NewUnreachableError()) + + } + }, + ) + + return &stdlib.WebAssemblyExport{ + Type: functionType, + Value: hostFunctionValue, + }, nil +} + +func TestRuntimeWebAssembly(t *testing.T) { + + t.Parallel() + + runtime := newTestInterpreterRuntime() + + addProgram := []byte{ + 0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x07, 0x01, 0x60, + 0x02, 0x7f, 0x7f, 0x01, 0x7f, 0x03, 0x02, 0x01, 0x00, 0x07, 0x07, 0x01, + 0x03, 0x61, 0x64, 0x64, 0x00, 0x00, 0x0a, 0x09, 0x01, 0x07, 0x00, 0x20, + 0x00, 0x20, 0x01, 0x6a, 0x0b, + } + + // language=cadence + script := []byte(` + access(all) + fun main(program: [UInt8], a: Int32, b: Int32): Int32 { + let instance = WebAssembly.compileAndInstantiate(bytes: program).instance + let add = instance.getExport(name: "add") + return add(a, b) + } + `) + + runtimeInterface := &testRuntimeInterface{ + storage: newTestLedger(nil, nil), + compileWebAssembly: func(bytes []byte) (stdlib.WebAssemblyModule, error) { + store := wasmtime.NewStore(wasmtime.NewEngine()) + module, err := wasmtime.NewModule(store.Engine, bytes) + if err != nil { + return nil, err + } + + return WasmtimeModule{ + Store: store, + Module: module, + }, nil + }, + decodeArgument: func(b []byte, _ cadence.Type) (cadence.Value, error) { + return json.Decode(nil, b) + }, + } + + result, err := runtime.ExecuteScript( + Script{ + Source: script, + Arguments: encodeArgs( + newBytesValue(addProgram), + cadence.Int32(1), + cadence.Int32(2), + ), + }, + Context{ + Interface: runtimeInterface, + Location: common.ScriptLocation{}, + }, + ) + + require.NoError(t, err) + assert.Equal(t, + cadence.Int32(3), + result, + ) +} From 02a01228c6bd97060acc390cbc6f9e8da8e3f897 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20M=C3=BCller?= Date: Fri, 22 Sep 2023 15:35:00 -0700 Subject: [PATCH 05/39] add comment explaining the program --- runtime/webassembly_test.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/runtime/webassembly_test.go b/runtime/webassembly_test.go index 275802c1be..1690f128d6 100644 --- a/runtime/webassembly_test.go +++ b/runtime/webassembly_test.go @@ -198,6 +198,8 @@ func TestRuntimeWebAssembly(t *testing.T) { runtime := newTestInterpreterRuntime() + // A simple program which exports a function `add` with type `(i32, i32) -> i32`, + // which sums the arguments and returns the result addProgram := []byte{ 0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x07, 0x01, 0x60, 0x02, 0x7f, 0x7f, 0x01, 0x7f, 0x03, 0x02, 0x01, 0x00, 0x07, 0x07, 0x01, From 8d9cbb6b4ea480c03a7051ec750a58250f5e5a8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20M=C3=BCller?= Date: Fri, 22 Sep 2023 15:35:10 -0700 Subject: [PATCH 06/39] convert type --- runtime/webassembly_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/webassembly_test.go b/runtime/webassembly_test.go index 1690f128d6..f6dc89c73b 100644 --- a/runtime/webassembly_test.go +++ b/runtime/webassembly_test.go @@ -158,7 +158,7 @@ func newWasmtimeFunctionWebAssemblyExport( convertedArgument = int32(argument.(interpreter.Int32Value)) case sema.Int64Type: - convertedArgument = argument.(interpreter.Int64Value) + convertedArgument = int64(argument.(interpreter.Int64Value)) default: panic(errors.NewUnreachableError()) From d4265f615a009a5d9d8fa731def58bdc8d4677e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20M=C3=BCller?= Date: Fri, 22 Sep 2023 16:44:27 -0700 Subject: [PATCH 07/39] inject WebAssembly standard library type into environment --- runtime/environment.go | 5 +++++ runtime/stdlib/builtin.go | 4 ++++ runtime/stdlib/webassembly.go | 6 ++++++ 3 files changed, 15 insertions(+) diff --git a/runtime/environment.go b/runtime/environment.go index 5416572caa..e8785a99ba 100644 --- a/runtime/environment.go +++ b/runtime/environment.go @@ -120,6 +120,11 @@ func newInterpreterEnvironment(config Config) *interpreterEnvironment { } env.InterpreterConfig = env.newInterpreterConfig() env.CheckerConfig = env.newCheckerConfig() + + for _, standardLibraryType := range stdlib.StandardLibraryTypes { + env.DeclareType(standardLibraryType) + } + return env } diff --git a/runtime/stdlib/builtin.go b/runtime/stdlib/builtin.go index 038001b9c9..0d26fdef44 100644 --- a/runtime/stdlib/builtin.go +++ b/runtime/stdlib/builtin.go @@ -62,3 +62,7 @@ func DefaultScriptStandardLibraryValues(handler StandardLibraryHandler) []Standa NewGetAuthAccountFunction(handler), ) } + +var StandardLibraryTypes = []StandardLibraryType{ + WebAssemblyContractType, +} diff --git a/runtime/stdlib/webassembly.go b/runtime/stdlib/webassembly.go index 73b9a3961f..5601c3a6d1 100644 --- a/runtime/stdlib/webassembly.go +++ b/runtime/stdlib/webassembly.go @@ -217,3 +217,9 @@ func NewWebAssemblyContract( Kind: common.DeclarationKindContract, } } + +var WebAssemblyContractType = StandardLibraryType{ + Name: WebAssemblyTypeName, + Type: WebAssemblyType, + Kind: common.DeclarationKindContract, +} From 384eef210cfd4b3230f639b294cecde3886ff81d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20M=C3=BCller?= Date: Fri, 22 Sep 2023 17:13:20 -0700 Subject: [PATCH 08/39] gate WebAssembly behind feture flag --- runtime/config.go | 2 ++ runtime/environment.go | 5 +++-- runtime/stdlib/builtin.go | 6 ------ runtime/webassembly_test.go | 41 ++++++++++++++++++++++++++++++++++--- 4 files changed, 43 insertions(+), 11 deletions(-) diff --git a/runtime/config.go b/runtime/config.go index 891e9e5032..9e762814d5 100644 --- a/runtime/config.go +++ b/runtime/config.go @@ -37,4 +37,6 @@ type Config struct { CoverageReport *CoverageReport // AttachmentsEnabled specifies if attachments are enabled AttachmentsEnabled bool + // WebAssemblyEnabled specifies if the WebAssembly API is enabled + WebAssemblyEnabled bool } diff --git a/runtime/environment.go b/runtime/environment.go index e8785a99ba..821c0aa346 100644 --- a/runtime/environment.go +++ b/runtime/environment.go @@ -121,8 +121,9 @@ func newInterpreterEnvironment(config Config) *interpreterEnvironment { env.InterpreterConfig = env.newInterpreterConfig() env.CheckerConfig = env.newCheckerConfig() - for _, standardLibraryType := range stdlib.StandardLibraryTypes { - env.DeclareType(standardLibraryType) + if config.WebAssemblyEnabled { + env.DeclareValue(stdlib.NewWebAssemblyContract(nil, env)) + env.DeclareType(stdlib.WebAssemblyContractType) } return env diff --git a/runtime/stdlib/builtin.go b/runtime/stdlib/builtin.go index 0d26fdef44..d462a5f83d 100644 --- a/runtime/stdlib/builtin.go +++ b/runtime/stdlib/builtin.go @@ -34,7 +34,6 @@ type StandardLibraryHandler interface { BLSPublicKeyAggregator BLSSignatureAggregator Hasher - WebAssemblyContractHandler } func DefaultStandardLibraryValues(handler StandardLibraryHandler) []StandardLibraryValue { @@ -52,7 +51,6 @@ func DefaultStandardLibraryValues(handler StandardLibraryHandler) []StandardLibr NewPublicKeyConstructor(handler, handler, handler), NewBLSContract(nil, handler), NewHashAlgorithmConstructor(handler), - NewWebAssemblyContract(nil, handler), } } @@ -62,7 +60,3 @@ func DefaultScriptStandardLibraryValues(handler StandardLibraryHandler) []Standa NewGetAuthAccountFunction(handler), ) } - -var StandardLibraryTypes = []StandardLibraryType{ - WebAssemblyContractType, -} diff --git a/runtime/webassembly_test.go b/runtime/webassembly_test.go index 2aca7615bc..85754907ab 100644 --- a/runtime/webassembly_test.go +++ b/runtime/webassembly_test.go @@ -35,6 +35,7 @@ import ( "github.com/onflow/cadence/runtime/sema" "github.com/onflow/cadence/runtime/stdlib" . "github.com/onflow/cadence/runtime/tests/runtime_utils" + . "github.com/onflow/cadence/runtime/tests/utils" ) type WasmtimeModule struct { @@ -198,7 +199,9 @@ func TestRuntimeWebAssembly(t *testing.T) { t.Parallel() - runtime := NewTestInterpreterRuntime() + runtime := NewTestInterpreterRuntimeWithConfig(Config{ + WebAssemblyEnabled: true, + }) // A simple program which exports a function `add` with type `(i32, i32) -> i32`, // which sums the arguments and returns the result @@ -222,8 +225,10 @@ func TestRuntimeWebAssembly(t *testing.T) { runtimeInterface := &TestRuntimeInterface{ Storage: NewTestLedger(nil, nil), OnCompileWebAssembly: func(bytes []byte) (stdlib.WebAssemblyModule, error) { - store := wasmtime.NewStore(wasmtime.NewEngine()) - module, err := wasmtime.NewModule(store.Engine, bytes) + engine := wasmtime.NewEngine() + store := wasmtime.NewStore(engine) + + module, err := wasmtime.NewModule(engine, bytes) if err != nil { return nil, err } @@ -259,3 +264,33 @@ func TestRuntimeWebAssembly(t *testing.T) { result, ) } + +func TestRuntimeWebAssemblyDisabled(t *testing.T) { + + t.Parallel() + + runtime := NewTestInterpreterRuntimeWithConfig(Config{ + WebAssemblyEnabled: false, + }) + + // language=cadence + script := []byte(` + access(all) + fun main() { + WebAssembly + } + `) + + runtimeInterface := &TestRuntimeInterface{} + + _, err := runtime.ExecuteScript( + Script{ + Source: script, + }, + Context{ + Interface: runtimeInterface, + Location: common.ScriptLocation{}, + }, + ) + RequireError(t, err) +} From 4240bf97619f4232ef91bf965c20f832081c7ab2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20M=C3=BCller?= Date: Fri, 22 Sep 2023 17:19:54 -0700 Subject: [PATCH 09/39] move wasmtime-based WebAssembly module to runtime, so it can be reused --- runtime/webassembly.go | 188 ++++++++++++++++++++++++++++++++++++ runtime/webassembly_test.go | 161 +----------------------------- 2 files changed, 189 insertions(+), 160 deletions(-) create mode 100644 runtime/webassembly.go diff --git a/runtime/webassembly.go b/runtime/webassembly.go new file mode 100644 index 0000000000..6b0e59eec5 --- /dev/null +++ b/runtime/webassembly.go @@ -0,0 +1,188 @@ +/* + * Cadence - The resource-oriented smart contract programming language + * + * Copyright Dapper Labs, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package runtime + +import ( + "fmt" + + "github.com/bytecodealliance/wasmtime-go/v12" + + "github.com/onflow/cadence/runtime/common" + "github.com/onflow/cadence/runtime/errors" + "github.com/onflow/cadence/runtime/interpreter" + "github.com/onflow/cadence/runtime/sema" + "github.com/onflow/cadence/runtime/stdlib" +) + +type WasmtimeModule struct { + Module *wasmtime.Module + Store *wasmtime.Store +} + +var _ stdlib.WebAssemblyModule = WasmtimeModule{} + +func (m WasmtimeModule) InstantiateWebAssemblyModule(_ common.MemoryGauge) (stdlib.WebAssemblyInstance, error) { + instance, err := wasmtime.NewInstance(m.Store, m.Module, nil) + if err != nil { + return nil, err + } + return WasmtimeInstance{ + Instance: instance, + Store: m.Store, + }, nil +} + +type WasmtimeInstance struct { + Instance *wasmtime.Instance + Store *wasmtime.Store +} + +var _ stdlib.WebAssemblyInstance = WasmtimeInstance{} + +func wasmtimeValKindToSemaType(valKind wasmtime.ValKind) sema.Type { + switch valKind { + case wasmtime.KindI32: + return sema.Int32Type + + case wasmtime.KindI64: + return sema.Int64Type + + default: + return nil + } +} + +func (i WasmtimeInstance) GetExport(gauge common.MemoryGauge, name string) (*stdlib.WebAssemblyExport, error) { + extern := i.Instance.GetExport(i.Store, name) + if extern == nil { + return nil, nil + } + + if function := extern.Func(); function != nil { + return newWasmtimeFunctionWebAssemblyExport(gauge, function, i.Store) + } + + return nil, fmt.Errorf("unsupported export") +} + +func newWasmtimeFunctionWebAssemblyExport( + gauge common.MemoryGauge, + function *wasmtime.Func, + store *wasmtime.Store, +) ( + *stdlib.WebAssemblyExport, + error, +) { + funcType := function.Type(store) + + functionType := &sema.FunctionType{} + + // Parameters + + for _, paramType := range funcType.Params() { + paramKind := paramType.Kind() + parameterType := wasmtimeValKindToSemaType(paramKind) + if parameterType == nil { + return nil, fmt.Errorf( + "unsupported export: function with unsupported parameter type '%s'", + paramKind, + ) + } + functionType.Parameters = append( + functionType.Parameters, + sema.Parameter{ + TypeAnnotation: sema.NewTypeAnnotation(parameterType), + }, + ) + } + + // Result + + results := funcType.Results() + switch len(results) { + case 0: + break + + case 1: + result := results[0] + resultKind := result.Kind() + returnType := wasmtimeValKindToSemaType(resultKind) + if returnType == nil { + return nil, fmt.Errorf( + "unsupported export: function with unsupported result type '%s'", + resultKind, + ) + } + functionType.ReturnTypeAnnotation = sema.NewTypeAnnotation(returnType) + + default: + return nil, fmt.Errorf("unsupported export: function has more than one result") + } + + hostFunctionValue := interpreter.NewHostFunctionValue( + gauge, + functionType, + func(invocation interpreter.Invocation) interpreter.Value { + arguments := invocation.Arguments + + convertedArguments := make([]any, 0, len(arguments)) + + for i, argument := range arguments { + ty := functionType.Parameters[i].TypeAnnotation.Type + + var convertedArgument any + + switch ty { + case sema.Int32Type: + convertedArgument = int32(argument.(interpreter.Int32Value)) + + case sema.Int64Type: + convertedArgument = int64(argument.(interpreter.Int64Value)) + + default: + panic(errors.NewUnreachableError()) + } + + convertedArguments = append(convertedArguments, convertedArgument) + } + + result, err := function.Call(store, convertedArguments...) + if err != nil { + panic(err) + } + + switch result := result.(type) { + case int32: + return interpreter.Int32Value(result) + + case int64: + return interpreter.Int64Value(result) + + default: + panic(errors.NewUnreachableError()) + + } + }, + ) + + return &stdlib.WebAssemblyExport{ + Type: functionType, + Value: hostFunctionValue, + }, nil +} diff --git a/runtime/webassembly_test.go b/runtime/webassembly_test.go index 85754907ab..4d64903c8d 100644 --- a/runtime/webassembly_test.go +++ b/runtime/webassembly_test.go @@ -19,7 +19,6 @@ package runtime_test import ( - "fmt" "testing" "github.com/bytecodealliance/wasmtime-go/v12" @@ -30,170 +29,12 @@ import ( "github.com/onflow/cadence/encoding/json" . "github.com/onflow/cadence/runtime" "github.com/onflow/cadence/runtime/common" - "github.com/onflow/cadence/runtime/errors" - "github.com/onflow/cadence/runtime/interpreter" - "github.com/onflow/cadence/runtime/sema" + "github.com/onflow/cadence/runtime/stdlib" . "github.com/onflow/cadence/runtime/tests/runtime_utils" . "github.com/onflow/cadence/runtime/tests/utils" ) -type WasmtimeModule struct { - Module *wasmtime.Module - Store *wasmtime.Store -} - -var _ stdlib.WebAssemblyModule = WasmtimeModule{} - -func (m WasmtimeModule) InstantiateWebAssemblyModule(_ common.MemoryGauge) (stdlib.WebAssemblyInstance, error) { - instance, err := wasmtime.NewInstance(m.Store, m.Module, nil) - if err != nil { - return nil, err - } - return WasmtimeInstance{ - Instance: instance, - Store: m.Store, - }, nil -} - -type WasmtimeInstance struct { - Instance *wasmtime.Instance - Store *wasmtime.Store -} - -var _ stdlib.WebAssemblyInstance = WasmtimeInstance{} - -func wasmtimeValKindToSemaType(valKind wasmtime.ValKind) sema.Type { - switch valKind { - case wasmtime.KindI32: - return sema.Int32Type - - case wasmtime.KindI64: - return sema.Int64Type - - default: - return nil - } -} - -func (i WasmtimeInstance) GetExport(gauge common.MemoryGauge, name string) (*stdlib.WebAssemblyExport, error) { - extern := i.Instance.GetExport(i.Store, name) - if extern == nil { - return nil, nil - } - - if function := extern.Func(); function != nil { - return newWasmtimeFunctionWebAssemblyExport(gauge, function, i.Store) - } - - return nil, fmt.Errorf("unsupported export") -} - -func newWasmtimeFunctionWebAssemblyExport( - gauge common.MemoryGauge, - function *wasmtime.Func, - store *wasmtime.Store, -) ( - *stdlib.WebAssemblyExport, - error, -) { - funcType := function.Type(store) - - functionType := &sema.FunctionType{} - - // Parameters - - for _, paramType := range funcType.Params() { - paramKind := paramType.Kind() - parameterType := wasmtimeValKindToSemaType(paramKind) - if parameterType == nil { - return nil, fmt.Errorf( - "unsupported export: function with unsupported parameter type '%s'", - paramKind, - ) - } - functionType.Parameters = append( - functionType.Parameters, - sema.Parameter{ - TypeAnnotation: sema.NewTypeAnnotation(parameterType), - }, - ) - } - - // Result - - results := funcType.Results() - switch len(results) { - case 0: - break - - case 1: - result := results[0] - resultKind := result.Kind() - returnType := wasmtimeValKindToSemaType(resultKind) - if returnType == nil { - return nil, fmt.Errorf( - "unsupported export: function with unsupported result type '%s'", - resultKind, - ) - } - functionType.ReturnTypeAnnotation = sema.NewTypeAnnotation(returnType) - - default: - return nil, fmt.Errorf("unsupported export: function has more than one result") - } - - hostFunctionValue := interpreter.NewHostFunctionValue( - gauge, - functionType, - func(invocation interpreter.Invocation) interpreter.Value { - arguments := invocation.Arguments - - convertedArguments := make([]any, 0, len(arguments)) - - for i, argument := range arguments { - ty := functionType.Parameters[i].TypeAnnotation.Type - - var convertedArgument any - - switch ty { - case sema.Int32Type: - convertedArgument = int32(argument.(interpreter.Int32Value)) - - case sema.Int64Type: - convertedArgument = int64(argument.(interpreter.Int64Value)) - - default: - panic(errors.NewUnreachableError()) - } - - convertedArguments = append(convertedArguments, convertedArgument) - } - - result, err := function.Call(store, convertedArguments...) - if err != nil { - panic(err) - } - - switch result := result.(type) { - case int32: - return interpreter.Int32Value(result) - - case int64: - return interpreter.Int64Value(result) - - default: - panic(errors.NewUnreachableError()) - - } - }, - ) - - return &stdlib.WebAssemblyExport{ - Type: functionType, - Value: hostFunctionValue, - }, nil -} func TestRuntimeWebAssembly(t *testing.T) { From 57b8d6ac627746a90bdc37bbe9f1b7c8ca000a46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20M=C3=BCller?= Date: Fri, 22 Sep 2023 17:21:04 -0700 Subject: [PATCH 10/39] rename --- runtime/webassembly.go | 6 +++--- runtime/webassembly_test.go | 3 +-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/runtime/webassembly.go b/runtime/webassembly.go index 6b0e59eec5..697e89bc9c 100644 --- a/runtime/webassembly.go +++ b/runtime/webassembly.go @@ -30,14 +30,14 @@ import ( "github.com/onflow/cadence/runtime/stdlib" ) -type WasmtimeModule struct { +type WasmtimeWebAssemblyModule struct { Module *wasmtime.Module Store *wasmtime.Store } -var _ stdlib.WebAssemblyModule = WasmtimeModule{} +var _ stdlib.WebAssemblyModule = WasmtimeWebAssemblyModule{} -func (m WasmtimeModule) InstantiateWebAssemblyModule(_ common.MemoryGauge) (stdlib.WebAssemblyInstance, error) { +func (m WasmtimeWebAssemblyModule) InstantiateWebAssemblyModule(_ common.MemoryGauge) (stdlib.WebAssemblyInstance, error) { instance, err := wasmtime.NewInstance(m.Store, m.Module, nil) if err != nil { return nil, err diff --git a/runtime/webassembly_test.go b/runtime/webassembly_test.go index 4d64903c8d..de6cfb1698 100644 --- a/runtime/webassembly_test.go +++ b/runtime/webassembly_test.go @@ -35,7 +35,6 @@ import ( . "github.com/onflow/cadence/runtime/tests/utils" ) - func TestRuntimeWebAssembly(t *testing.T) { t.Parallel() @@ -74,7 +73,7 @@ func TestRuntimeWebAssembly(t *testing.T) { return nil, err } - return WasmtimeModule{ + return WasmtimeWebAssemblyModule{ Store: store, Module: module, }, nil From 8d30d3a9f93775c2248ec39a9733e0e3ee4a5f44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20M=C3=BCller?= Date: Fri, 22 Sep 2023 17:24:03 -0700 Subject: [PATCH 11/39] extract constructor for wasmtime-based WebAssembly module --- runtime/webassembly.go | 16 ++++++++++++++++ runtime/webassembly_test.go | 14 +------------- 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/runtime/webassembly.go b/runtime/webassembly.go index 697e89bc9c..3187678bfd 100644 --- a/runtime/webassembly.go +++ b/runtime/webassembly.go @@ -35,6 +35,22 @@ type WasmtimeWebAssemblyModule struct { Store *wasmtime.Store } +func NewWasmtimeWebAssemblyModule(bytes []byte) (stdlib.WebAssemblyModule, error) { + engine := wasmtime.NewEngine() + store := wasmtime.NewStore(engine) + + // TODO: wrap error + module, err := wasmtime.NewModule(engine, bytes) + if err != nil { + return nil, err + } + + return WasmtimeWebAssemblyModule{ + Store: store, + Module: module, + }, nil +} + var _ stdlib.WebAssemblyModule = WasmtimeWebAssemblyModule{} func (m WasmtimeWebAssemblyModule) InstantiateWebAssemblyModule(_ common.MemoryGauge) (stdlib.WebAssemblyInstance, error) { diff --git a/runtime/webassembly_test.go b/runtime/webassembly_test.go index de6cfb1698..e18e344a20 100644 --- a/runtime/webassembly_test.go +++ b/runtime/webassembly_test.go @@ -21,7 +21,6 @@ package runtime_test import ( "testing" - "github.com/bytecodealliance/wasmtime-go/v12" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -65,18 +64,7 @@ func TestRuntimeWebAssembly(t *testing.T) { runtimeInterface := &TestRuntimeInterface{ Storage: NewTestLedger(nil, nil), OnCompileWebAssembly: func(bytes []byte) (stdlib.WebAssemblyModule, error) { - engine := wasmtime.NewEngine() - store := wasmtime.NewStore(engine) - - module, err := wasmtime.NewModule(engine, bytes) - if err != nil { - return nil, err - } - - return WasmtimeWebAssemblyModule{ - Store: store, - Module: module, - }, nil + return NewWasmtimeWebAssemblyModule(bytes) }, OnDecodeArgument: func(b []byte, _ cadence.Type) (cadence.Value, error) { return json.Decode(nil, b) From 606c3a2eeaa8a3ed72d88b1648cd884be98f5076 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20M=C3=BCller?= Date: Fri, 22 Sep 2023 18:43:57 -0700 Subject: [PATCH 12/39] add metering using fuel mechanism --- runtime/common/computationkind.go | 4 +++ runtime/webassembly.go | 56 +++++++++++++++++++++++++++---- runtime/webassembly_test.go | 35 ++++++++++++++++--- 3 files changed, 85 insertions(+), 10 deletions(-) diff --git a/runtime/common/computationkind.go b/runtime/common/computationkind.go index 90b96e858e..14fe17d6d7 100644 --- a/runtime/common/computationkind.go +++ b/runtime/common/computationkind.go @@ -142,4 +142,8 @@ const ( // RLP ComputationKindSTDLIBRLPDecodeString ComputationKindSTDLIBRLPDecodeList + _ + _ + // WebAssembly + ComputationKindWebAssemblyFuel ) diff --git a/runtime/webassembly.go b/runtime/webassembly.go index 3187678bfd..d585f4fe2d 100644 --- a/runtime/webassembly.go +++ b/runtime/webassembly.go @@ -36,12 +36,15 @@ type WasmtimeWebAssemblyModule struct { } func NewWasmtimeWebAssemblyModule(bytes []byte) (stdlib.WebAssemblyModule, error) { - engine := wasmtime.NewEngine() + config := wasmtime.NewConfig() + config.SetConsumeFuel(true) + + engine := wasmtime.NewEngineWithConfig(config) store := wasmtime.NewStore(engine) - // TODO: wrap error module, err := wasmtime.NewModule(engine, bytes) if err != nil { + // TODO: wrap error return nil, err } @@ -56,20 +59,21 @@ var _ stdlib.WebAssemblyModule = WasmtimeWebAssemblyModule{} func (m WasmtimeWebAssemblyModule) InstantiateWebAssemblyModule(_ common.MemoryGauge) (stdlib.WebAssemblyInstance, error) { instance, err := wasmtime.NewInstance(m.Store, m.Module, nil) if err != nil { + // TODO: wrap error return nil, err } - return WasmtimeInstance{ + return WasmtimeWebAssemblyInstance{ Instance: instance, Store: m.Store, }, nil } -type WasmtimeInstance struct { +type WasmtimeWebAssemblyInstance struct { Instance *wasmtime.Instance Store *wasmtime.Store } -var _ stdlib.WebAssemblyInstance = WasmtimeInstance{} +var _ stdlib.WebAssemblyInstance = WasmtimeWebAssemblyInstance{} func wasmtimeValKindToSemaType(valKind wasmtime.ValKind) sema.Type { switch valKind { @@ -84,7 +88,7 @@ func wasmtimeValKindToSemaType(valKind wasmtime.ValKind) sema.Type { } } -func (i WasmtimeInstance) GetExport(gauge common.MemoryGauge, name string) (*stdlib.WebAssemblyExport, error) { +func (i WasmtimeWebAssemblyInstance) GetExport(gauge common.MemoryGauge, name string) (*stdlib.WebAssemblyExport, error) { extern := i.Instance.GetExport(i.Store, name) if extern == nil { return nil, nil @@ -156,6 +160,9 @@ func newWasmtimeFunctionWebAssemblyExport( functionType, func(invocation interpreter.Invocation) interpreter.Value { arguments := invocation.Arguments + inter := invocation.Interpreter + + // Convert the arguments convertedArguments := make([]any, 0, len(arguments)) @@ -178,11 +185,48 @@ func newWasmtimeFunctionWebAssemblyExport( convertedArguments = append(convertedArguments, convertedArgument) } + // Call the function, with metering + + fuelConsumedBefore, _ := store.FuelConsumed() + + // TODO: get remaining computation and convert to fuel. + // needs e.g. invocation.Interpreter.RemainingComputation() + const todoAvailableFuel = 1000 + err := store.AddFuel(todoAvailableFuel) + if err != nil { + // TODO: wrap error + panic(err) + } + result, err := function.Call(store, convertedArguments...) if err != nil { + // TODO: wrap error + panic(err) + } + + fuelConsumedAfter, _ := store.FuelConsumed() + fuelDelta := fuelConsumedAfter - fuelConsumedBefore + + inter.ReportComputation(common.ComputationKindWebAssemblyFuel, uint(fuelDelta)) + + remainingFuel, err := store.ConsumeFuel(0) + if err != nil { + // TODO: wrap error panic(err) } + remainingFuel, err = store.ConsumeFuel(remainingFuel) + if err != nil { + // TODO: wrap error + panic(err) + } + + if remainingFuel != 0 { + panic(errors.NewUnreachableError()) + } + + // Return the result + switch result := result.(type) { case int32: return interpreter.Int32Value(result) diff --git a/runtime/webassembly_test.go b/runtime/webassembly_test.go index e18e344a20..275431f073 100644 --- a/runtime/webassembly_test.go +++ b/runtime/webassembly_test.go @@ -34,7 +34,7 @@ import ( . "github.com/onflow/cadence/runtime/tests/utils" ) -func TestRuntimeWebAssembly(t *testing.T) { +func TestRuntimeWebAssemblyAdd(t *testing.T) { t.Parallel() @@ -43,7 +43,16 @@ func TestRuntimeWebAssembly(t *testing.T) { }) // A simple program which exports a function `add` with type `(i32, i32) -> i32`, - // which sums the arguments and returns the result + // which sums the arguments and returns the result: + // + // (module + // (type (;0;) (func (param i32 i32) (result i32))) + // (func (;0;) (type 0) (param i32 i32) (result i32) + // local.get 0 + // local.get 1 + // i32.add) + // (export "add" (func 0))) + // addProgram := []byte{ 0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x07, 0x01, 0x60, 0x02, 0x7f, 0x7f, 0x01, 0x7f, 0x03, 0x02, 0x01, 0x00, 0x07, 0x07, 0x01, @@ -57,10 +66,12 @@ func TestRuntimeWebAssembly(t *testing.T) { fun main(program: [UInt8], a: Int32, b: Int32): Int32 { let instance = WebAssembly.compileAndInstantiate(bytes: program).instance let add = instance.getExport(name: "add") - return add(a, b) + return add(a, b) + add(a, b) } `) + var webAssemblyFuelComputationMeterings []uint + runtimeInterface := &TestRuntimeInterface{ Storage: NewTestLedger(nil, nil), OnCompileWebAssembly: func(bytes []byte) (stdlib.WebAssemblyModule, error) { @@ -69,6 +80,18 @@ func TestRuntimeWebAssembly(t *testing.T) { OnDecodeArgument: func(b []byte, _ cadence.Type) (cadence.Value, error) { return json.Decode(nil, b) }, + OnMeterComputation: func(compKind common.ComputationKind, intensity uint) error { + if compKind != common.ComputationKindWebAssemblyFuel { + return nil + } + + webAssemblyFuelComputationMeterings = append( + webAssemblyFuelComputationMeterings, + intensity, + ) + + return nil + }, } result, err := runtime.ExecuteScript( @@ -88,9 +111,13 @@ func TestRuntimeWebAssembly(t *testing.T) { require.NoError(t, err) assert.Equal(t, - cadence.Int32(3), + cadence.Int32(6), result, ) + assert.Equal(t, + []uint{4, 4}, + webAssemblyFuelComputationMeterings, + ) } func TestRuntimeWebAssemblyDisabled(t *testing.T) { From a6e7b9ae7a4b500f4995b8f5ed6754f03d8029aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20M=C3=BCller?= Date: Fri, 22 Sep 2023 18:44:16 -0700 Subject: [PATCH 13/39] fix return type conversion --- runtime/webassembly.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/webassembly.go b/runtime/webassembly.go index d585f4fe2d..a867c8c5ae 100644 --- a/runtime/webassembly.go +++ b/runtime/webassembly.go @@ -137,7 +137,7 @@ func newWasmtimeFunctionWebAssemblyExport( results := funcType.Results() switch len(results) { case 0: - break + functionType.ReturnTypeAnnotation = sema.VoidTypeAnnotation case 1: result := results[0] From 692aa2a7aa33777dbd205ffd03d90967158edbc0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20M=C3=BCller?= Date: Thu, 5 Oct 2023 15:52:37 -0700 Subject: [PATCH 14/39] re-generate --- runtime/common/computationkind_string.go | 4 ++++ runtime/stdlib/webassembly.gen.go | 4 ++-- runtime/stdlib/webassembly.go | 3 --- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/runtime/common/computationkind_string.go b/runtime/common/computationkind_string.go index 9ed621d72f..8528f6d299 100644 --- a/runtime/common/computationkind_string.go +++ b/runtime/common/computationkind_string.go @@ -27,6 +27,7 @@ func _() { _ = x[ComputationKindSTDLIBUnsafeRandom-1102] _ = x[ComputationKindSTDLIBRLPDecodeString-1108] _ = x[ComputationKindSTDLIBRLPDecodeList-1109] + _ = x[ComputationKindWebAssemblyFuel-1112] } const ( @@ -38,6 +39,7 @@ const ( _ComputationKind_name_5 = "EncodeValue" _ComputationKind_name_6 = "STDLIBPanicSTDLIBAssertSTDLIBUnsafeRandom" _ComputationKind_name_7 = "STDLIBRLPDecodeStringSTDLIBRLPDecodeList" + _ComputationKind_name_8 = "WebAssemblyFuel" ) var ( @@ -73,6 +75,8 @@ func (i ComputationKind) String() string { case 1108 <= i && i <= 1109: i -= 1108 return _ComputationKind_name_7[_ComputationKind_index_7[i]:_ComputationKind_index_7[i+1]] + case i == 1112: + return _ComputationKind_name_8 default: return "ComputationKind(" + strconv.FormatInt(int64(i), 10) + ")" } diff --git a/runtime/stdlib/webassembly.gen.go b/runtime/stdlib/webassembly.gen.go index 59f9073937..5c96daecee 100644 --- a/runtime/stdlib/webassembly.gen.go +++ b/runtime/stdlib/webassembly.gen.go @@ -94,7 +94,7 @@ const WebAssembly_InstanceTypeGetExportFunctionName = "getExport" var WebAssembly_InstanceTypeGetExportFunctionTypeParameterT = &sema.TypeParameter{ Name: "T", - TypeBound: AnyStructType, + TypeBound: sema.AnyStructType, } var WebAssembly_InstanceTypeGetExportFunctionType = &sema.FunctionType{ @@ -105,7 +105,7 @@ var WebAssembly_InstanceTypeGetExportFunctionType = &sema.FunctionType{ Parameters: []sema.Parameter{ { Identifier: "name", - TypeAnnotation: sema.NewTypeAnnotation(StringType), + TypeAnnotation: sema.NewTypeAnnotation(sema.StringType), }, }, ReturnTypeAnnotation: sema.NewTypeAnnotation( diff --git a/runtime/stdlib/webassembly.go b/runtime/stdlib/webassembly.go index 5601c3a6d1..cb641fdeb8 100644 --- a/runtime/stdlib/webassembly.go +++ b/runtime/stdlib/webassembly.go @@ -27,9 +27,6 @@ import ( //go:generate go run ../sema/gen -p stdlib webassembly.cdc webassembly.gen.go -var AnyStructType = sema.AnyStructType -var StringType = sema.StringType - func newWebAssemblyCompileAndInstantiateFunction( gauge common.MemoryGauge, handler WebAssemblyContractHandler, From b4c634b7aa44abb62304e2128705eceae6d1212e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20M=C3=BCller?= Date: Sun, 3 Mar 2024 10:35:11 -0800 Subject: [PATCH 15/39] update comment to reflect current functionality --- runtime/stdlib/webassembly.cdc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/stdlib/webassembly.cdc b/runtime/stdlib/webassembly.cdc index 773bc68c56..7baaf4cc58 100644 --- a/runtime/stdlib/webassembly.cdc +++ b/runtime/stdlib/webassembly.cdc @@ -2,7 +2,7 @@ access(all) contract WebAssembly { /// Compile WebAssembly binary code into a Module - /// and instantiate it with the given imports. + /// and instantiate it. Imports are not supported. access(all) view fun compileAndInstantiate(bytes: [UInt8]): &WebAssembly.InstantiatedSource From b67d23f71e1aedf953737f4562cea33f6cfb5fb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20M=C3=BCller?= Date: Mon, 24 Jun 2024 18:07:18 -0700 Subject: [PATCH 16/39] update to wasmtime v22 --- go.mod | 2 +- go.sum | 4 ++-- runtime/webassembly.go | 28 +++++++--------------------- tools/storage-explorer/go.sum | 2 ++ vm/vm.go | 2 +- 5 files changed, 13 insertions(+), 25 deletions(-) diff --git a/go.mod b/go.mod index 9fb0e574fe..b97befab2f 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,6 @@ go 1.22 require ( github.com/bits-and-blooms/bitset v1.5.0 - github.com/bytecodealliance/wasmtime-go/v12 v12.0.0 github.com/c-bata/go-prompt v0.2.6 github.com/dave/dst v0.27.2 github.com/fxamacker/cbor/v2 v2.4.1-0.20230228173756-c0c9f774e40c @@ -31,6 +30,7 @@ require ( require ( github.com/SaveTheRbtz/mph v0.1.1-0.20240117162131-4166ec7869bc + github.com/bytecodealliance/wasmtime-go/v22 v22.0.0 github.com/k0kubun/pp v3.0.1+incompatible github.com/kodova/html-to-markdown v1.0.1 github.com/onflow/crypto v0.25.0 diff --git a/go.sum b/go.sum index 7b83f8a0fd..cc473021b3 100644 --- a/go.sum +++ b/go.sum @@ -5,8 +5,8 @@ github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3 github.com/andybalholm/cascadia v1.0.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y= github.com/bits-and-blooms/bitset v1.5.0 h1:NpE8frKRLGHIcEzkR+gZhiioW1+WbYV6fKwD6ZIpQT8= github.com/bits-and-blooms/bitset v1.5.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= -github.com/bytecodealliance/wasmtime-go/v12 v12.0.0 h1:Wga02UaZXYF3p0LIeL5xFp09/RI7UhjfT2uB0mLrwlw= -github.com/bytecodealliance/wasmtime-go/v12 v12.0.0/go.mod h1:a3PRoftJxxUzkQvgjC6sv7pKyJJK0ZsFVmH+eeEKQC4= +github.com/bytecodealliance/wasmtime-go/v22 v22.0.0 h1:QHVD/Ppl3gsaBmrP3tytsiaw/Bs/gGB16kEsO3+0N7o= +github.com/bytecodealliance/wasmtime-go/v22 v22.0.0/go.mod h1:knqkvjTLavLtAXnA5NJUM0qbRiPJCVWPLXfYu75kZSo= github.com/c-bata/go-prompt v0.2.6 h1:POP+nrHE+DfLYx370bedwNhsqmpCUynWPxuHi0C5vZI= github.com/c-bata/go-prompt v0.2.6/go.mod h1:/LMAke8wD2FsNu9EXNdHxNLbd9MedkPnCdfpU9wwHfY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= diff --git a/runtime/webassembly.go b/runtime/webassembly.go index 80dbfd1afd..8859d8aae7 100644 --- a/runtime/webassembly.go +++ b/runtime/webassembly.go @@ -21,7 +21,7 @@ package runtime import ( "fmt" - "github.com/bytecodealliance/wasmtime-go/v12" + "github.com/bytecodealliance/wasmtime-go/v22" "github.com/onflow/cadence/runtime/common" "github.com/onflow/cadence/runtime/errors" @@ -187,12 +187,11 @@ func newWasmtimeFunctionWebAssemblyExport( // Call the function, with metering - fuelConsumedBefore, _ := store.FuelConsumed() - // TODO: get remaining computation and convert to fuel. // needs e.g. invocation.Interpreter.RemainingComputation() - const todoAvailableFuel = 1000 - err := store.AddFuel(todoAvailableFuel) + const todoAvailableFuel uint64 = 1000 + fuelBefore := todoAvailableFuel + err := store.SetFuel(fuelBefore) if err != nil { // TODO: wrap error panic(err) @@ -204,26 +203,13 @@ func newWasmtimeFunctionWebAssemblyExport( panic(err) } - fuelConsumedAfter, _ := store.FuelConsumed() - fuelDelta := fuelConsumedAfter - fuelConsumedBefore - - inter.ReportComputation(common.ComputationKindWebAssemblyFuel, uint(fuelDelta)) - - remainingFuel, err := store.ConsumeFuel(0) + fuelAfter, err := store.GetFuel() if err != nil { - // TODO: wrap error panic(err) } - remainingFuel, err = store.ConsumeFuel(remainingFuel) - if err != nil { - // TODO: wrap error - panic(err) - } - - if remainingFuel != 0 { - panic(errors.NewUnreachableError()) - } + fuelDelta := fuelBefore - fuelAfter + inter.ReportComputation(common.ComputationKindWebAssemblyFuel, uint(fuelDelta)) // Return the result diff --git a/tools/storage-explorer/go.sum b/tools/storage-explorer/go.sum index cb23d5b2bd..745f0e4bca 100644 --- a/tools/storage-explorer/go.sum +++ b/tools/storage-explorer/go.sum @@ -1064,7 +1064,9 @@ github.com/btcsuite/btcd/btcec/v2 v2.2.1 h1:xP60mv8fvp+0khmrN0zTdPC3cNm24rfeE6lh github.com/btcsuite/btcd/btcec/v2 v2.2.1/go.mod h1:9/CSmJxmuvqzX9Wh2fXMWToLOHhPd11lSPuIupwTkI8= github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= github.com/btcsuite/btcd/chaincfg/chainhash v1.0.2 h1:KdUfX2zKommPRa+PD0sWZUyXe9w277ABlgELO7H04IM= +github.com/bytecodealliance/wasmtime-go v1.0.0/go.mod h1:jjlqQbWUfVSbehpErw3UoWFndBXRRMvfikYH6KsCwOg= github.com/bytecodealliance/wasmtime-go/v12 v12.0.0/go.mod h1:a3PRoftJxxUzkQvgjC6sv7pKyJJK0ZsFVmH+eeEKQC4= +github.com/bytecodealliance/wasmtime-go/v22 v22.0.0/go.mod h1:knqkvjTLavLtAXnA5NJUM0qbRiPJCVWPLXfYu75kZSo= github.com/bytecodealliance/wasmtime-go/v7 v7.0.0/go.mod h1:bu6fic7trDt20w+LMooX7j3fsOwv4/ln6j8gAdP6vmA= github.com/c-bata/go-prompt v0.2.2/go.mod h1:VzqtzE2ksDBcdln8G7mk2RX9QyGjH+OVqOCSiVIqS34= github.com/c-bata/go-prompt v0.2.6/go.mod h1:/LMAke8wD2FsNu9EXNdHxNLbd9MedkPnCdfpU9wwHfY= diff --git a/vm/vm.go b/vm/vm.go index ecdc31519e..46da42ad04 100644 --- a/vm/vm.go +++ b/vm/vm.go @@ -27,7 +27,7 @@ import ( "C" - "github.com/bytecodealliance/wasmtime-go/v12" + "github.com/bytecodealliance/wasmtime-go/v22" "github.com/onflow/cadence/runtime/interpreter" ) From e470d4653a05ee45b38cfb7c08a1afc5e0faa20f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20M=C3=BCller?= Date: Tue, 25 Jun 2024 09:39:11 -0700 Subject: [PATCH 17/39] intgrate WebAssembly standard library values and types into existing standard library --- runtime/cmd/check/main.go | 5 +- runtime/cmd/cmd.go | 1 + runtime/cmd/compile/main.go | 5 +- runtime/cmd/info/main.go | 5 +- runtime/crypto_test.go | 4 +- runtime/environment.go | 23 ++++++--- runtime/repl.go | 5 +- runtime/runtime_test.go | 8 +-- runtime/stdlib/builtin.go | 50 +++++++++++++++++-- runtime/stdlib/webassembly.cdc | 8 ++- runtime/stdlib/webassembly.gen.go | 9 ++-- runtime/tests/checker/crypto_test.go | 25 ++++++++-- .../tests/interpreter/memory_metering_test.go | 5 +- tools/analysis/programs.go | 5 +- 14 files changed, 124 insertions(+), 34 deletions(-) diff --git a/runtime/cmd/check/main.go b/runtime/cmd/check/main.go index 69112b4aa4..0dc13099dd 100644 --- a/runtime/cmd/check/main.go +++ b/runtime/cmd/check/main.go @@ -237,7 +237,10 @@ func runPath( location := common.NewStringLocation(nil, path) // standard library handler is only needed for execution, but we're only checking - standardLibraryValues := stdlib.DefaultScriptStandardLibraryValues(nil) + standardLibraryValues := stdlib.DefaultScriptStandardLibraryValues( + nil, + stdlib.DefaultStandardLibraryOptions, + ) func() { defer func() { diff --git a/runtime/cmd/cmd.go b/runtime/cmd/cmd.go index 7e46941680..d1c6facc7b 100644 --- a/runtime/cmd/cmd.go +++ b/runtime/cmd/cmd.go @@ -179,6 +179,7 @@ func PrepareInterpreter(filename string, debugger *interpreter.Debugger) (*inter standardLibraryValues := stdlib.DefaultScriptStandardLibraryValues( &StandardLibraryHandler{}, + stdlib.DefaultStandardLibraryOptions, ) checker, must := PrepareChecker( diff --git a/runtime/cmd/compile/main.go b/runtime/cmd/compile/main.go index 192dfc5d62..bbf45c0b3f 100644 --- a/runtime/cmd/compile/main.go +++ b/runtime/cmd/compile/main.go @@ -46,7 +46,10 @@ func main() { program, must := cmd.PrepareProgramFromFile(location, codes) // standard library handler is only needed for execution, but we're only checking - standardLibraryValues := stdlib.DefaultScriptStandardLibraryValues(nil) + standardLibraryValues := stdlib.DefaultScriptStandardLibraryValues( + nil, + stdlib.DefaultStandardLibraryOptions, + ) checker, must := cmd.PrepareChecker( program, diff --git a/runtime/cmd/info/main.go b/runtime/cmd/info/main.go index fb8a56b277..a6551ca4ff 100644 --- a/runtime/cmd/info/main.go +++ b/runtime/cmd/info/main.go @@ -240,7 +240,10 @@ func dumpBuiltinValues() { } allBaseSemaValueTypes := checker.AllBaseSemaValueTypes() - standardLibraryValues := stdlib.DefaultScriptStandardLibraryValues(nil) + standardLibraryValues := stdlib.DefaultScriptStandardLibraryValues( + nil, + stdlib.DefaultStandardLibraryOptions, + ) valueTypes := make([]valueType, 0, len(allBaseSemaValueTypes)+len(standardLibraryValues)) diff --git a/runtime/crypto_test.go b/runtime/crypto_test.go index f155fd0122..60d88d5ba6 100644 --- a/runtime/crypto_test.go +++ b/runtime/crypto_test.go @@ -371,7 +371,7 @@ func TestRuntimeSignatureAlgorithmImport(t *testing.T) { Type: cadence.UInt8Type, }, }, - nil, + nil, )), ), }, @@ -452,7 +452,7 @@ func TestRuntimeHashAlgorithmImport(t *testing.T) { Type: cadence.UInt8Type, }, }, - nil, + nil, )), ), }, diff --git a/runtime/environment.go b/runtime/environment.go index dfef846efe..8c6d39a4a3 100644 --- a/runtime/environment.go +++ b/runtime/environment.go @@ -161,11 +161,6 @@ func newInterpreterEnvironment(config Config) *interpreterEnvironment { env.InterpreterConfig = env.newInterpreterConfig() env.CheckerConfig = env.newCheckerConfig() - if config.WebAssemblyEnabled { - env.DeclareValue(stdlib.NewWebAssemblyContract(nil, env), nil) - env.DeclareType(stdlib.WebAssemblyContractType, nil) - } - env.compositeValueFunctionsHandlers = stdlib.DefaultStandardLibraryCompositeValueFunctionHandlers(env) return env @@ -217,19 +212,33 @@ func (e *interpreterEnvironment) newCheckerConfig() *sema.Config { } } +func StandardLibraryOptionsFromConfig(config Config) stdlib.StandardLibraryOptions { + return stdlib.StandardLibraryOptions{ + WebAssemblyEnabled: config.WebAssemblyEnabled, + } +} + func NewBaseInterpreterEnvironment(config Config) *interpreterEnvironment { env := newInterpreterEnvironment(config) - for _, valueDeclaration := range stdlib.DefaultStandardLibraryValues(env) { + options := StandardLibraryOptionsFromConfig(config) + for _, valueDeclaration := range stdlib.DefaultStandardLibraryValues(env, options) { env.DeclareValue(valueDeclaration, nil) } + for _, typeDeclaration := range stdlib.DefaultStandardLibraryTypes(options) { + env.DeclareType(typeDeclaration, nil) + } return env } func NewScriptInterpreterEnvironment(config Config) Environment { env := newInterpreterEnvironment(config) - for _, valueDeclaration := range stdlib.DefaultScriptStandardLibraryValues(env) { + options := StandardLibraryOptionsFromConfig(config) + for _, valueDeclaration := range stdlib.DefaultScriptStandardLibraryValues(env, options) { env.DeclareValue(valueDeclaration, nil) } + for _, typeDeclaration := range stdlib.DefaultStandardLibraryTypes(options) { + env.DeclareType(typeDeclaration, nil) + } return env } diff --git a/runtime/repl.go b/runtime/repl.go index 37ce1421bf..5e93cf4772 100644 --- a/runtime/repl.go +++ b/runtime/repl.go @@ -55,7 +55,10 @@ func NewREPL() (*REPL, error) { codes := map[Location][]byte{} standardLibraryHandler := &cmd.StandardLibraryHandler{} - standardLibraryValues := stdlib.DefaultScriptStandardLibraryValues(standardLibraryHandler) + standardLibraryValues := stdlib.DefaultScriptStandardLibraryValues( + standardLibraryHandler, + stdlib.DefaultStandardLibraryOptions, + ) checkerConfig := cmd.DefaultCheckerConfig(checkers, codes, standardLibraryValues) checkerConfig.AccessCheckMode = sema.AccessCheckModeNotSpecifiedUnrestricted diff --git a/runtime/runtime_test.go b/runtime/runtime_test.go index dfbe0740b0..965b0d9653 100644 --- a/runtime/runtime_test.go +++ b/runtime/runtime_test.go @@ -652,8 +652,8 @@ func TestRuntimeTransactionWithArguments(t *testing.T) { Type: cadence.StringType, }, }, - nil, - )), + nil, + )), ), expectedLogs: []string{`"bar"`}, }, @@ -1028,8 +1028,8 @@ func TestRuntimeScriptArguments(t *testing.T) { Type: cadence.StringType, }, }, - nil, - )), + nil, + )), ), expectedLogs: []string{`"bar"`}, }, diff --git a/runtime/stdlib/builtin.go b/runtime/stdlib/builtin.go index afc9662f24..49be680dac 100644 --- a/runtime/stdlib/builtin.go +++ b/runtime/stdlib/builtin.go @@ -36,10 +36,32 @@ type StandardLibraryHandler interface { BLSPublicKeyAggregator BLSSignatureAggregator Hasher + WebAssemblyContractHandler } -func DefaultStandardLibraryValues(handler StandardLibraryHandler) []StandardLibraryValue { - return []StandardLibraryValue{ +type StandardLibraryOptions struct { + WebAssemblyEnabled bool +} + +var DefaultStandardLibraryOptions = StandardLibraryOptions{ + WebAssemblyEnabled: false, +} + +func DefaultStandardLibraryValues( + handler StandardLibraryHandler, + options StandardLibraryOptions, +) []StandardLibraryValue { + var values []StandardLibraryValue + + if options.WebAssemblyEnabled { + values = append( + values, + NewWebAssemblyContract(nil, handler), + ) + } + + return append( + values, AssertFunction, PanicFunction, SignatureAlgorithmConstructor, @@ -54,16 +76,34 @@ func DefaultStandardLibraryValues(handler StandardLibraryHandler) []StandardLibr NewPublicKeyConstructor(handler), NewBLSContract(nil, handler), NewHashAlgorithmConstructor(handler), - } + ) } -func DefaultScriptStandardLibraryValues(handler StandardLibraryHandler) []StandardLibraryValue { +func DefaultScriptStandardLibraryValues( + handler StandardLibraryHandler, + options StandardLibraryOptions, +) []StandardLibraryValue { return append( - DefaultStandardLibraryValues(handler), + DefaultStandardLibraryValues(handler, options), NewGetAuthAccountFunction(handler), ) } +func DefaultStandardLibraryTypes( + options StandardLibraryOptions, +) []StandardLibraryType { + var types []StandardLibraryType + + if options.WebAssemblyEnabled { + types = append( + types, + WebAssemblyContractType, + ) + } + + return types +} + type CompositeValueFunctionsHandler func( inter *interpreter.Interpreter, locationRange interpreter.LocationRange, diff --git a/runtime/stdlib/webassembly.cdc b/runtime/stdlib/webassembly.cdc index 7baaf4cc58..574d974298 100644 --- a/runtime/stdlib/webassembly.cdc +++ b/runtime/stdlib/webassembly.cdc @@ -1,8 +1,8 @@ access(all) contract WebAssembly { - /// Compile WebAssembly binary code into a Module - /// and instantiate it. Imports are not supported. + /// Compile WebAssembly binary code into a Module and instantiate it. + /// Imports are not supported. access(all) view fun compileAndInstantiate(bytes: [UInt8]): &WebAssembly.InstantiatedSource @@ -14,9 +14,13 @@ contract WebAssembly { let instance: &WebAssembly.Instance } + access(all) struct Instance { /// Get the exported value. + /// The type must match the type of the exported value. + /// If the export with the given name does not exist, + /// of if the type does not match, then the function will panic. access(all) view fun getExport(name: String): T } diff --git a/runtime/stdlib/webassembly.gen.go b/runtime/stdlib/webassembly.gen.go index 5c96daecee..8dc51ddf4a 100644 --- a/runtime/stdlib/webassembly.gen.go +++ b/runtime/stdlib/webassembly.gen.go @@ -2,7 +2,7 @@ /* * Cadence - The resource-oriented smart contract programming language * - * Copyright Dapper Labs, Inc. + * Copyright Flow Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -46,8 +46,8 @@ var WebAssemblyTypeCompileAndInstantiateFunctionType = &sema.FunctionType{ } const WebAssemblyTypeCompileAndInstantiateFunctionDocString = ` -Compile WebAssembly binary code into a Module -and instantiate it with the given imports. +Compile WebAssembly binary code into a Module and instantiate it. +Imports are not supported. ` const WebAssembly_InstantiatedSourceTypeInstanceFieldName = "instance" @@ -117,6 +117,9 @@ var WebAssembly_InstanceTypeGetExportFunctionType = &sema.FunctionType{ const WebAssembly_InstanceTypeGetExportFunctionDocString = ` Get the exported value. +The type must match the type of the exported value. +If the export with the given name does not exist, +of if the type does not match, then the function will panic. ` const WebAssembly_InstanceTypeName = "Instance" diff --git a/runtime/tests/checker/crypto_test.go b/runtime/tests/checker/crypto_test.go index 1e3764c060..2569c8fe67 100644 --- a/runtime/tests/checker/crypto_test.go +++ b/runtime/tests/checker/crypto_test.go @@ -34,7 +34,10 @@ func TestCheckHashAlgorithmCases(t *testing.T) { t.Parallel() baseValueActivation := sema.NewVariableActivation(sema.BaseValueActivation) - for _, value := range stdlib.DefaultScriptStandardLibraryValues(nil) { + for _, value := range stdlib.DefaultScriptStandardLibraryValues( + nil, + stdlib.DefaultStandardLibraryOptions, + ) { baseValueActivation.DeclareValue(value) } @@ -173,7 +176,10 @@ func TestCheckVerifyPoP(t *testing.T) { t.Parallel() baseValueActivation := sema.NewVariableActivation(sema.BaseValueActivation) - for _, valueDeclaration := range stdlib.DefaultStandardLibraryValues(nil) { + for _, valueDeclaration := range stdlib.DefaultStandardLibraryValues( + nil, + stdlib.DefaultStandardLibraryOptions, + ) { baseValueActivation.DeclareValue(valueDeclaration) } @@ -202,7 +208,10 @@ func TestCheckVerifyPoPInvalidArgument(t *testing.T) { t.Parallel() baseValueActivation := sema.NewVariableActivation(sema.BaseValueActivation) - for _, valueDeclaration := range stdlib.DefaultStandardLibraryValues(nil) { + for _, valueDeclaration := range stdlib.DefaultStandardLibraryValues( + nil, + stdlib.DefaultStandardLibraryOptions, + ) { baseValueActivation.DeclareValue(valueDeclaration) } @@ -283,7 +292,10 @@ func TestCheckBLSAggregatePublicKeys(t *testing.T) { t.Parallel() baseValueActivation := sema.NewVariableActivation(sema.BaseValueActivation) - for _, valueDeclaration := range stdlib.DefaultStandardLibraryValues(nil) { + for _, valueDeclaration := range stdlib.DefaultStandardLibraryValues( + nil, + stdlib.DefaultStandardLibraryOptions, + ) { baseValueActivation.DeclareValue(valueDeclaration) } @@ -313,7 +325,10 @@ func TestCheckInvalidBLSAggregatePublicKeys(t *testing.T) { t.Parallel() baseValueActivation := sema.NewVariableActivation(sema.BaseValueActivation) - for _, valueDeclaration := range stdlib.DefaultStandardLibraryValues(nil) { + for _, valueDeclaration := range stdlib.DefaultStandardLibraryValues( + nil, + stdlib.DefaultStandardLibraryOptions, + ) { baseValueActivation.DeclareValue(valueDeclaration) } diff --git a/runtime/tests/interpreter/memory_metering_test.go b/runtime/tests/interpreter/memory_metering_test.go index 4b040292e2..9358d2f40b 100644 --- a/runtime/tests/interpreter/memory_metering_test.go +++ b/runtime/tests/interpreter/memory_metering_test.go @@ -1048,7 +1048,10 @@ func TestInterpretHostFunctionMetering(t *testing.T) { baseValueActivation := sema.NewVariableActivation(sema.BaseValueActivation) baseActivation := activations.NewActivation(nil, interpreter.BaseActivation) - for _, valueDeclaration := range stdlib.DefaultStandardLibraryValues(nil) { + for _, valueDeclaration := range stdlib.DefaultStandardLibraryValues( + nil, + stdlib.DefaultStandardLibraryOptions, + ) { baseValueActivation.DeclareValue(valueDeclaration) interpreter.Declare(baseActivation, valueDeclaration) } diff --git a/tools/analysis/programs.go b/tools/analysis/programs.go index 08ae11ae49..6631cf2959 100644 --- a/tools/analysis/programs.go +++ b/tools/analysis/programs.go @@ -125,7 +125,10 @@ func (programs Programs) check( error, ) { baseValueActivation := sema.NewVariableActivation(sema.BaseValueActivation) - for _, value := range stdlib.DefaultScriptStandardLibraryValues(nil) { + for _, value := range stdlib.DefaultScriptStandardLibraryValues( + nil, + stdlib.DefaultStandardLibraryOptions, + ) { baseValueActivation.DeclareValue(value) } From ead17b8c0c413955d76a512945fbf3ef4645d6d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20M=C3=BCller?= Date: Tue, 25 Jun 2024 09:39:44 -0700 Subject: [PATCH 18/39] lint --- runtime/webassembly_test.go | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/runtime/webassembly_test.go b/runtime/webassembly_test.go index 275431f073..019cc716e2 100644 --- a/runtime/webassembly_test.go +++ b/runtime/webassembly_test.go @@ -29,7 +29,6 @@ import ( . "github.com/onflow/cadence/runtime" "github.com/onflow/cadence/runtime/common" - "github.com/onflow/cadence/runtime/stdlib" . "github.com/onflow/cadence/runtime/tests/runtime_utils" . "github.com/onflow/cadence/runtime/tests/utils" ) @@ -73,10 +72,8 @@ func TestRuntimeWebAssemblyAdd(t *testing.T) { var webAssemblyFuelComputationMeterings []uint runtimeInterface := &TestRuntimeInterface{ - Storage: NewTestLedger(nil, nil), - OnCompileWebAssembly: func(bytes []byte) (stdlib.WebAssemblyModule, error) { - return NewWasmtimeWebAssemblyModule(bytes) - }, + Storage: NewTestLedger(nil, nil), + OnCompileWebAssembly: NewWasmtimeWebAssemblyModule, OnDecodeArgument: func(b []byte, _ cadence.Type) (cadence.Value, error) { return json.Decode(nil, b) }, From e3c752fd70e36bbb933d931400592a49d869478b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20M=C3=BCller?= Date: Tue, 25 Jun 2024 09:44:43 -0700 Subject: [PATCH 19/39] update copyright --- migrations/cache.go | 2 +- runtime/stdlib/webassembly.go | 2 +- runtime/webassembly.go | 2 +- runtime/webassembly_test.go | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/migrations/cache.go b/migrations/cache.go index e36d610edc..753d3e68ee 100644 --- a/migrations/cache.go +++ b/migrations/cache.go @@ -1,7 +1,7 @@ /* * Cadence - The resource-oriented smart contract programming language * - * Copyright Dapper Labs, Inc. + * Copyright Flow Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/runtime/stdlib/webassembly.go b/runtime/stdlib/webassembly.go index 1e5a17d7ef..675292ff8c 100644 --- a/runtime/stdlib/webassembly.go +++ b/runtime/stdlib/webassembly.go @@ -1,7 +1,7 @@ /* * Cadence - The resource-oriented smart contract programming language * - * Copyright Dapper Labs, Inc. + * Copyright Flow Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/runtime/webassembly.go b/runtime/webassembly.go index 8859d8aae7..cafafa8166 100644 --- a/runtime/webassembly.go +++ b/runtime/webassembly.go @@ -1,7 +1,7 @@ /* * Cadence - The resource-oriented smart contract programming language * - * Copyright Dapper Labs, Inc. + * Copyright Flow Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/runtime/webassembly_test.go b/runtime/webassembly_test.go index 019cc716e2..2187314296 100644 --- a/runtime/webassembly_test.go +++ b/runtime/webassembly_test.go @@ -1,7 +1,7 @@ /* * Cadence - The resource-oriented smart contract programming language * - * Copyright Dapper Labs, Inc. + * Copyright Flow Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. From f197db0d5b0ee68bac394bdba1199ae1f7509e0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20M=C3=BCller?= Date: Tue, 25 Jun 2024 10:51:11 -0700 Subject: [PATCH 20/39] improve config --- runtime/webassembly.go | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/runtime/webassembly.go b/runtime/webassembly.go index cafafa8166..06ae2773bd 100644 --- a/runtime/webassembly.go +++ b/runtime/webassembly.go @@ -37,7 +37,20 @@ type WasmtimeWebAssemblyModule struct { func NewWasmtimeWebAssemblyModule(bytes []byte) (stdlib.WebAssemblyModule, error) { config := wasmtime.NewConfig() + config.SetConsumeFuel(true) + config.SetMaxWasmStack(512 * 1024) + + config.SetWasmBulkMemory(true) + config.SetWasmThreads(false) + config.SetWasmReferenceTypes(false) + config.SetWasmSIMD(false) + config.SetWasmMemory64(false) + config.SetWasmMultiMemory(false) + config.SetWasmMultiValue(false) + + config.SetStrategy(wasmtime.StrategyCranelift) + config.SetCraneliftFlag("enable_nan_canonicalization", "true") engine := wasmtime.NewEngineWithConfig(config) store := wasmtime.NewStore(engine) From 23795cb57c910784768fb8fab633dfabcf367dcf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20M=C3=BCller?= Date: Tue, 25 Jun 2024 10:51:31 -0700 Subject: [PATCH 21/39] improve metering: always meter, even on failure --- runtime/stdlib/webassembly.go | 1 + runtime/webassembly.go | 67 +++++++++++++++++++++++------------ 2 files changed, 45 insertions(+), 23 deletions(-) diff --git a/runtime/stdlib/webassembly.go b/runtime/stdlib/webassembly.go index 675292ff8c..fed7ea902c 100644 --- a/runtime/stdlib/webassembly.go +++ b/runtime/stdlib/webassembly.go @@ -107,6 +107,7 @@ func newWebAssemblyInstanceGetExportFunction( panic(err) } if export == nil { + // TODO: improve error panic(errors.NewDefaultUserError( "WebAssembly module does not have an export with name '%s'", name, diff --git a/runtime/webassembly.go b/runtime/webassembly.go index 06ae2773bd..92fc09fda5 100644 --- a/runtime/webassembly.go +++ b/runtime/webassembly.go @@ -107,11 +107,13 @@ func (i WasmtimeWebAssemblyInstance) GetExport(gauge common.MemoryGauge, name st return nil, nil } - if function := extern.Func(); function != nil { - return newWasmtimeFunctionWebAssemblyExport(gauge, function, i.Store) + function := extern.Func() + if function != nil { + // TODO: improve error + return nil, errors.NewDefaultUserError("invalid export: not a function") } - return nil, fmt.Errorf("unsupported export") + return newWasmtimeFunctionWebAssemblyExport(gauge, function, i.Store) } func newWasmtimeFunctionWebAssemblyExport( @@ -168,6 +170,34 @@ func newWasmtimeFunctionWebAssemblyExport( return nil, fmt.Errorf("unsupported export: function has more than one result") } + metered := func(inter *interpreter.Interpreter, f func() (any, error)) (any, error) { + // TODO: get remaining computation and convert to fuel. + // needs e.g. invocation.Interpreter.RemainingComputation() + const todoAvailableFuel uint64 = 1000 + + fuelBefore := todoAvailableFuel + err := store.SetFuel(fuelBefore) + if err != nil { + // TODO: wrap error + panic(err) + } + + callResult, callErr := f() + + // IMPORTANT: always report consumed fuel, even if there was an error + + fuelAfter, err := store.GetFuel() + if err != nil { + // TODO: wrap error + panic(err) + } + + fuelDelta := fuelBefore - fuelAfter + inter.ReportComputation(common.ComputationKindWebAssemblyFuel, uint(fuelDelta)) + + return callResult, callErr + } + hostFunctionValue := interpreter.NewStaticHostFunctionValue( gauge, functionType, @@ -200,30 +230,21 @@ func newWasmtimeFunctionWebAssemblyExport( // Call the function, with metering - // TODO: get remaining computation and convert to fuel. - // needs e.g. invocation.Interpreter.RemainingComputation() - const todoAvailableFuel uint64 = 1000 - fuelBefore := todoAvailableFuel - err := store.SetFuel(fuelBefore) - if err != nil { - // TODO: wrap error - panic(err) - } - - result, err := function.Call(store, convertedArguments...) - if err != nil { - // TODO: wrap error - panic(err) - } - - fuelAfter, err := store.GetFuel() + result, err := metered( + inter, + func() (any, error) { + res, err := function.Call(store, convertedArguments...) + if err != nil { + // TODO: wrap error + return nil, err + } + return res, nil + }, + ) if err != nil { panic(err) } - fuelDelta := fuelBefore - fuelAfter - inter.ReportComputation(common.ComputationKindWebAssemblyFuel, uint(fuelDelta)) - // Return the result switch result := result.(type) { From f6b6acfb160a5c2d153aecd73dc152c592916078 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20M=C3=BCller?= Date: Tue, 25 Jun 2024 16:45:50 -0700 Subject: [PATCH 22/39] disabling SIMD is broken https://github.com/bytecodealliance/wasmtime-go/issues/222 --- runtime/webassembly.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/runtime/webassembly.go b/runtime/webassembly.go index 92fc09fda5..3b26634146 100644 --- a/runtime/webassembly.go +++ b/runtime/webassembly.go @@ -44,7 +44,9 @@ func NewWasmtimeWebAssemblyModule(bytes []byte) (stdlib.WebAssemblyModule, error config.SetWasmBulkMemory(true) config.SetWasmThreads(false) config.SetWasmReferenceTypes(false) - config.SetWasmSIMD(false) + // TODO: disable all SIMD related functionality. + // Depends on https://github.com/bytecodealliance/wasmtime-go/pull/224 + // config.SetWasmSIMD(false) config.SetWasmMemory64(false) config.SetWasmMultiMemory(false) config.SetWasmMultiValue(false) From 8bcbf8cbb34497fba66733520ba97fdc2d7067b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20M=C3=BCller?= Date: Tue, 25 Jun 2024 16:46:00 -0700 Subject: [PATCH 23/39] fix check --- runtime/webassembly.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/webassembly.go b/runtime/webassembly.go index 3b26634146..d3601fb006 100644 --- a/runtime/webassembly.go +++ b/runtime/webassembly.go @@ -110,7 +110,7 @@ func (i WasmtimeWebAssemblyInstance) GetExport(gauge common.MemoryGauge, name st } function := extern.Func() - if function != nil { + if function == nil { // TODO: improve error return nil, errors.NewDefaultUserError("invalid export: not a function") } From 12b56a54ee6ac94f9a3ca98a979263d1f49c2ffd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20M=C3=BCller?= Date: Tue, 25 Jun 2024 16:46:14 -0700 Subject: [PATCH 24/39] limit store contents --- runtime/stdlib/webassembly.go | 2 ++ runtime/webassembly.go | 17 +++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/runtime/stdlib/webassembly.go b/runtime/stdlib/webassembly.go index fed7ea902c..7d5c391577 100644 --- a/runtime/stdlib/webassembly.go +++ b/runtime/stdlib/webassembly.go @@ -44,6 +44,8 @@ func newWebAssemblyCompileAndInstantiateFunction( panic(err) } + // TODO meter + module, err := handler.CompileWebAssembly(bytes) if err != nil { panic(err) diff --git a/runtime/webassembly.go b/runtime/webassembly.go index d3601fb006..ebb324bbf0 100644 --- a/runtime/webassembly.go +++ b/runtime/webassembly.go @@ -55,8 +55,25 @@ func NewWasmtimeWebAssemblyModule(bytes []byte) (stdlib.WebAssemblyModule, error config.SetCraneliftFlag("enable_nan_canonicalization", "true") engine := wasmtime.NewEngineWithConfig(config) + store := wasmtime.NewStore(engine) + // TODO: define memory limit + const todoMemoryLimit = 2 * 1024 * 1024 + // TODO: define table elements limit + const tableElementsLimit = 10_000 + // TODO: define tables limit + const todoTablesLimit = 1 + // TODO: define memories limit + const todoMemoriesLimit = 1 + store.Limiter( + todoMemoryLimit, + tableElementsLimit, + -1, + todoTablesLimit, + todoMemoriesLimit, + ) + module, err := wasmtime.NewModule(engine, bytes) if err != nil { // TODO: wrap error From 9089bc6a02abdbf3d70e9d574531253167f24b65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20M=C3=BCller?= Date: Wed, 26 Jun 2024 13:43:33 -0700 Subject: [PATCH 25/39] add comments --- runtime/webassembly.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/runtime/webassembly.go b/runtime/webassembly.go index ebb324bbf0..5135b68e3d 100644 --- a/runtime/webassembly.go +++ b/runtime/webassembly.go @@ -38,6 +38,9 @@ type WasmtimeWebAssemblyModule struct { func NewWasmtimeWebAssemblyModule(bytes []byte) (stdlib.WebAssemblyModule, error) { config := wasmtime.NewConfig() + // Deterministic configuration inspired by + // https://github.com/dfinity/ic/blob/a0ab22537bdf65bd1f473654d49283e4f95f5a61/rs/embedders/README.adoc#nondeterminism + config.SetConsumeFuel(true) config.SetMaxWasmStack(512 * 1024) @@ -51,9 +54,13 @@ func NewWasmtimeWebAssemblyModule(bytes []byte) (stdlib.WebAssemblyModule, error config.SetWasmMultiMemory(false) config.SetWasmMultiValue(false) + // NaN canonicalization is needed for determinism. config.SetStrategy(wasmtime.StrategyCranelift) config.SetCraneliftFlag("enable_nan_canonicalization", "true") + // Disable optimizations to keep compilation simple and fast. + config.SetCraneliftOptLevel(wasmtime.OptLevelNone) + engine := wasmtime.NewEngineWithConfig(config) store := wasmtime.NewStore(engine) From 6b6c8fb55c4952f2daa09f3d144230b2db6b89ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20M=C3=BCller?= Date: Wed, 26 Jun 2024 14:13:49 -0700 Subject: [PATCH 26/39] update wasmtime --- go.mod | 2 +- go.sum | 4 +- tools/storage-explorer/go.mod | 1 + tools/storage-explorer/go.sum | 78 +++++++++++++++++++++++++++++++++-- 4 files changed, 78 insertions(+), 7 deletions(-) diff --git a/go.mod b/go.mod index b97befab2f..41a793ce0e 100644 --- a/go.mod +++ b/go.mod @@ -30,7 +30,7 @@ require ( require ( github.com/SaveTheRbtz/mph v0.1.1-0.20240117162131-4166ec7869bc - github.com/bytecodealliance/wasmtime-go/v22 v22.0.0 + github.com/bytecodealliance/wasmtime-go/v22 v22.0.0-20240626142402-d03b414c50b4 github.com/k0kubun/pp v3.0.1+incompatible github.com/kodova/html-to-markdown v1.0.1 github.com/onflow/crypto v0.25.0 diff --git a/go.sum b/go.sum index cc473021b3..f025dee52d 100644 --- a/go.sum +++ b/go.sum @@ -5,8 +5,8 @@ github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3 github.com/andybalholm/cascadia v1.0.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y= github.com/bits-and-blooms/bitset v1.5.0 h1:NpE8frKRLGHIcEzkR+gZhiioW1+WbYV6fKwD6ZIpQT8= github.com/bits-and-blooms/bitset v1.5.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= -github.com/bytecodealliance/wasmtime-go/v22 v22.0.0 h1:QHVD/Ppl3gsaBmrP3tytsiaw/Bs/gGB16kEsO3+0N7o= -github.com/bytecodealliance/wasmtime-go/v22 v22.0.0/go.mod h1:knqkvjTLavLtAXnA5NJUM0qbRiPJCVWPLXfYu75kZSo= +github.com/bytecodealliance/wasmtime-go/v22 v22.0.0-20240626142402-d03b414c50b4 h1:Jtz9TgzQLwJgPZfF7gEcM8D0Vk6CizoV6UUdLmS/SiU= +github.com/bytecodealliance/wasmtime-go/v22 v22.0.0-20240626142402-d03b414c50b4/go.mod h1:knqkvjTLavLtAXnA5NJUM0qbRiPJCVWPLXfYu75kZSo= github.com/c-bata/go-prompt v0.2.6 h1:POP+nrHE+DfLYx370bedwNhsqmpCUynWPxuHi0C5vZI= github.com/c-bata/go-prompt v0.2.6/go.mod h1:/LMAke8wD2FsNu9EXNdHxNLbd9MedkPnCdfpU9wwHfY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= diff --git a/tools/storage-explorer/go.mod b/tools/storage-explorer/go.mod index 0a9784f6b3..dbde24ed2d 100644 --- a/tools/storage-explorer/go.mod +++ b/tools/storage-explorer/go.mod @@ -19,6 +19,7 @@ require ( github.com/beorn7/perks v1.0.1 // indirect github.com/bits-and-blooms/bitset v1.10.0 // indirect github.com/btcsuite/btcd/btcec/v2 v2.2.1 // indirect + github.com/bytecodealliance/wasmtime-go/v22 v22.0.0-20240626142402-d03b414c50b4 // indirect github.com/cenkalti/backoff/v4 v4.2.1 // indirect github.com/cespare/xxhash v1.1.0 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect diff --git a/tools/storage-explorer/go.sum b/tools/storage-explorer/go.sum index 745f0e4bca..b22ce2bf63 100644 --- a/tools/storage-explorer/go.sum +++ b/tools/storage-explorer/go.sum @@ -45,6 +45,7 @@ cloud.google.com/go v0.110.6/go.mod h1:+EYjdK8e5RME/VY/qLCAtuyALQ9q67dvuum8i+H5x cloud.google.com/go v0.110.7/go.mod h1:+EYjdK8e5RME/VY/qLCAtuyALQ9q67dvuum8i+H5xsI= cloud.google.com/go v0.110.8/go.mod h1:Iz8AkXJf1qmxC3Oxoep8R1T36w8B92yU29PcBhHO5fk= cloud.google.com/go v0.112.0 h1:tpFCD7hpHFlQ8yPwT3x+QeXqc2T6+n6T+hmABHfDUSM= +cloud.google.com/go v0.112.0/go.mod h1:3jEEVwZ/MHU4djK5t5RHuKOA/GbLddgTdVubX1qnPD4= cloud.google.com/go/accessapproval v1.4.0/go.mod h1:zybIuC3KpDOvotz59lFe5qxRZx6C75OtwbisN56xYB4= cloud.google.com/go/accessapproval v1.5.0/go.mod h1:HFy3tuiGvMdcd/u+Cu5b9NkO1pEICJ46IR82PoUdplw= cloud.google.com/go/accessapproval v1.6.0/go.mod h1:R0EiYnwV5fsRFiKZkPHr6mwyk2wxUJ30nL4j2pcFY2E= @@ -257,6 +258,7 @@ cloud.google.com/go/compute v1.21.0/go.mod h1:4tCnrn48xsqlwSAiLf1HXMQk8CONslYbdi cloud.google.com/go/compute v1.23.0/go.mod h1:4tCnrn48xsqlwSAiLf1HXMQk8CONslYbdiEZc9FEIbM= cloud.google.com/go/compute v1.23.1/go.mod h1:CqB3xpmPKKt3OJpW2ndFIXnA9A4xAy/F3Xp1ixncW78= cloud.google.com/go/compute v1.24.0 h1:phWcR2eWzRJaL/kOiJwfFsPs4BaKq1j6vnpZrc1YlVg= +cloud.google.com/go/compute v1.24.0/go.mod h1:kw1/T+h/+tK2LJK0wiPPx1intgdAM3j/g3hFDlscY40= cloud.google.com/go/compute/metadata v0.1.0/go.mod h1:Z1VN+bulIf6bt4P/C37K4DyZYZEXYonfTBHHFPO/4UU= cloud.google.com/go/compute/metadata v0.2.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= cloud.google.com/go/compute/metadata v0.2.1/go.mod h1:jgHgmJd2RKBGzXqF5LR2EZMGxBkeanZ9wwa75XHJgOM= @@ -488,6 +490,7 @@ cloud.google.com/go/iam v1.1.1/go.mod h1:A5avdyVL2tCppe4unb0951eI9jreack+RJ0/d+K cloud.google.com/go/iam v1.1.2/go.mod h1:A5avdyVL2tCppe4unb0951eI9jreack+RJ0/d+KUZOU= cloud.google.com/go/iam v1.1.3/go.mod h1:3khUlaBXfPKKe7huYgEpDn6FtgRyMEqbkvBxrQyY5SE= cloud.google.com/go/iam v1.1.6 h1:bEa06k05IO4f4uJonbB5iAgKTPpABy1ayxaIZV/GHVc= +cloud.google.com/go/iam v1.1.6/go.mod h1:O0zxdPeGBoFdWW3HWmBxJsk0pfvNM/p/qa82rWOGTwI= cloud.google.com/go/iap v1.4.0/go.mod h1:RGFwRJdihTINIe4wZ2iCP0zF/qu18ZwyKxrhMhygBEc= cloud.google.com/go/iap v1.5.0/go.mod h1:UH/CGgKd4KyohZL5Pt0jSKE4m3FR51qg6FKQ/z/Ix9A= cloud.google.com/go/iap v1.6.0/go.mod h1:NSuvI9C/j7UdjGjIde7t7HBz+QTwBcapPE07+sSRcLk= @@ -822,6 +825,7 @@ cloud.google.com/go/storage v1.28.1/go.mod h1:Qnisd4CqDdo6BGs2AD5LLnEsmSQ80wQ5og cloud.google.com/go/storage v1.29.0/go.mod h1:4puEjyTKnku6gfKoTfNOU/W+a9JyuVNxjpS5GBrB8h4= cloud.google.com/go/storage v1.30.1/go.mod h1:NfxhC0UJE1aXSx7CIIbCf7y9HKT7BiccwkR7+P7gN8E= cloud.google.com/go/storage v1.36.0 h1:P0mOkAcaJxhCTvAkMhxMfrTKiNcub4YmmPBtlhAyTr8= +cloud.google.com/go/storage v1.36.0/go.mod h1:M6M/3V/D3KpzMTJyPOR/HU6n2Si5QdaXYEsng2xgOs8= cloud.google.com/go/storagetransfer v1.5.0/go.mod h1:dxNzUopWy7RQevYFHewchb29POFv3/AaBgnhqzqiK0w= cloud.google.com/go/storagetransfer v1.6.0/go.mod h1:y77xm4CQV/ZhFZH75PLEXY0ROiS7Gh6pSKrM8dJyg6I= cloud.google.com/go/storagetransfer v1.7.0/go.mod h1:8Giuj1QNb1kfLAiWM1bN6dHzfdlDAVC9rv9abHot2W4= @@ -966,6 +970,7 @@ github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migc github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/OneOfOne/xxhash v1.2.8 h1:31czK/TI9sNkxIKfaUfGlU47BAxQ0ztGgd9vPyqimf8= +github.com/OneOfOne/xxhash v1.2.8/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q= github.com/PuerkitoBio/goquery v1.5.0/go.mod h1:qD2PgZ9lccMbQlc7eEOjaeRlFQON7xY8kdmcsrnKqMg= github.com/SaveTheRbtz/mph v0.1.1-0.20240117162131-4166ec7869bc h1:DCHzPQOcU/7gwDTWbFQZc5qHMPS1g0xTO56k8NXsv9M= github.com/SaveTheRbtz/mph v0.1.1-0.20240117162131-4166ec7869bc/go.mod h1:LJM5a3zcIJ/8TmZwlUczvROEJT8ntOdhdG9jjcR1B0I= @@ -1005,6 +1010,7 @@ github.com/aws/aws-sdk-go-v2 v1.2.0/go.mod h1:zEQs02YRBw1DjK0PoJv3ygDYOFTre1ejlJ github.com/aws/aws-sdk-go-v2 v1.21.2/go.mod h1:ErQhvNuEMhJjweavOYhxVkn2RUx7kQXVATHrjKtxIpM= github.com/aws/aws-sdk-go-v2 v1.23.1/go.mod h1:i1XDttT4rnf6vxc9AuskLc6s7XBee8rlLilKlc03uAA= github.com/aws/aws-sdk-go-v2 v1.26.1 h1:5554eUqIYVWpU0YmeeYZ0wU64H2VLBs8TlhRB2L+EkA= +github.com/aws/aws-sdk-go-v2 v1.26.1/go.mod h1:ffIFB97e2yNsv4aTSGkqtHnppsIJzw7G7BReUZ3jCXM= github.com/aws/aws-sdk-go-v2/config v1.1.1/go.mod h1:0XsVy9lBI/BCXm+2Tuvt39YmdHwS5unDQmxZOYe8F5Y= github.com/aws/aws-sdk-go-v2/config v1.18.45/go.mod h1:ZwDUgFnQgsazQTnWfeLWk5GjeqTQTL8lMkoE1UXzxdE= github.com/aws/aws-sdk-go-v2/config v1.25.5/go.mod h1:Bf4gDvy4ZcFIK0rqDu1wp9wrubNba2DojiPB2rt6nvI= @@ -1015,6 +1021,7 @@ github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.0.2/go.mod h1:3hGg3PpiEjHnrkrla github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.13/go.mod h1:f/Ib/qYjhV2/qdsf79H3QP/eRE4AkVyEf6sk7XfZ1tg= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.5/go.mod h1:VhnExhw6uXy9QzetvpXDolo1/hjhx4u9qukBGkuUwjs= github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.5.1 h1:VGkV9KmhGqOQWnHyi4gLG98kE6OecT42fdrCGFWxJsc= +github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.5.1/go.mod h1:PLlnMiki//sGnCJiW+aVpvP/C8Kcm8mEj/IVm9+9qk4= github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.43/go.mod h1:auo+PiyLl0n1l8A0e8RIeR8tOzYPfZZH/JNlrJ8igTQ= github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.4/go.mod h1:xEhvbJcyUf/31yfGSQBe01fukXwXJ0gxDp7rLfymWE0= github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.37/go.mod h1:Qe+2KtKml+FEsQF/DHmDV+xjtche/hwoF75EG4UlHW8= @@ -1023,15 +1030,19 @@ github.com/aws/aws-sdk-go-v2/internal/ini v1.3.45/go.mod h1:lD5M20o09/LCuQ2mE62M github.com/aws/aws-sdk-go-v2/internal/ini v1.7.1/go.mod h1:6fQQgfuGmw8Al/3M2IgIllycxV7ZW7WCdVSqfBeUiCY= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.1/go.mod h1:l9ymW25HOqymeU2m1gbUQ3rUIsTwKs8gYHXkqDQUhiI= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.2 h1:Ji0DY1xUsUr3I8cHps0G+XM3WWU16lP6yG8qu1GAZAs= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.2/go.mod h1:5CsjAbs3NlGQyZNFACh+zztPDI7fU6eW9QsxjfnuBKg= github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.0.2/go.mod h1:45MfaXZ0cNbeuT0KQ1XJylq8A6+OpVV2E5kvY/Kq+u8= github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.37/go.mod h1:vBmDnwWXWxNPFRMmG2m/3MKOe+xEcMDo1tanpaWCcck= github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.4/go.mod h1:aYCGNjyUCUelhofxlZyj63srdxWUSsBSGg5l6MCuXuE= github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.7 h1:ogRAwT1/gxJBcSWDMZlgyFUM962F51A5CRhDLbxLdmo= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.7/go.mod h1:YCsIZhXfRPLFFCl5xxY+1T9RKzOKjCut+28JSX2DnAk= github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.7.0 h1:HWsM0YQWX76V6MOp07YuTYacm8k7h69ObJuw7Nck+og= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.7.0/go.mod h1:LKb3cKNQIMh+itGnEpKGcnL/6OIjPZqrtYah1w5f+3o= github.com/aws/aws-sdk-go-v2/service/kms v1.26.3/go.mod h1:N3++/sLV97B8Zliz7KRqNcojOX7iMBZWKiuit5FKtH0= github.com/aws/aws-sdk-go-v2/service/route53 v1.1.1/go.mod h1:rLiOUrPLW/Er5kRcQ7NkwbjlijluLsrIbu/iyl35RO4= github.com/aws/aws-sdk-go-v2/service/route53 v1.30.2/go.mod h1:TQZBt/WaQy+zTHoW++rnl8JBrmZ0VO6EUbVua1+foCA= github.com/aws/aws-sdk-go-v2/service/s3 v1.15.0 h1:nPLfLPfglacc29Y949sDxpr3X/blaY40s3B85WT2yZU= +github.com/aws/aws-sdk-go-v2/service/s3 v1.15.0/go.mod h1:Iv2aJVtVSm/D22rFoX99cLG4q4uB7tppuCsulGe98k4= github.com/aws/aws-sdk-go-v2/service/sso v1.1.1/go.mod h1:SuZJxklHxLAXgLTc1iFXbEWkXs7QRTQpCLGaKIprQW0= github.com/aws/aws-sdk-go-v2/service/sso v1.15.2/go.mod h1:gsL4keucRCgW+xA85ALBpRFfdSLH4kHOVSnLMSuBECo= github.com/aws/aws-sdk-go-v2/service/sso v1.17.3/go.mod h1:oA6VjNsLll2eVuUoF2D+CMyORgNzPEW/3PyUdq6WQjI= @@ -1044,9 +1055,11 @@ github.com/aws/smithy-go v1.1.0/go.mod h1:EzMw8dbp/YJL4A5/sbhGddag+NPT7q084agLbB github.com/aws/smithy-go v1.15.0/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA= github.com/aws/smithy-go v1.17.0/go.mod h1:NukqUGpCZIILqqiV0NIjeFh24kd/FAa4beRb6nbIUPE= github.com/aws/smithy-go v1.20.2 h1:tbp628ireGtzcHDDmLT/6ADHidqnwgF57XOXZe6tp4Q= +github.com/aws/smithy-go v1.20.2/go.mod h1:krry+ya/rV9RDcV/Q16kpu6ypI4K2czasz0NC3qS14E= github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/benbjohnson/clock v1.3.5 h1:VvXlSJBzZpA/zum6Sj74hxwYI2DIxRWuNIoXAzHZz5o= +github.com/benbjohnson/clock v1.3.5/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -1064,10 +1077,9 @@ github.com/btcsuite/btcd/btcec/v2 v2.2.1 h1:xP60mv8fvp+0khmrN0zTdPC3cNm24rfeE6lh github.com/btcsuite/btcd/btcec/v2 v2.2.1/go.mod h1:9/CSmJxmuvqzX9Wh2fXMWToLOHhPd11lSPuIupwTkI8= github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= github.com/btcsuite/btcd/chaincfg/chainhash v1.0.2 h1:KdUfX2zKommPRa+PD0sWZUyXe9w277ABlgELO7H04IM= -github.com/bytecodealliance/wasmtime-go v1.0.0/go.mod h1:jjlqQbWUfVSbehpErw3UoWFndBXRRMvfikYH6KsCwOg= -github.com/bytecodealliance/wasmtime-go/v12 v12.0.0/go.mod h1:a3PRoftJxxUzkQvgjC6sv7pKyJJK0ZsFVmH+eeEKQC4= -github.com/bytecodealliance/wasmtime-go/v22 v22.0.0/go.mod h1:knqkvjTLavLtAXnA5NJUM0qbRiPJCVWPLXfYu75kZSo= -github.com/bytecodealliance/wasmtime-go/v7 v7.0.0/go.mod h1:bu6fic7trDt20w+LMooX7j3fsOwv4/ln6j8gAdP6vmA= +github.com/btcsuite/btcd/chaincfg/chainhash v1.0.2/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= +github.com/bytecodealliance/wasmtime-go/v22 v22.0.0-20240626142402-d03b414c50b4 h1:Jtz9TgzQLwJgPZfF7gEcM8D0Vk6CizoV6UUdLmS/SiU= +github.com/bytecodealliance/wasmtime-go/v22 v22.0.0-20240626142402-d03b414c50b4/go.mod h1:knqkvjTLavLtAXnA5NJUM0qbRiPJCVWPLXfYu75kZSo= github.com/c-bata/go-prompt v0.2.2/go.mod h1:VzqtzE2ksDBcdln8G7mk2RX9QyGjH+OVqOCSiVIqS34= github.com/c-bata/go-prompt v0.2.6/go.mod h1:/LMAke8wD2FsNu9EXNdHxNLbd9MedkPnCdfpU9wwHfY= github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM= @@ -1135,6 +1147,7 @@ github.com/consensys/gnark-crypto v0.10.0/go.mod h1:Iq/P3HHl0ElSjsg2E1gsMwhAyxnx github.com/consensys/gnark-crypto v0.12.1 h1:lHH39WuuFgVHONRl3J0LRBtuYdQTumFSDtJF7HpyG8M= github.com/consensys/gnark-crypto v0.12.1/go.mod h1:v2Gy7L/4ZRosZ7Ivs+9SfUDr0f5UlG+EM5t7MPHiLuY= github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM= +github.com/containerd/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHqJDGwsa1mIw= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= @@ -1171,6 +1184,7 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c h1:pFUpOrbxDR6AkioZ1ySsx5yxlDQZ8stG2b88gTPxgJU= +github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c/go.mod h1:6UhI8N9EjYm1c2odKpFpAYeR8dsBeM7PtzQhRgxRr9U= github.com/deckarep/golang-set v1.8.0/go.mod h1:5nI87KwE7wgsBU1F4GKAw2Qod7p5kyS383rP6+o6qqo= github.com/deckarep/golang-set/v2 v2.1.0 h1:g47V4Or+DUdzbs8FxCCmgb6VYd+ptPAngjM6dtGktsI= github.com/deckarep/golang-set/v2 v2.1.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= @@ -1215,6 +1229,7 @@ github.com/ef-ds/deque v1.0.4 h1:iFAZNmveMT9WERAkqLJ+oaABF9AcVQ5AjXem/hroniI= github.com/ef-ds/deque v1.0.4/go.mod h1:gXDnTC3yqvBcHbq2lcExjtAcVrOnJCbMcZXmuj8Z4tg= github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM= github.com/elastic/gosigar v0.14.2 h1:Dg80n8cr90OZ7x+bAax/QjoW/XqTI11RmA79ZwIm9/4= +github.com/elastic/gosigar v0.14.2/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= @@ -1247,6 +1262,7 @@ github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5Kwzbycv github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= +github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/fjl/gencodec v0.0.0-20220412091415-8bb9e558978c/go.mod h1:AzA8Lj6YtixmJWL+wkKoBGsLWy9gFrAzi4g+5bCKwpY= github.com/fjl/gencodec v0.0.0-20230517082657-f9840df7b83e/go.mod h1:AzA8Lj6YtixmJWL+wkKoBGsLWy9gFrAzi4g+5bCKwpY= github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= @@ -1254,7 +1270,9 @@ github.com/flosch/pongo2 v0.0.0-20190707114632-bbf5a6c351f4/go.mod h1:T9YF2M40nI github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= github.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJnXKk= +github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY= github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE= +github.com/frankban/quicktest v1.14.3/go.mod h1:mgiwOwqx65TmIk1wJ6Q7wvnVMocbUorkibMOrVTHZps= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= @@ -1265,8 +1283,11 @@ github.com/fxamacker/cbor/v2 v2.4.1-0.20230228173756-c0c9f774e40c/go.mod h1:TA1x github.com/fxamacker/circlehash v0.3.0 h1:XKdvTtIJV9t7DDUtsf0RIpC1OcxZtPbmgIH7ekx28WA= github.com/fxamacker/circlehash v0.3.0/go.mod h1:3aq3OfVvsWtkWMb6A1owjOQFA+TLsD5FgJflnaQwtMM= github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0= +github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk= github.com/gammazero/deque v0.1.0 h1:f9LnNmq66VDeuAlSAapemq/U7hJ2jpIWa4c09q8Dlik= +github.com/gammazero/deque v0.1.0/go.mod h1:KQw7vFau1hHuM8xmI9RbgKFbAsQFWmBpqQ2KenFLk6M= github.com/gammazero/workerpool v1.1.2 h1:vuioDQbgrz4HoaCi2q1HLlOXdpbap5AET7xu5/qj87g= +github.com/gammazero/workerpool v1.1.2/go.mod h1:UelbXcO0zCIGFcufcirHhq2/xtLXJdQ29qZNlXG9OjQ= github.com/garslo/gogen v0.0.0-20170306192744-1d203ffc1f61/go.mod h1:Q0X6pkwTILDlzrGEckF6HKjXe48EgsY/l7K7vhY4MW8= github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc= github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= @@ -1281,12 +1302,14 @@ github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeME github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s= github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/3rZdM= github.com/glebarez/go-sqlite v1.22.0 h1:uAcMJhaA6r3LHMTFgP0SifzgXg46yJkgxqyuyec+ruQ= +github.com/glebarez/go-sqlite v1.22.0/go.mod h1:PlBIdHe0+aUEFn+r2/uthrWq4FxbzugL0L8Li6yQJbc= github.com/glycerine/go-unsnap-stream v0.0.0-20180323001048-9f0cb55181dd/go.mod h1:/20jfyN9Y5QPEAprSgKAUr+glWDY39ZiUEAYOEv5dsE= github.com/glycerine/goconvey v0.0.0-20190410193231-58a59202ab31/go.mod h1:Ogl1Tioa0aV7gstGFO7KhffUsb9M4ydbEbbxpcEDc24= github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= github.com/go-chi/chi/v5 v5.0.0/go.mod h1:BBug9lr0cqtdAhsu6R4AAdvufI0/XBzAQSsUqJpoZOs= github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA= +github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= github.com/go-fonts/dejavu v0.1.0/go.mod h1:4Wt4I4OU2Nq9asgDCteaAaWZOV24E+0/Pwo0gppep4g= github.com/go-fonts/latin-modern v0.2.0/go.mod h1:rQVLdDMK+mK1xscDwsqM5J8U2jrRa3T0ecnM9pNujks= github.com/go-fonts/latin-modern v0.3.0/go.mod h1:ysEQXnuT/sCDOAONxC7ImeEDVINbltClhasMAqEtRK0= @@ -1329,14 +1352,18 @@ github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh github.com/go-pdf/fpdf v0.5.0/go.mod h1:HzcnA+A23uwogo0tp9yU+l3V+KXhiESpt1PMayhOh5M= github.com/go-pdf/fpdf v0.6.0/go.mod h1:HzcnA+A23uwogo0tp9yU+l3V+KXhiESpt1PMayhOh5M= github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= +github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= +github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= github.com/go-playground/validator/v10 v10.14.1 h1:9c50NUPC30zyuKprjL3vNZ0m5oG+jU0zvx4AqHGnv4k= +github.com/go-playground/validator/v10 v10.14.1/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= github.com/go-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg= github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-stack/stack v1.8.1 h1:ntEHSVwIt7PNXNpgPmVfMrNhLtgjlmnZha2kOpuRiDw= github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP3XYfe4= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= @@ -1344,6 +1371,7 @@ github.com/goccy/go-json v0.9.11/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MG github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= +github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw= github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= github.com/gofrs/uuid v3.3.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= @@ -1446,6 +1474,7 @@ github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17 github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.1.1-0.20200604201612-c04b05f3adfa/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8= +github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= @@ -1468,6 +1497,7 @@ github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLe github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20230207041349-798e818bf904/go.mod h1:uglQLonpP8qtYCYyzA+8c/9qtqgA3qsXGYqCPKARAFg= github.com/google/pprof v0.0.0-20231229205709-960ae82b1e42 h1:dHLYa5D8/Ta0aLR2XcPsrkpAgGeFs6thhMcQK0oQ0n8= +github.com/google/pprof v0.0.0-20231229205709-960ae82b1e42/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/s2a-go v0.1.0/go.mod h1:OJpEgntRZo8ugHpF9hkoLJbS5dSI20XZeXJ9JVywLlM= github.com/google/s2a-go v0.1.3/go.mod h1:Ej+mSEMGRnqRzjc7VtF+jdBwYG5fuJfiZ8ELkjEwM0A= @@ -1526,6 +1556,7 @@ github.com/graph-gophers/graphql-go v1.3.0/go.mod h1:9CQHMSxwO4MprSdzoIEobiHpoLt github.com/grpc-ecosystem/go-grpc-middleware v1.0.0 h1:Iju5GlWwrvL6UBg4zJJt3btmonfrMlCDdsejg4CZE7c= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0 h1:pRhl55Yx1eC7BZ1N+BBWwnKaMyD8uC+34TLdndZMAKk= +github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0/go.mod h1:XKMd7iuf/RGPSMJ/U4HP0zS2Z9Fh8Ps9a+6X26m/tmI= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= @@ -1604,11 +1635,13 @@ github.com/ipfs/go-cid v0.4.1/go.mod h1:uQHwDeX4c6CtyrFwdqyhpNcxVewur1M7l7fNU7LK github.com/ipfs/go-datastore v0.6.0 h1:JKyz+Gvz1QEZw0LsX1IBn+JFCJQH4SJVFtM4uWU0Myk= github.com/ipfs/go-datastore v0.6.0/go.mod h1:rt5M3nNbSO/8q1t4LNkLyUwRs8HupMeN/8O4Vn9YAT8= github.com/ipfs/go-detect-race v0.0.1 h1:qX/xay2W3E4Q1U7d9lNs1sU9nvguX0a7319XbyQ6cOk= +github.com/ipfs/go-detect-race v0.0.1/go.mod h1:8BNT7shDZPo99Q74BpGMK+4D8Mn4j46UU0LZ723meps= github.com/ipfs/go-ipfs-util v0.0.3 h1:2RFdGez6bu2ZlZdI+rWfIdbQb1KudQp3VGwPtdNCmE0= github.com/ipfs/go-ipfs-util v0.0.3/go.mod h1:LHzG1a0Ig4G+iZ26UUOMjHd+lfM84LZCrn17xAKWBvs= github.com/ipfs/go-ipld-format v0.6.0 h1:VEJlA2kQ3LqFSIm5Vu6eIlSxD/Ze90xtc4Meten1F5U= github.com/ipfs/go-ipld-format v0.6.0/go.mod h1:g4QVMTn3marU3qXchwjpKPKgJv+zF+OlaKMyhJ4LHPg= github.com/ipfs/go-log v1.0.5 h1:2dOuUCB1Z7uoczMWgAyDck5JLb72zHzrMnGnCNNbvY8= +github.com/ipfs/go-log v1.0.5/go.mod h1:j0b8ZoR+7+R99LD9jZ6+AJsrzkPbSXbZfGakb5JPtIo= github.com/ipfs/go-log/v2 v2.5.1 h1:1XdUzF7048prq4aBjDQQ4SL5RxftpRGdXhNRwKSAlcY= github.com/ipfs/go-log/v2 v2.5.1/go.mod h1:prSpmC1Gpllc9UYWxDiZDreBYw7zp4Iqp1kOLU9U5UI= github.com/ipfs/go-metrics-interface v0.0.1 h1:j+cpbjYvu4R8zbleSs36gvB7jR+wsL2fGD6n0jO4kdg= @@ -1624,6 +1657,7 @@ github.com/itchyny/timefmt-go v0.1.5/go.mod h1:nEP7L+2YmAbT2kZ2HfSs1d8Xtw9LY8D2s github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= github.com/jbenet/go-cienv v0.1.0/go.mod h1:TqNnHUmJgXau0nCzC7kXWeotg3J9W34CUv5Djy1+FlA= github.com/jbenet/go-temp-err-catcher v0.1.0 h1:zpb3ZH6wIE8Shj2sKS+khgRvf7T7RABoLk/+KKHggpk= +github.com/jbenet/go-temp-err-catcher v0.1.0/go.mod h1:0kJRvmDZXNMIiJirNPEYfhpPwbGVtZVWC34vc5WLsDk= github.com/jbenet/goprocess v0.1.4 h1:DRGOFReOMqqDNXwW70QkacFW0YN9QnwLV0Vqk+3oU0o= github.com/jbenet/goprocess v0.1.4/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4= github.com/jedisct1/go-minisign v0.0.0-20190909160543-45766022959e/go.mod h1:G1CVv03EnqU1wYL2dFwXxW2An0az9JTl/ZsqXQeBlkU= @@ -1720,23 +1754,32 @@ github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q= +github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8= github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg= github.com/libp2p/go-cidranger v1.1.0 h1:ewPN8EZ0dd1LSnrtuwd4709PXVcITVeuwbag38yPW7c= +github.com/libp2p/go-cidranger v1.1.0/go.mod h1:KWZTfSr+r9qEo9OkI9/SIEeAtw+NNoU0dXIXt15Okic= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= +github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= github.com/libp2p/go-libp2p v0.32.2 h1:s8GYN4YJzgUoyeYNPdW7JZeZ5Ee31iNaIBfGYMAY4FQ= github.com/libp2p/go-libp2p v0.32.2/go.mod h1:E0LKe+diV/ZVJVnOJby8VC5xzHF0660osg71skcxJvk= github.com/libp2p/go-libp2p-asn-util v0.4.1 h1:xqL7++IKD9TBFMgnLPZR6/6iYhawHKHl950SO9L6n94= +github.com/libp2p/go-libp2p-asn-util v0.4.1/go.mod h1:d/NI6XZ9qxw67b4e+NgpQexCIiFYJjErASrYW4PFDN8= github.com/libp2p/go-libp2p-kbucket v0.6.3 h1:p507271wWzpy2f1XxPzCQG9NiN6R6lHL9GiSErbQQo0= +github.com/libp2p/go-libp2p-kbucket v0.6.3/go.mod h1:RCseT7AH6eJWxxk2ol03xtP9pEHetYSPXOaJnOiD8i0= github.com/libp2p/go-libp2p-pubsub v0.10.0 h1:wS0S5FlISavMaAbxyQn3dxMOe2eegMfswM471RuHJwA= github.com/libp2p/go-libp2p-pubsub v0.10.0/go.mod h1:1OxbaT/pFRO5h+Dpze8hdHQ63R0ke55XTs6b6NwLLkw= github.com/libp2p/go-libp2p-testing v0.12.0 h1:EPvBb4kKMWO29qP4mZGyhVzUyR25dvfUIK5WDu6iPUA= +github.com/libp2p/go-libp2p-testing v0.12.0/go.mod h1:KcGDRXyN7sQCllucn1cOOS+Dmm7ujhfEyXQL5lvkcPg= github.com/libp2p/go-msgio v0.3.0 h1:mf3Z8B1xcFN314sWX+2vOTShIE0Mmn2TXn3YCUQGNj0= github.com/libp2p/go-msgio v0.3.0/go.mod h1:nyRM819GmVaF9LX3l03RMh10QdOroF++NBbxAb0mmDM= github.com/libp2p/go-netroute v0.2.1 h1:V8kVrpD8GK0Riv15/7VN6RbUQ3URNZVosw7H2v9tksU= +github.com/libp2p/go-netroute v0.2.1/go.mod h1:hraioZr0fhBjG0ZRXJJ6Zj2IVEVNx6tDTFQfSmcq7mQ= github.com/libp2p/go-reuseport v0.4.0 h1:nR5KU7hD0WxXCJbmw7r2rhRYruNRl2koHw8fQscQm2s= +github.com/libp2p/go-reuseport v0.4.0/go.mod h1:ZtI03j/wO5hZVDFo2jKywN6bYKWLOy8Se6DrI2E1cLU= github.com/libp2p/go-yamux/v4 v4.0.1 h1:FfDR4S1wj6Bw2Pqbc8Uz7pCxeRBPbwsBbEdfwiCypkQ= +github.com/libp2p/go-yamux/v4 v4.0.1/go.mod h1:NWjl8ZTLOGlozrXSOZ/HlfG++39iKNnM5wwmtQP1YB4= github.com/logrusorgru/aurora/v4 v4.0.0 h1:sRjfPpun/63iADiSvGGjgA1cAYegEWMPCJdUpJYn9JA= github.com/logrusorgru/aurora/v4 v4.0.0/go.mod h1:lP0iIa2nrnT/qoFXcOZSrZQpJ1o6n2CUf/hyHi2Q4ZQ= github.com/lyft/protoc-gen-star v0.6.0/go.mod h1:TGAoBVkt8w7MPG72TrKIu85MIdXwDuzJYeZuUPFPNwA= @@ -1749,6 +1792,7 @@ github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3v github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd h1:br0buuQ854V8u83wA0rVZ8ttrq5CpaPZdvrK0LP2lOk= +github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd/go.mod h1:QuCEs1Nt24+FYQEqAAncTDPJIuGs+LxK1MCiFL25pMU= github.com/matryer/moq v0.0.0-20190312154309-6cfb0558e1bd/go.mod h1:9ELz6aaclSIGnZBoaSLZ3NAl1VTufbOrXBPvtcy6WiQ= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= @@ -1795,8 +1839,11 @@ github.com/mediocregopher/radix/v3 v3.3.0/go.mod h1:EmfVyvspXz1uZEyPBMyGK+kjWiKQ github.com/mediocregopher/radix/v3 v3.4.2/go.mod h1:8FL3F6UQRXHXIBSPUs5h0RybMF8i4n7wVopoX3x7Bv8= github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc= github.com/miekg/dns v1.1.57 h1:Jzi7ApEIzwEPLHWRcafCN9LZSBbqQpxjt/wpgvg7wcM= +github.com/miekg/dns v1.1.57/go.mod h1:uqRjCRUuEAA6qsOiJvDd+CFo/vW+y5WR6SNmHE55hZk= github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b h1:z78hV3sbSMAUoyUMM0I83AUIT6Hu17AWfgjzIbtrYFc= +github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b/go.mod h1:lxPUiZwKoFL8DUUmalo2yJJUCxbPKtm8OKfqr2/FTNU= github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc h1:PTfri+PuQmWDqERdnNMiD9ZejrlswWrCpBEZgWOiTrc= +github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc/go.mod h1:cGKTAVKx4SxOuR/czcZ/E2RSJ3sfHs8FpHhQ5CWMf9s= github.com/minio/asm2plan9s v0.0.0-20200509001527-cdd76441f9d8/go.mod h1:mC1jAcsrzbxHt8iiaC+zU4b1ylILSosueou12R++wfY= github.com/minio/c2goasm v0.0.0-20190812172519-36a3d3bbc4f3/go.mod h1:RagcQ7I8IeTMnF8JTXieKnO4Z6JCsikNEzj0DwauVzE= github.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dzMM= @@ -1831,7 +1878,9 @@ github.com/multiformats/go-base36 v0.2.0/go.mod h1:qvnKE++v+2MWCfePClUEjE78Z7P2a github.com/multiformats/go-multiaddr v0.12.2 h1:9G9sTY/wCYajKa9lyfWPmpZAwe6oV+Wb1zcmMS1HG24= github.com/multiformats/go-multiaddr v0.12.2/go.mod h1:GKyaTYjZRdcUhyOetrxTk9z0cW+jA/YrnqTOvKgi44M= github.com/multiformats/go-multiaddr-dns v0.3.1 h1:QgQgR+LQVt3NPTjbrLLpsaT2ufAA2y0Mkk+QRVJbW3A= +github.com/multiformats/go-multiaddr-dns v0.3.1/go.mod h1:G/245BRQ6FJGmryJCrOuTdB37AMA5AMOVuO6NY3JwTk= github.com/multiformats/go-multiaddr-fmt v0.1.0 h1:WLEFClPycPkp4fnIzoFoV9FVd49/eQsuaL3/CWe167E= +github.com/multiformats/go-multiaddr-fmt v0.1.0/go.mod h1:hGtDIW4PU4BqJ50gW2quDuPVjyWNZxToGUh/HwTZYJo= github.com/multiformats/go-multibase v0.2.0 h1:isdYCVLvksgWlMW9OZRYJEa9pZETFivncJHmHnnd87g= github.com/multiformats/go-multibase v0.2.0/go.mod h1:bFBZX4lKCA/2lyOFSAoKH5SS6oPyjtnzK/XTFDPkNuk= github.com/multiformats/go-multicodec v0.9.0 h1:pb/dlPnzee/Sxv/j4PmkDRxCOi3hXTz3IbPKOXWJkmg= @@ -1855,6 +1904,7 @@ github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OS github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= +github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= @@ -1899,14 +1949,17 @@ github.com/onsi/ginkgo v1.13.0/go.mod h1:+REjRxOmWfHCjfv9TTWB1jD1Frx4XydAD3zm1ls github.com/onsi/ginkgo v1.14.0 h1:2mOpI4JVVPBN+WQRa0WKH2eXR+Ey+uK4n7Zj0aYpIQA= github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/ginkgo/v2 v2.13.2 h1:Bi2gGVkfn6gQcjNjZJVO8Gf0FHzMPf2phUei9tejVMs= +github.com/onsi/ginkgo/v2 v2.13.2/go.mod h1:XStQ8QcGwLyF4HdfcZB8SFOS/MWCgDuXMSBe6zrvLgM= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/opencontainers/runtime-spec v1.1.0 h1:HHUyrt9mwHUjtasSbXSMvs4cyFxh+Bll4AjJ9odEGpg= +github.com/opencontainers/runtime-spec v1.1.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/opentracing/opentracing-go v1.0.3-0.20180606204148-bd9c31933947/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= +github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= github.com/paulbellamy/ratecounter v0.2.0/go.mod h1:Hfx1hDpSGoqxkVVpBi/IlYD7kChlfo5C6hzIHwPqfFE= github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 h1:onHthvaw9LFnH4t2DcNVpwGmV9E1BkGknEliJkfwQj0= github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58/go.mod h1:DXv8WO4yhMYhSNPKjeNKa5WY9YCIEBRbNzFFPJbWO6Y= @@ -1978,8 +2031,11 @@ github.com/protolambda/bls12-381-util v0.0.0-20220416220906-d8552aa452c7/go.mod github.com/psiemens/sconfig v0.1.0 h1:xfWqW+TRpih7mXZIqKYTmpRhlZLQ1kbxV8EjllPv76s= github.com/psiemens/sconfig v0.1.0/go.mod h1:+MLKqdledP/8G3rOBpknbLh0IclCf4WneJUtS26JB2U= github.com/quic-go/qtls-go1-20 v0.4.1 h1:D33340mCNDAIKBqXuAvexTNMUByrYmFYVfKfDN5nfFs= +github.com/quic-go/qtls-go1-20 v0.4.1/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k= github.com/quic-go/quic-go v0.40.1 h1:X3AGzUNFs0jVuO3esAGnTfvdgvL4fq655WaOi1snv1Q= +github.com/quic-go/quic-go v0.40.1/go.mod h1:PeN7kuVJ4xZbxSv/4OX6S1USOX8MJvydwpTx31vx60c= github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= +github.com/raulk/go-watchdog v1.3.0/go.mod h1:fIvOnLbF0b0ZwkB9YU4mOW9Did//4vPZtDqv66NfsMU= github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= @@ -2164,7 +2220,9 @@ go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.47.0 h1:UNQQKPfTDe1J81ViolILjTKPr9WetKW6uei2hFgJmFs= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.47.0/go.mod h1:r9vWsPS/3AQItv3OSlEJ/E4mbrhUbbw18meOjArPtKQ= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.47.0 h1:sv9kVfal0MK0wBMCOGr+HeJm9v803BkJxGrk2au7j08= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.47.0/go.mod h1:SK2UL73Zy1quvRPonmOmRDiWk1KBV3LyIeeIxcEApWw= go.opentelemetry.io/otel v1.8.0/go.mod h1:2pkj+iMj0o03Y+cW6/m8Y4WkRdYN3AvCXCnzRMp9yvM= go.opentelemetry.io/otel v1.16.0/go.mod h1:vl0h9NUa1D5s1nv3A5vZOYWn8av4K8Ml6JDeHrT/bx4= go.opentelemetry.io/otel v1.24.0 h1:0LAOdjNmQeSTzGBzduGe/rU4tZhMwL5rWgtp9Ku5Jfo= @@ -2197,7 +2255,9 @@ go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.2.1/go.mod h1:qlT2yGI9QafXHhZZLxlSuNsMw3FFLxBr+tBRlmO1xH4= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= +go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU= +go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= @@ -2433,6 +2493,7 @@ golang.org/x/oauth2 v0.10.0/go.mod h1:kTpgurOux7LqtuxjuyZa4Gj2gdezIt/jQtGnNFfypQ golang.org/x/oauth2 v0.11.0/go.mod h1:LdF7O/8bLR/qWK9DrpXmbHLTouvRHK0SgJl0GmDBchk= golang.org/x/oauth2 v0.13.0/go.mod h1:/JMhi4ZRXAf4HG9LiNmxvk+45+96RUlVThiH8FzNBn0= golang.org/x/oauth2 v0.17.0 h1:6m3ZPmLEFdVxKKWnKq4VqZ60gutO35zm+zrAHVmHyDQ= +golang.org/x/oauth2 v0.17.0/go.mod h1:OzPDGQiuQMguemayvdylqddI7qcD9lnSDb+1FiwQ5HA= golang.org/x/perf v0.0.0-20230113213139-801c7ef9e5c5/go.mod h1:UBKtEnL8aqnd+0JHqZ+2qoMDwtuy6cYhhKNoHLBiTQc= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -2633,6 +2694,7 @@ golang.org/x/time v0.0.0-20220922220347-f3bd1da661af/go.mod h1:tRJNPiyCQ0inRvYxb golang.org/x/time v0.1.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= +golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -2808,6 +2870,7 @@ google.golang.org/api v0.139.0/go.mod h1:CVagp6Eekz9CjGZ718Z+sloknzkDJE7Vc1Ckj9+ google.golang.org/api v0.149.0/go.mod h1:Mwn1B7JTXrzXtnvmzQE2BD6bYZQ8DShKZDZbeN9I7qI= google.golang.org/api v0.151.0/go.mod h1:ccy+MJ6nrYFgE3WgRx/AMXOxOmU8Q4hSa+jjibzhxcg= google.golang.org/api v0.162.0 h1:Vhs54HkaEpkMBdgGdOT2P6F0csGG/vxDS0hWHJzmmps= +google.golang.org/api v0.162.0/go.mod h1:6SulDkfoBIg4NFmCuZ39XeeAgSHCPecfSUuDyYlAHs0= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -2971,6 +3034,7 @@ google.golang.org/genproto v0.0.0-20231002182017-d307bd883b97/go.mod h1:t1VqOqqv google.golang.org/genproto v0.0.0-20231012201019-e917dd12ba7a/go.mod h1:EMfReVxb80Dq1hhioy0sOsY9jCE46YDgHlJ7fWVUWRE= google.golang.org/genproto v0.0.0-20231016165738-49dd2c1f3d0b/go.mod h1:CgAqfJo+Xmu0GwA0411Ht3OU3OntXwsGmrmjI8ioGXI= google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de h1:F6qOa9AZTYJXOUEr4jDysRDLrm4PHePlge4v4TGAlxY= +google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:VUhTRKeHn9wwcdrk73nvdC9gF178Tzhmt/qyaFcPLSo= google.golang.org/genproto/googleapis/api v0.0.0-20230525234020-1aefcd67740a/go.mod h1:ts19tUU+Z0ZShN1y3aPyq2+O3d5FUNNgT6FtOzmrNn8= google.golang.org/genproto/googleapis/api v0.0.0-20230525234035-dd9d682886f9/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig= google.golang.org/genproto/googleapis/api v0.0.0-20230526203410-71b5a4ffd15e/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig= @@ -3122,6 +3186,7 @@ gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= +gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= @@ -3164,10 +3229,12 @@ modernc.org/libc v1.20.3/go.mod h1:ZRfIaEkgrYgZDl6pa4W39HgN5G/yDW+NRmNKZBDFrk0= modernc.org/libc v1.21.4/go.mod h1:przBsL5RDOZajTVslkugzLBj1evTue36jEomFQOoYuI= modernc.org/libc v1.22.2/go.mod h1:uvQavJ1pZ0hIoC/jfqNoMLURIMhKzINIWypNM17puug= modernc.org/libc v1.37.6 h1:orZH3c5wmhIQFTXF+Nt+eeauyd+ZIt2BX6ARe+kD+aw= +modernc.org/libc v1.37.6/go.mod h1:YAXkAZ8ktnkCKaN9sw/UDeUVkGYJ/YquGO4FTi5nmHE= modernc.org/mathutil v1.2.2/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= modernc.org/mathutil v1.4.1/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= modernc.org/mathutil v1.5.0/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= +modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo= modernc.org/memory v1.1.1/go.mod h1:/0wo5ibyrQiaoUoH7f9D8dnglAmILJ5/cxZlRECf+Nw= modernc.org/memory v1.2.0/go.mod h1:/0wo5ibyrQiaoUoH7f9D8dnglAmILJ5/cxZlRECf+Nw= modernc.org/memory v1.2.1/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU= @@ -3175,11 +3242,13 @@ modernc.org/memory v1.3.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU= modernc.org/memory v1.4.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU= modernc.org/memory v1.5.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU= modernc.org/memory v1.7.2 h1:Klh90S215mmH8c9gO98QxQFsY+W451E8AnzjoE2ee1E= +modernc.org/memory v1.7.2/go.mod h1:NO4NVCQy0N7ln+T9ngWqOQfi7ley4vpwvARR+Hjw95E= modernc.org/opt v0.1.1/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= modernc.org/sqlite v1.18.1/go.mod h1:6ho+Gow7oX5V+OiOQ6Tr4xeqbx13UZ6t+Fw9IRUG4d4= modernc.org/sqlite v1.18.2/go.mod h1:kvrTLEWgxUcHa2GfHBQtanR1H9ht3hTJNtKpzH9k1u0= modernc.org/sqlite v1.28.0 h1:Zx+LyDDmXczNnEQdvPuEfcFVA2ZPyaD7UCZDjef3BHQ= +modernc.org/sqlite v1.28.0/go.mod h1:Qxpazz0zH8Z1xCFyi5GSL3FzbtZ3fvbjmywNogldEW0= modernc.org/strutil v1.1.1/go.mod h1:DE+MQQ/hjKBZS2zNInV5hhcipt5rLPWkmpbGeW5mmdw= modernc.org/strutil v1.1.3/go.mod h1:MEHNA7PdEnEwLvspRMtWTNnp2nnyvMfkimT1NKNAGbw= modernc.org/tcl v1.13.1/go.mod h1:XOLfOwzhkljL4itZkK6T72ckMgvj0BDsnKNdZVUOecw= @@ -3190,6 +3259,7 @@ modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= modernc.org/z v1.5.1/go.mod h1:eWFB510QWW5Th9YGZT81s+LwvaAs3Q2yr4sP0rmLkv8= pgregory.net/rapid v0.4.7/go.mod h1:UYpPVyjFHzYBGHIxLFoupi8vwk6rXNzRY9OMvVxFIOU= pgregory.net/rapid v1.1.0 h1:CMa0sjHSru3puNx+J0MIAuiiEV4N0qj8/cMWGBBCsjw= +pgregory.net/rapid v1.1.0/go.mod h1:PY5XlDGj0+V1FCq0o192FdRhpKHGTRIWBgqjDBTrq04= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= From e55b81e4787ce055d925897897295093174a343b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20M=C3=BCller?= Date: Wed, 26 Jun 2024 14:14:03 -0700 Subject: [PATCH 27/39] improve wasmtime setup --- runtime/webassembly.go | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/runtime/webassembly.go b/runtime/webassembly.go index 5135b68e3d..cb065b623d 100644 --- a/runtime/webassembly.go +++ b/runtime/webassembly.go @@ -38,29 +38,37 @@ type WasmtimeWebAssemblyModule struct { func NewWasmtimeWebAssemblyModule(bytes []byte) (stdlib.WebAssemblyModule, error) { config := wasmtime.NewConfig() - // Deterministic configuration inspired by - // https://github.com/dfinity/ic/blob/a0ab22537bdf65bd1f473654d49283e4f95f5a61/rs/embedders/README.adoc#nondeterminism - config.SetConsumeFuel(true) - config.SetMaxWasmStack(512 * 1024) + // TODO: define max stack size + const todoMaxStackSize = 512 * 1024 + config.SetMaxWasmStack(todoMaxStackSize) + + // Enable bulk memory operations, + // programs can use them to operate on memory more efficiently. config.SetWasmBulkMemory(true) + + // Deterministic configuration inspired by + // https://github.com/dfinity/ic/blob/a0ab22537bdf65bd1f473654d49283e4f95f5a61/rs/embedders/README.adoc#nondeterminism + config.SetWasmThreads(false) - config.SetWasmReferenceTypes(false) - // TODO: disable all SIMD related functionality. - // Depends on https://github.com/bytecodealliance/wasmtime-go/pull/224 - // config.SetWasmSIMD(false) - config.SetWasmMemory64(false) - config.SetWasmMultiMemory(false) - config.SetWasmMultiValue(false) + config.SetWasmSIMD(false) + config.SetWasmRelaxedSIMD(false) + config.SetWasmRelaxedSIMDDeterministic(false) - // NaN canonicalization is needed for determinism. config.SetStrategy(wasmtime.StrategyCranelift) config.SetCraneliftFlag("enable_nan_canonicalization", "true") // Disable optimizations to keep compilation simple and fast. config.SetCraneliftOptLevel(wasmtime.OptLevelNone) + // Disable other features for now, + // maybe consider enabling them later. + config.SetWasmReferenceTypes(false) + config.SetWasmMemory64(false) + config.SetWasmMultiMemory(false) + config.SetWasmMultiValue(false) + engine := wasmtime.NewEngineWithConfig(config) store := wasmtime.NewStore(engine) From 8bd4f7f24b3256f645da86ae5eded6f9da746936 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20M=C3=BCller?= Date: Fri, 12 Jul 2024 13:58:07 -0700 Subject: [PATCH 28/39] update wasmtime --- go.mod | 2 +- go.sum | 4 ++-- tools/storage-explorer/go.mod | 2 +- tools/storage-explorer/go.sum | 1 + 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/go.mod b/go.mod index 41a793ce0e..c0eae09207 100644 --- a/go.mod +++ b/go.mod @@ -30,7 +30,7 @@ require ( require ( github.com/SaveTheRbtz/mph v0.1.1-0.20240117162131-4166ec7869bc - github.com/bytecodealliance/wasmtime-go/v22 v22.0.0-20240626142402-d03b414c50b4 + github.com/bytecodealliance/wasmtime-go/v22 v22.0.1 github.com/k0kubun/pp v3.0.1+incompatible github.com/kodova/html-to-markdown v1.0.1 github.com/onflow/crypto v0.25.0 diff --git a/go.sum b/go.sum index f025dee52d..a014499e9e 100644 --- a/go.sum +++ b/go.sum @@ -5,8 +5,8 @@ github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3 github.com/andybalholm/cascadia v1.0.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y= github.com/bits-and-blooms/bitset v1.5.0 h1:NpE8frKRLGHIcEzkR+gZhiioW1+WbYV6fKwD6ZIpQT8= github.com/bits-and-blooms/bitset v1.5.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= -github.com/bytecodealliance/wasmtime-go/v22 v22.0.0-20240626142402-d03b414c50b4 h1:Jtz9TgzQLwJgPZfF7gEcM8D0Vk6CizoV6UUdLmS/SiU= -github.com/bytecodealliance/wasmtime-go/v22 v22.0.0-20240626142402-d03b414c50b4/go.mod h1:knqkvjTLavLtAXnA5NJUM0qbRiPJCVWPLXfYu75kZSo= +github.com/bytecodealliance/wasmtime-go/v22 v22.0.1 h1:/wWcvXyffeWeDQQte3Db/fHVEov8HhxfVJ43gz9xVcM= +github.com/bytecodealliance/wasmtime-go/v22 v22.0.1/go.mod h1:knqkvjTLavLtAXnA5NJUM0qbRiPJCVWPLXfYu75kZSo= github.com/c-bata/go-prompt v0.2.6 h1:POP+nrHE+DfLYx370bedwNhsqmpCUynWPxuHi0C5vZI= github.com/c-bata/go-prompt v0.2.6/go.mod h1:/LMAke8wD2FsNu9EXNdHxNLbd9MedkPnCdfpU9wwHfY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= diff --git a/tools/storage-explorer/go.mod b/tools/storage-explorer/go.mod index dbde24ed2d..a9189162c6 100644 --- a/tools/storage-explorer/go.mod +++ b/tools/storage-explorer/go.mod @@ -19,7 +19,7 @@ require ( github.com/beorn7/perks v1.0.1 // indirect github.com/bits-and-blooms/bitset v1.10.0 // indirect github.com/btcsuite/btcd/btcec/v2 v2.2.1 // indirect - github.com/bytecodealliance/wasmtime-go/v22 v22.0.0-20240626142402-d03b414c50b4 // indirect + github.com/bytecodealliance/wasmtime-go/v22 v22.0.1 // indirect github.com/cenkalti/backoff/v4 v4.2.1 // indirect github.com/cespare/xxhash v1.1.0 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect diff --git a/tools/storage-explorer/go.sum b/tools/storage-explorer/go.sum index b22ce2bf63..043eaffd14 100644 --- a/tools/storage-explorer/go.sum +++ b/tools/storage-explorer/go.sum @@ -1080,6 +1080,7 @@ github.com/btcsuite/btcd/chaincfg/chainhash v1.0.2 h1:KdUfX2zKommPRa+PD0sWZUyXe9 github.com/btcsuite/btcd/chaincfg/chainhash v1.0.2/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= github.com/bytecodealliance/wasmtime-go/v22 v22.0.0-20240626142402-d03b414c50b4 h1:Jtz9TgzQLwJgPZfF7gEcM8D0Vk6CizoV6UUdLmS/SiU= github.com/bytecodealliance/wasmtime-go/v22 v22.0.0-20240626142402-d03b414c50b4/go.mod h1:knqkvjTLavLtAXnA5NJUM0qbRiPJCVWPLXfYu75kZSo= +github.com/bytecodealliance/wasmtime-go/v22 v22.0.1/go.mod h1:knqkvjTLavLtAXnA5NJUM0qbRiPJCVWPLXfYu75kZSo= github.com/c-bata/go-prompt v0.2.2/go.mod h1:VzqtzE2ksDBcdln8G7mk2RX9QyGjH+OVqOCSiVIqS34= github.com/c-bata/go-prompt v0.2.6/go.mod h1:/LMAke8wD2FsNu9EXNdHxNLbd9MedkPnCdfpU9wwHfY= github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM= From d737d3dbcc46ad2b16f7f35aa9ebf894e84660c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20M=C3=BCller?= Date: Fri, 12 Jul 2024 14:03:07 -0700 Subject: [PATCH 29/39] add tests --- runtime/webassembly_test.go | 130 +++++++++++++++++++++++++++++++++++- 1 file changed, 129 insertions(+), 1 deletion(-) diff --git a/runtime/webassembly_test.go b/runtime/webassembly_test.go index 2187314296..5eacf041db 100644 --- a/runtime/webassembly_test.go +++ b/runtime/webassembly_test.go @@ -28,7 +28,6 @@ import ( "github.com/onflow/cadence/encoding/json" . "github.com/onflow/cadence/runtime" "github.com/onflow/cadence/runtime/common" - . "github.com/onflow/cadence/runtime/tests/runtime_utils" . "github.com/onflow/cadence/runtime/tests/utils" ) @@ -146,3 +145,132 @@ func TestRuntimeWebAssemblyDisabled(t *testing.T) { ) RequireError(t, err) } + +func TestRuntimeWebAssemblyLoop(t *testing.T) { + + t.Parallel() + + runtime := NewTestInterpreterRuntimeWithConfig(Config{ + WebAssemblyEnabled: true, + }) + + // A simple program which exports a function that loops forever: + // + // (module + // (func (loop $loop (br 0))) + // (export "loop" (func 0))) + // + addProgram := []byte{ + 0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x04, 0x01, 0x60, + 0x00, 0x00, 0x03, 0x02, 0x01, 0x00, 0x07, 0x08, 0x01, 0x04, 0x6c, 0x6f, + 0x6f, 0x70, 0x00, 0x00, 0x0a, 0x09, 0x01, 0x07, 0x00, 0x03, 0x40, 0x0c, + 0x00, 0x0b, 0x0b, + } + + // language=cadence + script := []byte(` + access(all) + fun main(program: [UInt8]) { + let instance = WebAssembly.compileAndInstantiate(bytes: program).instance + let loop = instance.getExport(name: "loop") + loop() + } + `) + + var webAssemblyFuelComputationMeterings []uint + + runtimeInterface := &TestRuntimeInterface{ + Storage: NewTestLedger(nil, nil), + OnCompileWebAssembly: NewWasmtimeWebAssemblyModule, + OnDecodeArgument: func(b []byte, _ cadence.Type) (cadence.Value, error) { + return json.Decode(nil, b) + }, + OnMeterComputation: func(compKind common.ComputationKind, intensity uint) error { + if compKind != common.ComputationKindWebAssemblyFuel { + return nil + } + + webAssemblyFuelComputationMeterings = append( + webAssemblyFuelComputationMeterings, + intensity, + ) + + return nil + }, + } + + _, err := runtime.ExecuteScript( + Script{ + Source: script, + Arguments: encodeArgs( + newBytesValue(addProgram), + ), + }, + Context{ + Interface: runtimeInterface, + Location: common.ScriptLocation{}, + }, + ) + + require.Error(t, err) + // TODO: check error type + + assert.Equal(t, + // TODO: adjust, currently todoAvailableFuel + []uint{1000}, + webAssemblyFuelComputationMeterings, + ) +} + +func TestRuntimeWebAssemblyInfiniteLoopAtStart(t *testing.T) { + + t.Parallel() + + runtime := NewTestInterpreterRuntimeWithConfig(Config{ + WebAssemblyEnabled: true, + }) + + // A simple program which loops forever, on start/load: + // + // (module + // (func (loop $loop (br 0))) + // (start 0)) + // + addProgram := []byte{ + 0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x04, 0x01, 0x60, + 0x00, 0x00, 0x03, 0x02, 0x01, 0x00, 0x08, 0x01, 0x00, 0x0a, 0x09, 0x01, + 0x07, 0x00, 0x03, 0x40, 0x0c, 0x00, 0x0b, 0x0b, + } + + // language=cadence + script := []byte(` + access(all) + fun main(program: [UInt8]) { + let instance = WebAssembly.compileAndInstantiate(bytes: program).instance + } + `) + + runtimeInterface := &TestRuntimeInterface{ + Storage: NewTestLedger(nil, nil), + OnCompileWebAssembly: NewWasmtimeWebAssemblyModule, + OnDecodeArgument: func(b []byte, _ cadence.Type) (cadence.Value, error) { + return json.Decode(nil, b) + }, + } + + _, err := runtime.ExecuteScript( + Script{ + Source: script, + Arguments: encodeArgs( + newBytesValue(addProgram), + ), + }, + Context{ + Interface: runtimeInterface, + Location: common.ScriptLocation{}, + }, + ) + + RequireError(t, err) + // TODO: check error type +} From efa0800d41c5695812537b566cdebe0dc913c0d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20M=C3=BCller?= Date: Fri, 12 Jul 2024 14:12:20 -0700 Subject: [PATCH 30/39] convert wasmtime trap to generic stdlib trap error --- runtime/stdlib/webassembly.go | 8 ++++++++ runtime/webassembly.go | 7 +++++-- runtime/webassembly_test.go | 3 ++- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/runtime/stdlib/webassembly.go b/runtime/stdlib/webassembly.go index 7d5c391577..1108bb140e 100644 --- a/runtime/stdlib/webassembly.go +++ b/runtime/stdlib/webassembly.go @@ -226,3 +226,11 @@ var WebAssemblyContractType = StandardLibraryType{ Type: WebAssemblyType, Kind: common.DeclarationKindContract, } + +type WebAssemblyTrapError struct{} + +var _ error = WebAssemblyTrapError{} + +func (WebAssemblyTrapError) Error() string { + return "WebAssembly trap" +} diff --git a/runtime/webassembly.go b/runtime/webassembly.go index cb065b623d..0dac7d1fc8 100644 --- a/runtime/webassembly.go +++ b/runtime/webassembly.go @@ -106,8 +106,11 @@ var _ stdlib.WebAssemblyModule = WasmtimeWebAssemblyModule{} func (m WasmtimeWebAssemblyModule) InstantiateWebAssemblyModule(_ common.MemoryGauge) (stdlib.WebAssemblyInstance, error) { instance, err := wasmtime.NewInstance(m.Store, m.Module, nil) if err != nil { - // TODO: wrap error - return nil, err + if _, ok := err.(*wasmtime.Trap); ok { + return nil, stdlib.WebAssemblyTrapError{} + } + + panic(errors.NewUnexpectedError("WebAssembly module instantiation failed, but did not trap")) } return WasmtimeWebAssemblyInstance{ Instance: instance, diff --git a/runtime/webassembly_test.go b/runtime/webassembly_test.go index 5eacf041db..fa4abf4297 100644 --- a/runtime/webassembly_test.go +++ b/runtime/webassembly_test.go @@ -28,6 +28,7 @@ import ( "github.com/onflow/cadence/encoding/json" . "github.com/onflow/cadence/runtime" "github.com/onflow/cadence/runtime/common" + "github.com/onflow/cadence/runtime/stdlib" . "github.com/onflow/cadence/runtime/tests/runtime_utils" . "github.com/onflow/cadence/runtime/tests/utils" ) @@ -272,5 +273,5 @@ func TestRuntimeWebAssemblyInfiniteLoopAtStart(t *testing.T) { ) RequireError(t, err) - // TODO: check error type + require.ErrorAs(t, err, &stdlib.WebAssemblyTrapError{}) } From d9a6321ad111db9dd227098d577153d051fdb90b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20M=C3=BCller?= Date: Fri, 12 Jul 2024 14:23:03 -0700 Subject: [PATCH 31/39] make trap error a user error --- runtime/stdlib/webassembly.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/runtime/stdlib/webassembly.go b/runtime/stdlib/webassembly.go index 1108bb140e..670b9519f5 100644 --- a/runtime/stdlib/webassembly.go +++ b/runtime/stdlib/webassembly.go @@ -230,6 +230,9 @@ var WebAssemblyContractType = StandardLibraryType{ type WebAssemblyTrapError struct{} var _ error = WebAssemblyTrapError{} +var _ errors.UserError = WebAssemblyTrapError{} + +func (WebAssemblyTrapError) IsUserError() {} func (WebAssemblyTrapError) Error() string { return "WebAssembly trap" From 12817cb7112463ed5b4300e8f9bb1fbb64b5b6ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20M=C3=BCller?= Date: Fri, 12 Jul 2024 14:23:25 -0700 Subject: [PATCH 32/39] improve error for invalid non-function export --- runtime/stdlib/webassembly.go | 11 +++++++ runtime/webassembly.go | 3 +- runtime/webassembly_test.go | 55 +++++++++++++++++++++++++++++++++++ 3 files changed, 67 insertions(+), 2 deletions(-) diff --git a/runtime/stdlib/webassembly.go b/runtime/stdlib/webassembly.go index 670b9519f5..b5a82657f9 100644 --- a/runtime/stdlib/webassembly.go +++ b/runtime/stdlib/webassembly.go @@ -237,3 +237,14 @@ func (WebAssemblyTrapError) IsUserError() {} func (WebAssemblyTrapError) Error() string { return "WebAssembly trap" } + +type WebAssemblyNonFunctionExportError struct{} + +var _ error = WebAssemblyNonFunctionExportError{} +var _ errors.UserError = WebAssemblyNonFunctionExportError{} + +func (WebAssemblyNonFunctionExportError) IsUserError() {} + +func (WebAssemblyNonFunctionExportError) Error() string { + return "invalid WebAssembly export: not a function" +} diff --git a/runtime/webassembly.go b/runtime/webassembly.go index 0dac7d1fc8..b74aa3af42 100644 --- a/runtime/webassembly.go +++ b/runtime/webassembly.go @@ -146,8 +146,7 @@ func (i WasmtimeWebAssemblyInstance) GetExport(gauge common.MemoryGauge, name st function := extern.Func() if function == nil { - // TODO: improve error - return nil, errors.NewDefaultUserError("invalid export: not a function") + return nil, stdlib.WebAssemblyNonFunctionExportError{} } return newWasmtimeFunctionWebAssemblyExport(gauge, function, i.Store) diff --git a/runtime/webassembly_test.go b/runtime/webassembly_test.go index fa4abf4297..befe89f44c 100644 --- a/runtime/webassembly_test.go +++ b/runtime/webassembly_test.go @@ -275,3 +275,58 @@ func TestRuntimeWebAssemblyInfiniteLoopAtStart(t *testing.T) { RequireError(t, err) require.ErrorAs(t, err, &stdlib.WebAssemblyTrapError{}) } + +func TestRuntimeWebAssemblyNonFunctionExport(t *testing.T) { + + t.Parallel() + + runtime := NewTestInterpreterRuntimeWithConfig(Config{ + WebAssemblyEnabled: true, + }) + + // A simple program which exports a memory `add`. + // + // (module + // (memory (export "add") 1 4) + // (data (i32.const 0x1) "\01\02\03") + // ) + // + addProgram := []byte{ + 0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x05, 0x04, 0x01, 0x01, + 0x01, 0x04, 0x07, 0x07, 0x01, 0x03, 0x61, 0x64, 0x64, 0x02, 0x00, 0x0b, + 0x09, 0x01, 0x00, 0x41, 0x01, 0x0b, 0x03, 0x01, 0x02, 0x03, + } + + // language=cadence + script := []byte(` + access(all) + fun main(program: [UInt8]) { + let instance = WebAssembly.compileAndInstantiate(bytes: program).instance + instance.getExport(name: "add") + } + `) + + runtimeInterface := &TestRuntimeInterface{ + Storage: NewTestLedger(nil, nil), + OnCompileWebAssembly: NewWasmtimeWebAssemblyModule, + OnDecodeArgument: func(b []byte, _ cadence.Type) (cadence.Value, error) { + return json.Decode(nil, b) + }, + } + + _, err := runtime.ExecuteScript( + Script{ + Source: script, + Arguments: encodeArgs( + newBytesValue(addProgram), + ), + }, + Context{ + Interface: runtimeInterface, + Location: common.ScriptLocation{}, + }, + ) + + RequireError(t, err) + require.ErrorAs(t, err, &stdlib.WebAssemblyNonFunctionExportError{}) +} From ab8875627e7a93d4b0c0c29a135898d256d2dc7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20M=C3=BCller?= Date: Fri, 12 Jul 2024 14:30:14 -0700 Subject: [PATCH 33/39] improve error for WebAssembly module compilation failure --- runtime/stdlib/webassembly.go | 11 +++++++++ runtime/webassembly.go | 9 +++++--- runtime/webassembly_test.go | 43 +++++++++++++++++++++++++++++++++++ 3 files changed, 60 insertions(+), 3 deletions(-) diff --git a/runtime/stdlib/webassembly.go b/runtime/stdlib/webassembly.go index b5a82657f9..1e587e2650 100644 --- a/runtime/stdlib/webassembly.go +++ b/runtime/stdlib/webassembly.go @@ -248,3 +248,14 @@ func (WebAssemblyNonFunctionExportError) IsUserError() {} func (WebAssemblyNonFunctionExportError) Error() string { return "invalid WebAssembly export: not a function" } + +type WebAssemblyCompilationError struct{} + +var _ error = WebAssemblyCompilationError{} +var _ errors.UserError = WebAssemblyCompilationError{} + +func (WebAssemblyCompilationError) IsUserError() {} + +func (WebAssemblyCompilationError) Error() string { + return "invalid WebAssembly module" +} diff --git a/runtime/webassembly.go b/runtime/webassembly.go index b74aa3af42..393139a94b 100644 --- a/runtime/webassembly.go +++ b/runtime/webassembly.go @@ -91,8 +91,11 @@ func NewWasmtimeWebAssemblyModule(bytes []byte) (stdlib.WebAssemblyModule, error module, err := wasmtime.NewModule(engine, bytes) if err != nil { - // TODO: wrap error - return nil, err + if _, ok := err.(*wasmtime.Error); ok { + return nil, stdlib.WebAssemblyCompilationError{} + } + + panic(errors.NewUnexpectedError("WebAssembly module compilation failed with unknown error")) } return WasmtimeWebAssemblyModule{ @@ -110,7 +113,7 @@ func (m WasmtimeWebAssemblyModule) InstantiateWebAssemblyModule(_ common.MemoryG return nil, stdlib.WebAssemblyTrapError{} } - panic(errors.NewUnexpectedError("WebAssembly module instantiation failed, but did not trap")) + panic(errors.NewUnexpectedError("WebAssembly module instantiation failed with unknown error")) } return WasmtimeWebAssemblyInstance{ Instance: instance, diff --git a/runtime/webassembly_test.go b/runtime/webassembly_test.go index befe89f44c..fa2971a431 100644 --- a/runtime/webassembly_test.go +++ b/runtime/webassembly_test.go @@ -330,3 +330,46 @@ func TestRuntimeWebAssemblyNonFunctionExport(t *testing.T) { RequireError(t, err) require.ErrorAs(t, err, &stdlib.WebAssemblyNonFunctionExportError{}) } + +func TestRuntimeWebAssemblyInvalidModule(t *testing.T) { + + t.Parallel() + + runtime := NewTestInterpreterRuntimeWithConfig(Config{ + WebAssemblyEnabled: true, + }) + + program := []byte{0xFF} + + // language=cadence + script := []byte(` + access(all) + fun main(program: [UInt8]) { + WebAssembly.compileAndInstantiate(bytes: program).instance + } + `) + + runtimeInterface := &TestRuntimeInterface{ + Storage: NewTestLedger(nil, nil), + OnCompileWebAssembly: NewWasmtimeWebAssemblyModule, + OnDecodeArgument: func(b []byte, _ cadence.Type) (cadence.Value, error) { + return json.Decode(nil, b) + }, + } + + _, err := runtime.ExecuteScript( + Script{ + Source: script, + Arguments: encodeArgs( + newBytesValue(program), + ), + }, + Context{ + Interface: runtimeInterface, + Location: common.ScriptLocation{}, + }, + ) + + RequireError(t, err) + require.ErrorAs(t, err, &stdlib.WebAssemblyCompilationError{}) +} From a3fe557f85341c153c6df8109e6a366df706b0eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20M=C3=BCller?= Date: Fri, 12 Jul 2024 14:33:07 -0700 Subject: [PATCH 34/39] convert wasmtime call trap into generic WebAssembly trap error --- runtime/webassembly.go | 7 +++++-- runtime/webassembly_test.go | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/runtime/webassembly.go b/runtime/webassembly.go index 393139a94b..6c212eb138 100644 --- a/runtime/webassembly.go +++ b/runtime/webassembly.go @@ -274,8 +274,11 @@ func newWasmtimeFunctionWebAssemblyExport( func() (any, error) { res, err := function.Call(store, convertedArguments...) if err != nil { - // TODO: wrap error - return nil, err + if _, ok := err.(*wasmtime.Trap); ok { + return nil, stdlib.WebAssemblyTrapError{} + } + + panic(errors.NewUnexpectedError("WebAssembly invocation failed with unknown error")) } return res, nil }, diff --git a/runtime/webassembly_test.go b/runtime/webassembly_test.go index fa2971a431..26f5246bef 100644 --- a/runtime/webassembly_test.go +++ b/runtime/webassembly_test.go @@ -214,7 +214,7 @@ func TestRuntimeWebAssemblyLoop(t *testing.T) { ) require.Error(t, err) - // TODO: check error type + require.ErrorAs(t, err, &stdlib.WebAssemblyTrapError{}) assert.Equal(t, // TODO: adjust, currently todoAvailableFuel From 9b4c462650a1b70d74f3747a4153d09415a79b78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20M=C3=BCller?= Date: Fri, 12 Jul 2024 14:37:18 -0700 Subject: [PATCH 35/39] GetFuel/SetFuel should never error --- runtime/webassembly.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/runtime/webassembly.go b/runtime/webassembly.go index 6c212eb138..ac86491a9a 100644 --- a/runtime/webassembly.go +++ b/runtime/webassembly.go @@ -217,8 +217,8 @@ func newWasmtimeFunctionWebAssemblyExport( fuelBefore := todoAvailableFuel err := store.SetFuel(fuelBefore) if err != nil { - // TODO: wrap error - panic(err) + // "[SetFuel] will return an error if fuel consumption is not enabled" + panic(errors.NewUnreachableError()) } callResult, callErr := f() @@ -227,8 +227,8 @@ func newWasmtimeFunctionWebAssemblyExport( fuelAfter, err := store.GetFuel() if err != nil { - // TODO: wrap error - panic(err) + // "[GetFuel] will return an error if fuel consumption is not enabled" + panic(errors.NewUnreachableError()) } fuelDelta := fuelBefore - fuelAfter From 755d0d3c2fa710fb85211c6069d4b8230ac913c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20M=C3=BCller?= Date: Fri, 12 Jul 2024 16:52:49 -0700 Subject: [PATCH 36/39] add runtime interface method to get remaining computation for given kind --- runtime/environment.go | 11 ++++++++++ runtime/interface.go | 5 +++-- runtime/interpreter/config.go | 2 ++ runtime/interpreter/interpreter.go | 16 +++++++++++++++ runtime/tests/runtime_utils/testinterface.go | 21 ++++++++++++++------ 5 files changed, 47 insertions(+), 8 deletions(-) diff --git a/runtime/environment.go b/runtime/environment.go index 8c6d39a4a3..e3464f3b8d 100644 --- a/runtime/environment.go +++ b/runtime/environment.go @@ -190,6 +190,7 @@ func (e *interpreterEnvironment) newInterpreterConfig() *interpreter.Config { Debugger: e.config.Debugger, OnStatement: e.newOnStatementHandler(), OnMeterComputation: e.newOnMeterComputation(), + OnComputationRemaining: e.newOnComputationRemaining(), OnFunctionInvocation: e.newOnFunctionInvocationHandler(), OnInvokedFunctionReturn: e.newOnInvokedFunctionReturnHandler(), CapabilityBorrowHandler: stdlib.BorrowCapabilityController, @@ -1103,6 +1104,16 @@ func (e *interpreterEnvironment) newOnMeterComputation() interpreter.OnMeterComp } } +func (e *interpreterEnvironment) newOnComputationRemaining() interpreter.OnComputationRemainingFunc { + return func(compKind common.ComputationKind) uint { + var remaining uint + errors.WrapPanic(func() { + remaining = e.runtimeInterface.ComputationRemaining(compKind) + }) + return remaining + } +} + func (e *interpreterEnvironment) InterpretContract( location common.AddressLocation, program *interpreter.Program, diff --git a/runtime/interface.go b/runtime/interface.go index fa13fd17c6..805d89708a 100644 --- a/runtime/interface.go +++ b/runtime/interface.go @@ -150,8 +150,7 @@ type Interface interface { type MeterInterface interface { // MeterMemory gets called when new memory is allocated or used by the interpreter MeterMemory(usage common.MemoryUsage) error - // MeterComputation is a callback method for metering computation, it returns error - // when computation passes the limit (set by the environment) + // MeterComputation gets called when a computation is performed by the interpreter. MeterComputation(operationType common.ComputationKind, intensity uint) error // ComputationUsed returns the total computation used in the current runtime. ComputationUsed() (uint64, error) @@ -159,6 +158,8 @@ type MeterInterface interface { MemoryUsed() (uint64, error) // InteractionUsed returns the total storage interaction used in the current runtime. InteractionUsed() (uint64, error) + // ComputationRemaining returns the remaining amount of computation left for the given kind. + ComputationRemaining(kind common.ComputationKind) uint } type Metrics interface { diff --git a/runtime/interpreter/config.go b/runtime/interpreter/config.go index f9d322bd7f..85dfa61bee 100644 --- a/runtime/interpreter/config.go +++ b/runtime/interpreter/config.go @@ -35,6 +35,8 @@ type Config struct { OnResourceOwnerChange OnResourceOwnerChangeFunc // OnMeterComputation is triggered when a computation is about to happen OnMeterComputation OnMeterComputationFunc + // OnComputationRemaining is used to determine how much computation is remaining + OnComputationRemaining OnComputationRemainingFunc // InjectedCompositeFieldsHandler is used to initialize new composite values' fields InjectedCompositeFieldsHandler InjectedCompositeFieldsHandlerFunc // ContractValueHandler is used to handle imports of values diff --git a/runtime/interpreter/interpreter.go b/runtime/interpreter/interpreter.go index 46edcb3d48..da50abb5e0 100644 --- a/runtime/interpreter/interpreter.go +++ b/runtime/interpreter/interpreter.go @@ -106,6 +106,11 @@ type OnMeterComputationFunc func( intensity uint, ) +// OnComputationRemainingFunc is a function that is used to determine how much computation is remaining. +type OnComputationRemainingFunc func( + kind common.ComputationKind, +) uint + // CapabilityBorrowHandlerFunc is a function that is used to borrow ID capabilities. type CapabilityBorrowHandlerFunc func( inter *Interpreter, @@ -4950,6 +4955,17 @@ func (interpreter *Interpreter) ReportComputation(compKind common.ComputationKin } } +func (interpreter *Interpreter) ComputationRemaining(compKind common.ComputationKind) uint { + config := interpreter.SharedState.Config + + onComputationRemaining := config.OnComputationRemaining + if onComputationRemaining != nil { + return onComputationRemaining(compKind) + } + + return math.MaxUint +} + func (interpreter *Interpreter) getAccessOfMember(self Value, identifier string) sema.Access { typ, err := interpreter.ConvertStaticToSemaType(self.StaticType(interpreter)) // some values (like transactions) do not have types that can be looked up this way. These types diff --git a/runtime/tests/runtime_utils/testinterface.go b/runtime/tests/runtime_utils/testinterface.go index 7fcb3332b8..a340933130 100644 --- a/runtime/tests/runtime_utils/testinterface.go +++ b/runtime/tests/runtime_utils/testinterface.go @@ -22,6 +22,7 @@ import ( "bytes" "encoding/binary" "errors" + "math" "time" "github.com/onflow/atree" @@ -115,12 +116,13 @@ type TestRuntimeInterface struct { duration time.Duration, attrs []attribute.KeyValue, ) - OnMeterMemory func(usage common.MemoryUsage) error - OnComputationUsed func() (uint64, error) - OnMemoryUsed func() (uint64, error) - OnInteractionUsed func() (uint64, error) - OnGenerateAccountID func(address common.Address) (uint64, error) - OnCompileWebAssembly func(bytes []byte) (stdlib.WebAssemblyModule, error) + OnMeterMemory func(usage common.MemoryUsage) error + OnComputationUsed func() (uint64, error) + OnMemoryUsed func() (uint64, error) + OnInteractionUsed func() (uint64, error) + OnComputationRemaining func(kind common.ComputationKind) uint + OnGenerateAccountID func(address common.Address) (uint64, error) + OnCompileWebAssembly func(bytes []byte) (stdlib.WebAssemblyModule, error) lastUUID uint64 accountIDs map[common.Address]uint64 @@ -597,6 +599,13 @@ func (i *TestRuntimeInterface) InteractionUsed() (uint64, error) { return i.OnInteractionUsed() } +func (i *TestRuntimeInterface) ComputationRemaining(kind common.ComputationKind) uint { + if i.OnComputationRemaining == nil { + return math.MaxUint + } + return i.OnComputationRemaining(kind) +} + func (i *TestRuntimeInterface) onTransactionExecutionStart() { i.InvalidateUpdatedPrograms() } From ef5d37166b787561a88d100815fa78c237a734e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20M=C3=BCller?= Date: Fri, 12 Jul 2024 16:53:11 -0700 Subject: [PATCH 37/39] use new computation remaining for fuel --- runtime/webassembly.go | 11 ++++------- runtime/webassembly_test.go | 14 ++++++++++++++ 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/runtime/webassembly.go b/runtime/webassembly.go index ac86491a9a..49ceec796c 100644 --- a/runtime/webassembly.go +++ b/runtime/webassembly.go @@ -210,12 +210,9 @@ func newWasmtimeFunctionWebAssemblyExport( } metered := func(inter *interpreter.Interpreter, f func() (any, error)) (any, error) { - // TODO: get remaining computation and convert to fuel. - // needs e.g. invocation.Interpreter.RemainingComputation() - const todoAvailableFuel uint64 = 1000 - fuelBefore := todoAvailableFuel - err := store.SetFuel(fuelBefore) + fuelBefore := inter.ComputationRemaining(common.ComputationKindWebAssemblyFuel) + err := store.SetFuel(uint64(fuelBefore)) if err != nil { // "[SetFuel] will return an error if fuel consumption is not enabled" panic(errors.NewUnreachableError()) @@ -231,8 +228,8 @@ func newWasmtimeFunctionWebAssemblyExport( panic(errors.NewUnreachableError()) } - fuelDelta := fuelBefore - fuelAfter - inter.ReportComputation(common.ComputationKindWebAssemblyFuel, uint(fuelDelta)) + fuelDelta := fuelBefore - uint(fuelAfter) + inter.ReportComputation(common.ComputationKindWebAssemblyFuel, fuelDelta) return callResult, callErr } diff --git a/runtime/webassembly_test.go b/runtime/webassembly_test.go index 26f5246bef..786d76f5ed 100644 --- a/runtime/webassembly_test.go +++ b/runtime/webassembly_test.go @@ -198,6 +198,13 @@ func TestRuntimeWebAssemblyLoop(t *testing.T) { return nil }, + OnComputationRemaining: func(kind common.ComputationKind) uint { + if kind != common.ComputationKindWebAssemblyFuel { + return 0 + } + + return 1000 + }, } _, err := runtime.ExecuteScript( @@ -257,6 +264,13 @@ func TestRuntimeWebAssemblyInfiniteLoopAtStart(t *testing.T) { OnDecodeArgument: func(b []byte, _ cadence.Type) (cadence.Value, error) { return json.Decode(nil, b) }, + OnComputationRemaining: func(kind common.ComputationKind) uint { + if kind != common.ComputationKindWebAssemblyFuel { + return 0 + } + + return 1000 + }, } _, err := runtime.ExecuteScript( From d3cca437ad46965f86e70e9d04a73e78227041fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20M=C3=BCller?= Date: Wed, 16 Oct 2024 15:23:46 -0700 Subject: [PATCH 38/39] fix merge: implement new runtime interface functions --- runtime/empty.go | 9 +++++++++ runtime/tests/runtime_utils/testinterface.go | 1 + 2 files changed, 10 insertions(+) diff --git a/runtime/empty.go b/runtime/empty.go index 86b5b0abce..01e5f01e87 100644 --- a/runtime/empty.go +++ b/runtime/empty.go @@ -29,6 +29,7 @@ import ( "github.com/onflow/cadence/runtime/common" "github.com/onflow/cadence/runtime/interpreter" "github.com/onflow/cadence/runtime/sema" + "github.com/onflow/cadence/runtime/stdlib" ) // EmptyRuntimeInterface is an empty implementation of runtime.Interface. @@ -63,6 +64,10 @@ func (EmptyRuntimeInterface) ComputationUsed() (uint64, error) { panic("unexpected call to ComputationUsed") } +func (i EmptyRuntimeInterface) ComputationRemaining(_ common.ComputationKind) uint { + panic("unexpected call to ComputationRemaining") +} + func (EmptyRuntimeInterface) MemoryUsed() (uint64, error) { panic("unexpected call to MemoryUsed") } @@ -260,3 +265,7 @@ func (EmptyRuntimeInterface) ValidateAccountCapabilitiesPublish( ) (bool, error) { panic("unexpected call to ValidateAccountCapabilitiesPublish") } + +func (EmptyRuntimeInterface) CompileWebAssembly(_ []byte) (stdlib.WebAssemblyModule, error) { + panic("unexpected call to CompileWebAssembly") +} diff --git a/runtime/tests/runtime_utils/testinterface.go b/runtime/tests/runtime_utils/testinterface.go index 34c57a5c6c..6467e396e7 100644 --- a/runtime/tests/runtime_utils/testinterface.go +++ b/runtime/tests/runtime_utils/testinterface.go @@ -121,6 +121,7 @@ type TestRuntimeInterface struct { OnComputationUsed func() (uint64, error) OnMemoryUsed func() (uint64, error) OnInteractionUsed func() (uint64, error) + OnComputationRemaining func(kind common.ComputationKind) uint OnGenerateAccountID func(address common.Address) (uint64, error) OnRecoverProgram func(program *ast.Program, location common.Location) ([]byte, error) OnValidateAccountCapabilitiesGet func( From c0a9bf1ecf09b106995439b6c58c211decf89cda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20M=C3=BCller?= Date: Wed, 16 Oct 2024 15:30:21 -0700 Subject: [PATCH 39/39] update to wasmtime v25 --- go.mod | 2 +- go.sum | 4 ++-- runtime/webassembly.go | 2 +- vm/vm.go | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/go.mod b/go.mod index 8ca7fea93c..4b3d184b14 100644 --- a/go.mod +++ b/go.mod @@ -30,7 +30,7 @@ require ( require ( github.com/SaveTheRbtz/mph v0.1.1-0.20240117162131-4166ec7869bc - github.com/bytecodealliance/wasmtime-go/v22 v22.0.1 + github.com/bytecodealliance/wasmtime-go/v25 v25.0.0 github.com/k0kubun/pp v3.0.1+incompatible github.com/kodova/html-to-markdown v1.0.1 github.com/onflow/crypto v0.25.0 diff --git a/go.sum b/go.sum index 407a16d509..e229bf4a00 100644 --- a/go.sum +++ b/go.sum @@ -5,8 +5,8 @@ github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3 github.com/andybalholm/cascadia v1.0.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y= github.com/bits-and-blooms/bitset v1.5.0 h1:NpE8frKRLGHIcEzkR+gZhiioW1+WbYV6fKwD6ZIpQT8= github.com/bits-and-blooms/bitset v1.5.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= -github.com/bytecodealliance/wasmtime-go/v22 v22.0.1 h1:/wWcvXyffeWeDQQte3Db/fHVEov8HhxfVJ43gz9xVcM= -github.com/bytecodealliance/wasmtime-go/v22 v22.0.1/go.mod h1:knqkvjTLavLtAXnA5NJUM0qbRiPJCVWPLXfYu75kZSo= +github.com/bytecodealliance/wasmtime-go/v25 v25.0.0 h1:ZTn4Ho+srrk0466ugqPfTDCITczsWdT48A0ZMA/TpRU= +github.com/bytecodealliance/wasmtime-go/v25 v25.0.0/go.mod h1:8mMIYQ92CpVDwXPIb6udnhtFGI3vDZ/937cGeQr5I68= github.com/c-bata/go-prompt v0.2.6 h1:POP+nrHE+DfLYx370bedwNhsqmpCUynWPxuHi0C5vZI= github.com/c-bata/go-prompt v0.2.6/go.mod h1:/LMAke8wD2FsNu9EXNdHxNLbd9MedkPnCdfpU9wwHfY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= diff --git a/runtime/webassembly.go b/runtime/webassembly.go index 49ceec796c..c67745264b 100644 --- a/runtime/webassembly.go +++ b/runtime/webassembly.go @@ -21,7 +21,7 @@ package runtime import ( "fmt" - "github.com/bytecodealliance/wasmtime-go/v22" + "github.com/bytecodealliance/wasmtime-go/v25" "github.com/onflow/cadence/runtime/common" "github.com/onflow/cadence/runtime/errors" diff --git a/vm/vm.go b/vm/vm.go index 46da42ad04..fd981f8282 100644 --- a/vm/vm.go +++ b/vm/vm.go @@ -27,7 +27,7 @@ import ( "C" - "github.com/bytecodealliance/wasmtime-go/v22" + "github.com/bytecodealliance/wasmtime-go/v25" "github.com/onflow/cadence/runtime/interpreter" )