Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

chore: attempt to improve OriginCall funcs #495

Closed
Closed
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
3 changes: 3 additions & 0 deletions cmd/gnodev/test_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,9 @@ func TestTest(t *testing.T) {
args: []string{"test", "--verbose", "--run", ".*/hi", "../../examples/gno.land/p/demo/ufmt"},
stdoutShouldContain: "RUN TestSprintf",
stderrShouldContain: "ok ./../../examples/gno.land/p/demo/ufmt",
}, {
args: []string{"test", "../../tests/integ/origin-call"},
stderrShouldContain: "ok ./../../tests/integ/origin-call",
}, {
args: []string{"test", "--verbose", "--run", ".*/NoExists", "../../examples/gno.land/p/demo/ufmt"},
stderrShouldContain: "ok ./../../examples/gno.land/p/demo/ufmt",
Expand Down
10 changes: 6 additions & 4 deletions stdlibs/stdlibs.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,17 +142,18 @@ func InjectPackage(store gno.Store, pn *gno.PackageNode) {
pn.DefineGoNativeValue("IntSize", strconv.IntSize)
pn.DefineGoNativeValue("AppendUint", strconv.AppendUint)
case "std":
// NOTE: some of these are overridden in tests/imports_test.go
// NOTE: some of these are overridden in tests/imports.go
// Also see stdlibs/InjectPackage.
pn.DefineNative("AssertOriginCall",
gno.Flds( // params
),
gno.Flds( // results
),
func(m *gno.Machine) {
isOrigin := len(m.Frames) == 2
ctx := m.Context.(ExecContext)
isOrigin := ctx.Msg != nil && len(ctx.Msg.GetSigners()) > 0
if !isOrigin {
panic("invalid non-origin call")
m.Panic(typedString("invalid non-origin call"))
}
},
)
Expand All @@ -163,7 +164,8 @@ func InjectPackage(store gno.Store, pn *gno.PackageNode) {
"isOrigin", "bool",
),
func(m *gno.Machine) {
isOrigin := len(m.Frames) == 2
ctx := m.Context.(ExecContext)
isOrigin := ctx.Msg != nil && len(ctx.Msg.GetSigners()) > 0
res0 := gno.TypedValue{T: gno.BoolType}
res0.SetBool(isOrigin)
m.PushValue(res0)
Expand Down
3 changes: 2 additions & 1 deletion tests/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"github.com/gnolang/gno/pkgs/crypto"
gno "github.com/gnolang/gno/pkgs/gnolang"
osm "github.com/gnolang/gno/pkgs/os"
"github.com/gnolang/gno/pkgs/sdk/testutils"
"github.com/gnolang/gno/pkgs/std"
"github.com/gnolang/gno/stdlibs"
)
Expand All @@ -41,7 +42,7 @@ func testMachineCustom(store gno.Store, pkgPath string, stdout io.Writer, maxAll
ChainID: "dev",
Height: 123,
Timestamp: 1234567890,
Msg: nil,
Msg: testutils.NewTestMsg(caller),
OrigCaller: caller.Bech32(),
OrigPkgAddr: pkgAddr.Bech32(),
OrigSend: send,
Expand Down
44 changes: 14 additions & 30 deletions tests/imports.go
Original file line number Diff line number Diff line change
Expand Up @@ -465,36 +465,6 @@ func testPackageInjector(store gno.Store, pn *gno.PackageNode) {
pn.DefineGoNativeValue("ParseInt", strconv.ParseInt)
case "std":
// NOTE: some of these are overrides.
// Also see stdlibs/InjectPackage.
pn.DefineNativeOverride("AssertOriginCall",
/*
gno.Flds( // params
),
gno.Flds( // results
),
*/
func(m *gno.Machine) {
isOrigin := len(m.Frames) == 3
if !isOrigin {
panic("invalid non-origin call")
}
},
)
pn.DefineNativeOverride("IsOriginCall",
/*
gno.Flds( // params
),
gno.Flds( // results
"isOrigin", "bool",
),
*/
func(m *gno.Machine) {
isOrigin := len(m.Frames) == 3
res0 := gno.TypedValue{T: gno.BoolType}
res0.SetBool(isOrigin)
m.PushValue(res0)
},
)
pn.DefineNativeOverride("GetCallerAt",
/*
gno.Flds( // params
Expand Down Expand Up @@ -534,6 +504,20 @@ func testPackageInjector(store gno.Store, pn *gno.PackageNode) {
m.PushValue(res0)
},
)
// TestClearOriginCall sets ctx.Msg=nil (it's non-nil by default in test
// setup).
// This ensures that AssertOriginCall panics and IsOriginCall returns false.
pn.DefineNative("TestClearOriginCall",
gno.Flds( // params
),
gno.Flds( // results
),
func(m *gno.Machine) {
ctx := m.Context.(stdlibs.ExecContext)
ctx.Msg = nil
m.Context = ctx
},
)
pn.DefineNative("TestSetOrigCaller",
gno.Flds( // params
"", "Address",
Expand Down
1 change: 1 addition & 0 deletions tests/integ/origin-call/origincall.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
package origincall
35 changes: 35 additions & 0 deletions tests/integ/origin-call/origincall_filetest.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package main

import (
"std"
"testing"

"gno.land/p/demo/testutils"
)

func main() {
test()
std.TestClearOriginCall()
test()
}

func test() {
if std.IsOriginCall() {
println("IsOriginCall: true")
} else {
println("IsOriginCall: false")
}
defer func() {
if r := recover(); r != nil {
println("AssertOriginCall: panic:", r.(string))
}
}()
std.AssertOriginCall()
println("AssertOriginCall: no panic")
}

// Output:
// IsOriginCall: true
// AssertOriginCall: no panic
// IsOriginCall: false
// AssertOriginCall: panic: invalid non-origin call
37 changes: 37 additions & 0 deletions tests/integ/origin-call/origincall_test.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package origincall

import (
"std"
"testing"

"gno.land/p/demo/testutils"
)

func TestOriginCall(t *testing.T) {
std.AssertOriginCall()
if b := std.IsOriginCall(); !b {
t.Errorf("expect isOriginCall true, got false")
}

std.TestClearOriginCall()
requirePanic(t, func() {
std.AssertOriginCall()
}, "invalid non-origin call")
// NOTE(tb): it's deceptively not possible to have a test for AssertOriginCall
// and an other test for IsOriginCall because the context is shared between
// tests (e.g. if std.TestSetOrigCaller is called in a test, this affects also
// the following test).
if b := std.IsOriginCall(); b {
t.Errorf("expect isOriginCall false, got true")
}
}

func requirePanic(t *testing.T, f func(), expRecover string) {
defer func() {
r := recover()
if r == nil || r.(string) != expRecover {
t.Fatalf("expected panic with '%v', got '%v'", expRecover, r)
}
}()
f()
}