gnolang / gno

Gno: An interpreted, stack-based Go virtual machine to build succinct and composable apps + Gno.land: a blockchain for timeless code and fair open-source
https://gno.land/
Other
849 stars 345 forks source link

Unexpected primitive type: `float32` and `float64` #1427

Closed waymobetta closed 5 months ago

waymobetta commented 7 months ago

Unexpected primitive type: float32 and float64

Description

NOTE: The below also holds true for float64.

I just tried to use float32 in a realm and am getting the error: unexpected primitive type float32.

Your environment

Mac: Sonoma 14.1.2 Gno: v0.0.1-dev.2023.12.01 Master branch

Steps to reproduce

Something like the following could be used within a realm to recreate this error.

NOTE: When doing arithmetic with variables defined within the function scope, everything is fine (version 0); when performing arithmetic with variables that are passed in via transaction (gnokey), the error occurs (version 1).

It is possible that I am not passing in values correctly to gnokey.

Version 0:

// works
func Add() float32 {
    var x float32 = 10.0
    var y float32 = 20.5
    return x + y
}

Version 1:

// does not work
func Add(x, y float32) float32 {
    // var x float32 = 10.0
    // var y float32 = 20.5
    // should return: 30.5
    // instead fails with error
    return x + y
}

Gnokey Tx:


# tx
    gnokey maketx \
        call \
        --pkgpath "gno.land/r/demo/float_realm" \
        --func "Add" \
        --args 10.5 \
        --args 20 \
        --gas-fee 1000000ugnot \
        --gas-wanted 2000000 \
        --broadcast \
        --chainid dev \
        --remote localhost:26657 \
        demo

Expected behaviour

Variables should be added together and returned as float32

Actual behaviour

Error: Unexpected primitive type: float32

Logs

Msg Traces:
    0  /Users/jr/go/src/github.com/waymobetta/gno/tm2/pkg/crypto/keys/client/addpkg.go:214 - deliver transaction failed: log:recovered: unexpected primitive type float32
stack:
goroutine 88 [running]:
runtime/debug.Stack()
        /opt/homebrew/Cellar/go/1.21.4/libexec/src/runtime/debug/stack.go:24 +0x64
github.com/gnolang/gno/tm2/pkg/sdk.(*BaseApp).runTx.func1()
        /Users/jr/go/src/github.com/waymobetta/gno/tm2/pkg/sdk/baseapp.go:743 +0x230
panic({0x1030556e0?, 0x14007029ed0?})
        /opt/homebrew/Cellar/go/1.21.4/libexec/src/runtime/panic.go:914 +0x218
github.com/gnolang/gno/gno.land/pkg/sdk/vm.convertArgToGno({0x1400b8d7ba4, 0x4}, {0x10318ba88?, 0x102fedb80?})
        /Users/jr/go/src/github.com/waymobetta/gno/gno.land/pkg/sdk/vm/convert.go:157 +0x7ec
github.com/gnolang/gno/gno.land/pkg/sdk/vm.(*VMKeeper).Call(_, {{0x103189a08, 0x1400896d0e0}, 0x2, {0x103188938, 0x14007028fe0}, {0x103189d50, 0x140082a5600}, {0x1400b88414d, 0x3}, ...}, ...)
        /Users/jr/go/src/github.com/waymobetta/gno/gno.land/pkg/sdk/vm/keeper.go:235 +0x514
github.com/gnolang/gno/gno.land/pkg/sdk/vm.vmHandler.handleMsgCall({_}, {{0x103189a08, 0x1400896d0e0}, 0x2, {0x103188938, 0x14007028fe0}, {0x103189d50, 0x140082a5600}, {0x1400b88414d, 0x3}, ...}, ...)
        /Users/jr/go/src/github.com/waymobetta/gno/gno.land/pkg/sdk/vm/handler.go:64 +0x204
github.com/gnolang/gno/gno.land/pkg/sdk/vm.vmHandler.Process({0x1400bce0cf8?}, {{0x103189a08, 0x1400896d0e0}, 0x2, {0x103188938, 0x14007028fe0}, {0x103189d50, 0x140082a5600}, {0x1400b88414d, 0x3}, ...}, ...)
        /Users/jr/go/src/github.com/waymobetta/gno/gno.land/pkg/sdk/vm/handler.go:29 +0xcc
github.com/gnolang/gno/tm2/pkg/sdk.(*BaseApp).runMsgs(0x140005be000, {{0x103189a08, 0x1400896d0e0}, 0x2, {0x103188938, 0x14007028fe0}, {0x103189d50, 0x140082a5600}, {0x1400b88414d, 0x3}, ...}, ...)
        /Users/jr/go/src/github.com/waymobetta/gno/tm2/pkg/sdk/baseapp.go:644 +0x20c
github.com/gnolang/gno/tm2/pkg/sdk.(*BaseApp).runTx(0x140005be000, 0x2, {0x1400b725900, 0xf8, 0xf8}, {{0x14007028600, 0x1, 0x1}, {0x1e8480, {{0x1400b8d7bc7, ...}, ...}}, ...})
        /Users/jr/go/src/github.com/waymobetta/gno/tm2/pkg/sdk/baseapp.go:823 +0x714
