diff --git a/internal/adapter/interface.go b/internal/adapter/interface.go deleted file mode 100644 index 386ae9cce..000000000 --- a/internal/adapter/interface.go +++ /dev/null @@ -1,44 +0,0 @@ -// file: internal/runtime/wasm_runtime.go -package runtime - -import "github.com/CosmWasm/wasmvm/v2/types" - -type WasmRuntime interface { - // InitCache sets up any runtime-specific cache or resources. Returns a handle. - InitCache(config types.VMConfig) (any, error) - - // ReleaseCache frees resources created by InitCache. - ReleaseCache(handle any) - - // Compilation and code storage - StoreCode(code []byte, persist bool) (checksum []byte, err error) - StoreCodeUnchecked(code []byte) ([]byte, error) - GetCode(checksum []byte) ([]byte, error) - RemoveCode(checksum []byte) error - Pin(checksum []byte) error - Unpin(checksum []byte) error - AnalyzeCode(checksum []byte) (*types.AnalysisReport, error) - - // Execution lifecycles - Instantiate(checksum []byte, env []byte, info []byte, msg []byte, otherParams ...interface{}) ([]byte, types.GasReport, error) - Execute(checksum []byte, env []byte, info []byte, msg []byte, otherParams ...interface{}) ([]byte, types.GasReport, error) - Migrate(checksum []byte, env []byte, msg []byte, otherParams ...interface{}) ([]byte, types.GasReport, error) - MigrateWithInfo(checksum []byte, env []byte, msg []byte, migrateInfo []byte, otherParams ...interface{}) ([]byte, types.GasReport, error) - Sudo(checksum []byte, env []byte, msg []byte, otherParams ...interface{}) ([]byte, types.GasReport, error) - Reply(checksum []byte, env []byte, reply []byte, otherParams ...interface{}) ([]byte, types.GasReport, error) - Query(checksum []byte, env []byte, query []byte, otherParams ...interface{}) ([]byte, types.GasReport, error) - - // IBC entry points - IBCChannelOpen(checksum []byte, env []byte, msg []byte, otherParams ...interface{}) ([]byte, types.GasReport, error) - IBCChannelConnect(checksum []byte, env []byte, msg []byte, otherParams ...interface{}) ([]byte, types.GasReport, error) - IBCChannelClose(checksum []byte, env []byte, msg []byte, otherParams ...interface{}) ([]byte, types.GasReport, error) - IBCPacketReceive(checksum []byte, env []byte, msg []byte, otherParams ...interface{}) ([]byte, types.GasReport, error) - IBCPacketAck(checksum []byte, env []byte, msg []byte, otherParams ...interface{}) ([]byte, types.GasReport, error) - IBCPacketTimeout(checksum []byte, env []byte, msg []byte, otherParams ...interface{}) ([]byte, types.GasReport, error) - IBCSourceCallback(checksum []byte, env []byte, msg []byte, otherParams ...interface{}) ([]byte, types.GasReport, error) - IBCDestinationCallback(checksum []byte, env []byte, msg []byte, otherParams ...interface{}) ([]byte, types.GasReport, error) - - // Metrics - GetMetrics() (*types.Metrics, error) - GetPinnedMetrics() (*types.PinnedMetrics, error) -} diff --git a/internal/api/lib_test.go b/internal/api/lib_test.go index 31adedf3b..842b85925 100644 --- a/internal/api/lib_test.go +++ b/internal/api/lib_test.go @@ -3,10 +3,12 @@ package api import ( "bytes" "crypto/sha256" + "encoding/hex" "encoding/json" "fmt" "os" "path/filepath" + "strings" "sync" "testing" "time" @@ -1240,10 +1242,10 @@ func createReflectContract(tb testing.TB, cache Cache) []byte { return createContract(tb, cache, "../../testdata/reflect.wasm") } -//func createFloaty2(tb testing.TB, cache Cache) []byte { -// tb.Helper() -// return createContract(tb, cache, "../../testdata/floaty_2.0.wasm") -//} +func createFloaty2(tb testing.TB, cache Cache) []byte { + tb.Helper() + return createContract(tb, cache, "../../testdata/floaty_2.0.wasm") +} func createContract(tb testing.TB, cache Cache, wasmFile string) []byte { tb.Helper() @@ -1398,8 +1400,6 @@ func TestCustomReflectQuerier(t *testing.T) { // testfloats is disabled temporarily because of its high output -/* - // TestFloats is a port of the float_instrs_are_deterministic test in cosmwasm-vm func TestFloats(t *testing.T) { type Value struct { @@ -1496,7 +1496,6 @@ func TestFloats(t *testing.T) { hash := hasher.Sum(nil) require.Equal(t, "6e9ffbe929a2c1bcbffca0d4e9d0935371045bba50158a01ec082459a4cbbd2a", hex.EncodeToString(hash)) } -*/ // mockInfoBinNoAssert creates the message binary without using testify assertions func mockInfoBinNoAssert(sender types.HumanAddress) []byte { diff --git a/internal/runtime/hostfunctions.go b/internal/runtime/hostfunctions.go index 6aa741c51..ea512c5b4 100644 --- a/internal/runtime/hostfunctions.go +++ b/internal/runtime/hostfunctions.go @@ -1,7 +1,6 @@ package runtime import ( - "bytes" "context" "encoding/binary" "encoding/json" @@ -122,8 +121,13 @@ func allocateInContract(ctx context.Context, mod api.Module, size uint32) (uint3 return uint32(results[0]), nil } -// hostHumanizeAddress implements api_humanize_address. -func hostHumanizeAddress(ctx context.Context, mod api.Module, addrPtr, addrLen uint32) uint32 { +// hostHumanizeAddress implements addr_humanize. +// It reads a null-terminated address from memory (ignoring addrLen), +// calls the API's HumanizeAddress function, and writes back the result. +// hostHumanizeAddress reads a null-terminated address from memory, +// calls the API to humanize it, logs intermediate results, and writes +// the humanized address back into memory. +func hostHumanizeAddress(ctx context.Context, mod api.Module, addrPtr, _ uint32) uint32 { envVal := ctx.Value(envKey) if envVal == nil { fmt.Println("[ERROR] hostHumanizeAddress: runtime environment not found in context") @@ -132,29 +136,35 @@ func hostHumanizeAddress(ctx context.Context, mod api.Module, addrPtr, addrLen u env := envVal.(*RuntimeEnvironment) mem := mod.Memory() - addr, err := readMemory(mem, addrPtr, addrLen) + // Read the address as a null-terminated byte slice. + addr, err := readNullTerminatedString(mem, addrPtr) if err != nil { + fmt.Printf("[ERROR] hostHumanizeAddress: failed to read address from memory: %v\n", err) return 1 } + fmt.Printf("[DEBUG] hostHumanizeAddress: read address (hex): %x, as string: '%s'\n", addr, string(addr)) + // Call the API to convert to a human-readable address. human, _, err := env.API.HumanizeAddress(addr) if err != nil { + fmt.Printf("[ERROR] hostHumanizeAddress: API.HumanizeAddress failed: %v\n", err) return 1 } + fmt.Printf("[DEBUG] hostHumanizeAddress: humanized address: '%s'\n", human) - if uint32(len(human)) > addrLen { - return 1 - } - + // Write the result back into memory. if err := writeMemory(mem, addrPtr, []byte(human), false); err != nil { + fmt.Printf("[ERROR] hostHumanizeAddress: failed to write humanized address back to memory: %v\n", err) return 1 } - + fmt.Printf("[DEBUG] hostHumanizeAddress: successfully wrote humanized address back to memory at 0x%x\n", addrPtr) return 0 } -// hostCanonicalizeAddress implements addr_canonicalize. -func hostCanonicalizeAddress(ctx context.Context, mod api.Module, addrPtr, addrLen uint32) uint32 { +// hostCanonicalizeAddress reads a null-terminated address from memory, +// calls the API to canonicalize it, logs intermediate results, and writes +// the canonical address back into memory. +func hostCanonicalizeAddress(ctx context.Context, mod api.Module, addrPtr, _ uint32) uint32 { envVal := ctx.Value(envKey) if envVal == nil { fmt.Println("[ERROR] hostCanonicalizeAddress: runtime environment not found in context") @@ -163,46 +173,72 @@ func hostCanonicalizeAddress(ctx context.Context, mod api.Module, addrPtr, addrL env := envVal.(*RuntimeEnvironment) mem := mod.Memory() - addr, err := readMemory(mem, addrPtr, addrLen) + // Read the address as a null-terminated byte slice. + addr, err := readNullTerminatedString(mem, addrPtr) if err != nil { + fmt.Printf("[ERROR] hostCanonicalizeAddress: failed to read address from memory: %v\n", err) return 1 } + fmt.Printf("[DEBUG] hostCanonicalizeAddress: read address (hex): %x, as string: '%s'\n", addr, string(addr)) + // Call the API to canonicalize the address. canonical, _, err := env.API.CanonicalizeAddress(string(addr)) if err != nil { + fmt.Printf("[ERROR] hostCanonicalizeAddress: API.CanonicalizeAddress failed: %v\n", err) return 1 } + fmt.Printf("[DEBUG] hostCanonicalizeAddress: canonical address (hex): %x\n", canonical) - if uint32(len(canonical)) > addrLen { - return 1 - } - + // Write the canonical address back to memory. if err := writeMemory(mem, addrPtr, canonical, false); err != nil { + fmt.Printf("[ERROR] hostCanonicalizeAddress: failed to write canonical address back to memory: %v\n", err) return 1 } - + fmt.Printf("[DEBUG] hostCanonicalizeAddress: successfully wrote canonical address back to memory at 0x%x\n", addrPtr) return 0 } -// hostValidateAddress implements addr_validate. - +// hostValidateAddress reads a null-terminated address from memory, +// calls the API to validate it, and logs the process. +// Returns 1 if the address is valid and 0 otherwise. func hostValidateAddress(ctx context.Context, mod api.Module, addrPtr uint32) uint32 { env := ctx.Value(envKey).(*RuntimeEnvironment) mem := mod.Memory() - addr, err := readMemory(mem, addrPtr, 32) + + // Read the address as a null-terminated string. + addr, err := readNullTerminatedString(mem, addrPtr) if err != nil { - panic(fmt.Sprintf("failed to read address from memory: %v", err)) + panic(fmt.Sprintf("[ERROR] hostValidateAddress: failed to read address from memory: %v", err)) } - // Trim any trailing null bytes. - addr = bytes.TrimRight(addr, "\x00") - // Now validate the (trimmed) address. + fmt.Printf("[DEBUG] hostValidateAddress: read address (hex): %x, as string: '%s'\n", addr, string(addr)) + + // Validate the address. _, err = env.API.ValidateAddress(string(addr)) if err != nil { + fmt.Printf("[DEBUG] hostValidateAddress: API.ValidateAddress failed: %v\n", err) return 0 // reject invalid address } + fmt.Printf("[DEBUG] hostValidateAddress: address validated successfully\n") return 1 // valid } +// --- Helper: readNullTerminatedString --- +// Reads bytes from memory starting at addrPtr until a null byte is found. +func readNullTerminatedString(mem api.Memory, addrPtr uint32) ([]byte, error) { + var buf []byte + for i := addrPtr; ; i++ { + b, ok := mem.ReadByte(i) + if !ok { + return nil, fmt.Errorf("memory access error at offset %d", i) + } + if b == 0 { + break + } + buf = append(buf, b) + } + return buf, nil +} + // hostScan implements db_scan. func hostScan(ctx context.Context, mod api.Module, startPtr, startLen, order uint32) uint32 { envVal := ctx.Value(envKey) diff --git a/internal/runtime/registerhostfunctions.go b/internal/runtime/registerhostfunctions.go index f1a6877c2..f8a7c3caf 100644 --- a/internal/runtime/registerhostfunctions.go +++ b/internal/runtime/registerhostfunctions.go @@ -3,7 +3,6 @@ package runtime import ( "context" "fmt" - "time" "github.com/tetratelabs/wazero" "github.com/tetratelabs/wazero/api" @@ -12,50 +11,31 @@ import ( // RegisterHostFunctions registers all required host functions with the wazero runtime. // It provides detailed logging and ensures all CosmWasm‐required functions are implemented. func RegisterHostFunctions(runtime wazero.Runtime, env *RuntimeEnvironment) (wazero.CompiledModule, error) { - fmt.Printf("\n=== Starting Host Function Registration ===\n") - startTime := time.Now() - - // Map to track registered functions. - registeredFuncs := make(map[string]bool) - - // Helper function to log function registration. - logRegistration := func(name string) { - registeredFuncs[name] = true - fmt.Printf("Registered host function: %s\n", name) - } - // Create a builder for the "env" module. builder := runtime.NewHostModuleBuilder("env") // Register Memory Management Functions. - registerMemoryFunctions(builder, env, logRegistration) + registerMemoryFunctions(builder, env) // Register Debug Functions. - registerDebugFunctions(builder, env, logRegistration) + registerDebugFunctions(builder, env) // Register Storage Functions. - registerStorageFunctions(builder, env, logRegistration) + registerStorageFunctions(builder, env) // Register Iterator Functions. - registerIteratorFunctions(builder, env, logRegistration) + registerIteratorFunctions(builder, env) // Register Address Functions. - registerAddressFunctions(builder, env, logRegistration) + registerAddressFunctions(builder, env) // Register Query Functions. - registerQueryFunctions(builder, env, logRegistration) + registerQueryFunctions(builder, env) // Register Crypto Functions. - registerCryptoFunctions(builder, env, logRegistration) + registerCryptoFunctions(builder, env) // (Note: registerCryptoFunctions no longer calls registerIteratorFunctions.) - // Registration Summary. - fmt.Printf("\n=== Registration Summary ===\n") - fmt.Printf("Registered %d host functions in %v\n", len(registeredFuncs), time.Since(startTime)) - fmt.Printf("Memory model: wazero with 64KB pages\n") - fmt.Printf("Gas metering: enabled\n") - fmt.Printf("===================================\n\n") - // Compile and return the module. return builder.Compile(context.Background()) } @@ -63,9 +43,7 @@ func RegisterHostFunctions(runtime wazero.Runtime, env *RuntimeEnvironment) (waz // --- Registration Helpers --- // registerCryptoFunctions registers cryptographic functions like secp256k1_verify and ed25519_verify. -func registerCryptoFunctions(builder wazero.HostModuleBuilder, env *RuntimeEnvironment, log func(string)) { - fmt.Printf("\nRegistering Crypto Functions...\n") - +func registerCryptoFunctions(builder wazero.HostModuleBuilder, env *RuntimeEnvironment) { // secp256k1 Verify Function. builder.NewFunctionBuilder(). WithFunc(func(ctx context.Context, m api.Module, hashPtr, sigPtr, pubkeyPtr uint32) uint32 { @@ -75,7 +53,6 @@ func registerCryptoFunctions(builder wazero.HostModuleBuilder, env *RuntimeEnvir }). WithParameterNames("hash_ptr", "sig_ptr", "pubkey_ptr"). Export("secp256k1_verify") - log("secp256k1_verify") // secp256k1 Recover Pubkey Function. builder.NewFunctionBuilder(). @@ -86,7 +63,6 @@ func registerCryptoFunctions(builder wazero.HostModuleBuilder, env *RuntimeEnvir }). WithParameterNames("hash_ptr", "sig_ptr", "rec_id"). Export("secp256k1_recover_pubkey") - log("secp256k1_recover_pubkey") // ed25519 Verify Function. builder.NewFunctionBuilder(). @@ -97,7 +73,6 @@ func registerCryptoFunctions(builder wazero.HostModuleBuilder, env *RuntimeEnvir }). WithParameterNames("msg_ptr", "sig_ptr", "pubkey_ptr"). Export("ed25519_verify") - log("ed25519_verify") // ed25519 Batch Verify Function. builder.NewFunctionBuilder(). @@ -108,7 +83,6 @@ func registerCryptoFunctions(builder wazero.HostModuleBuilder, env *RuntimeEnvir }). WithParameterNames("msgs_ptr", "sigs_ptr", "pubkeys_ptr"). Export("ed25519_batch_verify") - log("ed25519_batch_verify") // BLS12-381 Aggregate G1 Function. builder.NewFunctionBuilder(). @@ -119,7 +93,6 @@ func registerCryptoFunctions(builder wazero.HostModuleBuilder, env *RuntimeEnvir }). WithParameterNames("ptr1", "ptr2"). Export("bls12_381_aggregate_g1") - log("bls12_381_aggregate_g1") // BLS12-381 Aggregate G2 Function. builder.NewFunctionBuilder(). @@ -130,7 +103,6 @@ func registerCryptoFunctions(builder wazero.HostModuleBuilder, env *RuntimeEnvir }). WithParameterNames("ptr1", "ptr2"). Export("bls12_381_aggregate_g2") - log("bls12_381_aggregate_g2") // BLS12-381 Pairing Equality Function. builder.NewFunctionBuilder(). @@ -142,7 +114,6 @@ func registerCryptoFunctions(builder wazero.HostModuleBuilder, env *RuntimeEnvir }). WithParameterNames("a1_ptr", "a2_ptr", "b1_ptr", "b2_ptr"). Export("bls12_381_pairing_equality") - log("bls12_381_pairing_equality") // BLS12-381 Hash to G1 Function. builder.NewFunctionBuilder(). @@ -154,7 +125,6 @@ func registerCryptoFunctions(builder wazero.HostModuleBuilder, env *RuntimeEnvir }). WithParameterNames("hash_ptr", "hash_len", "dst_ptr", "dst_len"). Export("bls12_381_hash_to_g1") - log("bls12_381_hash_to_g1") // BLS12-381 Hash to G2 Function. builder.NewFunctionBuilder(). @@ -166,7 +136,6 @@ func registerCryptoFunctions(builder wazero.HostModuleBuilder, env *RuntimeEnvir }). WithParameterNames("hash_ptr", "hash_len", "dst_ptr", "dst_len"). Export("bls12_381_hash_to_g2") - log("bls12_381_hash_to_g2") // Secp256r1 Verify Function. builder.NewFunctionBuilder(). @@ -178,7 +147,6 @@ func registerCryptoFunctions(builder wazero.HostModuleBuilder, env *RuntimeEnvir }). WithParameterNames("msg_ptr", "sig_ptr", "pubkey_ptr"). Export("secp256r1_verify") - log("secp256r1_verify") // Secp256r1 Recover Pubkey Function. builder.NewFunctionBuilder(). @@ -191,12 +159,10 @@ func registerCryptoFunctions(builder wazero.HostModuleBuilder, env *RuntimeEnvir }). WithParameterNames("hash_ptr", "sig_ptr", "recovery"). Export("secp256r1_recover_pubkey") - log("secp256r1_recover_pubkey") } // registerIteratorFunctions registers iterator-related functions like db_scan, db_next, db_next_key, and db_next_value. -func registerIteratorFunctions(builder wazero.HostModuleBuilder, env *RuntimeEnvironment, log func(string)) { - fmt.Printf("\nRegistering Iterator Functions...\n") +func registerIteratorFunctions(builder wazero.HostModuleBuilder, env *RuntimeEnvironment) { // DB Scan Function. builder.NewFunctionBuilder(). @@ -208,7 +174,6 @@ func registerIteratorFunctions(builder wazero.HostModuleBuilder, env *RuntimeEnv }). WithParameterNames("start_ptr", "start_len", "order"). Export("db_scan") - log("db_scan") // DB Next Function. builder.NewFunctionBuilder(). @@ -220,7 +185,6 @@ func registerIteratorFunctions(builder wazero.HostModuleBuilder, env *RuntimeEnv }). WithParameterNames("iter_id"). Export("db_next") - log("db_next") // DB Next Key Function. builder.NewFunctionBuilder(). @@ -233,7 +197,6 @@ func registerIteratorFunctions(builder wazero.HostModuleBuilder, env *RuntimeEnv }). WithParameterNames("iter_id"). Export("db_next_key") - log("db_next_key") // DB Next Value Function. builder.NewFunctionBuilder(). @@ -247,12 +210,10 @@ func registerIteratorFunctions(builder wazero.HostModuleBuilder, env *RuntimeEnv }). WithParameterNames("iter_id"). Export("db_next_value") - log("db_next_value") } // registerAddressFunctions registers address-related functions like addr_validate, addr_canonicalize, and addr_humanize. -func registerAddressFunctions(builder wazero.HostModuleBuilder, env *RuntimeEnvironment, log func(string)) { - fmt.Printf("\nRegistering Address Functions...\n") +func registerAddressFunctions(builder wazero.HostModuleBuilder, env *RuntimeEnvironment) { // Address Validation Function. builder.NewFunctionBuilder(). @@ -263,7 +224,6 @@ func registerAddressFunctions(builder wazero.HostModuleBuilder, env *RuntimeEnvi }). WithParameterNames("addr_ptr"). Export("addr_validate") - log("addr_validate") // Address Canonicalization Function. builder.NewFunctionBuilder(). @@ -274,7 +234,6 @@ func registerAddressFunctions(builder wazero.HostModuleBuilder, env *RuntimeEnvi }). WithParameterNames("addr_ptr", "addr_len"). Export("addr_canonicalize") - log("addr_canonicalize") // Address Humanization Function. builder.NewFunctionBuilder(). @@ -285,12 +244,10 @@ func registerAddressFunctions(builder wazero.HostModuleBuilder, env *RuntimeEnvi }). WithParameterNames("addr_ptr", "addr_len"). Export("addr_humanize") - log("addr_humanize") } // registerMemoryFunctions registers memory management functions like allocate and deallocate. -func registerMemoryFunctions(builder wazero.HostModuleBuilder, env *RuntimeEnvironment, log func(string)) { - fmt.Printf("\nRegistering Memory Management Functions...\n") +func registerMemoryFunctions(builder wazero.HostModuleBuilder, env *RuntimeEnvironment) { // Allocate Function. builder.NewFunctionBuilder(). @@ -305,7 +262,6 @@ func registerMemoryFunctions(builder wazero.HostModuleBuilder, env *RuntimeEnvir }). WithParameterNames("size"). Export("allocate") - log("allocate") // Deallocate Function (no-op). builder.NewFunctionBuilder(). @@ -315,12 +271,10 @@ func registerMemoryFunctions(builder wazero.HostModuleBuilder, env *RuntimeEnvir }). WithParameterNames("ptr"). Export("deallocate") - log("deallocate") } // registerDebugFunctions registers debug-related functions like debug and abort. -func registerDebugFunctions(builder wazero.HostModuleBuilder, env *RuntimeEnvironment, log func(string)) { - fmt.Printf("\nRegistering Debug Functions...\n") +func registerDebugFunctions(builder wazero.HostModuleBuilder, env *RuntimeEnvironment) { // Debug Function. builder.NewFunctionBuilder(). @@ -331,7 +285,6 @@ func registerDebugFunctions(builder wazero.HostModuleBuilder, env *RuntimeEnviro }). WithParameterNames("msg_ptr"). Export("debug") - log("debug") // Abort Function. builder.NewFunctionBuilder(). @@ -357,12 +310,10 @@ func registerDebugFunctions(builder wazero.HostModuleBuilder, env *RuntimeEnviro }). WithParameterNames("msg_ptr"). Export("abort") - log("abort") } // registerStorageFunctions registers storage-related functions like db_read, db_write, and db_remove. -func registerStorageFunctions(builder wazero.HostModuleBuilder, env *RuntimeEnvironment, log func(string)) { - fmt.Printf("\nRegistering Storage Functions...\n") +func registerStorageFunctions(builder wazero.HostModuleBuilder, env *RuntimeEnvironment) { // DB Read Function. builder.NewFunctionBuilder(). @@ -373,7 +324,6 @@ func registerStorageFunctions(builder wazero.HostModuleBuilder, env *RuntimeEnvi }). WithParameterNames("key_ptr"). Export("db_read") - log("db_read") // DB Write Function. builder.NewFunctionBuilder(). @@ -384,7 +334,6 @@ func registerStorageFunctions(builder wazero.HostModuleBuilder, env *RuntimeEnvi }). WithParameterNames("key_ptr", "value_ptr"). Export("db_write") - log("db_write") // DB Remove Function. builder.NewFunctionBuilder(). @@ -395,12 +344,10 @@ func registerStorageFunctions(builder wazero.HostModuleBuilder, env *RuntimeEnvi }). WithParameterNames("key_ptr"). Export("db_remove") - log("db_remove") } // registerQueryFunctions registers query-related functions like query_chain. -func registerQueryFunctions(builder wazero.HostModuleBuilder, env *RuntimeEnvironment, log func(string)) { - fmt.Printf("\nRegistering Query Functions...\n") +func registerQueryFunctions(builder wazero.HostModuleBuilder, env *RuntimeEnvironment) { // Query Chain Function. builder.NewFunctionBuilder(). @@ -411,5 +358,4 @@ func registerQueryFunctions(builder wazero.HostModuleBuilder, env *RuntimeEnviro }). WithParameterNames("req_ptr"). Export("query_chain") - log("query_chain") } diff --git a/internal/runtime/wazeroruntime.go b/internal/runtime/wazeroruntime.go index d3d613927..5cc47f3f8 100644 --- a/internal/runtime/wazeroruntime.go +++ b/internal/runtime/wazeroruntime.go @@ -696,27 +696,25 @@ func (w *WazeroRuntime) Query(checksum, env, query []byte, otherParams ...interf fmt.Printf("Error: %v\n", err) // Try to read and deserialize memory at various locations - if memory != nil { - // Try the env region - if envRegionData, ok := memory.Read(envRegionPtr, 12); ok { - fmt.Printf("\nEnvironment Region:\n") - offset := binary.LittleEndian.Uint32(envRegionData[0:4]) - length := binary.LittleEndian.Uint32(envRegionData[8:12]) - if data, err := readMemoryAndDeserialize(memory, offset, length); err == nil { - fmt.Printf("Data: %s\n", data) - } + // Try the env region + if envRegionData, ok := contractModule.Memory().Read(envRegionPtr, 12); ok { + fmt.Printf("\nEnvironment Region:\n") + offset := binary.LittleEndian.Uint32(envRegionData[0:4]) + length := binary.LittleEndian.Uint32(envRegionData[8:12]) + if data, err := readMemoryAndDeserialize(contractModule.Memory(), offset, length); err == nil { + fmt.Printf("Data: %s\n", data) } + } - // Try reading around the error location - errPtr := uint32(1047844) // Common error location - if data, err := readMemoryAndDeserialize(memory, errPtr-100, 200); err == nil { - fmt.Printf("\nAround error location (offset=%d):\n%s\n", errPtr, data) - } + // Try reading around the error location + errPtr := uint32(1047844) // Common error location + if data, err := readMemoryAndDeserialize(contractModule.Memory(), errPtr-100, 200); err == nil { + fmt.Printf("\nAround error location (offset=%d):\n%s\n", errPtr, data) + } - // Try reading the first page of memory - if data, err := readMemoryAndDeserialize(memory, 0, 256); err == nil { - fmt.Printf("\nFirst 256 bytes of memory:\n%s\n", data) - } + // Try reading the first page of memory + if data, err := readMemoryAndDeserialize(contractModule.Memory(), 0, 256); err == nil { + fmt.Printf("\nFirst 256 bytes of memory:\n%s\n", data) } fmt.Printf("=====================================\n\n") diff --git a/lib_libwasmvm_test.go b/lib_libwasmvm_test.go index 14648ae19..7196512e5 100644 --- a/lib_libwasmvm_test.go +++ b/lib_libwasmvm_test.go @@ -210,47 +210,76 @@ func TestRemoveCode(t *testing.T) { } func TestHappyPath(t *testing.T) { + t.Log("TestHappyPath: starting test") + + // Set up the VM and store the contract. vm := withVM(t) checksum := createTestContract(t, vm, HACKATOM_TEST_CONTRACT) + t.Logf("TestHappyPath: contract stored with checksum: %x", checksum) + // Define deserialization cost and set up gas and store. deserCost := types.UFraction{Numerator: 1, Denominator: 1} gasMeter1 := api.NewMockGasMeter(TESTING_GAS_LIMIT) - // instantiate it with this store store := api.NewLookup(gasMeter1) goapi := api.NewMockAPI() balance := types.Array[types.Coin]{types.NewCoin(250, "ATOM")} querier := api.DefaultQuerier(api.MOCK_CONTRACT_ADDR, balance) - // instantiate + // Prepare instantiation parameters. env := api.MockEnv() info := api.MockInfo("creator", nil) msg := []byte(`{"verifier": "fred", "beneficiary": "bob"}`) - i, _, err := vm.Instantiate(checksum, env, info, msg, store, *goapi, querier, gasMeter1, TESTING_GAS_LIMIT, deserCost) + t.Logf("TestHappyPath: Instantiating contract with msg: %s", msg) + t.Logf("TestHappyPath: Using env: %+v", env) + t.Logf("TestHappyPath: Using info: %+v", info) + + // Instantiate the contract. + instRes, gasUsedInst, err := vm.Instantiate( + checksum, env, info, msg, store, *goapi, querier, gasMeter1, TESTING_GAS_LIMIT, deserCost, + ) + if err != nil { + t.Logf("TestHappyPath: Instantiation failed with error: %v", err) + } require.NoError(t, err) - require.NotNil(t, i.Ok) - ires := i.Ok + require.NotNil(t, instRes.Ok) + t.Logf("TestHappyPath: Instantiation succeeded. Gas used: %d", gasUsedInst) + ires := instRes.Ok require.Empty(t, ires.Messages) - // execute + // Execute the contract (release funds). gasMeter2 := api.NewMockGasMeter(TESTING_GAS_LIMIT) store.SetGasMeter(gasMeter2) env = api.MockEnv() info = api.MockInfo("fred", nil) - h, _, err := vm.Execute(checksum, env, info, []byte(`{"release":{}}`), store, *goapi, querier, gasMeter2, TESTING_GAS_LIMIT, deserCost) + t.Logf("TestHappyPath: Executing contract with msg: %s", `{"release":{}}`) + + execRes, gasUsedExec, err := vm.Execute( + checksum, env, info, []byte(`{"release":{}}`), + store, *goapi, querier, gasMeter2, TESTING_GAS_LIMIT, deserCost, + ) + if err != nil { + t.Logf("TestHappyPath: Execution failed with error: %v", err) + } require.NoError(t, err) - require.NotNil(t, h.Ok) - hres := h.Ok + require.NotNil(t, execRes.Ok) + t.Logf("TestHappyPath: Execution succeeded. Gas used: %d", gasUsedExec) + hres := execRes.Ok require.Len(t, hres.Messages, 1) + t.Logf("TestHappyPath: Execution messages: %+v", hres.Messages) - // make sure it read the balance properly and we got 250 atoms + // Log dispatch message details. dispatch := hres.Messages[0].Msg - require.NotNil(t, dispatch.Bank, "%#v", dispatch) - require.NotNil(t, dispatch.Bank.Send, "%#v", dispatch) + require.NotNil(t, dispatch.Bank, "Dispatch message is missing the Bank field: %#v", dispatch) + require.NotNil(t, dispatch.Bank.Send, "Dispatch message is missing the Send field: %#v", dispatch) send := dispatch.Bank.Send + t.Logf("TestHappyPath: Dispatch message details: to_address=%s, amount=%+v", send.ToAddress, send.Amount) assert.Equal(t, "bob", send.ToAddress) assert.Equal(t, balance, send.Amount) - // check the data is properly formatted + + // Check and log the returned data. expectedData := []byte{0xF0, 0x0B, 0xAA} + t.Logf("TestHappyPath: Expected data (hex): %x", expectedData) + t.Logf("TestHappyPath: Actual data (hex): %x", hres.Data) assert.Equal(t, expectedData, hres.Data) }