From f4e487bf3a48120c6578744a8e70b665fee8cbd8 Mon Sep 17 00:00:00 2001 From: Thomas Bruyelle Date: Fri, 1 Mar 2024 16:54:36 +0100 Subject: [PATCH] feat: PrevRealm ignores user realms Fix #1664 As commented in the IsRealm() method, a better format of user realms should emerge in the form of `gno.land/u/user_address`, which would remove the confusion between standard realms and the realm forged under the MsgRun transaction. --- gno.land/cmd/gnoland/testdata/prevrealm.txtar | 188 ++++++++++++++++++ gnovm/pkg/gnolang/values.go | 9 +- 2 files changed, 196 insertions(+), 1 deletion(-) create mode 100644 gno.land/cmd/gnoland/testdata/prevrealm.txtar diff --git a/gno.land/cmd/gnoland/testdata/prevrealm.txtar b/gno.land/cmd/gnoland/testdata/prevrealm.txtar new file mode 100644 index 00000000000..f583dc9fa09 --- /dev/null +++ b/gno.land/cmd/gnoland/testdata/prevrealm.txtar @@ -0,0 +1,188 @@ +# This tests ensure the consistency of the std.PrevRealm function, in the +# following situations: +# +# +# | Num | Msg Type | Call from | Entry Point | Result | +# |-----|:--------:|:-------------------:|:---------------:|:------------:| +# | 1 | MsgCall | wallet direct | myrlm.A() | user address | +# | 2 | | | myrlm.B() | user address | +# | 3 | | through /r/foo | myrlm.A() | r/foo | +# | 4 | | | myrlm.B() | r/foo | +# | 5 | | through /p/demo/bar | myrlm.A() | user address | +# | 6 | | | myrlm.B() | user address | +# | 7 | MsgRun | wallet direct | myrlm.A() | user address | +# | 8 | | | myrlm.B() | user address | +# | 9 | | through /r/foo | myrlm.A() | r/foo | +# | 10 | | | myrlm.B() | r/foo | +# | 11 | | through /p/demo/bar | myrlm.A() | user address | +# | 12 | | | myrlm.B() | user address | +# | 13 | MsgCall | wallet direct | std.PrevRealm() | user address | +# | 14 | MsgRun | wallet direct | std.PrevRealm() | user address | + +# Init +## start a new node +gnoland start + +## deploy myrlm +gnokey maketx addpkg -pkgdir $WORK/r/myrlm -pkgpath gno.land/r/myrlm -gas-fee 1000000ugnot -gas-wanted 2000000 -broadcast -chainid=tendermint_test test1 +stdout 'OK!' + +## deploy r/foo +gnokey maketx addpkg -pkgdir $WORK/r/foo -pkgpath gno.land/r/foo -gas-fee 1000000ugnot -gas-wanted 2000000 -broadcast -chainid=tendermint_test test1 +stdout 'OK!' + +## deploy p/demo/bar +gnokey maketx addpkg -pkgdir $WORK/p/demo/bar -pkgpath gno.land/p/demo/bar -gas-fee 1000000ugnot -gas-wanted 2000000 -broadcast -chainid=tendermint_test test1 +stdout 'OK!' + +env RFOO_ADDR=g1evezrh92xaucffmtgsaa3rvmz5s8kedffsg469 + +# Test cases +## 1. MsgCall -> myrlm.A: user address +gnokey maketx call -pkgpath gno.land/r/myrlm -func A -gas-fee 100000ugnot -gas-wanted 2000000 -broadcast -chainid tendermint_test test1 +stdout ${USER_ADDR_test1} + +## 2. MsgCall -> myrealm.B -> myrlm.A: user address +gnokey maketx call -pkgpath gno.land/r/myrlm -func B -gas-fee 100000ugnot -gas-wanted 2000000 -broadcast -chainid tendermint_test test1 +stdout ${USER_ADDR_test1} + +## 3. MsgCall -> r/foo.A -> myrlm.A: r/foo +gnokey maketx call -pkgpath gno.land/r/foo -func A -gas-fee 100000ugnot -gas-wanted 2000000 -broadcast -chainid tendermint_test test1 +stdout ${RFOO_ADDR} + +## 4. MsgCall -> r/foo.B -> myrlm.B -> r/foo.A: r/foo +gnokey maketx call -pkgpath gno.land/r/foo -func B -gas-fee 100000ugnot -gas-wanted 2000000 -broadcast -chainid tendermint_test test1 +stdout ${RFOO_ADDR} + +## 5. MsgCall -> p/demo/bar.A -> myrlm.A: user address +gnokey maketx call -pkgpath gno.land/p/demo/bar -func A -gas-fee 100000ugnot -gas-wanted 2000000 -broadcast -chainid tendermint_test test1 +stdout ${USER_ADDR_test1} + +## 6. MsgCall -> p/demo/bar.B -> myrlm.B -> r/foo.A: user address +gnokey maketx call -pkgpath gno.land/p/demo/bar -func B -gas-fee 100000ugnot -gas-wanted 2000000 -broadcast -chainid tendermint_test test1 +stdout ${USER_ADDR_test1} + +## 7. MsgRun -> myrlm.A: user address +gnokey maketx run -gas-fee 100000ugnot -gas-wanted 2000000 -broadcast -chainid tendermint_test test1 $WORK/run/myrlmA.gno +stdout ${USER_ADDR_test1} + +## 8. MsgRun -> myrealm.B -> myrlm.A: user address +gnokey maketx run -gas-fee 100000ugnot -gas-wanted 2000000 -broadcast -chainid tendermint_test test1 $WORK/run/myrlmB.gno +stdout ${USER_ADDR_test1} + +## 9. MsgRun -> r/foo.A -> myrlm.A: r/foo +gnokey maketx run -gas-fee 100000ugnot -gas-wanted 2000000 -broadcast -chainid tendermint_test test1 $WORK/run/fooA.gno +stdout ${RFOO_ADDR} + +## 10. MsgRun -> r/foo.B -> myrlm.B -> r/foo.A: r/foo +gnokey maketx run -gas-fee 100000ugnot -gas-wanted 2000000 -broadcast -chainid tendermint_test test1 $WORK/run/fooB.gno +stdout ${RFOO_ADDR} + +## 11. MsgRun -> p/demo/bar.A -> myrlm.A: user address +gnokey maketx run -gas-fee 100000ugnot -gas-wanted 2000000 -broadcast -chainid tendermint_test test1 $WORK/run/barA.gno +stdout ${USER_ADDR_test1} + +## 12. MsgRun -> p/demo/bar.B -> myrlm.B -> r/foo.A: user address +gnokey maketx run -gas-fee 100000ugnot -gas-wanted 2000000 -broadcast -chainid tendermint_test test1 $WORK/run/barB.gno +stdout ${USER_ADDR_test1} + +## 13. MsgCall -> std.PrevRealm(): user address +gnokey maketx call -pkgpath std -func PrevRealm -gas-fee 100000ugnot -gas-wanted 2000000 -broadcast -chainid tendermint_test test1 +stdout ${USER_ADDR_test1} + +## 14. MsgRun -> std.PrevRealm(): user address +gnokey maketx run -gas-fee 100000ugnot -gas-wanted 2000000 -broadcast -chainid tendermint_test test1 $WORK/run/baz.gno +stdout ${USER_ADDR_test1} + +-- r/myrlm/myrlm.gno -- +package myrlm + +import "std" + +func A() string { + return std.PrevRealm().Addr().String() +} + +func B() string { + return A() +} +-- r/foo/foo.gno -- +package foo + +import "gno.land/r/myrlm" + +func A() string { + return myrlm.A() +} + +func B() string { + return myrlm.B() +} +-- p/demo/bar/bar.gno -- +package bar + +import "gno.land/r/myrlm" + +func A() string { + return myrlm.A() +} + +func B() string { + return myrlm.B() +} +-- run/myrlmA.gno -- +package main + +import myrlm "gno.land/r/myrlm" + +func main() { + println(myrlm.A()) +} +-- run/myrlmB.gno -- +package main + +import "gno.land/r/myrlm" + +func main() { + println(myrlm.B()) +} +-- run/fooA.gno -- +package main + +import "gno.land/r/foo" + +func main() { + println(foo.A()) +} +-- run/fooB.gno -- +package main + +import "gno.land/r/foo" + +func main() { + println(foo.B()) +} +-- run/barA.gno -- +package main + +import "gno.land/p/demo/bar" + +func main() { + println(bar.A()) +} +-- run/barB.gno -- +package main + +import "gno.land/p/demo/bar" + +func main() { + println(bar.B()) +} +-- run/baz.gno -- +package main + +import "std" + +func main() { + println(std.PrevRealm().Addr().String()) +} diff --git a/gnovm/pkg/gnolang/values.go b/gnovm/pkg/gnolang/values.go index 85e6562eca6..5234b4a0470 100644 --- a/gnovm/pkg/gnolang/values.go +++ b/gnovm/pkg/gnolang/values.go @@ -816,8 +816,15 @@ type PackageValue struct { fBlocksMap map[Name]*Block } +// IsRealm returns true if pv represents a realm. +// A user realm, forged by the MsgRun transaction, isn't considered as a realm. +// XXX The user realm format is: +// PkgPath="gno.land/r/user_address" PkgName="main" +// A less confusing format could emerge in the future, with the form of +// PkgPath="gno.land/u/user_address" func (pv *PackageValue) IsRealm() bool { - return IsRealmPath(pv.PkgPath) + return IsRealmPath(pv.PkgPath) && + pv.PkgName != "main" // Discard user realms forged by MsgRun } func (pv *PackageValue) getFBlocksMap() map[Name]*Block {