github.com/gnolang/gno/tm2/pkg/sdk.(*BaseApp).DeliverTx(0x0?, {{}, {0x1400b725900?, 0x0?, 0x0?}})
        /Users/jr/go/src/github.com/waymobetta/gno/tm2/pkg/sdk/baseapp.go:580 +0x15c
github.com/gnolang/gno/tm2/pkg/bft/abci/client.(*localClient).DeliverTxAsync(0x14000596600, {{}, {0x1400b725900, 0xf8, 0xf8}})
        /Users/jr/go/src/github.com/waymobetta/gno/tm2/pkg/bft/abci/client/local_client.go:82 +0xe4
github.com/gnolang/gno/tm2/pkg/bft/proxy.(*appConnConsensus).DeliverTxAsync(0x103111620?, {{}, {0x1400b725900?, 0x20?, 0x20?}})
        /Users/jr/go/src/github.com/waymobetta/gno/tm2/pkg/bft/proxy/app_conn.go:73 +0x2c
github.com/gnolang/gno/tm2/pkg/bft/state.execBlockOnProxyApp({0x10318a728, 0x1400b895dd0}, {0x10318d8d0, 0x140000c4f80}, 0x14007705040, {0x103192750, 0x14000070070})
        /Users/jr/go/src/github.com/waymobetta/gno/tm2/pkg/bft/state/execution.go:253 +0x428
github.com/gnolang/gno/tm2/pkg/bft/state.(*BlockExecutor).ApplyBlock(_, {{0x102d88184, 0xb}, {0x102d88184, 0xb}, {0x0, 0x0}, {0x14008f8f89d, 0x3}, 0xe, ...}, ...)
        /Users/jr/go/src/github.com/waymobetta/gno/tm2/pkg/bft/state/execution.go:102 +0xc0
github.com/gnolang/gno/tm2/pkg/bft/consensus.(*ConsensusState).finalizeCommit(0x1400dcdc900, 0xf)
        /Users/jr/go/src/github.com/waymobetta/gno/tm2/pkg/bft/consensus/state.go:1347 +0x754
github.com/gnolang/gno/tm2/pkg/bft/consensus.(*ConsensusState).tryFinalizeCommit(0x1400dcdc900, 0xf)
        /Users/jr/go/src/github.com/waymobetta/gno/tm2/pkg/bft/consensus/state.go:1275 +0x268
github.com/gnolang/gno/tm2/pkg/bft/consensus.(*ConsensusState).enterCommit.func1()
        /Users/jr/go/src/github.com/waymobetta/gno/tm2/pkg/bft/consensus/state.go:1221 +0x7c
github.com/gnolang/gno/tm2/pkg/bft/consensus.(*ConsensusState).enterCommit(0x1400dcdc900, 0xf, 0x0)
        /Users/jr/go/src/github.com/waymobetta/gno/tm2/pkg/bft/consensus/state.go:1252 +0x890
github.com/gnolang/gno/tm2/pkg/bft/consensus.(*ConsensusState).addVote(0x1400dcdc900, 0x14005472320, {0x0, 0x0})
        /Users/jr/go/src/github.com/waymobetta/gno/tm2/pkg/bft/consensus/state.go:1637 +0x738
github.com/gnolang/gno/tm2/pkg/bft/consensus.(*ConsensusState).tryAddVote(0x1400dcdc900, 0xf?, {0x0?, 0x0?})
        /Users/jr/go/src/github.com/waymobetta/gno/tm2/pkg/bft/consensus/state.go:1483 +0x24
github.com/gnolang/gno/tm2/pkg/bft/consensus.(*ConsensusState).handleMsg(0x1400dcdc900, {{0x103183ca0, 0x1400b89c068}, {0x0, 0x0}})
        /Users/jr/go/src/github.com/waymobetta/gno/tm2/pkg/bft/consensus/state.go:691 +0x294
github.com/gnolang/gno/tm2/pkg/bft/consensus.(*ConsensusState).receiveRoutine(0x1400dcdc900, 0x0)
        /Users/jr/go/src/github.com/waymobetta/gno/tm2/pkg/bft/consensus/state.go:650 +0x2a4
created by github.com/gnolang/gno/tm2/pkg/bft/consensus.(*ConsensusState).OnStart in goroutine 1
        /Users/jr/go/src/github.com/waymobetta/gno/tm2/pkg/bft/consensus/state.go:344 +0x418

--= /Error =--

Proposed solution

Possibly float32 is not supported? https://github.com/gnolang/gno/blob/master/gno.land/pkg/sdk/vm/convert.go#L156

deelawn commented 6 months ago

We cannot support floats due to potential non-deterministic results using amino to encode floats; they need to be passed as strings if the realm function wants to use them. Leaving this open because a better solution might be to add some additional checks either when calling addpkg or maketx to return a better error message that indicates float values are not supported.

https://github.com/gnolang/gno/blob/968f89e2bce754e8a11db7a5a9813f4473caefe1/tm2/pkg/amino/README.md?plain=1#L94

thehowl commented 6 months ago

:thinking:

I mean, I'm pretty sure argument parsing in maketx calls just combines the function into an expression to call the given function. So, ultimately, it's the gnovm parsing a literal, and we already have the code to do that...