Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 14 additions & 5 deletions gno.land/pkg/integration/testdata/maketx_call_pure.txtar
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,18 @@ stderr '"gnokey" error: --= Error =--\nData: invalid package path'
stderr '"gnokey" error: --= Error =--\nData: invalid package path'

# 4. normal call to realm ERROR (need crossing)
! gnokey maketx call -pkgpath gno.land/r/foo/call_realm -func Render -gas-fee 1000000ugnot -gas-wanted 2000000 -broadcast -chainid=tendermint_test test1
stderr 'wrong number of arguments in call to Render: want 0 got 1'
! gnokey maketx call -pkgpath gno.land/r/foo/call_realm -func Render2 -gas-fee 1000000ugnot -gas-wanted 2000000 -broadcast -chainid=tendermint_test test1
stderr 'function Render2 is non-crossing and cannot be called with MsgCall \(\/directly\). It can either be called with qeval, or via another code realm'

# 5. normal call to realm ERROR (need crossing)
! gnokey maketx call -pkgpath gno.land/r/foo/call_realm -func Render -args "" -gas-fee 1000000ugnot -gas-wanted 2000000 -broadcast -chainid=tendermint_test test1
stderr 'function Render is non-crossing and cannot be called with MsgCall \(\/directly\). It can either be called with qeval, or via another code realm'

# XXX: While the error is correct, the correct message should be something like the message below:
# stderr 'cannot cross-call a non-crossing function gno.land/r/foo/call_realm.Render from <no realm>'

# 5. normal eval realm SUCCESS
gnokey query vm/qeval --data 'gno.land/r/foo/call_realm.Render()'
gnokey query vm/qeval --data 'gno.land/r/foo/call_realm.Render2()'
stdout 'ok'

-- pure/package.gno --
Expand All @@ -36,6 +41,10 @@ func Hello() string {
-- realm/realm.gno --
package call_realm

func Render() string {
return "ok"
func Render(path string) string {
return path
}

func Render2() string {
return "ok"
}
4 changes: 4 additions & 0 deletions gno.land/pkg/sdk/vm/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -556,6 +556,10 @@ func (vm *VMKeeper) Call(ctx sdk.Context, msg MsgCall) (res string, err error) {
pl := gno.PackageNodeLocation(pkgPath)
pn := gnostore.GetBlockNode(pl).(*gno.PackageNode)
ft := pn.GetStaticTypeOf(gnostore, gno.Name(fnc)).(*gno.FuncType)
if len(ft.Params) == 0 || ft.Params[0].Type.String() != ".uverse.realm" {
panic(fmt.Sprintf("function %s is non-crossing and cannot be called with MsgCall (/directly). It can either be called with qeval, or via another code realm", fnc))
}

// Make main Package with imports.
mpn := gno.NewPackageNode("main", "", nil)
mpn.Define("pkg", gno.TypedValue{T: &gno.PackageType{}, V: pv})
Expand Down
56 changes: 56 additions & 0 deletions gno.land/pkg/sdk/vm/keeper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -931,6 +931,62 @@ func Echo(cur realm, msg string) string { // XXX remove crossing call ?
)
}

func TestNonCrossingCallError(t *testing.T) {
env := setupTestEnv()
ctx := env.vmk.MakeGnoTransactionStore(env.ctx)

// Give "addr1" some gnots.
addr := crypto.AddressFromPreimage([]byte("addr1"))
acc := env.acck.NewAccountWithAddress(ctx, addr)
env.acck.SetAccount(ctx, acc)
env.bankk.SetCoins(ctx, addr, initialBalance)
assert.True(t, env.bankk.GetCoins(ctx, addr).IsEqual(initialBalance))

// Create test package.
const pkgPath = "gno.land/r/test"
files := []*std.MemFile{
{Name: "gnomod.toml", Body: gnolang.GenGnoModLatest(pkgPath)},
{
Name: "test.gno",
Body: `package test

func Echo(msg string) string {
return "echo:"+msg
}

func EmptyCall() {
return
}

`,
},
}
msg1 := NewMsgAddPackage(addr, pkgPath, files)
err := env.vmk.AddPackage(ctx, msg1)
assert.NoError(t, err)

// Call Echo function which is not a crossing call
coins := std.MustParseCoins(ugnot.ValueString(1))
msg2 := NewMsgCall(addr, coins, pkgPath, "Echo", []string{"hello world"})
assert.PanicsWithValue(
t,
"function Echo is non-crossing and cannot be called with MsgCall (/directly). It can either be called with qeval, or via another code realm",
func() {
env.vmk.Call(ctx, msg2)
},
)

// Call EmptyCall function which is not a crossing call
msg3 := NewMsgCall(addr, coins, pkgPath, "EmptyCall", []string{})
assert.PanicsWithValue(
t,
"function EmptyCall is non-crossing and cannot be called with MsgCall (/directly). It can either be called with qeval, or via another code realm",
func() {
env.vmk.Call(ctx, msg3)
},
)
}

func TestVMKeeperReinitialize(t *testing.T) {
env := setupTestEnv()
ctx := env.vmk.MakeGnoTransactionStore(env.ctx)
Expand Down
Loading