diff --git a/docs/resources/gno-interrealm.md b/docs/resources/gno-interrealm.md index 74aed39aeaa..8949f830d4a 100644 --- a/docs/resources/gno-interrealm.md +++ b/docs/resources/gno-interrealm.md @@ -106,3 +106,324 @@ be upgraded. Both `crossing()` and `cross(fn)(...)` statements may become special syntax in future Gno versions. + +### Usage + +P package code cannot containing crossing functions, nor use crossing(). P +package code also cannot import R realm packages. But code can call named +crossing functions e.g. those passed in as parameters. + +You must declare a public realm function to be crossing() if it is intended to +be called by end users, because users cannot MsgCall non-crossing functions +(for safety/consistency) or p package functions (there's no point). + +Utility functions that are a common sequence of non-crossing logic can be +offered in realm packages as non-crossing functions. These can also import and +use other realm utility non-crossing functions; whereas p packages cannot +import realm packages at all. And convenience/utility functions that are being +staged before publishing as permanent p code should also reside in upgreadeable +realms. + +Generally you want your methods to be non-crossing. Because they should work +for everyone. They are functions that are pre-bound to an object, and that +object is like a quasi-realm in itself, that could reside and migrate to other +realms possibly. This is consistent with any p code copied over to r realms; +none of those methods would be crossing, and behavior would be the same; stored +in any realm, mostly non-crossing methods that anyone can call. Why is a +quasi-realm self-encapsulated Object in need to modify the realm in which it is +declared, by crossing? That's intrusive, but sometimes desired. + +You can always cross-call a method from a non-crossing method if you need it. + +Implementation for `std.CurrentRealm()` and `std.PreviousRealm()` are defined +in `stdlibs/std/native.gno/go` and related files in the directory, while +overrides for testing are defined in `testing/stdlibs/std/std.gno/go`. All +stdlibs functions are available unless overridden by the latter. + +`std.CurrentRealm()` shifts to `std.PreviousRealm()` if and only if a function +is called like cross(fn)(...). + +#### MsgCall + +MsgCall may only call crossing functions. This is to prevent potential +confusion of non-sophisticated users. Non-crossing calls of non-crossing +functions of other realms is still possible with MsgRun. + +```go +// PKGPATH: gno.land/r/test/test + +func Public() { + crossing() + + // Returns ( + // addr:, + // pkgpath:"" + // ) == std.NewUserRealm(origin_caller) + std.PreviousRealm() + + // Returns ( + // addr:, + // pkgpath:"gno.land/r/test/test" + // ) == std.NewCodeRealm("gno.land/r/test/test") + std.CurrentRealm() + + // Already in gno.land/r/test/test realm, + // no need to cross unless the intent + // is to call AnotherPublic() as a consumer + // in which case cross(AnotherPublic)() needed. + AnotherPublic() +} + +func AnotherPublic() { + crossing() + ... +} +``` + +#### MsgRun + +```go +// PKGPATH: gno.land/r/g1user/run + +import "gno.land/r/realmA" + +func main() { + // There is assumed to be in "frame -1" + // a crossing from UserRealm(g1user) to + // CodeRealm(gno.land/r/g1user/run) before + // main() is called, so crossing() here + // is redundant. + // crossing() + + // Returns ( + // addr:g1user, + // pkgpath:"" + // ) == std.NewUserRealm(g1user) + std.PreviousRealm() + + // Returns ( + // addr:g1user, + // pkgpath:"gno.land/r/g1user/run" + // ) == std.NewCodeRealm("gno.land/r/g1user/run") + std.CurrentRealm() + + realmA.PublicNoncrossing() + cross(realmA.PublicCrossing)() +} +``` + +Notice in gnovm/pkg/gnolang/misc.go, the following: + +```go +// For keeping record of package & realm coins. +// If you need the bech32 address it is faster to call DerivePkgBech32Addr(). +func DerivePkgCryptoAddr(pkgPath string) crypto.Address { + b32addr, ok := IsGnoRunPath(pkgPath) + if ok { + addr, err := crypto.AddressFromBech32(b32addr) + if err != nil { + panic("invalid bech32 address in run path: " + pkgPath) + } + return addr + } + // NOTE: must not collide with pubkey addrs. + return crypto.AddressFromPreimage([]byte("pkgPath:" + pkgPath)) +} + +func DerivePkgBech32Addr(pkgPath string) crypto.Bech32Address { + b32addr, ok := IsGnoRunPath(pkgPath) + if ok { + return crypto.Bech32Address(b32addr) + } + // NOTE: must not collide with pubkey addrs. + return crypto.AddressFromPreimage([]byte("pkgPath:" + pkgPath)).Bech32() +} +``` + +These function names are distinct from what is available in Gno +from stdlibs/std/crypto.gno: + +```go +// Returns a crypto hash derived pkgPath, unless pkgPath is a MsgRun run path, +// in which case the address is extracted from the path. +func DerivePkgAddr(pkgPath string) Address { + addr := derivePkgAddr(pkgPath) <-- calls gno.DerivePkgBech32Addr() + return Address(addr) +} +``` + +1. `std.DerivePkgAddr("gno.land/r/name123/realm")` - bech32 from hash(path) +2. `std.DerivePkgAddr("gno.land/r/g1user/run")` - bech32 substring "g1user" + +Therefore in the MsgRun file's init() function the previous realm and current +realm have different pkgpaths (the origin caller always has empty pkgpath) but +the address is the same. + +#### MsgAddPackage + +During MsgAddPackage `std.PreviousRealm()` refers to the package deployer both +in gloval var decls as well as inside `init()` functions. After that the +package deployer is no longer provided, so packages need to remember the +deployer in the initialization if needed. + +```go +// PKGPATH: gno.land/r/test/test + +func init() { + // Returns ( + // addr:, + // pkgpath:"" + // ) == std.NewUserRealm(origin_deployer) + // Inside init() and global var decls + // are the only time std.PreviousRealm() + // returns the deployer of the package. + // Save it here or lose it forever. + std.PreviousRealm() + + // Returns ( + // addr:, + // pkgpath:"gno.land/r/test/test" + // ) == std.NewCodeRealm("gno.land/r/test/test") + std.CurrentRealm() +} + +// Same as in init(). +var _ = std.PreviousRealm() +``` + +```go +// PKGPATH: gno.land/r/g1user/run + +func init() { + // Returns ( + // addr:g1user, + // pkgpath:"" + // ) == std.NewUserRealm(g1user) + std.PreviousRealm() + + // Returns ( + // addr:g1user, + // pkgpath:"gno.land/r/g1user/run" + // ) == std.NewCodeRealm("gno.land/r/g1user/run") + std.CurrentRealm() +} +``` + +The same applies for p package initialization. Initialization and tests are the +only times that `std.CurrentRealm()` will return a p package path that starts +with "/p/" instead of "/r/". The package is technically still mutable during +initialization. + +#### Testing overrides with stdlibs/testing + +The `gnovm/tests/stdlibs/testing/context_testing.gno` file provides functions +for overriding frame details from Gno test code. + +`testing.SetRealm(std.NewUserRealm("g1user"))` is identical to +`testing.SetOriginCaller("g1user"). Both will override the Gno frame to make it +appear as if the current frame is the end user signing with a hardware signer. +Both will also set ExecContext.OriginCaller to that user. One of these will +become deprecated. + +#### Gno test cases with `_test.gno` like `TestFoo(t *testing.T)` + +```go +// PKGPATH: gno.land/r/user/myrealm +package myrealm + +import ( + "std" + "stdlibs/testing" +) + +func TestFoo(t *testing.T) { + // At first OriginCaller is not set. + + // Override the OriginCaller. + testing.SetRealm(std.NewUserRealm("g1user")) + + // Identical behavior: + testing.SetOriginCaller("g1user") + + // This panics now: seeking beyond the overridden origin frame: + // std.PreviousRealm() + + // Simulate g1user cross-calling Public(). + // Produce a new frame to override + func() { + testing.SetRealm(std.SetCodeRealm("gno.land/r/user/myrealm")) + + std.PreviousRealm() // "g1user", "" + std.CurrentRealm() // bech32(hash("gno.land/r/user/myrealm")), "gno.land/r/user/myrealm" + + Public(...) // already in "gno.land/r/user/myrealm" + }() + + // The following is identical to the above, + // but not possible in p packages which + // cannot import realms. + cross(Public)(...) +} +``` + +#### Gno filetest cases with `_filetest.gno` + +```go +// PKGPATH: gno.land/r/test/test +package test + +import ( + "std" + "stdlibs/testing" + + "gno.land/r/user/myrealm" +) + +func init() { + // XXX Frame not found, there is no deployer for filetests. + std.PreviousRealm() + + // Returns ( + // addr:std.DerivePkgAddr("gno.land/r/test/test") + // pkgpath:"gno.land/r/test/test" + // ) == std.NewCodeRealm("gno.land/r/test/test") + std.CurrentRealm() +} + +func main() { + // There is assumed to be in "frame -1" + // a crossing from UserRealm(g1user) to + // CodeRealm(gno.land/r/test/test) before + // main() is called, so crossing() here + // is redundant. + // crossing() + + // Returns ( + // addr:g1user, + // pkgpath:"" + // ) == std.NewUserRealm(g1user) + std.PreviousRealm() + + // Returns ( + // addr:g1user, + // pkgpath:"gno.land/r/test/test" + // ) == std.NewCodeRealm("gno.land/r/test/test") + std.CurrentRealm() + + // gno.land/r/test/test cross-calling + // gno.land/r/user/myrealm: + cross(myrealm.Public)(...) +} + +// Output: +// XXX +``` + +#### Future Work + +std.SetOriginCaller() should maybe be deprecated in favor of +std.SetRealm(std.NewUserRealm(user)) renamed to +std.SetRealm(std.NewOriginRealm(user)). + +std.SetRealm(std.NewCodeRealm(path)) renamed to +std.SetRealm(std.NewPackageRealm(path)). diff --git a/examples/gno.land/p/agherasie/forms/create.gno b/examples/gno.land/p/agherasie/forms/create.gno index f37c3ba24ad..a2efe8a92b1 100644 --- a/examples/gno.land/p/agherasie/forms/create.gno +++ b/examples/gno.land/p/agherasie/forms/create.gno @@ -64,7 +64,7 @@ func (db *FormDB) CreateForm(title string, description string, openAt string, cl // Creating the form form := Form{ ID: id, - Owner: std.PreviousRealm().Address(), + Owner: std.CurrentRealm().Address(), Title: title, Description: description, CreatedAt: time.Now(), diff --git a/examples/gno.land/p/agherasie/forms/create_test.gno b/examples/gno.land/p/agherasie/forms/create_test.gno index c27000e403c..07d2fe72815 100644 --- a/examples/gno.land/p/agherasie/forms/create_test.gno +++ b/examples/gno.land/p/agherasie/forms/create_test.gno @@ -11,7 +11,8 @@ import ( func TestCreateForm(t *testing.T) { alice := testutils.TestAddress("alice") testing.SetOriginCaller(alice) - testing.SetRealm(std.NewUserRealm("g1user")) + testing.SetRealm(std.NewUserRealm(alice)) + db := NewDB() title := "Simple Form" description := "This is a form" @@ -58,7 +59,7 @@ func TestCreateForm(t *testing.T) { } urequire.True(t, form.ID == id, "Form ID is not correct") - urequire.True(t, form.Owner == alice, "Owner is not correct") + urequire.Equal(t, form.Owner, alice, "Owner is not correct") urequire.True(t, form.Title == title, "Title is not correct") urequire.True(t, form.Description == description, "Description is not correct") urequire.True(t, len(form.Fields) == 5, "Not enough fields were provided") diff --git a/examples/gno.land/p/agherasie/forms/submit.gno b/examples/gno.land/p/agherasie/forms/submit.gno index 249fc8b335a..681b0df5d42 100644 --- a/examples/gno.land/p/agherasie/forms/submit.gno +++ b/examples/gno.land/p/agherasie/forms/submit.gno @@ -14,7 +14,7 @@ func (db *FormDB) SubmitForm(formID string, answers string) { } // Check if form was already submitted by this user - previousAnswer, err := db.GetAnswer(formID, std.PreviousRealm().Address()) + previousAnswer, err := db.GetAnswer(formID, std.CurrentRealm().Address()) if previousAnswer != nil { panic(errAlreadySubmitted) } @@ -33,7 +33,7 @@ func (db *FormDB) SubmitForm(formID string, answers string) { answer := Submission{ FormID: formID, Answers: answers, - Author: std.PreviousRealm().Address(), + Author: std.CurrentRealm().Address(), SubmittedAt: time.Now(), } db.Answers = append(db.Answers, &answer) diff --git a/examples/gno.land/p/demo/avl/z_0_filetest.gno b/examples/gno.land/p/demo/avl/z_0_filetest.gno index 385f7bf5c54..8ba55bb3a0e 100644 --- a/examples/gno.land/p/demo/avl/z_0_filetest.gno +++ b/examples/gno.land/p/demo/avl/z_0_filetest.gno @@ -13,6 +13,8 @@ func init() { } func main() { + crossing() + var updated bool node, updated = node.Set("key1", "value1") // println(node, updated) @@ -22,21 +24,23 @@ func main() { // Output: // false 2 + + // Realm: // finalizerealm["gno.land/r/test"] -// u[a8ada09dee16d791fd406d629fe29bb0ed084a30:4]= +// u[a8ada09dee16d791fd406d629fe29bb0ed084a30:7]= // @@ -1,8 +1,8 @@ // { // "ObjectInfo": { -// "ID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:4", +// "ID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:7", // - "ModTime": "0", -// - "OwnerID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:2", -// + "ModTime": "7", -// + "OwnerID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:7", +// - "OwnerID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:3", +// + "ModTime": "10", +// + "OwnerID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:10", // "RefCount": "1" // }, // "Value": { -// c[a8ada09dee16d791fd406d629fe29bb0ed084a30:9]={ +// c[a8ada09dee16d791fd406d629fe29bb0ed084a30:12]={ // "Fields": [ // { // "T": { @@ -91,17 +95,17 @@ func main() { // } // ], // "ObjectInfo": { -// "ID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:9", +// "ID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:12", // "ModTime": "0", -// "OwnerID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:8", +// "OwnerID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:11", // "RefCount": "1" // } // } -// c[a8ada09dee16d791fd406d629fe29bb0ed084a30:8]={ +// c[a8ada09dee16d791fd406d629fe29bb0ed084a30:11]={ // "ObjectInfo": { -// "ID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:8", +// "ID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:11", // "ModTime": "0", -// "OwnerID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:7", +// "OwnerID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:10", // "RefCount": "1" // }, // "Value": { @@ -111,12 +115,12 @@ func main() { // }, // "V": { // "@type": "/gno.RefValue", -// "Hash": "b28057ab7be6383785c0a5503e8a531bdbc21851", -// "ObjectID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:9" +// "Hash": "3288b3597947d02e04dfdc35f06b380f3c323ed5", +// "ObjectID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:12" // } // } // } -// c[a8ada09dee16d791fd406d629fe29bb0ed084a30:7]={ +// c[a8ada09dee16d791fd406d629fe29bb0ed084a30:10]={ // "Fields": [ // { // "T": { @@ -155,8 +159,8 @@ func main() { // "@type": "/gno.PointerValue", // "Base": { // "@type": "/gno.RefValue", -// "Hash": "6da365f0d6cacbcdf53cd5a4b125803cddce08c2", -// "ObjectID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:4" +// "Hash": "27689d532d3d0324ffa3fda9408ef11e3e12b2d9", +// "ObjectID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:7" // }, // "Index": "0", // "TV": null @@ -174,8 +178,8 @@ func main() { // "@type": "/gno.PointerValue", // "Base": { // "@type": "/gno.RefValue", -// "Hash": "f216afe7b5a17f4ebdbb98dceccedbc22e237596", -// "ObjectID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:8" +// "Hash": "149bdb243dd96ad31fd4f897d7dbe1fe932734c0", +// "ObjectID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:11" // }, // "Index": "0", // "TV": null @@ -183,17 +187,17 @@ func main() { // } // ], // "ObjectInfo": { -// "ID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:7", +// "ID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:10", // "ModTime": "0", -// "OwnerID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:6", +// "OwnerID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:9", // "RefCount": "1" // } // } -// c[a8ada09dee16d791fd406d629fe29bb0ed084a30:6]={ +// c[a8ada09dee16d791fd406d629fe29bb0ed084a30:9]={ // "ObjectInfo": { -// "ID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:6", +// "ID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:9", // "ModTime": "0", -// "OwnerID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:2", +// "OwnerID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:3", // "RefCount": "1" // }, // "Value": { @@ -203,29 +207,29 @@ func main() { // }, // "V": { // "@type": "/gno.RefValue", -// "Hash": "ff1a50d8489090af37a2c7766d659f0d717939b5", -// "ObjectID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:7" +// "Hash": "2a80953f4db02c933cfd1b5b9fed586c4695e845", +// "ObjectID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:10" // } // } // } -// u[a8ada09dee16d791fd406d629fe29bb0ed084a30:2]= -// @@ -3,7 +3,7 @@ +// u[a8ada09dee16d791fd406d629fe29bb0ed084a30:3]= +// @@ -1,7 +1,7 @@ +// { // "ObjectInfo": { -// "ID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:2", -// "IsEscaped": true, -// - "ModTime": "3", -// + "ModTime": "5", -// "RefCount": "2" +// "ID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:3", +// - "ModTime": "6", +// + "ModTime": "8", +// "OwnerID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:2", +// "RefCount": "1" // }, -// "Parent": null, -// @@ -30,8 +30,8 @@ -// "@type": "/gno.PointerValue", -// "Base": { -// "@type": "/gno.RefValue", -// - "Hash": "424b49c215f471979ccd718172a016e6ec9dd934", -// - "ObjectID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:4" -// + "Hash": "ae86874f9b47fa5e64c30b3e92e9d07f2ec967a4", -// + "ObjectID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:6" -// }, -// "Index": "0", -// "TV": null +// @@ -17,8 +17,8 @@ +// "@type": "/gno.PointerValue", +// "Base": { +// "@type": "/gno.RefValue", +// - "Hash": "276d9e20c54d77da7b8d9652d5e4c0102be192f7", +// - "ObjectID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:7" +// + "Hash": "7112df693d0606ff9f21eb56b5e21228f9fd0463", +// + "ObjectID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:9" +// }, +// "Index": "0", +// "TV": null diff --git a/examples/gno.land/p/demo/avl/z_1_filetest.gno b/examples/gno.land/p/demo/avl/z_1_filetest.gno index 512b13c135e..8139816de7c 100644 --- a/examples/gno.land/p/demo/avl/z_1_filetest.gno +++ b/examples/gno.land/p/demo/avl/z_1_filetest.gno @@ -13,6 +13,8 @@ func init() { } func main() { + crossing() + var updated bool node, updated = node.Set("key2", "value2") // println(node, updated) @@ -22,29 +24,31 @@ func main() { // Output: // false 3 + + // Realm: // finalizerealm["gno.land/r/test"] -// u[a8ada09dee16d791fd406d629fe29bb0ed084a30:6]= +// u[a8ada09dee16d791fd406d629fe29bb0ed084a30:9]= // @@ -1,7 +1,7 @@ // { // "ObjectInfo": { -// "ID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:6", +// "ID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:9", // - "ModTime": "0", -// + "ModTime": "11", -// "OwnerID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:5", +// + "ModTime": "14", +// "OwnerID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:8", // "RefCount": "1" // }, -// u[a8ada09dee16d791fd406d629fe29bb0ed084a30:8]= +// u[a8ada09dee16d791fd406d629fe29bb0ed084a30:11]= // @@ -1,7 +1,7 @@ // { // "ObjectInfo": { -// "ID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:8", +// "ID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:11", // - "ModTime": "0", -// + "ModTime": "13", -// "OwnerID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:5", +// + "ModTime": "16", +// "OwnerID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:8", // "RefCount": "1" // }, -// c[a8ada09dee16d791fd406d629fe29bb0ed084a30:15]={ +// c[a8ada09dee16d791fd406d629fe29bb0ed084a30:18]={ // "Fields": [ // { // "T": { @@ -99,17 +103,17 @@ func main() { // } // ], // "ObjectInfo": { -// "ID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:15", +// "ID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:18", // "ModTime": "0", -// "OwnerID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:14", +// "OwnerID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:17", // "RefCount": "1" // } // } -// c[a8ada09dee16d791fd406d629fe29bb0ed084a30:14]={ +// c[a8ada09dee16d791fd406d629fe29bb0ed084a30:17]={ // "ObjectInfo": { -// "ID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:14", +// "ID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:17", // "ModTime": "0", -// "OwnerID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:13", +// "OwnerID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:16", // "RefCount": "1" // }, // "Value": { @@ -119,12 +123,12 @@ func main() { // }, // "V": { // "@type": "/gno.RefValue", -// "Hash": "143aebc820da33550f7338723fb1e2eec575b196", -// "ObjectID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:15" +// "Hash": "27c82fe9c0e010bd7055e873dcc8e394963b7fd2", +// "ObjectID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:18" // } // } // } -// c[a8ada09dee16d791fd406d629fe29bb0ed084a30:13]={ +// c[a8ada09dee16d791fd406d629fe29bb0ed084a30:16]={ // "Fields": [ // { // "T": { @@ -163,8 +167,8 @@ func main() { // "@type": "/gno.PointerValue", // "Base": { // "@type": "/gno.RefValue", -// "Hash": "cafae89e4d4aaaefe7fdf0691084508d4274a981", -// "ObjectID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:8" +// "Hash": "6fedda0be1874c2ab889c6498ab942a5b4788635", +// "ObjectID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:11" // }, // "Index": "0", // "TV": null @@ -182,8 +186,8 @@ func main() { // "@type": "/gno.PointerValue", // "Base": { // "@type": "/gno.RefValue", -// "Hash": "2e733a8e9e74fe14f0a5d10fb0f6728fa53d052d", -// "ObjectID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:14" +// "Hash": "98954fd1c465552a4ba7dd00877348820d4dc0a2", +// "ObjectID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:17" // }, // "Index": "0", // "TV": null @@ -191,17 +195,17 @@ func main() { // } // ], // "ObjectInfo": { -// "ID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:13", +// "ID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:16", // "ModTime": "0", -// "OwnerID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:12", +// "OwnerID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:15", // "RefCount": "1" // } // } -// c[a8ada09dee16d791fd406d629fe29bb0ed084a30:12]={ +// c[a8ada09dee16d791fd406d629fe29bb0ed084a30:15]={ // "ObjectInfo": { -// "ID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:12", +// "ID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:15", // "ModTime": "0", -// "OwnerID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:11", +// "OwnerID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:14", // "RefCount": "1" // }, // "Value": { @@ -211,12 +215,12 @@ func main() { // }, // "V": { // "@type": "/gno.RefValue", -// "Hash": "b2e446f490656c19a83c43055de29c96e92a1549", -// "ObjectID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:13" +// "Hash": "7c93c5b0ba175d456548c4aa126490dec76fd9ea", +// "ObjectID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:16" // } // } // } -// c[a8ada09dee16d791fd406d629fe29bb0ed084a30:11]={ +// c[a8ada09dee16d791fd406d629fe29bb0ed084a30:14]={ // "Fields": [ // { // "T": { @@ -255,8 +259,8 @@ func main() { // "@type": "/gno.PointerValue", // "Base": { // "@type": "/gno.RefValue", -// "Hash": "4e56eeb96eb1d9b27cf603140cd03a1622b6358b", -// "ObjectID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:6" +// "Hash": "4bdce8127e004a4f9d332aeb5a78cfe8c6ca96b0", +// "ObjectID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:9" // }, // "Index": "0", // "TV": null @@ -274,8 +278,8 @@ func main() { // "@type": "/gno.PointerValue", // "Base": { // "@type": "/gno.RefValue", -// "Hash": "7b61530859954d1d14b2f696c91c5f37d39c21e7", -// "ObjectID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:12" +// "Hash": "6073f435fc15cdb2c58b42fa7d297b8c4d3543fa", +// "ObjectID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:15" // }, // "Index": "0", // "TV": null @@ -283,17 +287,17 @@ func main() { // } // ], // "ObjectInfo": { -// "ID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:11", +// "ID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:14", // "ModTime": "0", -// "OwnerID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:10", +// "OwnerID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:13", // "RefCount": "1" // } // } -// c[a8ada09dee16d791fd406d629fe29bb0ed084a30:10]={ +// c[a8ada09dee16d791fd406d629fe29bb0ed084a30:13]={ // "ObjectInfo": { -// "ID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:10", +// "ID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:13", // "ModTime": "0", -// "OwnerID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:2", +// "OwnerID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:3", // "RefCount": "1" // }, // "Value": { @@ -303,31 +307,31 @@ func main() { // }, // "V": { // "@type": "/gno.RefValue", -// "Hash": "fedc6d430b38c985dc6a985b2fcaee97e88ba6da", -// "ObjectID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:11" +// "Hash": "0eb69253ed71f09f5fa08ff9f2234f576f296b13", +// "ObjectID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:14" // } // } // } -// u[a8ada09dee16d791fd406d629fe29bb0ed084a30:2]= -// @@ -3,7 +3,7 @@ +// u[a8ada09dee16d791fd406d629fe29bb0ed084a30:3]= +// @@ -1,7 +1,7 @@ +// { // "ObjectInfo": { -// "ID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:2", -// "IsEscaped": true, -// - "ModTime": "3", -// + "ModTime": "9", -// "RefCount": "2" +// "ID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:3", +// - "ModTime": "6", +// + "ModTime": "12", +// "OwnerID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:2", +// "RefCount": "1" // }, -// "Parent": null, -// @@ -30,8 +30,8 @@ -// "@type": "/gno.PointerValue", -// "Base": { -// "@type": "/gno.RefValue", -// - "Hash": "213a2c56908ed00c6d21377f37be61a76102cd5f", -// - "ObjectID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:4" -// + "Hash": "515b45e4a6f5fa153a0251d7108781d86c52ce1c", -// + "ObjectID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:10" -// }, -// "Index": "0", -// "TV": null -// d[a8ada09dee16d791fd406d629fe29bb0ed084a30:4] -// d[a8ada09dee16d791fd406d629fe29bb0ed084a30:5] +// @@ -17,8 +17,8 @@ +// "@type": "/gno.PointerValue", +// "Base": { +// "@type": "/gno.RefValue", +// - "Hash": "b04c19a6409cd14ac64426556d8d883ee2b6a55d", +// - "ObjectID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:7" +// + "Hash": "d32ff23c6146ecf73934b20d0a0367ac558d87e4", +// + "ObjectID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:13" +// }, +// "Index": "0", +// "TV": null +// d[a8ada09dee16d791fd406d629fe29bb0ed084a30:7] +// d[a8ada09dee16d791fd406d629fe29bb0ed084a30:8] diff --git a/examples/gno.land/p/demo/avl/z_2_filetest.gno b/examples/gno.land/p/demo/avl/z_2_filetest.gno index 8cf534923f5..2887216f535 100644 --- a/examples/gno.land/p/demo/avl/z_2_filetest.gno +++ b/examples/gno.land/p/demo/avl/z_2_filetest.gno @@ -13,6 +13,8 @@ func init() { } func main() { + crossing() + var updated bool updated = tree.Set("key2", "value2") println(updated, tree.Size()) @@ -21,29 +23,31 @@ func main() { // Output: // false 3 + + // Realm: // finalizerealm["gno.land/r/test"] -// u[a8ada09dee16d791fd406d629fe29bb0ed084a30:7]= +// u[a8ada09dee16d791fd406d629fe29bb0ed084a30:10]= // @@ -1,7 +1,7 @@ // { // "ObjectInfo": { -// "ID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:7", +// "ID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:10", // - "ModTime": "0", -// + "ModTime": "12", -// "OwnerID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:6", +// + "ModTime": "15", +// "OwnerID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:9", // "RefCount": "1" // }, -// u[a8ada09dee16d791fd406d629fe29bb0ed084a30:9]= +// u[a8ada09dee16d791fd406d629fe29bb0ed084a30:12]= // @@ -1,7 +1,7 @@ // { // "ObjectInfo": { -// "ID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:9", +// "ID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:12", // - "ModTime": "0", -// + "ModTime": "14", -// "OwnerID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:6", +// + "ModTime": "17", +// "OwnerID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:9", // "RefCount": "1" // }, -// c[a8ada09dee16d791fd406d629fe29bb0ed084a30:16]={ +// c[a8ada09dee16d791fd406d629fe29bb0ed084a30:19]={ // "Fields": [ // { // "T": { @@ -98,17 +102,17 @@ func main() { // } // ], // "ObjectInfo": { -// "ID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:16", +// "ID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:19", // "ModTime": "0", -// "OwnerID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:15", +// "OwnerID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:18", // "RefCount": "1" // } // } -// c[a8ada09dee16d791fd406d629fe29bb0ed084a30:15]={ +// c[a8ada09dee16d791fd406d629fe29bb0ed084a30:18]={ // "ObjectInfo": { -// "ID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:15", +// "ID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:18", // "ModTime": "0", -// "OwnerID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:14", +// "OwnerID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:17", // "RefCount": "1" // }, // "Value": { @@ -118,12 +122,12 @@ func main() { // }, // "V": { // "@type": "/gno.RefValue", -// "Hash": "db333c89cd6773709e031f1f4e4ed4d3fed66c11", -// "ObjectID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:16" +// "Hash": "2423218f208c0869e37a0ea1656aba6a4306af11", +// "ObjectID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:19" // } // } // } -// c[a8ada09dee16d791fd406d629fe29bb0ed084a30:14]={ +// c[a8ada09dee16d791fd406d629fe29bb0ed084a30:17]={ // "Fields": [ // { // "T": { @@ -162,8 +166,8 @@ func main() { // "@type": "/gno.PointerValue", // "Base": { // "@type": "/gno.RefValue", -// "Hash": "db39c9c0a60e0d5b30dbaf9be6150d3fec16aa4b", -// "ObjectID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:9" +// "Hash": "781ea5027f658c0fdf0d8531a56765a76286762c", +// "ObjectID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:12" // }, // "Index": "0", // "TV": null @@ -181,8 +185,8 @@ func main() { // "@type": "/gno.PointerValue", // "Base": { // "@type": "/gno.RefValue", -// "Hash": "b4fc2fdd2d0fe936c87ed2ace97136cffeed207f", -// "ObjectID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:15" +// "Hash": "73578da89595fb1e3364ec9736600b4db8b58f50", +// "ObjectID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:18" // }, // "Index": "0", // "TV": null @@ -190,17 +194,17 @@ func main() { // } // ], // "ObjectInfo": { -// "ID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:14", +// "ID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:17", // "ModTime": "0", -// "OwnerID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:13", +// "OwnerID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:16", // "RefCount": "1" // } // } -// c[a8ada09dee16d791fd406d629fe29bb0ed084a30:13]={ +// c[a8ada09dee16d791fd406d629fe29bb0ed084a30:16]={ // "ObjectInfo": { -// "ID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:13", +// "ID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:16", // "ModTime": "0", -// "OwnerID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:12", +// "OwnerID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:15", // "RefCount": "1" // }, // "Value": { @@ -210,12 +214,12 @@ func main() { // }, // "V": { // "@type": "/gno.RefValue", -// "Hash": "2e9127534f91b385426d76e8e164f50f635cc1de", -// "ObjectID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:14" +// "Hash": "9513b1650cf70e769c535b95601499c833efb8b7", +// "ObjectID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:17" // } // } // } -// c[a8ada09dee16d791fd406d629fe29bb0ed084a30:12]={ +// c[a8ada09dee16d791fd406d629fe29bb0ed084a30:15]={ // "Fields": [ // { // "T": { @@ -254,8 +258,8 @@ func main() { // "@type": "/gno.PointerValue", // "Base": { // "@type": "/gno.RefValue", -// "Hash": "43e03b0c877b40c34e12bc2b15560e8ecd42ae9d", -// "ObjectID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:7" +// "Hash": "b091d6b6d709a2f269c09a2174dd355aa1c0f2a1", +// "ObjectID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:10" // }, // "Index": "0", // "TV": null @@ -273,8 +277,8 @@ func main() { // "@type": "/gno.PointerValue", // "Base": { // "@type": "/gno.RefValue", -// "Hash": "4b123e2424d900a427f9dee88a70ce61f3cdcf5b", -// "ObjectID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:13" +// "Hash": "ae8473c4faf712907e8fbfa022450cff478c198e", +// "ObjectID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:16" // }, // "Index": "0", // "TV": null @@ -282,17 +286,17 @@ func main() { // } // ], // "ObjectInfo": { -// "ID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:12", +// "ID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:15", // "ModTime": "0", -// "OwnerID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:11", +// "OwnerID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:14", // "RefCount": "1" // } // } -// c[a8ada09dee16d791fd406d629fe29bb0ed084a30:11]={ +// c[a8ada09dee16d791fd406d629fe29bb0ed084a30:14]={ // "ObjectInfo": { -// "ID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:11", +// "ID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:14", // "ModTime": "0", -// "OwnerID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:3", +// "OwnerID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:4", // "RefCount": "1" // }, // "Value": { @@ -302,31 +306,31 @@ func main() { // }, // "V": { // "@type": "/gno.RefValue", -// "Hash": "76d9227e755efd6674d8fa34e12decb7a9855488", -// "ObjectID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:12" +// "Hash": "03ea997daa854392fbf7f97fa31cf24c5c3efec9", +// "ObjectID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:15" // } // } // } -// u[a8ada09dee16d791fd406d629fe29bb0ed084a30:3]= +// u[a8ada09dee16d791fd406d629fe29bb0ed084a30:4]= // @@ -12,8 +12,8 @@ // "@type": "/gno.PointerValue", // "Base": { // "@type": "/gno.RefValue", -// - "Hash": "fbf007d972314fd7a2005d628c444b0831c16402", -// - "ObjectID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:5" -// + "Hash": "ff46b4dd63457c3fd59801e725f65af524ec829d", -// + "ObjectID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:11" +// - "Hash": "68396d329b22f15f22c1e39b39bcf06bdec5a04e", +// - "ObjectID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:8" +// + "Hash": "ee04a11aa85a194ee29e261499db321b12b833bd", +// + "ObjectID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:14" // }, // "Index": "0", // "TV": null // @@ -22,7 +22,7 @@ // ], // "ObjectInfo": { -// "ID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:3", -// - "ModTime": "4", -// + "ModTime": "10", -// "OwnerID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:2", +// "ID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:4", +// - "ModTime": "7", +// + "ModTime": "13", +// "OwnerID": "a8ada09dee16d791fd406d629fe29bb0ed084a30:3", // "RefCount": "1" // } -// d[a8ada09dee16d791fd406d629fe29bb0ed084a30:5] -// d[a8ada09dee16d791fd406d629fe29bb0ed084a30:6] +// d[a8ada09dee16d791fd406d629fe29bb0ed084a30:8] +// d[a8ada09dee16d791fd406d629fe29bb0ed084a30:9] diff --git a/examples/gno.land/p/demo/entropy/z_filetest.gno b/examples/gno.land/p/demo/entropy/z_filetest.gno index d855c8de4a5..04e98f7625d 100644 --- a/examples/gno.land/p/demo/entropy/z_filetest.gno +++ b/examples/gno.land/p/demo/entropy/z_filetest.gno @@ -40,23 +40,23 @@ func main() { // Output: // --- -// 4129293727 -// 2141104956 -// 1950222777 -// 3348280598 -// 438354259 -// 6353385488959065197 +// 2916840437 +// 3981870829 +// 1311573733 +// 2267403229 +// 484167125 +// 5277608318285564101 // --- -// 4129293727 -// 2141104956 -// 1950222777 -// 3348280598 -// 438354259 -// 6353385488959065197 +// 2916840437 +// 3981870829 +// 1311573733 +// 2267403229 +// 484167125 +// 5277608318285564101 // --- -// 49506731 -// 1539580078 -// 2695928529 -// 1895482388 -// 3462727799 -// 16745038698684748445 +// 3603434145 +// 911682639 +// 1320246589 +// 2861798763 +// 1938803929 +// 17792872788806539637 diff --git a/examples/gno.land/p/demo/grc/grc1155/basic_grc1155_token_test.gno b/examples/gno.land/p/demo/grc/grc1155/basic_grc1155_token_test.gno index 4092af72037..9267a67e42b 100644 --- a/examples/gno.land/p/demo/grc/grc1155/basic_grc1155_token_test.gno +++ b/examples/gno.land/p/demo/grc/grc1155/basic_grc1155_token_test.gno @@ -4,6 +4,7 @@ import ( "std" "testing" + "gno.land/p/demo/testutils" "gno.land/p/demo/uassert" ) @@ -88,6 +89,9 @@ func TestIsApprovedForAll(t *testing.T) { } func TestSetApprovalForAll(t *testing.T) { + //alice := testutils.TestAddress("alice") + //testing.SetOriginCaller(alice) + dummy := NewBasicGRC1155Token(dummyURI) uassert.True(t, dummy != nil, "should not be nil") @@ -111,6 +115,9 @@ func TestSetApprovalForAll(t *testing.T) { } func TestSafeTransferFrom(t *testing.T) { + alice := testutils.TestAddress("alice") + testing.SetOriginCaller(alice) + dummy := NewBasicGRC1155Token(dummyURI) uassert.True(t, dummy != nil, "should not be nil") @@ -142,6 +149,9 @@ func TestSafeTransferFrom(t *testing.T) { } func TestSafeBatchTransferFrom(t *testing.T) { + alice := testutils.TestAddress("alice") + testing.SetOriginCaller(alice) + dummy := NewBasicGRC1155Token(dummyURI) uassert.True(t, dummy != nil, "should not be nil") diff --git a/examples/gno.land/p/demo/grc/grc20/tellers.gno b/examples/gno.land/p/demo/grc/grc20/tellers.gno index 733d10148e3..9ec5bbe2d42 100644 --- a/examples/gno.land/p/demo/grc/grc20/tellers.gno +++ b/examples/gno.land/p/demo/grc/grc20/tellers.gno @@ -14,7 +14,7 @@ func (tok *Token) CallerTeller() Teller { return &fnTeller{ accountFn: func() std.Address { - caller := std.PreviousRealm().Address() + caller := std.CurrentRealm().Address() return caller }, Token: tok, @@ -44,7 +44,7 @@ func (tok *Token) RealmTeller() Teller { panic("Token cannot be nil") } - caller := std.PreviousRealm().Address() + caller := std.CurrentRealm().Address() return &fnTeller{ accountFn: func() std.Address { @@ -61,7 +61,7 @@ func (tok *Token) RealmSubTeller(slug string) Teller { panic("Token cannot be nil") } - caller := std.PreviousRealm().Address() + caller := std.CurrentRealm().Address() account := accountSlugAddr(caller, slug) return &fnTeller{ diff --git a/examples/gno.land/p/demo/grc/grc20/tellers_test.gno b/examples/gno.land/p/demo/grc/grc20/tellers_test.gno index 83ff7f3cdfe..08acba99952 100644 --- a/examples/gno.land/p/demo/grc/grc20/tellers_test.gno +++ b/examples/gno.land/p/demo/grc/grc20/tellers_test.gno @@ -1,6 +1,7 @@ package grc20 import ( + "std" "testing" "gno.land/p/demo/testutils" @@ -114,12 +115,12 @@ func TestCallerTeller(t *testing.T) { checkBalances(1000, 0, 0) checkAllowances(0, 0, 0, 0, 0, 0) - testing.SetOriginCaller(alice) + testing.SetRealm(std.NewUserRealm(alice)) urequire.NoError(t, teller.Approve(bob, 600)) checkBalances(1000, 0, 0) checkAllowances(600, 0, 0, 0, 0, 0) - testing.SetOriginCaller(bob) + testing.SetRealm(std.NewUserRealm(bob)) urequire.Error(t, teller.TransferFrom(alice, carl, 700)) checkBalances(1000, 0, 0) checkAllowances(600, 0, 0, 0, 0, 0) diff --git a/examples/gno.land/p/demo/grc/grc721/basic_nft.gno b/examples/gno.land/p/demo/grc/grc721/basic_nft.gno index b5f7b21c9bb..63ec56c09c4 100644 --- a/examples/gno.land/p/demo/grc/grc721/basic_nft.gno +++ b/examples/gno.land/p/demo/grc/grc721/basic_nft.gno @@ -81,7 +81,7 @@ func (s *basicNFT) SetTokenURI(tid TokenID, tURI TokenURI) (bool, error) { if err != nil { return false, err } - caller := std.PreviousRealm().Address() + caller := std.CurrentRealm().Address() if caller != owner { return false, ErrCallerIsNotOwner } @@ -115,7 +115,7 @@ func (s *basicNFT) Approve(to std.Address, tid TokenID) error { return ErrApprovalToCurrentOwner } - caller := std.PreviousRealm().Address() + caller := std.CurrentRealm().Address() if caller != owner && !s.IsApprovedForAll(owner, caller) { return ErrCallerIsNotOwnerOrApproved } @@ -147,7 +147,7 @@ func (s *basicNFT) SetApprovalForAll(operator std.Address, approved bool) error return ErrInvalidAddress } - caller := std.PreviousRealm().Address() + caller := std.CurrentRealm().Address() return s.setApprovalForAll(caller, operator, approved) } @@ -155,7 +155,7 @@ func (s *basicNFT) SetApprovalForAll(operator std.Address, approved bool) error // contract recipients are aware of the GRC721 protocol to prevent // tokens from being forever locked. func (s *basicNFT) SafeTransferFrom(from, to std.Address, tid TokenID) error { - caller := std.PreviousRealm().Address() + caller := std.CurrentRealm().Address() if !s.isApprovedOrOwner(caller, tid) { return ErrCallerIsNotOwnerOrApproved } @@ -174,7 +174,7 @@ func (s *basicNFT) SafeTransferFrom(from, to std.Address, tid TokenID) error { // Transfers `tokenId` token from `from` to `to`. func (s *basicNFT) TransferFrom(from, to std.Address, tid TokenID) error { - caller := std.PreviousRealm().Address() + caller := std.CurrentRealm().Address() if !s.isApprovedOrOwner(caller, tid) { return ErrCallerIsNotOwnerOrApproved } diff --git a/examples/gno.land/p/demo/grc/grc721/basic_nft_test.gno b/examples/gno.land/p/demo/grc/grc721/basic_nft_test.gno index a416a243a2e..8af8e1a0585 100644 --- a/examples/gno.land/p/demo/grc/grc721/basic_nft_test.gno +++ b/examples/gno.land/p/demo/grc/grc721/basic_nft_test.gno @@ -112,7 +112,7 @@ func TestSetApprovalForAll(t *testing.T) { dummy := NewBasicNFT(dummyNFTName, dummyNFTSymbol) uassert.True(t, dummy != nil, "should not be nil") - caller := std.PreviousRealm().Address() + caller := std.CurrentRealm().Address() addr := std.Address("g1var589z07ppjsjd24ukm4uguzwdt0tw7g47cgm") // Test setting approval to true @@ -142,15 +142,19 @@ func TestGetApproved(t *testing.T) { } func TestApprove(t *testing.T) { + alice := testutils.TestAddress("alice") + testing.SetOriginCaller(alice) + dummy := NewBasicNFT(dummyNFTName, dummyNFTSymbol) uassert.True(t, dummy != nil, "should not be nil") - caller := std.PreviousRealm().Address() + caller := std.CurrentRealm().Address() addr := std.Address("g1var589z07ppjsjd24ukm4uguzwdt0tw7g47cgm") - dummy.mint(caller, TokenID("1")) + err := dummy.mint(caller, TokenID("1")) + uassert.NoError(t, err, "failed to mint") - _, err := dummy.GetApproved(TokenID("1")) + _, err = dummy.GetApproved(TokenID("1")) uassert.Error(t, err, "should result in error") err = dummy.Approve(addr, TokenID("1")) @@ -162,10 +166,13 @@ func TestApprove(t *testing.T) { } func TestTransferFrom(t *testing.T) { + alice := testutils.TestAddress("alice") + testing.SetOriginCaller(alice) + dummy := NewBasicNFT(dummyNFTName, dummyNFTSymbol) uassert.True(t, dummy != nil, "should not be nil") - caller := std.PreviousRealm().Address() + caller := std.CurrentRealm().Address() addr := std.Address("g1var589z07ppjsjd24ukm4uguzwdt0tw7g47cgm") dummy.mint(caller, TokenID("1")) @@ -191,10 +198,13 @@ func TestTransferFrom(t *testing.T) { } func TestSafeTransferFrom(t *testing.T) { + alice := testutils.TestAddress("alice") + testing.SetOriginCaller(alice) + dummy := NewBasicNFT(dummyNFTName, dummyNFTSymbol) uassert.True(t, dummy != nil, "should not be nil") - caller := std.PreviousRealm().Address() + caller := std.CurrentRealm().Address() addr := std.Address("g1var589z07ppjsjd24ukm4uguzwdt0tw7g47cgm") dummy.mint(caller, TokenID("1")) diff --git a/examples/gno.land/p/demo/grc/grc721/grc721_royalty.gno b/examples/gno.land/p/demo/grc/grc721/grc721_royalty.gno index df13ae76d20..4e9891613df 100644 --- a/examples/gno.land/p/demo/grc/grc721/grc721_royalty.gno +++ b/examples/gno.land/p/demo/grc/grc721/grc721_royalty.gno @@ -45,7 +45,7 @@ func (r *royaltyNFT) SetTokenRoyalty(tid TokenID, royaltyInfo RoyaltyInfo) error if err != nil { return err } - caller := std.PreviousRealm().Address() + caller := std.CurrentRealm().Address() if caller != owner { return ErrCallerIsNotOwner } diff --git a/examples/gno.land/p/demo/memeland/memeland.gno b/examples/gno.land/p/demo/memeland/memeland.gno index ec3ae82e3e6..e18a3c22cb5 100644 --- a/examples/gno.land/p/demo/memeland/memeland.gno +++ b/examples/gno.land/p/demo/memeland/memeland.gno @@ -50,7 +50,7 @@ func (m *Memeland) PostMeme(data string, timestamp int64) string { newPost := &Post{ ID: id, Data: data, - Author: std.PreviousRealm().Address(), + Author: std.CurrentRealm().Address(), Timestamp: time.Unix(timestamp, 0), UpvoteTracker: avl.NewTree(), } @@ -65,7 +65,7 @@ func (m *Memeland) Upvote(id string) string { panic("post with specified ID does not exist") } - caller := std.PreviousRealm().Address().String() + caller := std.CurrentRealm().Address().String() if _, exists := post.UpvoteTracker.Get(caller); exists { panic("user has already upvoted this post") @@ -160,7 +160,7 @@ func (m *Memeland) RemovePost(id string) string { panic("id cannot be empty") } - if !m.OwnedByPrevious() { + if !m.OwnedByCurrent() { panic(ownable.ErrUnauthorized) } diff --git a/examples/gno.land/p/demo/memeland/memeland_test.gno b/examples/gno.land/p/demo/memeland/memeland_test.gno index e19db872c36..b9ca4188de5 100644 --- a/examples/gno.land/p/demo/memeland/memeland_test.gno +++ b/examples/gno.land/p/demo/memeland/memeland_test.gno @@ -1,6 +1,7 @@ package memeland import ( + "std" "strings" "testing" "time" @@ -122,7 +123,7 @@ func TestGetPostsInRangeByUpvote(t *testing.T) { // Change caller so avoid double upvote panic alice := testutils.TestAddress("alice") - testing.SetOriginCaller(alice) + testing.SetRealm(std.NewUserRealm(alice)) m.Upvote(id1) // Final upvote count: @@ -236,21 +237,21 @@ func TestUpvote(t *testing.T) { func TestDelete(t *testing.T) { alice := testutils.TestAddress("alice") - testing.SetOriginCaller(alice) + testing.SetRealm(std.NewUserRealm(alice)) // Alice is admin m := NewMemeland() // Set caller to Bob bob := testutils.TestAddress("bob") - testing.SetOriginCaller(bob) + testing.SetRealm(std.NewUserRealm(bob)) // Bob adds post to Memeland now := time.Now() postID := m.PostMeme("Meme #1", now.Unix()) // Alice removes Bob's post - testing.SetOriginCaller(alice) + testing.SetRealm(std.NewUserRealm(alice)) id := m.RemovePost(postID) uassert.Equal(t, postID, id, "post IDs not matching") @@ -259,7 +260,7 @@ func TestDelete(t *testing.T) { func TestDeleteByNonAdmin(t *testing.T) { alice := testutils.TestAddress("alice") - testing.SetOriginCaller(alice) + testing.SetRealm(std.NewUserRealm(alice)) m := NewMemeland() @@ -269,7 +270,7 @@ func TestDeleteByNonAdmin(t *testing.T) { // Bob will try to delete meme posted by Alice, which should fail bob := testutils.TestAddress("bob") - testing.SetOriginCaller(bob) + testing.SetRealm(std.NewUserRealm(bob)) defer func() { if r := recover(); r == nil { diff --git a/examples/gno.land/p/demo/ownable/exts/authorizable/authorizable.gno b/examples/gno.land/p/demo/ownable/exts/authorizable/authorizable.gno index 98c6e306dbf..96a6a15f38b 100644 --- a/examples/gno.land/p/demo/ownable/exts/authorizable/authorizable.gno +++ b/examples/gno.land/p/demo/ownable/exts/authorizable/authorizable.gno @@ -29,6 +29,17 @@ func NewAuthorizable() *Authorizable { return a } +func NewAuthorizableWithOrigin() *Authorizable { + a := &Authorizable{ + ownable.NewWithOrigin(), + avl.NewTree(), + } + + // Add owner to auth list + a.authorized.Set(a.Owner().String(), struct{}{}) + return a +} + func NewAuthorizableWithAddress(addr std.Address) *Authorizable { a := &Authorizable{ ownable.NewWithAddress(addr), @@ -41,7 +52,7 @@ func NewAuthorizableWithAddress(addr std.Address) *Authorizable { } func (a *Authorizable) AddToAuthList(addr std.Address) error { - if !a.OwnedByPrevious() { + if !a.OwnedByCurrent() { return ErrNotSuperuser } @@ -55,7 +66,7 @@ func (a *Authorizable) AddToAuthList(addr std.Address) error { } func (a *Authorizable) DeleteFromAuthList(addr std.Address) error { - if !a.OwnedByPrevious() { + if !a.OwnedByCurrent() { return ErrNotSuperuser } @@ -72,7 +83,7 @@ func (a *Authorizable) DeleteFromAuthList(addr std.Address) error { } func (a Authorizable) CallerOnAuthList() error { - caller := std.PreviousRealm().Address() + caller := std.CurrentRealm().Address() if !a.authorized.Has(caller.String()) { return ErrNotInAuthList @@ -82,7 +93,7 @@ func (a Authorizable) CallerOnAuthList() error { } func (a Authorizable) AssertOnAuthList() { - caller := std.PreviousRealm().Address() + caller := std.CurrentRealm().Address() if !a.authorized.Has(caller.String()) { panic(ErrNotInAuthList) diff --git a/examples/gno.land/p/demo/ownable/exts/authorizable/authorizable_test.gno b/examples/gno.land/p/demo/ownable/exts/authorizable/authorizable_test.gno index c479e37f3df..169488d0857 100644 --- a/examples/gno.land/p/demo/ownable/exts/authorizable/authorizable_test.gno +++ b/examples/gno.land/p/demo/ownable/exts/authorizable/authorizable_test.gno @@ -1,6 +1,7 @@ package authorizable import ( + "std" "testing" "gno.land/p/demo/testutils" @@ -14,7 +15,7 @@ var ( ) func TestNewAuthorizable(t *testing.T) { - testing.SetOriginCaller(alice) + testing.SetRealm(std.NewUserRealm(alice)) a := NewAuthorizable() got := a.Owner() @@ -36,7 +37,7 @@ func TestNewAuthorizableWithAddress(t *testing.T) { func TestCallerOnAuthList(t *testing.T) { a := NewAuthorizableWithAddress(alice) - testing.SetOriginCaller(alice) + testing.SetRealm(std.NewUserRealm(alice)) if err := a.CallerOnAuthList(); err == ErrNotInAuthList { t.Fatalf("expected alice to be on the list") @@ -45,7 +46,7 @@ func TestCallerOnAuthList(t *testing.T) { func TestNotCallerOnAuthList(t *testing.T) { a := NewAuthorizableWithAddress(alice) - testing.SetOriginCaller(bob) + testing.SetRealm(std.NewUserRealm(bob)) if err := a.CallerOnAuthList(); err == nil { t.Fatalf("expected bob to not be on the list") @@ -54,13 +55,13 @@ func TestNotCallerOnAuthList(t *testing.T) { func TestAddToAuthList(t *testing.T) { a := NewAuthorizableWithAddress(alice) - testing.SetOriginCaller(alice) + testing.SetRealm(std.NewUserRealm(alice)) if err := a.AddToAuthList(bob); err != nil { t.Fatalf("Expected no error, got %v", err) } - testing.SetOriginCaller(bob) + testing.SetRealm(std.NewUserRealm(bob)) if err := a.AddToAuthList(bob); err == nil { t.Fatalf("Expected AddToAuth to error while bob called it, but it didn't") @@ -69,7 +70,7 @@ func TestAddToAuthList(t *testing.T) { func TestDeleteFromList(t *testing.T) { a := NewAuthorizableWithAddress(alice) - testing.SetOriginCaller(alice) + testing.SetRealm(std.NewUserRealm(alice)) if err := a.AddToAuthList(bob); err != nil { t.Fatalf("Expected no error, got %v", err) @@ -79,14 +80,14 @@ func TestDeleteFromList(t *testing.T) { t.Fatalf("Expected no error, got %v", err) } - testing.SetOriginCaller(bob) + testing.SetRealm(std.NewUserRealm(bob)) // Try an unauthorized deletion if err := a.DeleteFromAuthList(alice); err == nil { t.Fatalf("Expected DelFromAuth to error with %v", err) } - testing.SetOriginCaller(alice) + testing.SetRealm(std.NewUserRealm(alice)) if err := a.DeleteFromAuthList(charlie); err != nil { t.Fatalf("Expected no error, got %v", err) @@ -94,11 +95,11 @@ func TestDeleteFromList(t *testing.T) { } func TestAssertOnList(t *testing.T) { - testing.SetOriginCaller(alice) + testing.SetRealm(std.NewUserRealm(alice)) a := NewAuthorizableWithAddress(alice) - testing.SetOriginCaller(bob) + testing.SetRealm(std.NewUserRealm(bob)) uassert.PanicsWithMessage(t, ErrNotInAuthList.Error(), func() { a.AssertOnAuthList() diff --git a/examples/gno.land/p/demo/ownable/ownable.gno b/examples/gno.land/p/demo/ownable/ownable.gno index c8de82be88a..3fdc6edaa81 100644 --- a/examples/gno.land/p/demo/ownable/ownable.gno +++ b/examples/gno.land/p/demo/ownable/ownable.gno @@ -1,6 +1,8 @@ package ownable -import "std" +import ( + "std" +) const OwnershipTransferEvent = "OwnershipTransfer" @@ -17,6 +19,17 @@ func New() *Ownable { } } +func NewWithOrigin() *Ownable { + origin := std.OriginCaller() + previous := std.PreviousRealm() + if origin != previous.Address() { + panic("NewWithOrigin() should be called from init() where std.PreviousRealm() is origin") + } + return &Ownable{ + owner: origin, + } +} + func NewWithAddress(addr std.Address) *Ownable { return &Ownable{ owner: addr, @@ -25,7 +38,7 @@ func NewWithAddress(addr std.Address) *Ownable { // TransferOwnership transfers ownership of the Ownable struct to a new address func (o *Ownable) TransferOwnership(newOwner std.Address) error { - if !o.OwnedByPrevious() { + if !o.OwnedByCurrent() { return ErrUnauthorized } @@ -48,7 +61,7 @@ func (o *Ownable) TransferOwnership(newOwner std.Address) error { // Top-level usage: disables all only-owner actions/functions, // Embedded usage: behaves like a burn functionality, removing the owner from the struct func (o *Ownable) DropOwnership() error { - if !o.OwnedByPrevious() { + if !o.OwnedByCurrent() { return ErrUnauthorized } @@ -72,21 +85,32 @@ func (o *Ownable) Owner() std.Address { return o.owner } -// OwnedByPrevious( checks if the caller of the function is the Realm's owner -func (o *Ownable) OwnedByPrevious() bool { +// OwnedByCurrent checks if the caller of the function is the Realm's owner +func (o *Ownable) OwnedByCurrent() bool { if o == nil { return false } return std.CurrentRealm().Address() == o.owner } -// AssertOwnedByPrevious panics if the caller is not the owner -func (o *Ownable) AssertOwnedByPrevious() { - if o == nil { +// AssertOwnedByCurrent panics if the caller is not the owner +func (o *Ownable) AssertOwnedByCurrent() { + if !o.OwnedByCurrent() { panic(ErrUnauthorized) } - caller := std.CurrentRealm().Address() - if caller != o.owner { +} + +// OwnedByPrevious checks if the caller of the function is the Realm's owner +func (o *Ownable) OwnedByPrevious() bool { + if o == nil { + return false + } + return std.PreviousRealm().Address() == o.owner +} + +// AssertOwnedByPrevious panics if the caller is not the owner +func (o *Ownable) AssertOwnedByPrevious() { + if !o.OwnedByPrevious() { panic(ErrUnauthorized) } } diff --git a/examples/gno.land/p/demo/ownable/ownable_test.gno b/examples/gno.land/p/demo/ownable/ownable_test.gno index f37ae4f41fd..2b68c2a9a3d 100644 --- a/examples/gno.land/p/demo/ownable/ownable_test.gno +++ b/examples/gno.land/p/demo/ownable/ownable_test.gno @@ -15,11 +15,35 @@ var ( ) func TestNew(t *testing.T) { - testing.SetOriginCaller(alice) + testing.SetRealm(std.NewCodeRealm("gno.land/r/test/test")) + current := std.CurrentRealm().Address() o := New() got := o.Owner() - uassert.Equal(t, got, alice) + uassert.Equal(t, got, current) +} + +func TestNewWithOriginPanic(t *testing.T) { + testing.SetOriginCaller(alice) + testing.SetRealm(std.NewUserRealm(alice)) + + uassert.PanicsWithMessage(t, "frame not found: cannot seek beyond origin caller override", func() { + NewWithOrigin() + }) +} + +func TestNewWithOrigin(t *testing.T) { + testing.SetOriginCaller(alice) + testing.SetRealm(std.NewUserRealm(alice)) + + func() { + // This is the only way to test crosses from a p package for now. + testing.SetRealm(std.NewCodeRealm("gno.land/r/test/test")) + + o := NewWithOrigin() + got := o.Owner() + uassert.Equal(t, got, alice) + }() } func TestNewWithAddress(t *testing.T) { @@ -30,27 +54,86 @@ func TestNewWithAddress(t *testing.T) { } func TestTransferOwnership(t *testing.T) { - testing.SetOriginCaller(alice) + testing.SetRealm(std.NewUserRealm(alice)) o := New() - err := o.TransferOwnership(bob) urequire.NoError(t, err) - got := o.Owner() - uassert.Equal(t, got, bob) } -func TestOwnedByPrevious(t *testing.T) { +func TestTransferOwnershipUnauthorized(t *testing.T) { + testing.SetOriginCaller(alice) + testing.SetRealm(std.NewUserRealm(alice)) + + var o *Ownable + func() { + testing.SetRealm(std.NewCodeRealm("gno.land/r/test/test")) + + o = NewWithOrigin() + + // current is gno.land/r/test/test so of course errors. + uassert.ErrorContains(t, o.TransferOwnership(bob), ErrUnauthorized.Error()) + uassert.ErrorContains(t, o.DropOwnership(), ErrUnauthorized.Error()) + }() + + // Set realm to an unauthorized user bob. + testing.SetRealm(std.NewUserRealm(bob)) + + uassert.ErrorContains(t, o.TransferOwnership(alice), ErrUnauthorized.Error()) + uassert.ErrorContains(t, o.DropOwnership(), ErrUnauthorized.Error()) + + // Reset realm to alice. + testing.SetRealm(std.NewUserRealm(alice)) + uassert.NoError(t, o.TransferOwnership(alice)) + uassert.NoError(t, o.DropOwnership()) +} + +func TestOwnedByCurrent(t *testing.T) { testing.SetRealm(std.NewUserRealm(alice)) o := New() + uassert.True(t, o.OwnedByCurrent()) +} + +func TestOwnedByCurrentUnauthorized(t *testing.T) { + testing.SetOriginCaller(alice) + testing.SetRealm(std.NewUserRealm(alice)) + + var o *Ownable + func() { + testing.SetRealm(std.NewCodeRealm("gno.land/r/test/test")) + o = NewWithOrigin() + }() + + uassert.True(t, o.OwnedByCurrent()) + unauthorizedCaller := bob + testing.SetRealm(std.NewUserRealm(unauthorizedCaller)) + uassert.False(t, o.OwnedByCurrent()) +} - testing.SetOriginCaller(unauthorizedCaller) +func TestOwnedByPrevious(t *testing.T) { + testing.SetRealm(std.NewUserRealm(alice)) - uassert.False(t, o.OwnedByPrevious()) + o := New() + func() { + testing.SetRealm(std.NewCodeRealm("gno.land/r/test/test")) + uassert.True(t, o.OwnedByPrevious()) + }() +} + +func TestOwnedByPreviousUnauthorized(t *testing.T) { + testing.SetRealm(std.NewUserRealm(alice)) + + o := New() + unauthorizedCaller := bob + testing.SetRealm(std.NewUserRealm(unauthorizedCaller)) + func() { + testing.SetRealm(std.NewCodeRealm("gno.land/r/test/test")) + uassert.False(t, o.OwnedByPrevious()) + }() } func TestDropOwnership(t *testing.T) { @@ -67,19 +150,8 @@ func TestDropOwnership(t *testing.T) { // Errors -func TestErrUnauthorized(t *testing.T) { - testing.SetOriginCaller(alice) - - o := New() - - testing.SetOriginCaller(bob) - - uassert.ErrorContains(t, o.TransferOwnership(alice), ErrUnauthorized.Error()) - uassert.ErrorContains(t, o.DropOwnership(), ErrUnauthorized.Error()) -} - func TestErrInvalidAddress(t *testing.T) { - testing.SetOriginCaller(alice) + testing.SetRealm(std.NewCodeRealm("gno.land/r/test/test")) o := New() @@ -90,29 +162,38 @@ func TestErrInvalidAddress(t *testing.T) { uassert.ErrorContains(t, err, ErrInvalidAddress.Error()) } -func TestAssertOwnedByPrevious(t *testing.T) { +func TestAssertOwnedByCurrent(t *testing.T) { testing.SetRealm(std.NewUserRealm(alice)) - testing.SetOriginCaller(alice) o := New() // Should not panic when caller is owner - o.AssertOwnedByPrevious() + o.AssertOwnedByCurrent() // Should panic when caller is not owner testing.SetRealm(std.NewUserRealm(bob)) - testing.SetOriginCaller(bob) + uassert.PanicsWithMessage(t, ErrUnauthorized.Error(), func() { + o.AssertOwnedByCurrent() + }) +} - defer func() { - r := recover() - if r == nil { - t.Error("expected panic but got none") - } - if r != ErrUnauthorized { - t.Errorf("expected ErrUnauthorized but got %v", r) - } +func TestAssertOwnedByPrevious(t *testing.T) { + testing.SetRealm(std.NewUserRealm(alice)) + + o := New() + + func() { + testing.SetRealm(std.NewCodeRealm("gno.land/r/test/test")) + + // Should not panic when previous is owner + o.AssertOwnedByPrevious() + + // Should panic when previous is not owner + testing.SetRealm(std.NewUserRealm(bob)) + uassert.PanicsWithMessage(t, ErrUnauthorized.Error(), func() { + o.AssertOwnedByCurrent() + }) }() - o.AssertOwnedByPrevious() } func TestNilReceiver(t *testing.T) { diff --git a/examples/gno.land/p/demo/pausable/pausable.gno b/examples/gno.land/p/demo/pausable/pausable.gno index 28fc294b0f2..38f129c0f15 100644 --- a/examples/gno.land/p/demo/pausable/pausable.gno +++ b/examples/gno.land/p/demo/pausable/pausable.gno @@ -32,7 +32,7 @@ func (p Pausable) IsPaused() bool { // Pause sets the state of Pausable to true, meaning all pausable functions are paused func (p *Pausable) Pause() error { - if !p.o.OwnedByPrevious() { + if !p.o.OwnedByCurrent() { return ownable.ErrUnauthorized } @@ -44,7 +44,7 @@ func (p *Pausable) Pause() error { // Unpause sets the state of Pausable to false, meaning all pausable functions are resumed func (p *Pausable) Unpause() error { - if !p.o.OwnedByPrevious() { + if !p.o.OwnedByCurrent() { return ownable.ErrUnauthorized } diff --git a/examples/gno.land/p/demo/subscription/lifetime/lifetime.gno b/examples/gno.land/p/demo/subscription/lifetime/lifetime.gno index beddc833069..e15a6cd9cbd 100644 --- a/examples/gno.land/p/demo/subscription/lifetime/lifetime.gno +++ b/examples/gno.land/p/demo/subscription/lifetime/lifetime.gno @@ -45,7 +45,7 @@ func (ls *LifetimeSubscription) processSubscription(receiver std.Address) error // Subscribe processes the payment for a lifetime subscription. func (ls *LifetimeSubscription) Subscribe() error { - caller := std.PreviousRealm().Address() + caller := std.CurrentRealm().Address() return ls.processSubscription(caller) } @@ -67,7 +67,7 @@ func (ls *LifetimeSubscription) HasValidSubscription(addr std.Address) error { // UpdateAmount allows the owner of the LifetimeSubscription contract to update the subscription price. func (ls *LifetimeSubscription) UpdateAmount(newAmount int64) error { - if !ls.OwnedByPrevious() { + if !ls.OwnedByCurrent() { return ErrNotAuthorized } diff --git a/examples/gno.land/p/demo/subscription/lifetime/lifetime_test.gno b/examples/gno.land/p/demo/subscription/lifetime/lifetime_test.gno index 8a3e046119d..ac4fe6ecfd0 100644 --- a/examples/gno.land/p/demo/subscription/lifetime/lifetime_test.gno +++ b/examples/gno.land/p/demo/subscription/lifetime/lifetime_test.gno @@ -22,7 +22,7 @@ func TestLifetimeSubscription(t *testing.T) { err := ls.Subscribe() uassert.NoError(t, err, "Expected ProcessPayment to succeed") - err = ls.HasValidSubscription(std.PreviousRealm().Address()) + err = ls.HasValidSubscription(std.CurrentRealm().Address()) uassert.NoError(t, err, "Expected Alice to have access") } @@ -42,20 +42,20 @@ func TestLifetimeSubscriptionGift(t *testing.T) { } func TestUpdateAmountAuthorization(t *testing.T) { - testing.SetOriginCaller(alice) + testing.SetRealm(std.NewUserRealm(alice)) ls := NewLifetimeSubscription(1000) err := ls.UpdateAmount(2000) uassert.NoError(t, err, "Expected Alice to succeed in updating amount") - testing.SetOriginCaller(bob) + testing.SetRealm(std.NewUserRealm(bob)) err = ls.UpdateAmount(3000) uassert.Error(t, err, "Expected Bob to fail when updating amount") } func TestIncorrectPaymentAmount(t *testing.T) { - testing.SetOriginCaller(alice) + testing.SetRealm(std.NewUserRealm(alice)) ls := NewLifetimeSubscription(1000) testing.SetOriginSend([]std.Coin{{Denom: "ugnot", Amount: 500}}) @@ -64,7 +64,7 @@ func TestIncorrectPaymentAmount(t *testing.T) { } func TestMultipleSubscriptionAttempts(t *testing.T) { - testing.SetOriginCaller(alice) + testing.SetRealm(std.NewUserRealm(alice)) ls := NewLifetimeSubscription(1000) testing.SetOriginSend([]std.Coin{{Denom: "ugnot", Amount: 1000}}) @@ -77,7 +77,7 @@ func TestMultipleSubscriptionAttempts(t *testing.T) { } func TestGiftSubscriptionWithIncorrectAmount(t *testing.T) { - testing.SetOriginCaller(alice) + testing.SetRealm(std.NewUserRealm(alice)) ls := NewLifetimeSubscription(1000) testing.SetOriginSend([]std.Coin{{Denom: "ugnot", Amount: 500}}) @@ -89,7 +89,7 @@ func TestGiftSubscriptionWithIncorrectAmount(t *testing.T) { } func TestUpdateAmountEffectiveness(t *testing.T) { - testing.SetOriginCaller(alice) + testing.SetRealm(std.NewUserRealm(alice)) ls := NewLifetimeSubscription(1000) err := ls.UpdateAmount(2000) diff --git a/examples/gno.land/p/demo/subscription/recurring/recurring.gno b/examples/gno.land/p/demo/subscription/recurring/recurring.gno index c8c34a0d0ee..01c7fe913ed 100644 --- a/examples/gno.land/p/demo/subscription/recurring/recurring.gno +++ b/examples/gno.land/p/demo/subscription/recurring/recurring.gno @@ -68,7 +68,7 @@ func (rs *RecurringSubscription) processSubscription(receiver std.Address) error // Subscribe handles the payment for the caller's subscription. func (rs *RecurringSubscription) Subscribe() error { - caller := std.PreviousRealm().Address() + caller := std.CurrentRealm().Address() return rs.processSubscription(caller) } @@ -90,7 +90,7 @@ func (rs *RecurringSubscription) GetExpiration(addr std.Address) (time.Time, err // UpdateAmount allows the owner of the subscription contract to change the required subscription amount. func (rs *RecurringSubscription) UpdateAmount(newAmount int64) error { - if !rs.OwnedByPrevious() { + if !rs.OwnedByCurrent() { return ErrNotAuthorized } diff --git a/examples/gno.land/p/demo/subscription/recurring/recurring_test.gno b/examples/gno.land/p/demo/subscription/recurring/recurring_test.gno index 46df972c6c6..0185fcf94fb 100644 --- a/examples/gno.land/p/demo/subscription/recurring/recurring_test.gno +++ b/examples/gno.land/p/demo/subscription/recurring/recurring_test.gno @@ -23,10 +23,10 @@ func TestRecurringSubscription(t *testing.T) { err := rs.Subscribe() uassert.NoError(t, err, "Expected ProcessPayment to succeed for Alice") - err = rs.HasValidSubscription(std.PreviousRealm().Address()) + err = rs.HasValidSubscription(std.CurrentRealm().Address()) uassert.NoError(t, err, "Expected Alice to have access") - _, err = rs.GetExpiration(std.PreviousRealm().Address()) + _, err = rs.GetExpiration(std.CurrentRealm().Address()) uassert.NoError(t, err, "Expected to get expiration for Alice") } @@ -53,30 +53,30 @@ func TestRecurringSubscriptionExpiration(t *testing.T) { err := rs.Subscribe() uassert.NoError(t, err, "Expected ProcessPayment to succeed for Alice") - err = rs.HasValidSubscription(std.PreviousRealm().Address()) + err = rs.HasValidSubscription(std.CurrentRealm().Address()) uassert.NoError(t, err, "Expected Alice to have access") expiration := time.Now().Add(-time.Hour * 2) - rs.subs.Set(std.PreviousRealm().Address().String(), expiration) + rs.subs.Set(std.CurrentRealm().Address().String(), expiration) - err = rs.HasValidSubscription(std.PreviousRealm().Address()) + err = rs.HasValidSubscription(std.CurrentRealm().Address()) uassert.Error(t, err, "Expected Alice's subscription to be expired") } func TestUpdateAmountAuthorization(t *testing.T) { - testing.SetOriginCaller(alice) + testing.SetRealm(std.NewUserRealm(alice)) rs := NewRecurringSubscription(time.Hour*24, 1000) err := rs.UpdateAmount(2000) uassert.NoError(t, err, "Expected Alice to succeed in updating amount") - testing.SetOriginCaller(bob) + testing.SetRealm(std.NewUserRealm(bob)) err = rs.UpdateAmount(3000) uassert.Error(t, err, "Expected Bob to fail when updating amount") } func TestGetAmount(t *testing.T) { - testing.SetOriginCaller(alice) + testing.SetRealm(std.NewUserRealm(alice)) rs := NewRecurringSubscription(time.Hour*24, 1000) amount := rs.GetAmount() @@ -91,6 +91,7 @@ func TestGetAmount(t *testing.T) { func TestIncorrectPaymentAmount(t *testing.T) { testing.SetOriginCaller(alice) + testing.SetRealm(std.NewUserRealm(alice)) rs := NewRecurringSubscription(time.Hour*24, 1000) testing.SetOriginSend([]std.Coin{{Denom: "ugnot", Amount: 500}}) @@ -100,6 +101,7 @@ func TestIncorrectPaymentAmount(t *testing.T) { func TestMultiplePaymentsForSameUser(t *testing.T) { testing.SetOriginCaller(alice) + testing.SetRealm(std.NewUserRealm(alice)) rs := NewRecurringSubscription(time.Hour*24, 1000) testing.SetOriginSend([]std.Coin{{Denom: "ugnot", Amount: 1000}}) @@ -113,22 +115,23 @@ func TestMultiplePaymentsForSameUser(t *testing.T) { func TestRecurringSubscriptionWithMultiplePayments(t *testing.T) { testing.SetOriginCaller(alice) + testing.SetRealm(std.NewUserRealm(alice)) rs := NewRecurringSubscription(time.Hour, 1000) testing.SetOriginSend([]std.Coin{{Denom: "ugnot", Amount: 1000}}) err := rs.Subscribe() uassert.NoError(t, err, "Expected first ProcessPayment to succeed for Alice") - err = rs.HasValidSubscription(std.PreviousRealm().Address()) + err = rs.HasValidSubscription(std.CurrentRealm().Address()) uassert.NoError(t, err, "Expected Alice to have access after first payment") expiration := time.Now().Add(-time.Hour * 2) - rs.subs.Set(std.PreviousRealm().Address().String(), expiration) + rs.subs.Set(std.CurrentRealm().Address().String(), expiration) testing.SetOriginSend([]std.Coin{{Denom: "ugnot", Amount: 1000}}) err = rs.Subscribe() uassert.NoError(t, err, "Expected second ProcessPayment to succeed for Alice") - err = rs.HasValidSubscription(std.PreviousRealm().Address()) + err = rs.HasValidSubscription(std.CurrentRealm().Address()) uassert.NoError(t, err, "Expected Alice to have access after second payment") } diff --git a/examples/gno.land/p/demo/tests/p_crossrealm/p_crossrealm.gno b/examples/gno.land/p/demo/tests/p_crossrealm/p_crossrealm.gno index 6d46203e98c..bfe6e68dd0f 100644 --- a/examples/gno.land/p/demo/tests/p_crossrealm/p_crossrealm.gno +++ b/examples/gno.land/p/demo/tests/p_crossrealm/p_crossrealm.gno @@ -1,5 +1,7 @@ package p_crossrealm +import "std" + type Stringer interface { String() string } @@ -22,3 +24,7 @@ func (c *Container) Print() { println("B:", c.B.String()) } } + +func CurrentRealm() std.Realm { + return std.CurrentRealm() +} diff --git a/examples/gno.land/p/moul/authz/authz.gno b/examples/gno.land/p/moul/authz/authz.gno index 7f2b9759f41..267e70b65e3 100644 --- a/examples/gno.land/p/moul/authz/authz.gno +++ b/examples/gno.land/p/moul/authz/authz.gno @@ -69,7 +69,7 @@ type PrivilegedActionHandler func(title string, action PrivilegedAction) error // New creates a new Authorizer with the current realm's address as authority func New() *Authorizer { return &Authorizer{ - current: NewMemberAuthority(std.PreviousRealm().Address()), + current: NewMemberAuthority(std.CurrentRealm().Address()), } } @@ -118,7 +118,7 @@ func NewMemberAuthority(members ...std.Address) *MemberAuthority { } func (a *MemberAuthority) Authorize(title string, action PrivilegedAction, args ...any) error { - caller := std.PreviousRealm().Address() + caller := std.CurrentRealm().Address() if !a.members.Has(caller) { return errors.New("unauthorized") } @@ -222,7 +222,7 @@ func (a *ContractAuthority) Authorize(title string, action PrivilegedAction, arg // Wrap the action to ensure it can only be executed by the contract wrappedAction := func() error { - caller := std.PreviousRealm().Address() + caller := std.CurrentRealm().Address() if caller != a.contractAddr { return errors.New("action can only be executed by the contract") } diff --git a/examples/gno.land/p/moul/debug/debug_test.gno b/examples/gno.land/p/moul/debug/debug_test.gno index 02ce5f7c9c5..6e7050fbfa5 100644 --- a/examples/gno.land/p/moul/debug/debug_test.gno +++ b/examples/gno.land/p/moul/debug/debug_test.gno @@ -11,10 +11,16 @@ import ( func TestPackage(t *testing.T) { testing.SetRealm(std.NewUserRealm("g1user")) + testPackage(t) +} + +func testPackage(t *testing.T) { + testing.SetRealm(std.NewCodeRealm("gno.land/r/test/test")) + // no debug got := Render("") expected := `` - uassert.Equal(t, got, expected) + uassert.Equal(t, expected, got) // debug without logs got = Render("?debug=1") @@ -23,10 +29,10 @@ func TestPackage(t *testing.T) { ### Metadata | Key | Value | | --- | --- | -| ±std.CurrentRealm().PkgPath()± | | -| ±std.CurrentRealm().Address()± | g1wymu47drhr0kuq2098m792lytgtj2nyx77yrsm | +| ±std.CurrentRealm().PkgPath()± | gno.land/r/test/test | +| ±std.CurrentRealm().Address()± | g1z7fga7u94pdmamlvcrtvsfwxgsye0qv3rres7n | | ±std.PreviousRealm().PkgPath()± | | -| ±std.PreviousRealm().Address()± | g1wymu47drhr0kuq2098m792lytgtj2nyx77yrsm | +| ±std.PreviousRealm().Address()± | g1user | | ±std.ChainHeight()± | 123 | | ±time.Now().Format(time.RFC3339)± | 2009-02-13T23:31:30Z | @@ -40,9 +46,7 @@ func TestPackage(t *testing.T) { println(expected) println("###################") - uassert.Equal(t, got, expected) - - return + uassert.Equal(t, expected, got) // debug with logs var d Debug @@ -50,20 +54,20 @@ func TestPackage(t *testing.T) { d.Log("foobar") got = d.Render("?debug=1") expected = `
debug - + ### Logs - hello world! - foobar ### Metadata | Key | Value | | --- | --- | -| ±std.CurrentRealm().PkgPath()± | | -| ±std.CurrentRealm().Address()± | g1wymu47drhr0kuq2098m792lytgtj2nyx77yrsm | +| ±std.CurrentRealm().PkgPath()± | gno.land/r/test/test | +| ±std.CurrentRealm().Address()± | g1z7fga7u94pdmamlvcrtvsfwxgsye0qv3rres7n | | ±std.PreviousRealm().PkgPath()± | | -| ±std.PreviousRealm().Address()± | g1wymu47drhr0kuq2098m792lytgtj2nyx77yrsm | +| ±std.PreviousRealm().Address()± | g1user | | ±std.ChainHeight()± | 123 | | ±time.Now().Format(time.RFC3339)± | 2009-02-13T23:31:30Z | - +
` expected = strings.ReplaceAll(expected, "±", "`") diff --git a/examples/gno.land/p/moul/helplink/helplink_test.gno b/examples/gno.land/p/moul/helplink/helplink_test.gno index 741bcf41112..f99f0eabbc6 100644 --- a/examples/gno.land/p/moul/helplink/helplink_test.gno +++ b/examples/gno.land/p/moul/helplink/helplink_test.gno @@ -16,11 +16,11 @@ func TestFunc(t *testing.T) { want string realm Realm }{ - {"Example", "foo", []string{"bar", "1", "baz", "2"}, "[Example]($help&func=foo&bar=1&baz=2)", ""}, + {"Example", "foo", []string{"bar", "1", "baz", "2"}, "[Example](/p/moul/helplink$help&func=foo&bar=1&baz=2)", ""}, {"Realm Example", "foo", []string{"bar", "1", "baz", "2"}, "[Realm Example](/r/lorem/ipsum$help&func=foo&bar=1&baz=2)", Realm(cd + "/r/lorem/ipsum")}, - {"Single Arg", "testFunc", []string{"key", "value"}, "[Single Arg]($help&func=testFunc&key=value)", ""}, - {"No Args", "noArgsFunc", []string{}, "[No Args]($help&func=noArgsFunc)", ""}, - {"Odd Args", "oddArgsFunc", []string{"key"}, "[Odd Args]($help&func=oddArgsFunc&error=odd+number+of+arguments)", ""}, + {"Single Arg", "testFunc", []string{"key", "value"}, "[Single Arg](/p/moul/helplink$help&func=testFunc&key=value)", ""}, + {"No Args", "noArgsFunc", []string{}, "[No Args](/p/moul/helplink$help&func=noArgsFunc)", ""}, + {"Odd Args", "oddArgsFunc", []string{"key"}, "[Odd Args](/p/moul/helplink$help&func=oddArgsFunc&error=odd+number+of+arguments)", ""}, } for _, tt := range tests { @@ -50,10 +50,10 @@ func TestFuncURL(t *testing.T) { want string realm Realm }{ - {"foo", []string{"bar", "1", "baz", "2"}, "$help&func=foo&bar=1&baz=2", ""}, - {"testFunc", []string{"key", "value"}, "$help&func=testFunc&key=value", ""}, - {"noArgsFunc", []string{}, "$help&func=noArgsFunc", ""}, - {"oddArgsFunc", []string{"key"}, "$help&func=oddArgsFunc&error=odd+number+of+arguments", ""}, + {"foo", []string{"bar", "1", "baz", "2"}, "/p/moul/helplink$help&func=foo&bar=1&baz=2", ""}, + {"testFunc", []string{"key", "value"}, "/p/moul/helplink$help&func=testFunc&key=value", ""}, + {"noArgsFunc", []string{}, "/p/moul/helplink$help&func=noArgsFunc", ""}, + {"oddArgsFunc", []string{"key"}, "/p/moul/helplink$help&func=oddArgsFunc&error=odd+number+of+arguments", ""}, {"foo", []string{"bar", "1", "baz", "2"}, "/r/lorem/ipsum$help&func=foo&bar=1&baz=2", Realm(cd + "/r/lorem/ipsum")}, {"testFunc", []string{"key", "value"}, "/r/lorem/ipsum$help&func=testFunc&key=value", Realm(cd + "/r/lorem/ipsum")}, {"noArgsFunc", []string{}, "/r/lorem/ipsum$help&func=noArgsFunc", Realm(cd + "/r/lorem/ipsum")}, diff --git a/examples/gno.land/p/moul/md/z1_filetest.gno b/examples/gno.land/p/moul/md/z1_filetest.gno index 5ee5592d89b..0cdb7021325 100644 --- a/examples/gno.land/p/moul/md/z1_filetest.gno +++ b/examples/gno.land/p/moul/md/z1_filetest.gno @@ -174,4 +174,3 @@ func main() { // ||| // // -// diff --git a/examples/gno.land/p/moul/txlink/txlink_test.gno b/examples/gno.land/p/moul/txlink/txlink_test.gno index b85cecaacc8..6ab464ae554 100644 --- a/examples/gno.land/p/moul/txlink/txlink_test.gno +++ b/examples/gno.land/p/moul/txlink/txlink_test.gno @@ -16,10 +16,10 @@ func TestCall(t *testing.T) { want string realm Realm }{ - {"foo", []string{"bar", "1", "baz", "2"}, "$help&func=foo&bar=1&baz=2", ""}, - {"testFunc", []string{"key", "value"}, "$help&func=testFunc&key=value", ""}, - {"noArgsFunc", []string{}, "$help&func=noArgsFunc", ""}, - {"oddArgsFunc", []string{"key"}, "$help&func=oddArgsFunc&error=odd+number+of+arguments", ""}, + {"foo", []string{"bar", "1", "baz", "2"}, "/p/moul/txlink$help&func=foo&bar=1&baz=2", ""}, + {"testFunc", []string{"key", "value"}, "/p/moul/txlink$help&func=testFunc&key=value", ""}, + {"noArgsFunc", []string{}, "/p/moul/txlink$help&func=noArgsFunc", ""}, + {"oddArgsFunc", []string{"key"}, "/p/moul/txlink$help&func=oddArgsFunc&error=odd+number+of+arguments", ""}, {"foo", []string{"bar", "1", "baz", "2"}, "/r/lorem/ipsum$help&func=foo&bar=1&baz=2", Realm(cd + "/r/lorem/ipsum")}, {"testFunc", []string{"key", "value"}, "/r/lorem/ipsum$help&func=testFunc&key=value", Realm(cd + "/r/lorem/ipsum")}, {"noArgsFunc", []string{}, "/r/lorem/ipsum$help&func=noArgsFunc", Realm(cd + "/r/lorem/ipsum")}, @@ -28,10 +28,10 @@ func TestCall(t *testing.T) { {"testFunc", []string{"key", "value"}, "https://gno.world/r/lorem/ipsum$help&func=testFunc&key=value", "gno.world/r/lorem/ipsum"}, {"noArgsFunc", []string{}, "https://gno.world/r/lorem/ipsum$help&func=noArgsFunc", "gno.world/r/lorem/ipsum"}, {"oddArgsFunc", []string{"key"}, "https://gno.world/r/lorem/ipsum$help&func=oddArgsFunc&error=odd+number+of+arguments", "gno.world/r/lorem/ipsum"}, - {"test", []string{"key", "hello world"}, "$help&func=test&key=hello+world", ""}, - {"test", []string{"key", "a&b=c"}, "$help&func=test&key=a%26b%3Dc", ""}, - {"test", []string{"key", ""}, "$help&func=test&key=", ""}, - {"testSend", []string{"key", "hello world", ".send", "1000000ugnot"}, "$help&func=testSend&.send=1000000ugnot&key=hello+world", ""}, + {"test", []string{"key", "hello world"}, "/p/moul/txlink$help&func=test&key=hello+world", ""}, + {"test", []string{"key", "a&b=c"}, "/p/moul/txlink$help&func=test&key=a%26b%3Dc", ""}, + {"test", []string{"key", ""}, "/p/moul/txlink$help&func=test&key=", ""}, + {"testSend", []string{"key", "hello world", ".send", "1000000ugnot"}, "/p/moul/txlink$help&func=testSend&.send=1000000ugnot&key=hello+world", ""}, } for _, tt := range tests { @@ -73,7 +73,7 @@ func TestBuilder(t *testing.T) { build: func() string { return NewLink("MyFunc").URL() }, - expected: "$help&func=MyFunc", + expected: "/p/moul/txlink$help&func=MyFunc", }, // Realm tests @@ -105,7 +105,7 @@ func TestBuilder(t *testing.T) { AddArgs("key", "value"). URL() }, - expected: "$help&func=func&key=value", + expected: "/p/moul/txlink$help&func=func&key=value", }, // URL encoding tests @@ -116,7 +116,7 @@ func TestBuilder(t *testing.T) { AddArgs("key", "hello world"). URL() }, - expected: "$help&func=test&key=hello+world", + expected: "/p/moul/txlink$help&func=test&key=hello+world", }, { name: "url_encoding_with_special_chars", @@ -125,7 +125,7 @@ func TestBuilder(t *testing.T) { AddArgs("key", "a&b=c"). URL() }, - expected: "$help&func=test&key=a%26b%3Dc", + expected: "/p/moul/txlink$help&func=test&key=a%26b%3Dc", }, { name: "url_encoding_with_unicode", @@ -134,7 +134,7 @@ func TestBuilder(t *testing.T) { AddArgs("key", "🌟"). URL() }, - expected: "$help&func=func&key=%F0%9F%8C%9F", + expected: "/p/moul/txlink$help&func=func&key=%F0%9F%8C%9F", }, { name: "url_encoding_with_special_chars_in_key", @@ -143,7 +143,7 @@ func TestBuilder(t *testing.T) { AddArgs("my/key", "value"). URL() }, - expected: "$help&func=func&my%2Fkey=value", + expected: "/p/moul/txlink$help&func=func&my%2Fkey=value", }, // AddArgs tests @@ -154,7 +154,7 @@ func TestBuilder(t *testing.T) { AddArgs("key1", "value1", "key2", "value2"). URL() }, - expected: "$help&func=MyFunc&key1=value1&key2=value2", + expected: "/p/moul/txlink$help&func=MyFunc&key1=value1&key2=value2", }, { name: "addargs_with_odd_number_of_args", @@ -183,7 +183,7 @@ func TestBuilder(t *testing.T) { AddArgs("", "value"). URL() }, - expected: "$help&func=func", + expected: "/p/moul/txlink$help&func=func", }, { name: "empty_value_should_be_kept", @@ -192,7 +192,7 @@ func TestBuilder(t *testing.T) { AddArgs("key", ""). URL() }, - expected: "$help&func=func&key=", + expected: "/p/moul/txlink$help&func=func&key=", }, // Send tests @@ -204,7 +204,7 @@ func TestBuilder(t *testing.T) { SetSend("1000000ugnot"). URL() }, - expected: "$help&func=MyFunc&.send=1000000ugnot&key=value", + expected: "/p/moul/txlink$help&func=MyFunc&.send=1000000ugnot&key=value", }, { name: "send_via_addarg_method_panic", @@ -231,7 +231,7 @@ func TestBuilder(t *testing.T) { SetSend("2000000ugnot"). URL() }, - expected: "$help&func=MyFunc&.send=2000000ugnot", + expected: "/p/moul/txlink$help&func=MyFunc&.send=2000000ugnot", }, } diff --git a/examples/gno.land/p/n2p5/loci/loci.gno b/examples/gno.land/p/n2p5/loci/loci.gno index a50c537a8f4..b0849b3ece4 100644 --- a/examples/gno.land/p/n2p5/loci/loci.gno +++ b/examples/gno.land/p/n2p5/loci/loci.gno @@ -25,10 +25,10 @@ func New() *LociStore { } } -// Set stores a byte slice in the AVL tree using the `std.PreviousRealm().Address()` +// Set stores a byte slice in the AVL tree using the `std.CurrentRealm().Address()` // string as the key. func (s *LociStore) Set(value []byte) { - key := string(std.PreviousRealm().Address()) + key := string(std.CurrentRealm().Address()) s.internal.Set(key, value) } diff --git a/examples/gno.land/p/n2p5/loci/loci_test.gno b/examples/gno.land/p/n2p5/loci/loci_test.gno index a99ca37a507..3e96ed4d425 100644 --- a/examples/gno.land/p/n2p5/loci/loci_test.gno +++ b/examples/gno.land/p/n2p5/loci/loci_test.gno @@ -1,14 +1,13 @@ package loci import ( - "std" "testing" "gno.land/p/demo/testutils" ) func TestLociStore(t *testing.T) { - testing.SetRealm(std.NewCodeRealm("gno.land/r/test/test")) + //testing.SetRealm(std.NewCodeRealm("gno.land/r/test/test")) t.Run("TestSet", func(t *testing.T) { t.Parallel() diff --git a/examples/gno.land/p/n2p5/mgroup/mgroup.gno b/examples/gno.land/p/n2p5/mgroup/mgroup.gno index 13256e5dbd4..ceb61ebb891 100644 --- a/examples/gno.land/p/n2p5/mgroup/mgroup.gno +++ b/examples/gno.land/p/n2p5/mgroup/mgroup.gno @@ -36,17 +36,27 @@ func New(ownerAddress std.Address) *ManagedGroup { backupOwners: avl.NewTree(), members: avl.NewTree(), } - g.AddBackupOwner(ownerAddress) - g.AddMember(ownerAddress) + err := g.addBackupOwner(ownerAddress) + if err != nil { + panic(err) + } + err = g.addMember(ownerAddress) + if err != nil { + panic(err) + } return g } // AddBackupOwner adds a backup owner to the group by std.Address. // If the caller is not the owner, an error is returned. func (g *ManagedGroup) AddBackupOwner(addr std.Address) error { - if !g.owner.OwnedByPrevious() { + if !g.owner.OwnedByCurrent() { return ownable.ErrUnauthorized } + return g.addBackupOwner(addr) +} + +func (g *ManagedGroup) addBackupOwner(addr std.Address) error { if !addr.IsValid() { return ErrInvalidAddress } @@ -57,7 +67,7 @@ func (g *ManagedGroup) AddBackupOwner(addr std.Address) error { // RemoveBackupOwner removes a backup owner from the group by std.Address. // The owner cannot be removed. If the caller is not the owner, an error is returned. func (g *ManagedGroup) RemoveBackupOwner(addr std.Address) error { - if !g.owner.OwnedByPrevious() { + if !g.owner.OwnedByCurrent() { return ownable.ErrUnauthorized } if !addr.IsValid() { @@ -74,7 +84,7 @@ func (g *ManagedGroup) RemoveBackupOwner(addr std.Address) error { // If the caller is not a backup owner, an error is returned. // The caller is automatically added as a member of the group. func (g *ManagedGroup) ClaimOwnership() error { - caller := std.PreviousRealm().Address() + caller := std.CurrentRealm().Address() // already owner, skip if caller == g.Owner() { return nil @@ -83,16 +93,20 @@ func (g *ManagedGroup) ClaimOwnership() error { return ErrNotMember } g.owner = ownable.NewWithAddress(caller) - g.AddMember(caller) - return nil + err := g.addMember(caller) + return err } // AddMember adds a member to the group by std.Address. // If the caller is not the owner, an error is returned. func (g *ManagedGroup) AddMember(addr std.Address) error { - if !g.owner.OwnedByPrevious() { + if !g.owner.OwnedByCurrent() { return ownable.ErrUnauthorized } + return g.addMember(addr) +} + +func (g *ManagedGroup) addMember(addr std.Address) error { if !addr.IsValid() { return ErrInvalidAddress } @@ -104,7 +118,7 @@ func (g *ManagedGroup) AddMember(addr std.Address) error { // The owner cannot be removed. If the caller is not the owner, // an error is returned. func (g *ManagedGroup) RemoveMember(addr std.Address) error { - if !g.owner.OwnedByPrevious() { + if !g.owner.OwnedByCurrent() { return ownable.ErrUnauthorized } if !addr.IsValid() { diff --git a/examples/gno.land/p/n2p5/mgroup/mgroup_test.gno b/examples/gno.land/p/n2p5/mgroup/mgroup_test.gno index e59a08ecffa..53283631325 100644 --- a/examples/gno.land/p/n2p5/mgroup/mgroup_test.gno +++ b/examples/gno.land/p/n2p5/mgroup/mgroup_test.gno @@ -7,6 +7,7 @@ import ( "gno.land/p/demo/avl" "gno.land/p/demo/ownable" "gno.land/p/demo/testutils" + "gno.land/p/demo/uassert" ) func TestManagedGroup(t *testing.T) { @@ -93,7 +94,14 @@ func TestManagedGroup(t *testing.T) { t.Run("ClaimOwnership", func(t *testing.T) { t.Parallel() g := New(u1) - g.AddBackupOwner(u2) + // add backup owner + { + testing.SetOriginCaller(u1) + err := g.AddBackupOwner(u2) + if err != nil { + t.Errorf("expected nil, got %v", err.Error()) + } + } // happy path { testing.SetOriginCaller(u2) @@ -132,9 +140,7 @@ func TestManagedGroup(t *testing.T) { { testing.SetOriginCaller(u1) err := g.AddMember(u2) - if err != nil { - t.Errorf("expected nil, got %v", err.Error()) - } + uassert.NoError(t, err) if !g.IsMember(u2) { t.Errorf("expected %v to be a member", u2) } @@ -143,18 +149,14 @@ func TestManagedGroup(t *testing.T) { { testing.SetOriginCaller(u2) err := g.AddMember(u3) - if err != ownable.ErrUnauthorized { - t.Errorf("expected %v, got %v", ownable.ErrUnauthorized.Error(), err.Error()) - } + uassert.ErrorIs(t, err, ownable.ErrUnauthorized) } // ensure invalid address is caught { testing.SetOriginCaller(u1) var badAddr std.Address err := g.AddMember(badAddr) - if err != ErrInvalidAddress { - t.Errorf("expected %v, got %v", ErrInvalidAddress.Error(), err.Error()) - } + uassert.ErrorContains(t, err, "address is invalid") } }) t.Run("RemoveMember", func(t *testing.T) { @@ -163,8 +165,9 @@ func TestManagedGroup(t *testing.T) { // happy path { testing.SetOriginCaller(u1) - g.AddMember(u2) - err := g.RemoveMember(u2) + err := g.AddMember(u2) + uassert.NoError(t, err) + err = g.RemoveMember(u2) if err != nil { t.Errorf("expected nil, got %v", err.Error()) } @@ -209,51 +212,44 @@ func TestManagedGroup(t *testing.T) { t.Run("MemberCount", func(t *testing.T) { t.Parallel() g := New(u1) - if g.MemberCount() != 1 { - t.Errorf("expected 0, got %v", g.MemberCount()) - } - g.AddMember(u2) - if g.MemberCount() != 2 { - t.Errorf("expected 1, got %v", g.MemberCount()) - } - g.AddMember(u3) - if g.MemberCount() != 3 { - t.Errorf("expected 2, got %v", g.MemberCount()) - } + testing.SetOriginCaller(u1) + + uassert.Equal(t, 1, g.MemberCount()) + err := g.AddMember(u2) + uassert.NoError(t, err) + uassert.Equal(t, 2, g.MemberCount()) + err = g.AddMember(u3) + uassert.NoError(t, err) + uassert.Equal(t, 3, g.MemberCount()) g.RemoveMember(u2) - if g.MemberCount() != 2 { - t.Errorf("expected 1, got %v", g.MemberCount()) - } + uassert.Equal(t, 2, g.MemberCount()) }) t.Run("BackupOwnerCount", func(t *testing.T) { t.Parallel() g := New(u1) - if g.BackupOwnerCount() != 1 { - t.Errorf("expected 0, got %v", g.BackupOwnerCount()) - } + testing.SetOriginCaller(u1) + + uassert.Equal(t, 1, g.BackupOwnerCount()) g.AddBackupOwner(u2) - if g.BackupOwnerCount() != 2 { - t.Errorf("expected 1, got %v", g.BackupOwnerCount()) - } + uassert.Equal(t, 2, g.BackupOwnerCount()) g.AddBackupOwner(u3) - if g.BackupOwnerCount() != 3 { - t.Errorf("expected 2, got %v", g.BackupOwnerCount()) - } + uassert.Equal(t, 3, g.BackupOwnerCount()) g.RemoveBackupOwner(u2) - if g.BackupOwnerCount() != 2 { - t.Errorf("expected 1, got %v", g.BackupOwnerCount()) - } + uassert.Equal(t, 2, g.BackupOwnerCount()) }) t.Run("IsMember", func(t *testing.T) { t.Parallel() g := New(u1) + testing.SetOriginCaller(u1) + if !g.IsMember(u1) { t.Errorf("expected %v to be a member", u1) } if g.IsMember(u2) { t.Errorf("expected %v to not be a member", u2) } - g.AddMember(u2) + err := g.AddMember(u2) + uassert.NoError(t, err) if !g.IsMember(u2) { t.Errorf("expected %v to be a member", u2) } @@ -261,6 +257,8 @@ func TestManagedGroup(t *testing.T) { t.Run("IsBackupOwner", func(t *testing.T) { t.Parallel() g := New(u1) + testing.SetOriginCaller(u1) + if !g.IsBackupOwner(u1) { t.Errorf("expected %v to be a backup owner", u1) } @@ -275,6 +273,8 @@ func TestManagedGroup(t *testing.T) { t.Run("Owner", func(t *testing.T) { t.Parallel() g := New(u1) + testing.SetOriginCaller(u1) + if g.Owner() != u1 { t.Errorf("expected %v, got %v", u1, g.Owner()) } @@ -312,8 +312,10 @@ func TestManagedGroup(t *testing.T) { t.Parallel() testing.SetOriginCaller(u1) g := New(u1) - g.AddMember(u2) - g.AddMember(u3) + err := g.AddMember(u2) + uassert.NoError(t, err) + err = g.AddMember(u3) + uassert.NoError(t, err) members := g.Members() if len(members) != 3 { t.Errorf("expected 2, got %v", len(members)) diff --git a/examples/gno.land/p/oxtekgrinder/ownable2step/ownable.gno b/examples/gno.land/p/oxtekgrinder/ownable2step/ownable.gno index 54fd6b821f6..8aca5fe004f 100644 --- a/examples/gno.land/p/oxtekgrinder/ownable2step/ownable.gno +++ b/examples/gno.land/p/oxtekgrinder/ownable2step/ownable.gno @@ -8,6 +8,7 @@ const OwnershipTransferEvent = "OwnershipTransfer" // Ownable2Step is a two-step ownership transfer package // It allows the current owner to set a new owner and the new owner will need to accept the ownership before it is transferred +// XXX Implement using Ownable instead of replicating it. type Ownable2Step struct { owner std.Address pendingOwner std.Address @@ -15,11 +16,22 @@ type Ownable2Step struct { func New() *Ownable2Step { return &Ownable2Step{ - owner: std.PreviousRealm().Address(), + owner: std.CurrentRealm().Address(), pendingOwner: "", } } +func NewWithOrigin() *Ownable2Step { + origin := std.OriginCaller() + previous := std.PreviousRealm() + if origin != previous.Address() { + panic("NewWithOrigin() should be called from init() where std.PreviousRealm() is origin") + } + return &Ownable2Step{ + owner: origin, + } +} + func NewWithAddress(addr std.Address) *Ownable2Step { return &Ownable2Step{ owner: addr, @@ -29,7 +41,7 @@ func NewWithAddress(addr std.Address) *Ownable2Step { // TransferOwnership initiate the transfer of the ownership to a new address by setting the PendingOwner func (o *Ownable2Step) TransferOwnership(newOwner std.Address) error { - if !o.OwnedByPrevious() { + if !o.OwnedByCurrent() { return ErrUnauthorized } if !newOwner.IsValid() { @@ -45,7 +57,7 @@ func (o *Ownable2Step) AcceptOwnership() error { if o.pendingOwner.String() == "" { return ErrNoPendingOwner } - if std.PreviousRealm().Address() != o.pendingOwner { + if std.CurrentRealm().Address() != o.pendingOwner { return ErrPendingUnauthorized } @@ -59,7 +71,7 @@ func (o *Ownable2Step) AcceptOwnership() error { // Top-level usage: disables all only-owner actions/functions, // Embedded usage: behaves like a burn functionality, removing the owner from the struct func (o *Ownable2Step) DropOwnership() error { - if !o.OwnedByPrevious() { + if !o.OwnedByCurrent() { return ErrUnauthorized } @@ -85,7 +97,19 @@ func (o *Ownable2Step) PendingOwner() std.Address { return o.pendingOwner } -// OwnedByPrevious( checks if the caller of the function is the Realm's owner +// OwnedByCurrent checks if the caller of the function is the Realm's owner +func (o *Ownable2Step) OwnedByCurrent() bool { + return std.CurrentRealm().Address() == o.owner +} + +// AssertOwnedByCurrent panics if the caller is not the owner +func (o *Ownable2Step) AssertOwnedByCurrent() { + if std.CurrentRealm().Address() != o.owner { + panic(ErrUnauthorized) + } +} + +// OwnedByPrevious checks if the caller of the function is the Realm's owner func (o *Ownable2Step) OwnedByPrevious() bool { return std.PreviousRealm().Address() == o.owner } diff --git a/examples/gno.land/p/oxtekgrinder/ownable2step/ownable_test.gno b/examples/gno.land/p/oxtekgrinder/ownable2step/ownable_test.gno index fa020ae6552..6542fa8e7b3 100644 --- a/examples/gno.land/p/oxtekgrinder/ownable2step/ownable_test.gno +++ b/examples/gno.land/p/oxtekgrinder/ownable2step/ownable_test.gno @@ -1,6 +1,7 @@ package ownable2step import ( + "std" "testing" "gno.land/p/demo/testutils" @@ -75,15 +76,52 @@ func TestTransferOwnership(t *testing.T) { uassert.Equal(t, pendingOwner.String(), "") } -func TestOwnedByPrevious(t *testing.T) { +func TestOwnedByCurrent(t *testing.T) { testing.SetOriginCaller(alice) o := New() unauthorizedCaller := bob - testing.SetOriginCaller(unauthorizedCaller) + uassert.False(t, o.OwnedByCurrent()) +} + +func TestOwnedByCurrentUnauthorized(t *testing.T) { + testing.SetOriginCaller(alice) + testing.SetRealm(std.NewUserRealm(alice)) + + var o *Ownable2Step + func() { + testing.SetRealm(std.NewCodeRealm("gno.land/r/test/test")) + o = NewWithOrigin() + }() + + uassert.True(t, o.OwnedByCurrent()) + + unauthorizedCaller := bob + testing.SetRealm(std.NewUserRealm(unauthorizedCaller)) + uassert.False(t, o.OwnedByCurrent()) +} - uassert.False(t, o.OwnedByPrevious()) +func TestOwnedByPrevious(t *testing.T) { + testing.SetOriginCaller(alice) + + o := New() + func() { + testing.SetRealm(std.NewCodeRealm("gno.land/r/test/test")) + uassert.True(t, o.OwnedByPrevious()) + }() +} + +func TestOwnedByPreviousUnauthorized(t *testing.T) { + testing.SetRealm(std.NewUserRealm(alice)) + + o := New() + unauthorizedCaller := bob + testing.SetRealm(std.NewUserRealm(unauthorizedCaller)) + func() { + testing.SetRealm(std.NewCodeRealm("gno.land/r/test/test")) + uassert.False(t, o.OwnedByPrevious()) + }() } func TestDropOwnership(t *testing.T) { diff --git a/examples/gno.land/p/thox/accesscontrol/accesscontrol.gno b/examples/gno.land/p/thox/accesscontrol/accesscontrol.gno index 7894fa082b8..39cfed757e9 100644 --- a/examples/gno.land/p/thox/accesscontrol/accesscontrol.gno +++ b/examples/gno.land/p/thox/accesscontrol/accesscontrol.gno @@ -55,7 +55,7 @@ func (rs *Roles) CreateRole(name string) (*Role, error) { return nil, ErrNameRole } - if !rs.Ownable.OwnedByPrevious() { + if !rs.Ownable.OwnedByCurrent() { return nil, ErrNotOwner } @@ -104,7 +104,7 @@ func (rs *Roles) GrantRole(name string, account std.Address) error { return ErrRoleNotFound } - if !r.Ownable.OwnedByPrevious() { + if !r.Ownable.OwnedByCurrent() { return ErrNotOwner } @@ -122,7 +122,7 @@ func (rs *Roles) GrantRole(name string, account std.Address) error { RoleGrantedEvent, "roleName", r.Name, "account", account.String(), - "sender", std.PreviousRealm().Address().String(), + "sender", std.CurrentRealm().Address().String(), ) return nil @@ -135,7 +135,7 @@ func (rs *Roles) RevokeRole(name string, account std.Address) error { return ErrRoleNotFound } - if !r.Ownable.OwnedByPrevious() { + if !r.Ownable.OwnedByCurrent() { return ErrNotOwner } @@ -157,7 +157,7 @@ func (rs *Roles) RevokeRole(name string, account std.Address) error { RoleRevokedEvent, "roleName", r.Name, "account", account.String(), - "sender", std.PreviousRealm().Address().String(), + "sender", std.CurrentRealm().Address().String(), ) return nil diff --git a/examples/gno.land/p/wyhaines/rand/isaac/isaac_test.gno b/examples/gno.land/p/wyhaines/rand/isaac/isaac_test.gno index fdf633bb543..4b8e8f492b7 100644 --- a/examples/gno.land/p/wyhaines/rand/isaac/isaac_test.gno +++ b/examples/gno.land/p/wyhaines/rand/isaac/isaac_test.gno @@ -18,21 +18,20 @@ func TestISAACSeeding(t *testing.T) { } func TestISAACRand(t *testing.T) { - source := New(987654321) - rng := rand.New(source) + rnd := New(987654321) + rng := rand.New(rnd) - // Expected outputs for the first 5 random floats with the given seed expected := []float64{ - 0.17828173023837635, - 0.7327795780287832, - 0.4850369074875177, - 0.9474842397428482, - 0.6747135561813891, - 0.7522507082868403, - 0.041115261836534356, - 0.7405243709084567, - 0.672863376128768, - 0.11866211399980553, + 0.3590173976876423, + 0.7045500585814575, + 0.3307624938209778, + 0.9174646414250772, + 0.11232269485263391, + 0.9276658847827113, + 0.9561549853128902, + 0.3921638978394879, + 0.9824881209760224, + 0.8213784955963486, } for i, exp := range expected { @@ -44,23 +43,23 @@ func TestISAACRand(t *testing.T) { } func TestISAACUint64(t *testing.T) { - isaac := New() + rnd := New(1000) expected := []uint64{ - 5986068031949215749, - 10437354066128700566, - 13478007513323023970, - 8969511410255984224, - 3869229557962857982, - 1762449743873204415, - 5292356290662282456, - 7893982194485405616, - 4296136494566588699, - 12414349056998262772, + 13706738165129397958, + 11158865851759859683, + 7282911433372880595, + 10191257834247701829, + 6756510588635422211, + 9188469355127567259, + 3870407692778398450, + 7510499000403643056, + 11921506945015596058, + 5594436529078496461, } for i, exp := range expected { - val := isaac.Uint64() + val := rnd.Uint64() if exp != val { t.Errorf("ISAAC.Uint64() at iteration %d: got %d, expected %d", i, val, exp) } @@ -81,83 +80,83 @@ func dupState(i *ISAAC) *OpenISAAC { } func TestISAACMarshalUnmarshal(t *testing.T) { - isaac := New() + rnd := New(1001) expected1 := []uint64{ - 5986068031949215749, - 10437354066128700566, - 13478007513323023970, - 8969511410255984224, - 3869229557962857982, + 15520355889829550420, + 14048062122838424762, + 17386984608929258959, + 6631892771034928162, + 10939419587267807737, } expected2 := []uint64{ - 1762449743873204415, - 5292356290662282456, - 7893982194485405616, - 4296136494566588699, - 12414349056998262772, + 3835981378089717525, + 13955658256492919532, + 10077846634918708781, + 5773204650675356768, + 4971527406542890875, } for i, exp := range expected1 { - val := isaac.Uint64() + val := rnd.Uint64() if exp != val { t.Errorf("ISAAC.Uint64() at iteration %d: got %d, expected %d", i, val, exp) } } - marshalled, err := isaac.MarshalBinary() + marshalled, err := rnd.MarshalBinary() - t.Logf("State: [%v]\n", dupState(isaac)) - t.Logf("Marshalled State: [%x] -- %v\n", marshalled, err) - state_before := dupState(isaac) + // t.Logf("State: [%v]\n", dupState(rnd)) + // t.Logf("Marshalled State: [%x] -- %v\n", marshalled, err) + state_before := dupState(rnd) if err != nil { t.Errorf("ISAAC.MarshalBinary() error: %v", err) } // Advance state by one number; then check the next 5. The expectation is that they _will_ fail. - isaac.Uint64() + rnd.Uint64() for i, exp := range expected2 { - val := isaac.Uint64() + val := rnd.Uint64() if exp == val { t.Errorf(" Iteration %d matched %d; which is from iteration %d; something strange is happening.", (i + 6), val, (i + 5)) } } - t.Logf("State before unmarshall: [%v]\n", dupState(isaac)) + // t.Logf("State before unmarshall: [%v]\n", dupState(rnd)) // Now restore the state of the PRNG - err = isaac.UnmarshalBinary(marshalled) + err = rnd.UnmarshalBinary(marshalled) - t.Logf("State after unmarshall: [%v]\n", dupState(isaac)) + // t.Logf("State after unmarshall: [%v]\n", dupState(rnd)) - if state_before.Seed != dupState(isaac).Seed { + if state_before.Seed != dupState(rnd).Seed { t.Errorf("Seed mismatch") } - if state_before.Randrsl != dupState(isaac).Randrsl { + if state_before.Randrsl != dupState(rnd).Randrsl { t.Errorf("Randrsl mismatch") } - if state_before.Mm != dupState(isaac).Mm { + if state_before.Mm != dupState(rnd).Mm { t.Errorf("Mm mismatch") } - if state_before.Aa != dupState(isaac).Aa { + if state_before.Aa != dupState(rnd).Aa { t.Errorf("Aa mismatch") } - if state_before.Bb != dupState(isaac).Bb { + if state_before.Bb != dupState(rnd).Bb { t.Errorf("Bb mismatch") } - if state_before.Cc != dupState(isaac).Cc { + if state_before.Cc != dupState(rnd).Cc { t.Errorf("Cc mismatch") } - if state_before.Randcnt != dupState(isaac).Randcnt { + if state_before.Randcnt != dupState(rnd).Randcnt { t.Errorf("Randcnt mismatch") } // Now we should be back on track for the last 5 numbers for i, exp := range expected2 { - val := isaac.Uint64() + val := rnd.Uint64() if exp != val { t.Errorf("ISAAC.Uint64() at iteration %d: got %d, expected %d", (i + 5), val, exp) } diff --git a/examples/gno.land/p/wyhaines/rand/isaac64/isaac64_test.gno b/examples/gno.land/p/wyhaines/rand/isaac64/isaac64_test.gno index 74abf2c13ca..be8fef53b6c 100644 --- a/examples/gno.land/p/wyhaines/rand/isaac64/isaac64_test.gno +++ b/examples/gno.land/p/wyhaines/rand/isaac64/isaac64_test.gno @@ -18,21 +18,21 @@ func TestISAACSeeding(t *testing.T) { } func TestISAACRand(t *testing.T) { - source := New(987654321) - rng := rand.New(source) + rnd := New(987654321) + rng := rand.New(rnd) // Expected outputs for the first 5 random floats with the given seed expected := []float64{ - 0.9273376778618531, - 0.327620245173309, - 0.49315436150113456, - 0.9222536383598948, - 0.2999297342641162, - 0.4050531597269049, - 0.5321357451089953, - 0.19478000239059667, - 0.5156043950865713, - 0.9233494881511063, + 0.2818878834295122, + 0.8575461830821571, + 0.9878021063787968, + 0.6503544780116336, + 0.5158329690433359, + 0.7959152461588924, + 0.5432366486934906, + 0.824665978209607, + 0.8615372170680458, + 0.22954589404739578, } for i, exp := range expected { @@ -44,23 +44,23 @@ func TestISAACRand(t *testing.T) { } func TestISAACUint64(t *testing.T) { - isaac := New() + rnd := New(1000) expected := []uint64{ - 6781932227698873623, - 14800945299485332986, - 4114322996297394168, - 5328012296808356526, - 12789214124608876433, - 17611101631239575547, - 6877490613942924608, - 15954522518901325556, - 14180160756719376887, - 4977949063252893357, + 10083220283665581455, + 10039389761195725041, + 6820016387036140989, + 6784213597523088182, + 13120722600477653778, + 3491117614651563646, + 1297676147275528930, + 15006384980354042338, + 3104467119059991036, + 4914319123654344819, } for i, exp := range expected { - val := isaac.Uint64() + val := rnd.Uint64() if exp != val { t.Errorf("ISAAC.Uint64() at iteration %d: got %d, expected %d", i, val, exp) } @@ -81,83 +81,83 @@ func dupState(i *ISAAC) *OpenISAAC { } func TestISAACMarshalUnmarshal(t *testing.T) { - isaac := New() + rnd := New(1001) expected1 := []uint64{ - 6781932227698873623, - 14800945299485332986, - 4114322996297394168, - 5328012296808356526, - 12789214124608876433, + 4398183556077595549, + 14479654616302101831, + 15852653767232940552, + 2801765968457115882, + 8875575139772470433, } expected2 := []uint64{ - 17611101631239575547, - 6877490613942924608, - 15954522518901325556, - 14180160756719376887, - 4977949063252893357, + 17583056722733587141, + 16906215529544723388, + 7599862885469865851, + 9623269843822592805, + 4311429062865512072, } for i, exp := range expected1 { - val := isaac.Uint64() + val := rnd.Uint64() if exp != val { t.Errorf("ISAAC.Uint64() at iteration %d: got %d, expected %d", i, val, exp) } } - marshalled, err := isaac.MarshalBinary() + marshalled, err := rnd.MarshalBinary() - t.Logf("State: [%v]\n", dupState(isaac)) - t.Logf("Marshalled State: [%x] -- %v\n", marshalled, err) - state_before := dupState(isaac) + // t.Logf("State: [%v]\n", dupState(rnd)) + // t.Logf("Marshalled State: [%x] -- %v\n", marshalled, err) + state_before := dupState(rnd) if err != nil { t.Errorf("ISAAC.MarshalBinary() error: %v", err) } // Advance state by one number; then check the next 5. The expectation is that they _will_ fail. - isaac.Uint64() + rnd.Uint64() for i, exp := range expected2 { - val := isaac.Uint64() + val := rnd.Uint64() if exp == val { t.Errorf(" Iteration %d matched %d; which is from iteration %d; something strange is happening.", (i + 6), val, (i + 5)) } } - t.Logf("State before unmarshall: [%v]\n", dupState(isaac)) + // t.Logf("State before unmarshall: [%v]\n", dupState(rnd)) // Now restore the state of the PRNG - err = isaac.UnmarshalBinary(marshalled) + err = rnd.UnmarshalBinary(marshalled) - t.Logf("State after unmarshall: [%v]\n", dupState(isaac)) + // t.Logf("State after unmarshall: [%v]\n", dupState(rnd)) - if state_before.Seed != dupState(isaac).Seed { + if state_before.Seed != dupState(rnd).Seed { t.Errorf("Seed mismatch") } - if state_before.Randrsl != dupState(isaac).Randrsl { + if state_before.Randrsl != dupState(rnd).Randrsl { t.Errorf("Randrsl mismatch") } - if state_before.Mm != dupState(isaac).Mm { + if state_before.Mm != dupState(rnd).Mm { t.Errorf("Mm mismatch") } - if state_before.Aa != dupState(isaac).Aa { + if state_before.Aa != dupState(rnd).Aa { t.Errorf("Aa mismatch") } - if state_before.Bb != dupState(isaac).Bb { + if state_before.Bb != dupState(rnd).Bb { t.Errorf("Bb mismatch") } - if state_before.Cc != dupState(isaac).Cc { + if state_before.Cc != dupState(rnd).Cc { t.Errorf("Cc mismatch") } - if state_before.Randcnt != dupState(isaac).Randcnt { + if state_before.Randcnt != dupState(rnd).Randcnt { t.Errorf("Randcnt mismatch") } // Now we should be back on track for the last 5 numbers for i, exp := range expected2 { - val := isaac.Uint64() + val := rnd.Uint64() if exp != val { t.Errorf("ISAAC.Uint64() at iteration %d: got %d, expected %d", (i + 5), val, exp) } diff --git a/examples/gno.land/p/wyhaines/rand/xorshift64star/xorshift64star_test.gno b/examples/gno.land/p/wyhaines/rand/xorshift64star/xorshift64star_test.gno index 8a73bd9718d..07eab99d73a 100644 --- a/examples/gno.land/p/wyhaines/rand/xorshift64star/xorshift64star_test.gno +++ b/examples/gno.land/p/wyhaines/rand/xorshift64star/xorshift64star_test.gno @@ -6,20 +6,20 @@ import ( ) func TestXorshift64StarSeeding(t *testing.T) { - xs64s := New() - value1 := xs64s.Uint64() + rnd := New() + value1 := rnd.Uint64() - xs64s = New(987654321) - value2 := xs64s.Uint64() + rnd = New(987654321) + value2 := rnd.Uint64() - if value1 != 5083824587905981259 || value2 != 18211065302896784785 || value1 == value2 { - t.Errorf("Expected 5083824587905981259 to be != to 18211065302896784785; got: %d == %d", value1, value2) + if value1 != 3506338452768534464 || value2 != 18211065302896784785 || value1 == value2 { + t.Errorf("Expected 2 different values; got: %d and %d", value1, value2) } } func TestXorshift64StarRand(t *testing.T) { - source := New(987654321) - rng := rand.New(source) + rnd := New(987654321) + rng := rand.New(rnd) // Expected outputs for the first 5 random floats with the given seed expected := []float64{ @@ -44,23 +44,23 @@ func TestXorshift64StarRand(t *testing.T) { } func TestXorshift64StarUint64(t *testing.T) { - xs64s := New() + rnd := New(1000) expected := []uint64{ - 5083824587905981259, - 4607286371009545754, - 2070557085263023674, - 14094662988579565368, - 2910745910478213381, - 18037409026311016155, - 17169624916429864153, - 10459214929523155306, - 11840179828060641081, - 1198750959721587199, + 12487186097140327178, + 14661465266242046735, + 14694269887751719025, + 15763651124252725051, + 6358063137690011177, + 16123467710013993794, + 8086526499083208127, + 5907916440057635441, + 7074828965897564835, + 219959441764368518, } for i, exp := range expected { - val := xs64s.Uint64() + val := rnd.Uint64() if exp != val { t.Errorf("Xorshift64Star.Uint64() at iteration %d: got %d, expected %d", i, val, exp) } @@ -68,65 +68,65 @@ func TestXorshift64StarUint64(t *testing.T) { } func TestXorshift64StarMarshalUnmarshal(t *testing.T) { - xs64s := New() + rnd := New(1001) expected1 := []uint64{ - 5083824587905981259, - 4607286371009545754, - 2070557085263023674, - 14094662988579565368, - 2910745910478213381, + 17667678392346722343, + 8998941448230025236, + 6038719778092581458, + 9916057400810746083, + 3240504040424884895, } expected2 := []uint64{ - 18037409026311016155, - 17169624916429864153, - 10459214929523155306, - 11840179828060641081, - 1198750959721587199, + 3977048231667561376, + 18438555156602529247, + 2172795924893074637, + 12043507788481457357, + 8032279100325099159, } for i, exp := range expected1 { - val := xs64s.Uint64() + val := rnd.Uint64() if exp != val { t.Errorf("Xorshift64Star.Uint64() at iteration %d: got %d, expected %d", i, val, exp) } } - marshalled, err := xs64s.MarshalBinary() + marshalled, err := rnd.MarshalBinary() - t.Logf("Original State: [%x]\n", xs64s.seed) - t.Logf("Marshalled State: [%x] -- %v\n", marshalled, err) - state_before := xs64s.seed + // t.Logf("Original State: [%x]\n", rnd.seed) + // t.Logf("Marshalled State: [%x] -- %v\n", marshalled, err) + state_before := rnd.seed if err != nil { t.Errorf("Xorshift64Star.MarshalBinary() error: %v", err) } // Advance state by one number; then check the next 5. The expectation is that they _will_ fail. - xs64s.Uint64() + rnd.Uint64() for i, exp := range expected2 { - val := xs64s.Uint64() + val := rnd.Uint64() if exp == val { t.Errorf(" Iteration %d matched %d; which is from iteration %d; something strange is happening.", (i + 6), val, (i + 5)) } } - t.Logf("State before unmarshall: [%x]\n", xs64s.seed) + // t.Logf("State before unmarshall: [%x]\n", rnd.seed) // Now restore the state of the PRNG - err = xs64s.UnmarshalBinary(marshalled) + err = rnd.UnmarshalBinary(marshalled) - t.Logf("State after unmarshall: [%x]\n", xs64s.seed) + // t.Logf("State after unmarshall: [%x]\n", rnd.seed) - if state_before != xs64s.seed { - t.Errorf("States before and after marshal/unmarshal are not equal; go %x and %x", state_before, xs64s.seed) + if state_before != rnd.seed { + t.Errorf("States before and after marshal/unmarshal are not equal; go %x and %x", state_before, rnd.seed) } // Now we should be back on track for the last 5 numbers for i, exp := range expected2 { - val := xs64s.Uint64() + val := rnd.Uint64() if exp != val { t.Errorf("Xorshift64Star.Uint64() at iteration %d: got %d, expected %d", (i + 5), val, exp) } diff --git a/examples/gno.land/p/wyhaines/rand/xorshiftr128plus/xorshiftr128plus_test.gno b/examples/gno.land/p/wyhaines/rand/xorshiftr128plus/xorshiftr128plus_test.gno index c5d86edd073..9313082d720 100644 --- a/examples/gno.land/p/wyhaines/rand/xorshiftr128plus/xorshiftr128plus_test.gno +++ b/examples/gno.land/p/wyhaines/rand/xorshiftr128plus/xorshiftr128plus_test.gno @@ -6,41 +6,41 @@ import ( ) func TestXorshift64StarSeeding(t *testing.T) { - xs128p := New() - value1 := xs128p.Uint64() + rnd := New() + value1 := rnd.Uint64() - xs128p = New(987654321) - value2 := xs128p.Uint64() + rnd = New(987654321) + value2 := rnd.Uint64() - xs128p = New(987654321, 9876543210) - value3 := xs128p.Uint64() + rnd = New(987654321, 9876543210) + value3 := rnd.Uint64() - if value1 != 13970141264473760763 || - value2 != 17031892808144362974 || + if value1 != 4368859828809982745 || + value2 != 6152356058823566752 || value3 != 8285073084540510 || value1 == value2 || value2 == value3 || value1 == value3 { - t.Errorf("Expected three different values: 13970141264473760763, 17031892808144362974, and 8285073084540510\n got: %d, %d, %d", value1, value2, value3) + t.Errorf("Expected three different values\n got: %d, %d, %d", value1, value2, value3) } } func TestXorshiftr128PlusRand(t *testing.T) { - source := New(987654321) - rng := rand.New(source) + rnd := New(987654321) + rng := rand.New(rnd) // Expected outputs for the first 5 random floats with the given seed expected := []float64{ - 0.9199548549485674, - 0.0027491282372705816, - 0.31493362274701164, - 0.3531250819119609, - 0.09957852858060356, - 0.731941362705936, - 0.3476937688876708, - 0.1444018086140385, - 0.9106467321832331, - 0.8024870151488901, + 0.048735219800779106, + 0.0372152171449619, + 0.667254760531175, + 0.16615979111253953, + 0.27578895545492665, + 0.48342823127830337, + 0.7825693830495895, + 0.14643955390763952, + 0.29003469381875835, + 0.726334398545258, } for i, exp := range expected { @@ -52,7 +52,7 @@ func TestXorshiftr128PlusRand(t *testing.T) { } func TestXorshiftr128PlusUint64(t *testing.T) { - xs128p := New(987654321, 9876543210) + rnd := New(987654321, 9876543210) expected := []uint64{ 8285073084540510, @@ -68,7 +68,7 @@ func TestXorshiftr128PlusUint64(t *testing.T) { } for i, exp := range expected { - val := xs128p.Uint64() + val := rnd.Uint64() if exp != val { t.Errorf("Xorshiftr128Plus.Uint64() at iteration %d: got %d, expected %d", i, val, exp) } @@ -76,7 +76,7 @@ func TestXorshiftr128PlusUint64(t *testing.T) { } func TestXorshiftr128PlusMarshalUnmarshal(t *testing.T) { - xs128p := New(987654321, 9876543210) + rnd := New(987654321, 9876543210) expected1 := []uint64{ 8285073084540510, @@ -95,46 +95,46 @@ func TestXorshiftr128PlusMarshalUnmarshal(t *testing.T) { } for i, exp := range expected1 { - val := xs128p.Uint64() + val := rnd.Uint64() if exp != val { t.Errorf("Xorshiftr128Plus.Uint64() at iteration %d: got %d, expected %d", i, val, exp) } } - marshalled, err := xs128p.MarshalBinary() + marshalled, err := rnd.MarshalBinary() - t.Logf("Original State: [%x]\n", xs128p.seed) - t.Logf("Marshalled State: [%x] -- %v\n", marshalled, err) - state_before := xs128p.seed + // t.Logf("Original State: [%x]\n", rnd.seed) + // t.Logf("Marshalled State: [%x] -- %v\n", marshalled, err) + state_before := rnd.seed if err != nil { t.Errorf("Xorshiftr128Plus.MarshalBinary() error: %v", err) } // Advance state by one number; then check the next 5. The expectation is that they _will_ fail. - xs128p.Uint64() + rnd.Uint64() for i, exp := range expected2 { - val := xs128p.Uint64() + val := rnd.Uint64() if exp == val { t.Errorf(" Iteration %d matched %d; which is from iteration %d; something strange is happening.", (i + 6), val, (i + 5)) } } - t.Logf("State before unmarshall: [%x]\n", xs128p.seed) + // t.Logf("State before unmarshall: [%x]\n", rnd.seed) // Now restore the state of the PRNG - err = xs128p.UnmarshalBinary(marshalled) + err = rnd.UnmarshalBinary(marshalled) - t.Logf("State after unmarshall: [%x]\n", xs128p.seed) + // t.Logf("State after unmarshall: [%x]\n", rnd.seed) - if state_before != xs128p.seed { - t.Errorf("States before and after marshal/unmarshal are not equal; go %x and %x", state_before, xs128p.seed) + if state_before != rnd.seed { + t.Errorf("States before and after marshal/unmarshal are not equal; go %x and %x", state_before, rnd.seed) } // Now we should be back on track for the last 5 numbers for i, exp := range expected2 { - val := xs128p.Uint64() + val := rnd.Uint64() if exp != val { t.Errorf("Xorshiftr128Plus.Uint64() at iteration %d: got %d, expected %d", (i + 5), val, exp) } diff --git a/examples/gno.land/r/demo/atomicswap/atomicswap.gno b/examples/gno.land/r/demo/atomicswap/atomicswap.gno index 4b65796fa46..90e0970bb48 100644 --- a/examples/gno.land/r/demo/atomicswap/atomicswap.gno +++ b/examples/gno.land/r/demo/atomicswap/atomicswap.gno @@ -59,6 +59,8 @@ var ( // NewCoinSwap creates a new atomic swap contract for native coins. // It uses a default timelock duration. func NewCoinSwap(recipient std.Address, hashlock string) (int, *Swap) { + crossing() + timelock := time.Now().Add(defaultTimelockDuration) return NewCustomCoinSwap(recipient, hashlock, timelock) } @@ -66,6 +68,8 @@ func NewCoinSwap(recipient std.Address, hashlock string) (int, *Swap) { // NewGRC20Swap creates a new atomic swap contract for grc20 tokens. // It uses gno.land/r/demo/grc20reg to lookup for a registered token. func NewGRC20Swap(recipient std.Address, hashlock string, tokenRegistryKey string) (int, *Swap) { + crossing() + timelock := time.Now().Add(defaultTimelockDuration) tokenGetter := grc20reg.MustGet(tokenRegistryKey) token := tokenGetter() @@ -76,12 +80,16 @@ func NewGRC20Swap(recipient std.Address, hashlock string, tokenRegistryKey strin // It allows specifying a custom timelock duration. // It is not callable with `gnokey maketx call`, but can be imported by another contract or `gnokey maketx run`. func NewCustomCoinSwap(recipient std.Address, hashlock string, timelock time.Time) (int, *Swap) { + crossing() + sender := std.PreviousRealm().Address() sent := std.OriginSend() require(len(sent) != 0, "at least one coin needs to be sent") // Create the swap sendFn := func(to std.Address) { + crossing() + banker := std.NewBanker(std.BankerTypeRealmSend) pkgAddr := std.CurrentRealm().Address() banker.SendCoins(pkgAddr, to, sent) @@ -98,6 +106,8 @@ func NewCustomCoinSwap(recipient std.Address, hashlock string, timelock time.Tim // NewCustomGRC20Swap creates a new atomic swap contract for grc20 tokens. // It is not callable with `gnokey maketx call`, but can be imported by another contract or `gnokey maketx run`. func NewCustomGRC20Swap(recipient std.Address, hashlock string, timelock time.Time, token *grc20.Token) (int, *Swap) { + crossing() + sender := std.PreviousRealm().Address() curAddr := std.CurrentRealm().Address() @@ -110,6 +120,8 @@ func NewCustomGRC20Swap(recipient std.Address, hashlock string, timelock time.Ti amountStr := ufmt.Sprintf("%d%s", allowance, token.GetSymbol()) sendFn := func(to std.Address) { + crossing() + err := userTeller.Transfer(to, allowance) require(err == nil, "cannot transfer tokens") } @@ -125,12 +137,16 @@ func NewCustomGRC20Swap(recipient std.Address, hashlock string, timelock time.Ti // Claim loads a registered swap and tries to claim it. func Claim(id int, secret string) { + crossing() + swap := mustGet(id) swap.Claim(secret) } // Refund loads a registered swap and tries to refund it. func Refund(id int) { + crossing() + swap := mustGet(id) swap.Refund() } diff --git a/examples/gno.land/r/demo/atomicswap/atomicswap_test.gno b/examples/gno.land/r/demo/atomicswap/atomicswap_test.gno index e12174c3421..6547642670f 100644 --- a/examples/gno.land/r/demo/atomicswap/atomicswap_test.gno +++ b/examples/gno.land/r/demo/atomicswap/atomicswap_test.gno @@ -16,21 +16,22 @@ import ( var testRun bool func TestNewCustomCoinSwap_Claim(t *testing.T) { - t.Skip("skipping due to bad support for unit-test driven banker") defer resetTestState() // Setup + pkgAddr := std.DerivePkgAddr("gno.land/r/demo/atomicswap") sender := testutils.TestAddress("sender1") recipient := testutils.TestAddress("recipient1") amount := std.Coins{{Denom: "ugnot", Amount: 1}} hashlock := sha256.Sum256([]byte("secret")) hashlockHex := hex.EncodeToString(hashlock[:]) timelock := time.Now().Add(1 * time.Hour) + testing.IssueCoins(pkgAddr, std.Coins{{"ugnot", 100000000}}) // Create a new swap testing.SetRealm(std.NewUserRealm(sender)) testing.SetOriginSend(amount) - id, swap := NewCustomCoinSwap(recipient, hashlockHex, timelock) + id, swap := cross(NewCustomCoinSwap)(recipient, hashlockHex, timelock) uassert.Equal(t, 1, id) expected := `- status: active @@ -77,6 +78,7 @@ func TestNewCustomCoinSwap_Refund(t *testing.T) { defer resetTestState() // Setup + pkgAddr := std.DerivePkgAddr("gno.land/r/demo/atomicswap") sender := testutils.TestAddress("sender2") recipient := testutils.TestAddress("recipient2") amount := std.Coins{{Denom: "ugnot", Amount: 1}} @@ -87,7 +89,7 @@ func TestNewCustomCoinSwap_Refund(t *testing.T) { // Create a new swap testing.SetRealm(std.NewUserRealm(sender)) testing.SetOriginSend(amount) - id, swap := NewCustomCoinSwap(recipient, hashlockHex, timelock) // Create a new swap + id, swap := cross(NewCustomCoinSwap)(recipient, hashlockHex, timelock) // Create a new swap uassert.Equal(t, 1, id) expected := `- status: active @@ -101,7 +103,6 @@ func TestNewCustomCoinSwap_Refund(t *testing.T) { uassert.Equal(t, expected, Render("1")) // Test Refund - pkgAddr := std.DerivePkgAddr("gno.land/r/demo/atomicswap") testing.IssueCoins(pkgAddr, std.Coins{{"ugnot", 100000000}}) uassert.PanicsWithMessage(t, "timelock not expired", swap.Refund) swap.timelock = time.Now().Add(-1 * time.Hour) // override timelock @@ -134,7 +135,7 @@ func TestNewCustomGRC20Swap_Claim(t *testing.T) { // Create a new swap testing.SetRealm(std.NewUserRealm(sender)) - id, swap := NewCustomGRC20Swap(recipient, hashlockHex, timelock, test20.Token) + id, swap := cross(NewCustomGRC20Swap)(recipient, hashlockHex, timelock, test20.Token) uassert.Equal(t, 1, id) expected := `- status: active @@ -195,6 +196,7 @@ func TestNewCustomGRC20Swap_Refund(t *testing.T) { defer resetTestState() // Setup + pkgAddr := std.DerivePkgAddr("gno.land/r/demo/atomicswap") sender := testutils.TestAddress("sender5") recipient := testutils.TestAddress("recipient5") rlm := std.DerivePkgAddr("gno.land/r/demo/atomicswap") @@ -207,7 +209,7 @@ func TestNewCustomGRC20Swap_Refund(t *testing.T) { // Create a new swap testing.SetRealm(std.NewUserRealm(sender)) - id, swap := NewCustomGRC20Swap(recipient, hashlockHex, timelock, test20.Token) + id, swap := cross(NewCustomGRC20Swap)(recipient, hashlockHex, timelock, test20.Token) uassert.Equal(t, 1, id) expected := `- status: active @@ -231,7 +233,6 @@ func TestNewCustomGRC20Swap_Refund(t *testing.T) { uassert.Equal(t, bal, uint64(0)) // Test Refund - pkgAddr := std.DerivePkgAddr("gno.land/r/demo/atomicswap") testing.IssueCoins(pkgAddr, std.Coins{{"ugnot", 100000000}}) uassert.PanicsWithMessage(t, "timelock not expired", swap.Refund) swap.timelock = time.Now().Add(-1 * time.Hour) // override timelock @@ -272,7 +273,7 @@ func TestNewGRC20Swap_Claim(t *testing.T) { // Create a new swap testing.SetRealm(std.NewUserRealm(sender)) - id, swap := NewGRC20Swap(recipient, hashlockHex, "gno.land/r/demo/tests/test20") + id, swap := cross(NewGRC20Swap)(recipient, hashlockHex, "gno.land/r/demo/tests/test20") uassert.Equal(t, 1, id) expected := `- status: active @@ -333,6 +334,7 @@ func TestNewGRC20Swap_Refund(t *testing.T) { defer resetTestState() // Setup + pkgAddr := std.DerivePkgAddr("gno.land/r/demo/atomicswap") sender := testutils.TestAddress("sender6") recipient := testutils.TestAddress("recipient6") rlm := std.DerivePkgAddr("gno.land/r/demo/atomicswap") @@ -345,7 +347,7 @@ func TestNewGRC20Swap_Refund(t *testing.T) { // Create a new swap testing.SetRealm(std.NewUserRealm(sender)) - id, swap := NewGRC20Swap(recipient, hashlockHex, "gno.land/r/demo/tests/test20") + id, swap := cross(NewGRC20Swap)(recipient, hashlockHex, "gno.land/r/demo/tests/test20") uassert.Equal(t, 1, id) expected := `- status: active @@ -369,7 +371,6 @@ func TestNewGRC20Swap_Refund(t *testing.T) { uassert.Equal(t, bal, uint64(0)) // Test Refund - pkgAddr := std.DerivePkgAddr("gno.land/r/demo/atomicswap") testing.IssueCoins(pkgAddr, std.Coins{{"ugnot", 100000000}}) uassert.PanicsWithMessage(t, "timelock not expired", swap.Refund) swap.timelock = time.Now().Add(-1 * time.Hour) // override timelock @@ -411,10 +412,10 @@ func TestRender(t *testing.T) { userTeller := test20.Token.CallerTeller() userTeller.Approve(rlm, 10_000) - _, bobSwap := NewCustomGRC20Swap(bob, hashlockHex, timelock, test20.Token) + _, bobSwap := cross(NewCustomGRC20Swap)(bob, hashlockHex, timelock, test20.Token) userTeller.Approve(rlm, 20_000) - _, _ = NewCustomGRC20Swap(charly, hashlockHex, timelock, test20.Token) + _, _ = cross(NewCustomGRC20Swap)(charly, hashlockHex, timelock, test20.Token) testing.SetRealm(std.NewUserRealm(bob)) bobSwap.Claim("secret") diff --git a/examples/gno.land/r/demo/atomicswap/swap.gno b/examples/gno.land/r/demo/atomicswap/swap.gno index 299a369db26..32341824d42 100644 --- a/examples/gno.land/r/demo/atomicswap/swap.gno +++ b/examples/gno.land/r/demo/atomicswap/swap.gno @@ -47,25 +47,25 @@ func newSwap( func (s *Swap) Claim(preimage string) { require(!s.claimed, "already claimed") require(!s.refunded, "already refunded") - require(std.PreviousRealm().Address() == s.recipient, "unauthorized") + require(std.CurrentRealm().Address() == s.recipient, "unauthorized") hashlock := sha256.Sum256([]byte(preimage)) hashlockHex := hex.EncodeToString(hashlock[:]) require(hashlockHex == s.hashlock, "invalid preimage") s.claimed = true - s.sendFn(s.recipient) + cross(s.sendFn)(s.recipient) } // Refund allows the sender to refund the funds after the timelock has expired. func (s *Swap) Refund() { require(!s.claimed, "already claimed") require(!s.refunded, "already refunded") - require(std.PreviousRealm().Address() == s.sender, "unauthorized") + require(std.CurrentRealm().Address() == s.sender, "unauthorized") require(time.Now().After(s.timelock), "timelock not expired") s.refunded = true - s.sendFn(s.sender) + cross(s.sendFn)(s.sender) } func (s Swap) Status() string { diff --git a/examples/gno.land/r/demo/banktest/banktest.gno b/examples/gno.land/r/demo/banktest/banktest.gno index a2611159cac..eefbd4e483c 100644 --- a/examples/gno.land/r/demo/banktest/banktest.gno +++ b/examples/gno.land/r/demo/banktest/banktest.gno @@ -21,8 +21,18 @@ func (act *activity) String() string { var latest [10]*activity -// Deposit will take the coins (to the realm's pkgaddr) or return them to user. +func addActivity(act *activity) { + for i := len(latest) - 2; i >= 0; i-- { + latest[i+1] = latest[i] // shift by +1. + } + latest[0] = act +} + +// Deposit will take the coins (to the realm's pkgaddr) if returnAmount is 0, +// or return the specified return amount back to user. func Deposit(returnDenom string, returnAmount int64) string { + crossing() + std.AssertOriginCall() caller := std.OriginCaller() send := std.Coins{{returnDenom, returnAmount}} @@ -33,10 +43,7 @@ func Deposit(returnDenom string, returnAmount int64) string { returned: send, time: time.Now(), } - for i := len(latest) - 2; i >= 0; i-- { - latest[i+1] = latest[i] // shift by +1. - } - latest[0] = act + addActivity(act) // return if any. if returnAmount > 0 { banker := std.NewBanker(std.BankerTypeOriginSend) @@ -49,10 +56,16 @@ func Deposit(returnDenom string, returnAmount int64) string { } } +func bankerAddr() std.Address { + crossing() + + return std.CurrentRealm().Address() +} + func Render(path string) string { // get realm coins. banker := std.NewBanker(std.BankerTypeReadonly) - coins := banker.GetCoins(std.CurrentRealm().Address()) + coins := banker.GetCoins(cross(bankerAddr)()) // render res := "" diff --git a/examples/gno.land/r/demo/banktest/z_0_filetest.gno b/examples/gno.land/r/demo/banktest/z_0_filetest.gno index 91bfb418a09..a5ec8587162 100644 --- a/examples/gno.land/r/demo/banktest/z_0_filetest.gno +++ b/examples/gno.land/r/demo/banktest/z_0_filetest.gno @@ -1,8 +1,4 @@ -// Empty line between the directives is important for them to be parsed -// independently. :facepalm: - // PKGPATH: gno.land/r/demo/bank1 - // SEND: 100000000ugnot package bank1 @@ -29,8 +25,8 @@ func main() { // simulate a Deposit call. use Send + OriginSend to simulate -send. banker.SendCoins(mainaddr, banktestAddr, std.Coins{{"ugnot", 100_000_000}}) testing.SetOriginSend(std.Coins{{"ugnot", 100_000_000}}) - testing.SetRealm(std.NewCodeRealm("gno.land/r/demo/banktest")) - res := banktest.Deposit("ugnot", 50_000_000) + testing.SetRealm(std.NewUserRealm(mainaddr)) + res := cross(banktest.Deposit)("ugnot", 50_000_000) // bank1 can't send? should be r/demo/bank1 to r/demo/banktest, is bank1 -> bank1. println("Deposit():", res) // print main balance after. diff --git a/examples/gno.land/r/demo/banktest/z_1_filetest.gno b/examples/gno.land/r/demo/banktest/z_1_filetest.gno index beef64a2125..b98d014d85e 100644 --- a/examples/gno.land/r/demo/banktest/z_1_filetest.gno +++ b/examples/gno.land/r/demo/banktest/z_1_filetest.gno @@ -1,6 +1,3 @@ -// Empty line between the directives is important for them to be parsed -// independently. :facepalm: - // PKGPATH: gno.land/r/demo/bank1 package bank1 @@ -14,12 +11,14 @@ import ( func main() { banktestAddr := std.DerivePkgAddr("gno.land/r/demo/banktest") + mainaddr := std.DerivePkgAddr("gno.land/r/demo/bank1") // simulate a Deposit call. testing.IssueCoins(banktestAddr, std.Coins{{"ugnot", 100000000}}) testing.SetOriginSend(std.Coins{{"ugnot", 100000000}}) - testing.SetRealm(std.NewCodeRealm("gno.land/r/demo/banktest")) - res := banktest.Deposit("ugnot", 101000000) + testing.SetRealm(std.NewUserRealm(mainaddr)) + + res := cross(banktest.Deposit)("ugnot", 101000000) println(res) } diff --git a/examples/gno.land/r/demo/banktest/z_2_filetest.gno b/examples/gno.land/r/demo/banktest/z_2_filetest.gno index 094c004607a..602e1a8153a 100644 --- a/examples/gno.land/r/demo/banktest/z_2_filetest.gno +++ b/examples/gno.land/r/demo/banktest/z_2_filetest.gno @@ -1,6 +1,3 @@ -// Empty line between the directives is important for them to be parsed -// independently. :facepalm: - // PKGPATH: gno.land/r/demo/bank1 package bank1 @@ -14,9 +11,9 @@ import ( func main() { banktestAddr := std.DerivePkgAddr("gno.land/r/demo/banktest") + mainaddr := std.DerivePkgAddr("gno.land/r/demo/bank1") // print main balance before. - mainaddr := std.DerivePkgAddr("gno.land/r/demo/bank1") testing.SetOriginCaller(mainaddr) banker := std.NewBanker(std.BankerTypeReadonly) @@ -26,8 +23,8 @@ func main() { // simulate a Deposit call. testing.IssueCoins(banktestAddr, std.Coins{{"ugnot", 100000000}}) testing.SetOriginSend(std.Coins{{"ugnot", 100000000}}) - testing.SetRealm(std.NewCodeRealm("gno.land/r/demo/banktest")) - res := banktest.Deposit("ugnot", 55000000) + testing.SetRealm(std.NewUserRealm(mainaddr)) + res := cross(banktest.Deposit)("ugnot", 55000000) println("Deposit():", res) // print main balance after. diff --git a/examples/gno.land/r/demo/banktest/z_3_filetest.gno b/examples/gno.land/r/demo/banktest/z_3_filetest.gno index f70e0fb8433..7088cd656c3 100644 --- a/examples/gno.land/r/demo/banktest/z_3_filetest.gno +++ b/examples/gno.land/r/demo/banktest/z_3_filetest.gno @@ -1,6 +1,3 @@ -// Empty line between the directives is important for them to be parsed -// independently. :facepalm: - // PKGPATH: gno.land/r/demo/bank1 package bank1 diff --git a/examples/gno.land/r/demo/boards/board.gno b/examples/gno.land/r/demo/boards/board.gno index 84964f24a00..5caa00df324 100644 --- a/examples/gno.land/r/demo/boards/board.gno +++ b/examples/gno.land/r/demo/boards/board.gno @@ -6,7 +6,6 @@ import ( "time" "gno.land/p/demo/avl" - "gno.land/p/moul/txlink" ) //---------------------------------------- @@ -135,5 +134,5 @@ func (board *Board) GetURLFromThreadAndReplyID(threadID, replyID PostID) string } func (board *Board) GetPostFormURL() string { - return txlink.Call("CreateThread", "bid", board.id.String()) + return txlinkCall("CreateThread", "bid", board.id.String()) } diff --git a/examples/gno.land/r/demo/boards/boards.gno b/examples/gno.land/r/demo/boards/boards.gno index 5de0555a2f9..0e79633e89f 100644 --- a/examples/gno.land/r/demo/boards/boards.gno +++ b/examples/gno.land/r/demo/boards/boards.gno @@ -2,14 +2,17 @@ package boards import ( "regexp" + "std" "gno.land/p/demo/avl" + "gno.land/p/moul/txlink" ) //---------------------------------------- // Realm (package) state var ( + gRealmPath string // Realm package path gBoards avl.Tree // id -> *Board gBoardsCtr int // increments Board.id gBoardsByName avl.Tree // name -> *Board @@ -20,3 +23,12 @@ var ( // Constants var reName = regexp.MustCompile(`^[a-z]+[_a-z0-9]{2,29}$`) + +func init() { + gRealmPath = std.CurrentRealm().PkgPath() +} + +func txlinkCall(fn string, args ...string) string { + // Use gRealmPath to build TX link to allow links to be built during render calls + return txlink.Realm(gRealmPath).Call(fn, args...) +} diff --git a/examples/gno.land/r/demo/boards/post.gno b/examples/gno.land/r/demo/boards/post.gno index b66b7f17912..8877570d45a 100644 --- a/examples/gno.land/r/demo/boards/post.gno +++ b/examples/gno.land/r/demo/boards/post.gno @@ -6,7 +6,6 @@ import ( "time" "gno.land/p/demo/avl" - "gno.land/p/moul/txlink" ) //---------------------------------------- @@ -156,7 +155,7 @@ func (post *Post) GetURL() string { } func (post *Post) GetReplyFormURL() string { - return txlink.Call("CreateReply", + return txlinkCall("CreateReply", "bid", post.board.id.String(), "threadid", post.threadID.String(), "postid", post.id.String(), @@ -164,14 +163,14 @@ func (post *Post) GetReplyFormURL() string { } func (post *Post) GetRepostFormURL() string { - return txlink.Call("CreateRepost", + return txlinkCall("CreateRepost", "bid", post.board.id.String(), "postid", post.id.String(), ) } func (post *Post) GetDeleteFormURL() string { - return txlink.Call("DeletePost", + return txlinkCall("DeletePost", "bid", post.board.id.String(), "threadid", post.threadID.String(), "postid", post.id.String(), diff --git a/examples/gno.land/r/demo/boards/public.gno b/examples/gno.land/r/demo/boards/public.gno index 002370861e6..e516eec5bda 100644 --- a/examples/gno.land/r/demo/boards/public.gno +++ b/examples/gno.land/r/demo/boards/public.gno @@ -17,6 +17,8 @@ func GetBoardIDFromName(name string) (BoardID, bool) { } func CreateBoard(name string) BoardID { + crossing() + if !std.PreviousRealm().IsUser() { panic("invalid non-user call") } @@ -44,9 +46,12 @@ func checkAnonFee() bool { } func CreateThread(bid BoardID, title string, body string) PostID { + crossing() + if !std.PreviousRealm().IsUser() { panic("invalid non-user call") } + caller := std.OriginCaller() if usernameOf(caller) == "" { if !checkAnonFee() { @@ -62,9 +67,12 @@ func CreateThread(bid BoardID, title string, body string) PostID { } func CreateReply(bid BoardID, threadid, postid PostID, body string) PostID { + crossing() + if !std.PreviousRealm().IsUser() { panic("invalid non-user call") } + caller := std.OriginCaller() if usernameOf(caller) == "" { if !checkAnonFee() { @@ -92,9 +100,12 @@ func CreateReply(bid BoardID, threadid, postid PostID, body string) PostID { // If dstBoard is private, does not ping back. // If board specified by bid is private, panics. func CreateRepost(bid BoardID, postid PostID, title string, body string, dstBoardID BoardID) PostID { + crossing() + if !std.PreviousRealm().IsUser() { panic("invalid non-user call") } + caller := std.OriginCaller() if usernameOf(caller) == "" { // TODO: allow with gDefaultAnonFee payment. @@ -122,9 +133,12 @@ func CreateRepost(bid BoardID, postid PostID, title string, body string, dstBoar } func DeletePost(bid BoardID, threadid, postid PostID, reason string) { + crossing() + if !std.PreviousRealm().IsUser() { panic("invalid non-user call") } + caller := std.OriginCaller() board := getBoard(bid) if board == nil { @@ -154,9 +168,12 @@ func DeletePost(bid BoardID, threadid, postid PostID, reason string) { } func EditPost(bid BoardID, threadid, postid PostID, title, body string) { + crossing() + if !std.PreviousRealm().IsUser() { panic("invalid non-user call") } + caller := std.OriginCaller() board := getBoard(bid) if board == nil { diff --git a/examples/gno.land/r/demo/boards/z_0_a_filetest.gno b/examples/gno.land/r/demo/boards/z_0_a_filetest.gno index 4a8cc86749a..155f72e5d5d 100644 --- a/examples/gno.land/r/demo/boards/z_0_a_filetest.gno +++ b/examples/gno.land/r/demo/boards/z_0_a_filetest.gno @@ -16,10 +16,10 @@ var bid boards.BoardID func init() { caller := testutils.TestAddress("caller") testing.SetRealm(std.NewUserRealm(caller)) - bid = boards.CreateBoard("test_board") - boards.CreateThread(bid, "First Post (title)", "Body of the first post. (body)") - pid := boards.CreateThread(bid, "Second Post (title)", "Body of the second post. (body)") - boards.CreateReply(bid, pid, pid, "Reply of the second post") + bid = cross(boards.CreateBoard)("test_board") + cross(boards.CreateThread)(bid, "First Post (title)", "Body of the first post. (body)") + pid := cross(boards.CreateThread)(bid, "Second Post (title)", "Body of the second post. (body)") + cross(boards.CreateReply)(bid, pid, pid, "Reply of the second post") } func main() { diff --git a/examples/gno.land/r/demo/boards/z_0_c_filetest.gno b/examples/gno.land/r/demo/boards/z_0_c_filetest.gno index 4216e98cc80..f5b2c0a43a1 100644 --- a/examples/gno.land/r/demo/boards/z_0_c_filetest.gno +++ b/examples/gno.land/r/demo/boards/z_0_c_filetest.gno @@ -15,8 +15,8 @@ var bid boards.BoardID func init() { testing.SetRealm(std.NewUserRealm(std.Address("g1wymu47drhr0kuq2098m792lytgtj2nyx77yrsm"))) // so that CurrentRealm.Addr() matches OrigCaller - users.Register("gnouser123") - boards.CreateThread(1, "First Post (title)", "Body of the first post. (body)") + cross(users.Register)("gnouser123") + cross(boards.CreateThread)(1, "First Post (title)", "Body of the first post. (body)") } func main() { diff --git a/examples/gno.land/r/demo/boards/z_0_d_filetest.gno b/examples/gno.land/r/demo/boards/z_0_d_filetest.gno index 9aca12858ba..3db13203d41 100644 --- a/examples/gno.land/r/demo/boards/z_0_d_filetest.gno +++ b/examples/gno.land/r/demo/boards/z_0_d_filetest.gno @@ -15,9 +15,9 @@ var bid boards.BoardID func init() { testing.SetRealm(std.NewUserRealm(std.Address("g1wymu47drhr0kuq2098m792lytgtj2nyx77yrsm"))) // so that CurrentRealm.Addr() matches OrigCaller - users.Register("gnouser123") - bid = boards.CreateBoard("test_board") - boards.CreateReply(bid, 0, 0, "Reply of the second post") + cross(users.Register)("gnouser123") + bid = cross(boards.CreateBoard)("test_board") + cross(boards.CreateReply)(bid, 0, 0, "Reply of the second post") } func main() { diff --git a/examples/gno.land/r/demo/boards/z_0_e_filetest.gno b/examples/gno.land/r/demo/boards/z_0_e_filetest.gno index 3dd5d157a81..73a034c3858 100644 --- a/examples/gno.land/r/demo/boards/z_0_e_filetest.gno +++ b/examples/gno.land/r/demo/boards/z_0_e_filetest.gno @@ -15,8 +15,8 @@ var bid boards.BoardID func init() { testing.SetRealm(std.NewUserRealm(std.Address("g1wymu47drhr0kuq2098m792lytgtj2nyx77yrsm"))) // so that CurrentRealm.Addr() matches OrigCaller - users.Register("gnouser123") - boards.CreateReply(bid, 0, 0, "Reply of the second post") + cross(users.Register)("gnouser123") + cross(boards.CreateReply)(bid, 0, 0, "Reply of the second post") } func main() { diff --git a/examples/gno.land/r/demo/boards/z_0_filetest.gno b/examples/gno.land/r/demo/boards/z_0_filetest.gno index 879911f68b4..65c16de062e 100644 --- a/examples/gno.land/r/demo/boards/z_0_filetest.gno +++ b/examples/gno.land/r/demo/boards/z_0_filetest.gno @@ -1,5 +1,4 @@ -// PKGPATH: gno.land/r/demo/boards_test -package boards_test +package main // SEND: 1000000ugnot @@ -15,12 +14,12 @@ var bid boards.BoardID func init() { testing.SetRealm(std.NewUserRealm(std.Address("g1wymu47drhr0kuq2098m792lytgtj2nyx77yrsm"))) // so that CurrentRealm.Addr() matches OrigCaller - users.Register("gnouser123") + cross(users.Register)("gnouser123") - bid = boards.CreateBoard("test_board") - boards.CreateThread(bid, "First Post (title)", "Body of the first post. (body)") - pid := boards.CreateThread(bid, "Second Post (title)", "Body of the second post. (body)") - boards.CreateReply(bid, pid, pid, "Reply of the second post") + bid = cross(boards.CreateBoard)("test_board") + cross(boards.CreateThread)(bid, "First Post (title)", "Body of the first post. (body)") + pid := cross(boards.CreateThread)(bid, "Second Post (title)", "Body of the second post. (body)") + cross(boards.CreateReply)(bid, pid, pid, "Reply of the second post") } func main() { diff --git a/examples/gno.land/r/demo/boards/z_10_a_filetest.gno b/examples/gno.land/r/demo/boards/z_10_a_filetest.gno index 3f6e5e869ab..2d0da5e5607 100644 --- a/examples/gno.land/r/demo/boards/z_10_a_filetest.gno +++ b/examples/gno.land/r/demo/boards/z_10_a_filetest.gno @@ -1,5 +1,4 @@ -// PKGPATH: gno.land/r/demo/boards_test -package boards_test +package main // SEND: 1000000ugnot import ( @@ -18,19 +17,19 @@ var ( func init() { testing.SetRealm(std.NewUserRealm(std.Address("g1wymu47drhr0kuq2098m792lytgtj2nyx77yrsm"))) // so that CurrentRealm.Addr() matches OrigCaller - users.Register("gnouser123") + cross(users.Register)("gnouser123") - bid = boards.CreateBoard("test_board") - pid = boards.CreateThread(bid, "First Post in (title)", "Body of the first post. (body)") + bid = cross(boards.CreateBoard)("test_board") + pid = cross(boards.CreateThread)(bid, "First Post in (title)", "Body of the first post. (body)") } func main() { println(boards.Render("test_board/" + strconv.Itoa(int(pid)))) // boardId 2 not exist - boards.DeletePost(2, pid, pid, "") + cross(boards.DeletePost)(2, pid, pid, "") println("----------------------------------------------------") println(boards.Render("test_board/" + strconv.Itoa(int(pid)))) } // Error: -// invalid non-user call +// board not exist diff --git a/examples/gno.land/r/demo/boards/z_10_b_filetest.gno b/examples/gno.land/r/demo/boards/z_10_b_filetest.gno index 6d4208c675a..cdc45227346 100644 --- a/examples/gno.land/r/demo/boards/z_10_b_filetest.gno +++ b/examples/gno.land/r/demo/boards/z_10_b_filetest.gno @@ -1,5 +1,4 @@ -// PKGPATH: gno.land/r/demo/boards_test -package boards_test +package main // SEND: 1000000ugnot @@ -19,19 +18,19 @@ var ( func init() { testing.SetRealm(std.NewUserRealm(std.Address("g1wymu47drhr0kuq2098m792lytgtj2nyx77yrsm"))) // so that CurrentRealm.Addr() matches OrigCaller - users.Register("gnouser123") + cross(users.Register)("gnouser123") - bid = boards.CreateBoard("test_board") - pid = boards.CreateThread(bid, "First Post in (title)", "Body of the first post. (body)") + bid = cross(boards.CreateBoard)("test_board") + pid = cross(boards.CreateThread)(bid, "First Post in (title)", "Body of the first post. (body)") } func main() { println(boards.Render("test_board/" + strconv.Itoa(int(pid)))) // pid of 2 not exist - boards.DeletePost(bid, 2, 2, "") + cross(boards.DeletePost)(bid, 2, 2, "") println("----------------------------------------------------") println(boards.Render("test_board/" + strconv.Itoa(int(pid)))) } // Error: -// invalid non-user call +// thread not exist diff --git a/examples/gno.land/r/demo/boards/z_10_c_filetest.gno b/examples/gno.land/r/demo/boards/z_10_c_filetest.gno index 956921ca65d..f7253ba4818 100644 --- a/examples/gno.land/r/demo/boards/z_10_c_filetest.gno +++ b/examples/gno.land/r/demo/boards/z_10_c_filetest.gno @@ -1,5 +1,4 @@ -// PKGPATH: gno.land/r/demo/boards_test -package boards_test +package main // SEND: 1000000ugnot @@ -20,17 +19,17 @@ var ( func init() { testing.SetRealm(std.NewUserRealm(std.Address("g1wymu47drhr0kuq2098m792lytgtj2nyx77yrsm"))) // so that CurrentRealm.Addr() matches OrigCaller - users.Register("gnouser123") + cross(users.Register)("gnouser123") - bid = boards.CreateBoard("test_board") - pid = boards.CreateThread(bid, "First Post in (title)", "Body of the first post. (body)") - rid = boards.CreateReply(bid, pid, pid, "First reply of the First post\n") + bid = cross(boards.CreateBoard)("test_board") + pid = cross(boards.CreateThread)(bid, "First Post in (title)", "Body of the first post. (body)") + rid = cross(boards.CreateReply)(bid, pid, pid, "First reply of the First post\n") } func main() { println(boards.Render("test_board/" + strconv.Itoa(int(pid)))) testing.SetRealm(std.NewUserRealm(std.Address("g1wymu47drhr0kuq2098m792lytgtj2nyx77yrsm"))) - boards.DeletePost(bid, pid, rid, "") + cross(boards.DeletePost)(bid, pid, rid, "") println("----------------------------------------------------") println(boards.Render("test_board/" + strconv.Itoa(int(pid)))) } @@ -42,7 +41,7 @@ func main() { // \- [@gnouser123](/u/gnouser123), [2009-02-13 11:31pm (UTC)](/r/demo/boards:test_board/1) \[[reply](/r/demo/boards$help&func=CreateReply&bid=1&postid=1&threadid=1)] \[[repost](/r/demo/boards$help&func=CreateRepost&bid=1&postid=1)] \[[x](/r/demo/boards$help&func=DeletePost&bid=1&postid=1&threadid=1)] // // > First reply of the First post -// > +// > // > \- [@gnouser123](/u/gnouser123), [2009-02-13 11:31pm (UTC)](/r/demo/boards:test_board/1/2) \[[reply](/r/demo/boards$help&func=CreateReply&bid=1&postid=2&threadid=1)] \[[x](/r/demo/boards$help&func=DeletePost&bid=1&postid=2&threadid=1)] // // ---------------------------------------------------- diff --git a/examples/gno.land/r/demo/boards/z_10_filetest.gno b/examples/gno.land/r/demo/boards/z_10_filetest.gno index 3acb8f31dfe..a24636a74d3 100644 --- a/examples/gno.land/r/demo/boards/z_10_filetest.gno +++ b/examples/gno.land/r/demo/boards/z_10_filetest.gno @@ -1,5 +1,4 @@ -// PKGPATH: gno.land/r/demo/boards_test -package boards_test +package main // SEND: 1000000ugnot @@ -19,16 +18,16 @@ var ( func init() { testing.SetRealm(std.NewUserRealm(std.Address("g1wymu47drhr0kuq2098m792lytgtj2nyx77yrsm"))) // so that CurrentRealm.Addr() matches OrigCaller - users.Register("gnouser123") + cross(users.Register)("gnouser123") - bid = boards.CreateBoard("test_board") - pid = boards.CreateThread(bid, "First Post in (title)", "Body of the first post. (body)") + bid = cross(boards.CreateBoard)("test_board") + pid = cross(boards.CreateThread)(bid, "First Post in (title)", "Body of the first post. (body)") } func main() { println(boards.Render("test_board/" + strconv.Itoa(int(pid)))) testing.SetRealm(std.NewUserRealm(std.Address("g1wymu47drhr0kuq2098m792lytgtj2nyx77yrsm"))) - boards.DeletePost(bid, pid, pid, "") + cross(boards.DeletePost)(bid, pid, pid, "") println("----------------------------------------------------") println(boards.Render("test_board/" + strconv.Itoa(int(pid)))) } diff --git a/examples/gno.land/r/demo/boards/z_11_a_filetest.gno b/examples/gno.land/r/demo/boards/z_11_a_filetest.gno index 515130be6bd..030f8b87fb0 100644 --- a/examples/gno.land/r/demo/boards/z_11_a_filetest.gno +++ b/examples/gno.land/r/demo/boards/z_11_a_filetest.gno @@ -1,5 +1,4 @@ -// PKGPATH: gno.land/r/demo/boards_test -package boards_test +package main // SEND: 1000000ugnot @@ -19,19 +18,19 @@ var ( func init() { testing.SetRealm(std.NewUserRealm(std.Address("g1wymu47drhr0kuq2098m792lytgtj2nyx77yrsm"))) // so that CurrentRealm.Addr() matches OrigCaller - users.Register("gnouser123") + cross(users.Register)("gnouser123") - bid = boards.CreateBoard("test_board") - pid = boards.CreateThread(bid, "First Post in (title)", "Body of the first post. (body)") + bid = cross(boards.CreateBoard)("test_board") + pid = cross(boards.CreateThread)(bid, "First Post in (title)", "Body of the first post. (body)") } func main() { println(boards.Render("test_board/" + strconv.Itoa(int(pid)))) // board 2 not exist - boards.EditPost(2, pid, pid, "Edited: First Post in (title)", "Edited: Body of the first post. (body)") + cross(boards.EditPost)(2, pid, pid, "Edited: First Post in (title)", "Edited: Body of the first post. (body)") println("----------------------------------------------------") println(boards.Render("test_board/" + strconv.Itoa(int(pid)))) } // Error: -// invalid non-user call +// board not exist diff --git a/examples/gno.land/r/demo/boards/z_11_b_filetest.gno b/examples/gno.land/r/demo/boards/z_11_b_filetest.gno index f3561b49e92..088881372b5 100644 --- a/examples/gno.land/r/demo/boards/z_11_b_filetest.gno +++ b/examples/gno.land/r/demo/boards/z_11_b_filetest.gno @@ -1,5 +1,4 @@ -// PKGPATH: gno.land/r/demo/boards_test -package boards_test +package main // SEND: 1000000ugnot @@ -19,19 +18,19 @@ var ( func init() { testing.SetRealm(std.NewUserRealm(std.Address("g1wymu47drhr0kuq2098m792lytgtj2nyx77yrsm"))) // so that CurrentRealm.Addr() matches OrigCaller - users.Register("gnouser123") + cross(users.Register)("gnouser123") - bid = boards.CreateBoard("test_board") - pid = boards.CreateThread(bid, "First Post in (title)", "Body of the first post. (body)") + bid = cross(boards.CreateBoard)("test_board") + pid = cross(boards.CreateThread)(bid, "First Post in (title)", "Body of the first post. (body)") } func main() { println(boards.Render("test_board/" + strconv.Itoa(int(pid)))) // thread 2 not exist - boards.EditPost(bid, 2, pid, "Edited: First Post in (title)", "Edited: Body of the first post. (body)") + cross(boards.EditPost)(bid, 2, pid, "Edited: First Post in (title)", "Edited: Body of the first post. (body)") println("----------------------------------------------------") println(boards.Render("test_board/" + strconv.Itoa(int(pid)))) } // Error: -// invalid non-user call +// thread not exist diff --git a/examples/gno.land/r/demo/boards/z_11_c_filetest.gno b/examples/gno.land/r/demo/boards/z_11_c_filetest.gno index 840a3ec8d4d..abd3335f370 100644 --- a/examples/gno.land/r/demo/boards/z_11_c_filetest.gno +++ b/examples/gno.land/r/demo/boards/z_11_c_filetest.gno @@ -1,5 +1,4 @@ -// PKGPATH: gno.land/r/demo/boards_test -package boards_test +package main // SEND: 1000000ugnot @@ -19,19 +18,19 @@ var ( func init() { testing.SetRealm(std.NewUserRealm(std.Address("g1wymu47drhr0kuq2098m792lytgtj2nyx77yrsm"))) // so that CurrentRealm.Addr() matches OrigCaller - users.Register("gnouser123") + cross(users.Register)("gnouser123") - bid = boards.CreateBoard("test_board") - pid = boards.CreateThread(bid, "First Post in (title)", "Body of the first post. (body)") + bid = cross(boards.CreateBoard)("test_board") + pid = cross(boards.CreateThread)(bid, "First Post in (title)", "Body of the first post. (body)") } func main() { println(boards.Render("test_board/" + strconv.Itoa(int(pid)))) // post 2 not exist - boards.EditPost(bid, pid, 2, "Edited: First Post in (title)", "Edited: Body of the first post. (body)") + cross(boards.EditPost)(bid, pid, 2, "Edited: First Post in (title)", "Edited: Body of the first post. (body)") println("----------------------------------------------------") println(boards.Render("test_board/" + strconv.Itoa(int(pid)))) } // Error: -// invalid non-user call +// post not exist diff --git a/examples/gno.land/r/demo/boards/z_11_d_filetest.gno b/examples/gno.land/r/demo/boards/z_11_d_filetest.gno index 42befe3b1ea..c489c8bbc21 100644 --- a/examples/gno.land/r/demo/boards/z_11_d_filetest.gno +++ b/examples/gno.land/r/demo/boards/z_11_d_filetest.gno @@ -1,5 +1,4 @@ -// PKGPATH: gno.land/r/demo/boards_test -package boards_test +package main // SEND: 1000000ugnot @@ -20,17 +19,17 @@ var ( func init() { testing.SetRealm(std.NewUserRealm(std.Address("g1wymu47drhr0kuq2098m792lytgtj2nyx77yrsm"))) // so that CurrentRealm.Addr() matches OrigCaller - users.Register("gnouser123") + cross(users.Register)("gnouser123") - bid = boards.CreateBoard("test_board") - pid = boards.CreateThread(bid, "First Post in (title)", "Body of the first post. (body)") - rid = boards.CreateReply(bid, pid, pid, "First reply of the First post\n") + bid = cross(boards.CreateBoard)("test_board") + pid = cross(boards.CreateThread)(bid, "First Post in (title)", "Body of the first post. (body)") + rid = cross(boards.CreateReply)(bid, pid, pid, "First reply of the First post\n") } func main() { println(boards.Render("test_board/" + strconv.Itoa(int(pid)))) testing.SetRealm(std.NewUserRealm(std.Address("g1wymu47drhr0kuq2098m792lytgtj2nyx77yrsm"))) - boards.EditPost(bid, pid, rid, "", "Edited: First reply of the First post\n") + cross(boards.EditPost)(bid, pid, rid, "", "Edited: First reply of the First post\n") println("----------------------------------------------------") println(boards.Render("test_board/" + strconv.Itoa(int(pid)))) } @@ -42,7 +41,7 @@ func main() { // \- [@gnouser123](/u/gnouser123), [2009-02-13 11:31pm (UTC)](/r/demo/boards:test_board/1) \[[reply](/r/demo/boards$help&func=CreateReply&bid=1&postid=1&threadid=1)] \[[repost](/r/demo/boards$help&func=CreateRepost&bid=1&postid=1)] \[[x](/r/demo/boards$help&func=DeletePost&bid=1&postid=1&threadid=1)] // // > First reply of the First post -// > +// > // > \- [@gnouser123](/u/gnouser123), [2009-02-13 11:31pm (UTC)](/r/demo/boards:test_board/1/2) \[[reply](/r/demo/boards$help&func=CreateReply&bid=1&postid=2&threadid=1)] \[[x](/r/demo/boards$help&func=DeletePost&bid=1&postid=2&threadid=1)] // // ---------------------------------------------------- @@ -52,6 +51,6 @@ func main() { // \- [@gnouser123](/u/gnouser123), [2009-02-13 11:31pm (UTC)](/r/demo/boards:test_board/1) \[[reply](/r/demo/boards$help&func=CreateReply&bid=1&postid=1&threadid=1)] \[[repost](/r/demo/boards$help&func=CreateRepost&bid=1&postid=1)] \[[x](/r/demo/boards$help&func=DeletePost&bid=1&postid=1&threadid=1)] // // > Edited: First reply of the First post -// > +// > // > \- [@gnouser123](/u/gnouser123), [2009-02-13 11:31pm (UTC)](/r/demo/boards:test_board/1/2) \[[reply](/r/demo/boards$help&func=CreateReply&bid=1&postid=2&threadid=1)] \[[x](/r/demo/boards$help&func=DeletePost&bid=1&postid=2&threadid=1)] // diff --git a/examples/gno.land/r/demo/boards/z_11_filetest.gno b/examples/gno.land/r/demo/boards/z_11_filetest.gno index 4473192da28..18de930199c 100644 --- a/examples/gno.land/r/demo/boards/z_11_filetest.gno +++ b/examples/gno.land/r/demo/boards/z_11_filetest.gno @@ -1,5 +1,4 @@ -// PKGPATH: gno.land/r/demo/boards_test -package boards_test +package main // SEND: 1000000ugnot @@ -19,16 +18,16 @@ var ( func init() { testing.SetRealm(std.NewUserRealm(std.Address("g1wymu47drhr0kuq2098m792lytgtj2nyx77yrsm"))) // so that CurrentRealm.Addr() matches OrigCaller - users.Register("gnouser123") + cross(users.Register)("gnouser123") - bid = boards.CreateBoard("test_board") - pid = boards.CreateThread(bid, "First Post in (title)", "Body of the first post. (body)") + bid = cross(boards.CreateBoard)("test_board") + pid = cross(boards.CreateThread)(bid, "First Post in (title)", "Body of the first post. (body)") } func main() { println(boards.Render("test_board/" + strconv.Itoa(int(pid)))) testing.SetRealm(std.NewUserRealm(std.Address("g1wymu47drhr0kuq2098m792lytgtj2nyx77yrsm"))) - boards.EditPost(bid, pid, pid, "Edited: First Post in (title)", "Edited: Body of the first post. (body)") + cross(boards.EditPost)(bid, pid, pid, "Edited: First Post in (title)", "Edited: Body of the first post. (body)") println("----------------------------------------------------") println(boards.Render("test_board/" + strconv.Itoa(int(pid)))) } diff --git a/examples/gno.land/r/demo/boards/z_12_a_filetest.gno b/examples/gno.land/r/demo/boards/z_12_a_filetest.gno index 162b444522d..2c8d1ca8ae1 100644 --- a/examples/gno.land/r/demo/boards/z_12_a_filetest.gno +++ b/examples/gno.land/r/demo/boards/z_12_a_filetest.gno @@ -1,5 +1,4 @@ -// PKGPATH: gno.land/r/demo/boards_test -package boards_test +package main // SEND: 1000000ugnot @@ -14,18 +13,18 @@ import ( func main() { testing.SetRealm(std.NewUserRealm(std.Address("g1wymu47drhr0kuq2098m792lytgtj2nyx77yrsm"))) // so that CurrentRealm.Addr() matches OrigCaller - users.Register("gnouser123") + cross(users.Register)("gnouser123") // create a post via registered user - bid1 := boards.CreateBoard("test_board1") - pid := boards.CreateThread(bid1, "First Post (title)", "Body of the first post. (body)") - bid2 := boards.CreateBoard("test_board2") + bid1 := cross(boards.CreateBoard)("test_board1") + pid := cross(boards.CreateThread)(bid1, "First Post (title)", "Body of the first post. (body)") + bid2 := cross(boards.CreateBoard)("test_board2") // create a repost via anon user test2 := testutils.TestAddress("test2") testing.SetOriginCaller(test2) testing.SetOriginSend(std.Coins{{"ugnot", 9000000}}) - rid := boards.CreateRepost(bid1, pid, "", "Check this out", bid2) + rid := cross(boards.CreateRepost)(bid1, pid, "", "Check this out", bid2) println(rid) println(boards.Render("test_board1")) } diff --git a/examples/gno.land/r/demo/boards/z_12_b_filetest.gno b/examples/gno.land/r/demo/boards/z_12_b_filetest.gno index f9c826c1c99..4cf8b642c62 100644 --- a/examples/gno.land/r/demo/boards/z_12_b_filetest.gno +++ b/examples/gno.land/r/demo/boards/z_12_b_filetest.gno @@ -1,5 +1,4 @@ -// PKGPATH: gno.land/r/demo/boards_test -package boards_test +package main // SEND: 1000000ugnot @@ -13,13 +12,13 @@ import ( func main() { testing.SetRealm(std.NewUserRealm(std.Address("g1wymu47drhr0kuq2098m792lytgtj2nyx77yrsm"))) // so that CurrentRealm.Addr() matches OrigCaller - users.Register("gnouser123") - bid1 := boards.CreateBoard("test_board1") - pid := boards.CreateThread(bid1, "First Post (title)", "Body of the first post. (body)") - bid2 := boards.CreateBoard("test_board2") + cross(users.Register)("gnouser123") + bid1 := cross(boards.CreateBoard)("test_board1") + pid := cross(boards.CreateThread)(bid1, "First Post (title)", "Body of the first post. (body)") + bid2 := cross(boards.CreateBoard)("test_board2") // create a repost to a non-existing board - rid := boards.CreateRepost(5, pid, "", "Check this out", bid2) + rid := cross(boards.CreateRepost)(5, pid, "", "Check this out", bid2) println(rid) println(boards.Render("test_board1")) } diff --git a/examples/gno.land/r/demo/boards/z_12_c_filetest.gno b/examples/gno.land/r/demo/boards/z_12_c_filetest.gno index 665e8ae4820..f0cd0d6e20b 100644 --- a/examples/gno.land/r/demo/boards/z_12_c_filetest.gno +++ b/examples/gno.land/r/demo/boards/z_12_c_filetest.gno @@ -1,5 +1,4 @@ -// PKGPATH: gno.land/r/demo/boards_test -package boards_test +package main // SEND: 1000000ugnot @@ -13,13 +12,13 @@ import ( func main() { testing.SetRealm(std.NewUserRealm(std.Address("g1wymu47drhr0kuq2098m792lytgtj2nyx77yrsm"))) // so that CurrentRealm.Addr() matches OrigCaller - users.Register("gnouser123") - bid1 := boards.CreateBoard("test_board1") - boards.CreateThread(bid1, "First Post (title)", "Body of the first post. (body)") - bid2 := boards.CreateBoard("test_board2") + cross(users.Register)("gnouser123") + bid1 := cross(boards.CreateBoard)("test_board1") + cross(boards.CreateThread)(bid1, "First Post (title)", "Body of the first post. (body)") + bid2 := cross(boards.CreateBoard)("test_board2") // create a repost to a non-existing thread - rid := boards.CreateRepost(bid1, 5, "", "Check this out", bid2) + rid := cross(boards.CreateRepost)(bid1, 5, "", "Check this out", bid2) println(rid) println(boards.Render("test_board1")) } diff --git a/examples/gno.land/r/demo/boards/z_12_d_filetest.gno b/examples/gno.land/r/demo/boards/z_12_d_filetest.gno index 6f07220f67e..2923fd66605 100644 --- a/examples/gno.land/r/demo/boards/z_12_d_filetest.gno +++ b/examples/gno.land/r/demo/boards/z_12_d_filetest.gno @@ -1,5 +1,4 @@ -// PKGPATH: gno.land/r/demo/boards_test -package boards_test +package main // SEND: 1000000ugnot @@ -13,13 +12,13 @@ import ( func main() { testing.SetRealm(std.NewUserRealm(std.Address("g1wymu47drhr0kuq2098m792lytgtj2nyx77yrsm"))) // so that CurrentRealm.Addr() matches OrigCaller - users.Register("gnouser123") - bid1 := boards.CreateBoard("test_board1") - pid := boards.CreateThread(bid1, "First Post (title)", "Body of the first post. (body)") - boards.CreateBoard("test_board2") + cross(users.Register)("gnouser123") + bid1 := cross(boards.CreateBoard)("test_board1") + pid := cross(boards.CreateThread)(bid1, "First Post (title)", "Body of the first post. (body)") + cross(boards.CreateBoard)("test_board2") // create a repost to a non-existing destination board - rid := boards.CreateRepost(bid1, pid, "", "Check this out", 5) + rid := cross(boards.CreateRepost)(bid1, pid, "", "Check this out", 5) println(rid) println(boards.Render("test_board1")) } diff --git a/examples/gno.land/r/demo/boards/z_12_filetest.gno b/examples/gno.land/r/demo/boards/z_12_filetest.gno index 72631ee7eeb..a89fd359119 100644 --- a/examples/gno.land/r/demo/boards/z_12_filetest.gno +++ b/examples/gno.land/r/demo/boards/z_12_filetest.gno @@ -1,5 +1,4 @@ -// PKGPATH: gno.land/r/demo/boards_test -package boards_test +package main // SEND: 1000000ugnot @@ -19,16 +18,16 @@ var ( func init() { testing.SetRealm(std.NewUserRealm(std.Address("g1wymu47drhr0kuq2098m792lytgtj2nyx77yrsm"))) // so that CurrentRealm.Addr() matches OrigCaller - users.Register("gnouser123") + cross(users.Register)("gnouser123") - bid1 = boards.CreateBoard("test_board1") - pid = boards.CreateThread(bid1, "First Post (title)", "Body of the first post. (body)") - bid2 = boards.CreateBoard("test_board2") + bid1 = cross(boards.CreateBoard)("test_board1") + pid = cross(boards.CreateThread)(bid1, "First Post (title)", "Body of the first post. (body)") + bid2 = cross(boards.CreateBoard)("test_board2") } func main() { testing.SetRealm(std.NewUserRealm(std.Address("g1wymu47drhr0kuq2098m792lytgtj2nyx77yrsm"))) - rid := boards.CreateRepost(bid1, pid, "", "Check this out", bid2) + rid := cross(boards.CreateRepost)(bid1, pid, "", "Check this out", bid2) println(rid) println(boards.Render("test_board2")) } diff --git a/examples/gno.land/r/demo/boards/z_1_filetest.gno b/examples/gno.land/r/demo/boards/z_1_filetest.gno index 7f31058d843..eb72c865807 100644 --- a/examples/gno.land/r/demo/boards/z_1_filetest.gno +++ b/examples/gno.land/r/demo/boards/z_1_filetest.gno @@ -1,5 +1,4 @@ -// PKGPATH: gno.land/r/demo/boards_test -package boards_test +package main // SEND: 1000000ugnot @@ -15,10 +14,10 @@ var board *boards.Board func init() { testing.SetRealm(std.NewUserRealm(std.Address("g1wymu47drhr0kuq2098m792lytgtj2nyx77yrsm"))) // so that CurrentRealm.Addr() matches OrigCaller - users.Register("gnouser123") + cross(users.Register)("gnouser123") - _ = boards.CreateBoard("test_board_1") - _ = boards.CreateBoard("test_board_2") + _ = cross(boards.CreateBoard)("test_board_1") + _ = cross(boards.CreateBoard)("test_board_2") } func main() { diff --git a/examples/gno.land/r/demo/boards/z_2_filetest.gno b/examples/gno.land/r/demo/boards/z_2_filetest.gno index fa0c539e0e5..9c2bb32a0b8 100644 --- a/examples/gno.land/r/demo/boards/z_2_filetest.gno +++ b/examples/gno.land/r/demo/boards/z_2_filetest.gno @@ -1,5 +1,4 @@ -// PKGPATH: gno.land/r/demo/boards_test -package boards_test +package main // SEND: 1000000ugnot @@ -19,12 +18,12 @@ var ( func init() { testing.SetRealm(std.NewUserRealm(std.Address("g1wymu47drhr0kuq2098m792lytgtj2nyx77yrsm"))) // so that CurrentRealm.Addr() matches OrigCaller - users.Register("gnouser123") + cross(users.Register)("gnouser123") - bid = boards.CreateBoard("test_board") - boards.CreateThread(bid, "First Post (title)", "Body of the first post. (body)") - pid = boards.CreateThread(bid, "Second Post (title)", "Body of the second post. (body)") - boards.CreateReply(bid, pid, pid, "Reply of the second post") + bid = cross(boards.CreateBoard)("test_board") + cross(boards.CreateThread)(bid, "First Post (title)", "Body of the first post. (body)") + pid = cross(boards.CreateThread)(bid, "Second Post (title)", "Body of the second post. (body)") + cross(boards.CreateReply)(bid, pid, pid, "Reply of the second post") } func main() { diff --git a/examples/gno.land/r/demo/boards/z_3_filetest.gno b/examples/gno.land/r/demo/boards/z_3_filetest.gno index dd09fcb42de..4724207bd9b 100644 --- a/examples/gno.land/r/demo/boards/z_3_filetest.gno +++ b/examples/gno.land/r/demo/boards/z_3_filetest.gno @@ -1,5 +1,4 @@ -// PKGPATH: gno.land/r/demo/boards_test -package boards_test +package main // SEND: 1000000ugnot @@ -19,16 +18,16 @@ var ( func init() { testing.SetRealm(std.NewUserRealm(std.Address("g1wymu47drhr0kuq2098m792lytgtj2nyx77yrsm"))) // so that CurrentRealm.Addr() matches OrigCaller - users.Register("gnouser123") + cross(users.Register)("gnouser123") - bid = boards.CreateBoard("test_board") - boards.CreateThread(bid, "First Post (title)", "Body of the first post. (body)") - pid = boards.CreateThread(bid, "Second Post (title)", "Body of the second post. (body)") + bid = cross(boards.CreateBoard)("test_board") + cross(boards.CreateThread)(bid, "First Post (title)", "Body of the first post. (body)") + pid = cross(boards.CreateThread)(bid, "Second Post (title)", "Body of the second post. (body)") } func main() { testing.SetRealm(std.NewUserRealm(std.Address("g1wymu47drhr0kuq2098m792lytgtj2nyx77yrsm"))) - rid := boards.CreateReply(bid, pid, pid, "Reply of the second post") + rid := cross(boards.CreateReply)(bid, pid, pid, "Reply of the second post") println(rid) println(boards.Render("test_board/" + strconv.Itoa(int(pid)))) } diff --git a/examples/gno.land/r/demo/boards/z_4_filetest.gno b/examples/gno.land/r/demo/boards/z_4_filetest.gno index 634a8fe09a2..2b921ecc01e 100644 --- a/examples/gno.land/r/demo/boards/z_4_filetest.gno +++ b/examples/gno.land/r/demo/boards/z_4_filetest.gno @@ -1,5 +1,4 @@ -// PKGPATH: gno.land/r/demo/boards_test -package boards_test +package main // SEND: 1000000ugnot @@ -19,18 +18,18 @@ var ( func init() { testing.SetRealm(std.NewUserRealm(std.Address("g1wymu47drhr0kuq2098m792lytgtj2nyx77yrsm"))) // so that CurrentRealm.Addr() matches OrigCaller - users.Register("gnouser123") + cross(users.Register)("gnouser123") - bid = boards.CreateBoard("test_board") - boards.CreateThread(bid, "First Post (title)", "Body of the first post. (body)") - pid = boards.CreateThread(bid, "Second Post (title)", "Body of the second post. (body)") - rid := boards.CreateReply(bid, pid, pid, "Reply of the second post") + bid = cross(boards.CreateBoard)("test_board") + cross(boards.CreateThread)(bid, "First Post (title)", "Body of the first post. (body)") + pid = cross(boards.CreateThread)(bid, "Second Post (title)", "Body of the second post. (body)") + rid := cross(boards.CreateReply)(bid, pid, pid, "Reply of the second post") println(rid) } func main() { testing.SetRealm(std.NewUserRealm(std.Address("g1wymu47drhr0kuq2098m792lytgtj2nyx77yrsm"))) - rid2 := boards.CreateReply(bid, pid, pid, "Second reply of the second post") + rid2 := cross(boards.CreateReply)(bid, pid, pid, "Second reply of the second post") println(rid2) println(boards.Render("test_board/" + strconv.Itoa(int(pid)))) } @@ -49,791 +48,3 @@ func main() { // > Second reply of the second post // > \- [@gnouser123](/u/gnouser123), [2009-02-13 11:31pm (UTC)](/r/demo/boards:test_board/2/4) \[[reply](/r/demo/boards$help&func=CreateReply&bid=1&postid=4&threadid=2)] \[[x](/r/demo/boards$help&func=DeletePost&bid=1&postid=4&threadid=2)] // - -// Realm: -// finalizerealm["gno.land/r/sys/users"] -// finalizerealm["gno.land/r/sys/users"] -// finalizerealm["gno.land/r/demo/boards"] -// u[f6dbf411da22e67d74cd7ddba6a76cd7e14a4822:111]= -// @@ -1,8 +1,8 @@ -// { -// "ObjectInfo": { -// "ID": "f6dbf411da22e67d74cd7ddba6a76cd7e14a4822:111", -// - "ModTime": "0", -// - "OwnerID": "f6dbf411da22e67d74cd7ddba6a76cd7e14a4822:106", -// + "ModTime": "123", -// + "OwnerID": "f6dbf411da22e67d74cd7ddba6a76cd7e14a4822:123", -// "RefCount": "1" -// }, -// "Value": { -// c[f6dbf411da22e67d74cd7ddba6a76cd7e14a4822:125]={ -// "Fields": [ -// { -// "T": { -// "@type": "/gno.PrimitiveType", -// "value": "16" -// }, -// "V": { -// "@type": "/gno.StringValue", -// "value": "0000000004" -// } -// }, -// { -// "T": { -// "@type": "/gno.PointerType", -// "Elt": { -// "@type": "/gno.RefType", -// "ID": "gno.land/r/demo/boards.Post" -// } -// }, -// "V": { -// "@type": "/gno.PointerValue", -// "Base": { -// "@type": "/gno.RefValue", -// "Escaped": true, -// "ObjectID": "f6dbf411da22e67d74cd7ddba6a76cd7e14a4822:126" -// }, -// "Index": "0", -// "TV": null -// } -// }, -// { -// "T": { -// "@type": "/gno.PrimitiveType", -// "value": "64" -// } -// }, -// { -// "N": "AQAAAAAAAAA=", -// "T": { -// "@type": "/gno.PrimitiveType", -// "value": "32" -// } -// }, -// { -// "T": { -// "@type": "/gno.PointerType", -// "Elt": { -// "@type": "/gno.RefType", -// "ID": "gno.land/p/demo/avl.Node" -// } -// } -// }, -// { -// "T": { -// "@type": "/gno.PointerType", -// "Elt": { -// "@type": "/gno.RefType", -// "ID": "gno.land/p/demo/avl.Node" -// } -// } -// } -// ], -// "ObjectInfo": { -// "ID": "f6dbf411da22e67d74cd7ddba6a76cd7e14a4822:125", -// "ModTime": "0", -// "OwnerID": "f6dbf411da22e67d74cd7ddba6a76cd7e14a4822:124", -// "RefCount": "1" -// } -// } -// c[f6dbf411da22e67d74cd7ddba6a76cd7e14a4822:124]={ -// "ObjectInfo": { -// "ID": "f6dbf411da22e67d74cd7ddba6a76cd7e14a4822:124", -// "ModTime": "0", -// "OwnerID": "f6dbf411da22e67d74cd7ddba6a76cd7e14a4822:123", -// "RefCount": "1" -// }, -// "Value": { -// "T": { -// "@type": "/gno.RefType", -// "ID": "gno.land/p/demo/avl.Node" -// }, -// "V": { -// "@type": "/gno.RefValue", -// "Hash": "3f34ac77289aa1d5f9a2f8b6d083138325816fb0", -// "ObjectID": "f6dbf411da22e67d74cd7ddba6a76cd7e14a4822:125" -// } -// } -// } -// c[f6dbf411da22e67d74cd7ddba6a76cd7e14a4822:123]={ -// "Fields": [ -// { -// "T": { -// "@type": "/gno.PrimitiveType", -// "value": "16" -// }, -// "V": { -// "@type": "/gno.StringValue", -// "value": "0000000004" -// } -// }, -// {}, -// { -// "N": "AQAAAAAAAAA=", -// "T": { -// "@type": "/gno.PrimitiveType", -// "value": "64" -// } -// }, -// { -// "N": "AgAAAAAAAAA=", -// "T": { -// "@type": "/gno.PrimitiveType", -// "value": "32" -// } -// }, -// { -// "T": { -// "@type": "/gno.PointerType", -// "Elt": { -// "@type": "/gno.RefType", -// "ID": "gno.land/p/demo/avl.Node" -// } -// }, -// "V": { -// "@type": "/gno.PointerValue", -// "Base": { -// "@type": "/gno.RefValue", -// "Hash": "94a6665a44bac6ede7f3e3b87173e537b12f9532", -// "ObjectID": "f6dbf411da22e67d74cd7ddba6a76cd7e14a4822:111" -// }, -// "Index": "0", -// "TV": null -// } -// }, -// { -// "T": { -// "@type": "/gno.PointerType", -// "Elt": { -// "@type": "/gno.RefType", -// "ID": "gno.land/p/demo/avl.Node" -// } -// }, -// "V": { -// "@type": "/gno.PointerValue", -// "Base": { -// "@type": "/gno.RefValue", -// "Hash": "bc8e5b4e782a0bbc4ac9689681f119beb7b34d59", -// "ObjectID": "f6dbf411da22e67d74cd7ddba6a76cd7e14a4822:124" -// }, -// "Index": "0", -// "TV": null -// } -// } -// ], -// "ObjectInfo": { -// "ID": "f6dbf411da22e67d74cd7ddba6a76cd7e14a4822:123", -// "ModTime": "0", -// "OwnerID": "f6dbf411da22e67d74cd7ddba6a76cd7e14a4822:122", -// "RefCount": "1" -// } -// } -// c[f6dbf411da22e67d74cd7ddba6a76cd7e14a4822:122]={ -// "ObjectInfo": { -// "ID": "f6dbf411da22e67d74cd7ddba6a76cd7e14a4822:122", -// "ModTime": "0", -// "OwnerID": "f6dbf411da22e67d74cd7ddba6a76cd7e14a4822:106", -// "RefCount": "1" -// }, -// "Value": { -// "T": { -// "@type": "/gno.RefType", -// "ID": "gno.land/p/demo/avl.Node" -// }, -// "V": { -// "@type": "/gno.RefValue", -// "Hash": "9957eadbc91dd32f33b0d815e041a32dbdea0671", -// "ObjectID": "f6dbf411da22e67d74cd7ddba6a76cd7e14a4822:123" -// } -// } -// } -// c[f6dbf411da22e67d74cd7ddba6a76cd7e14a4822:128]={ -// "Fields": [ -// { -// "T": { -// "@type": "/gno.PointerType", -// "Elt": { -// "@type": "/gno.RefType", -// "ID": "gno.land/p/demo/avl.Node" -// } -// } -// } -// ], -// "ObjectInfo": { -// "ID": "f6dbf411da22e67d74cd7ddba6a76cd7e14a4822:128", -// "ModTime": "0", -// "OwnerID": "f6dbf411da22e67d74cd7ddba6a76cd7e14a4822:127", -// "RefCount": "1" -// } -// } -// c[f6dbf411da22e67d74cd7ddba6a76cd7e14a4822:129]={ -// "Fields": [ -// { -// "T": { -// "@type": "/gno.PointerType", -// "Elt": { -// "@type": "/gno.RefType", -// "ID": "gno.land/p/demo/avl.Node" -// } -// } -// } -// ], -// "ObjectInfo": { -// "ID": "f6dbf411da22e67d74cd7ddba6a76cd7e14a4822:129", -// "ModTime": "0", -// "OwnerID": "f6dbf411da22e67d74cd7ddba6a76cd7e14a4822:127", -// "RefCount": "1" -// } -// } -// c[f6dbf411da22e67d74cd7ddba6a76cd7e14a4822:130]={ -// "Fields": [ -// { -// "T": { -// "@type": "/gno.PointerType", -// "Elt": { -// "@type": "/gno.RefType", -// "ID": "gno.land/p/demo/avl.Node" -// } -// } -// } -// ], -// "ObjectInfo": { -// "ID": "f6dbf411da22e67d74cd7ddba6a76cd7e14a4822:130", -// "ModTime": "0", -// "OwnerID": "f6dbf411da22e67d74cd7ddba6a76cd7e14a4822:127", -// "RefCount": "1" -// } -// } -// c[f6dbf411da22e67d74cd7ddba6a76cd7e14a4822:131]={ -// "Fields": [ -// { -// "N": "AAAAgJSeXbo=", -// "T": { -// "@type": "/gno.PrimitiveType", -// "value": "65536" -// } -// }, -// { -// "N": "AbSNdvQQIhE=", -// "T": { -// "@type": "/gno.PrimitiveType", -// "value": "1024" -// } -// }, -// { -// "T": { -// "@type": "/gno.PointerType", -// "Elt": { -// "@type": "/gno.RefType", -// "ID": "time.Location" -// } -// }, -// "V": { -// "@type": "/gno.PointerValue", -// "Base": { -// "@type": "/gno.RefValue", -// "Escaped": true, -// "ObjectID": "336074805fc853987abe6f7fe3ad97a6a6f3077a:2" -// }, -// "Index": "182", -// "TV": null -// } -// } -// ], -// "ObjectInfo": { -// "ID": "f6dbf411da22e67d74cd7ddba6a76cd7e14a4822:131", -// "ModTime": "0", -// "OwnerID": "f6dbf411da22e67d74cd7ddba6a76cd7e14a4822:127", -// "RefCount": "1" -// } -// } -// c[f6dbf411da22e67d74cd7ddba6a76cd7e14a4822:132]={ -// "Fields": [ -// { -// "T": { -// "@type": "/gno.PrimitiveType", -// "value": "65536" -// } -// }, -// { -// "T": { -// "@type": "/gno.PrimitiveType", -// "value": "1024" -// } -// }, -// { -// "T": { -// "@type": "/gno.PointerType", -// "Elt": { -// "@type": "/gno.RefType", -// "ID": "time.Location" -// } -// } -// } -// ], -// "ObjectInfo": { -// "ID": "f6dbf411da22e67d74cd7ddba6a76cd7e14a4822:132", -// "ModTime": "0", -// "OwnerID": "f6dbf411da22e67d74cd7ddba6a76cd7e14a4822:127", -// "RefCount": "1" -// } -// } -// c[f6dbf411da22e67d74cd7ddba6a76cd7e14a4822:127]={ -// "Fields": [ -// { -// "T": { -// "@type": "/gno.PointerType", -// "Elt": { -// "@type": "/gno.RefType", -// "ID": "gno.land/r/demo/boards.Board" -// } -// }, -// "V": { -// "@type": "/gno.PointerValue", -// "Base": { -// "@type": "/gno.RefValue", -// "Escaped": true, -// "ObjectID": "f6dbf411da22e67d74cd7ddba6a76cd7e14a4822:84" -// }, -// "Index": "0", -// "TV": null -// } -// }, -// { -// "N": "BAAAAAAAAAA=", -// "T": { -// "@type": "/gno.RefType", -// "ID": "gno.land/r/demo/boards.PostID" -// } -// }, -// { -// "T": { -// "@type": "/gno.RefType", -// "ID": "std.Address" -// }, -// "V": { -// "@type": "/gno.StringValue", -// "value": "g1wymu47drhr0kuq2098m792lytgtj2nyx77yrsm" -// } -// }, -// { -// "T": { -// "@type": "/gno.PrimitiveType", -// "value": "16" -// }, -// "V": { -// "@type": "/gno.StringValue", -// "value": "" -// } -// }, -// { -// "T": { -// "@type": "/gno.PrimitiveType", -// "value": "16" -// }, -// "V": { -// "@type": "/gno.StringValue", -// "value": "Second reply of the second post" -// } -// }, -// { -// "T": { -// "@type": "/gno.RefType", -// "ID": "gno.land/p/demo/avl.Tree" -// }, -// "V": { -// "@type": "/gno.RefValue", -// "Hash": "f91e355bd19240f0f3350a7fa0e6a82b72225916", -// "ObjectID": "f6dbf411da22e67d74cd7ddba6a76cd7e14a4822:128" -// } -// }, -// { -// "T": { -// "@type": "/gno.RefType", -// "ID": "gno.land/p/demo/avl.Tree" -// }, -// "V": { -// "@type": "/gno.RefValue", -// "Hash": "9ee9c4117be283fc51ffcc5ecd65b75ecef5a9dd", -// "ObjectID": "f6dbf411da22e67d74cd7ddba6a76cd7e14a4822:129" -// } -// }, -// { -// "T": { -// "@type": "/gno.RefType", -// "ID": "gno.land/p/demo/avl.Tree" -// }, -// "V": { -// "@type": "/gno.RefValue", -// "Hash": "eb768b0140a5fe95f9c58747f0960d647dacfd42", -// "ObjectID": "f6dbf411da22e67d74cd7ddba6a76cd7e14a4822:130" -// } -// }, -// { -// "N": "AgAAAAAAAAA=", -// "T": { -// "@type": "/gno.RefType", -// "ID": "gno.land/r/demo/boards.PostID" -// } -// }, -// { -// "N": "AgAAAAAAAAA=", -// "T": { -// "@type": "/gno.RefType", -// "ID": "gno.land/r/demo/boards.PostID" -// } -// }, -// { -// "T": { -// "@type": "/gno.RefType", -// "ID": "gno.land/r/demo/boards.BoardID" -// } -// }, -// { -// "T": { -// "@type": "/gno.RefType", -// "ID": "time.Time" -// }, -// "V": { -// "@type": "/gno.RefValue", -// "Hash": "0fd3352422af0a56a77ef2c9e88f479054e3d51f", -// "ObjectID": "f6dbf411da22e67d74cd7ddba6a76cd7e14a4822:131" -// } -// }, -// { -// "T": { -// "@type": "/gno.RefType", -// "ID": "time.Time" -// }, -// "V": { -// "@type": "/gno.RefValue", -// "Hash": "bed4afa8ffdbbf775451c947fc68b27a345ce32a", -// "ObjectID": "f6dbf411da22e67d74cd7ddba6a76cd7e14a4822:132" -// } -// } -// ], -// "ObjectInfo": { -// "ID": "f6dbf411da22e67d74cd7ddba6a76cd7e14a4822:127", -// "ModTime": "0", -// "OwnerID": "f6dbf411da22e67d74cd7ddba6a76cd7e14a4822:126", -// "RefCount": "1" -// } -// } -// c[f6dbf411da22e67d74cd7ddba6a76cd7e14a4822:126]={ -// "ObjectInfo": { -// "ID": "f6dbf411da22e67d74cd7ddba6a76cd7e14a4822:126", -// "IsEscaped": true, -// "ModTime": "0", -// "RefCount": "2" -// }, -// "Value": { -// "T": { -// "@type": "/gno.RefType", -// "ID": "gno.land/r/demo/boards.Post" -// }, -// "V": { -// "@type": "/gno.RefValue", -// "Hash": "c45bbd47a46681a63af973db0ec2180922e4a8ae", -// "ObjectID": "f6dbf411da22e67d74cd7ddba6a76cd7e14a4822:127" -// } -// } -// } -// u[f6dbf411da22e67d74cd7ddba6a76cd7e14a4822:120]= -// @@ -1,8 +1,8 @@ -// { -// "ObjectInfo": { -// "ID": "f6dbf411da22e67d74cd7ddba6a76cd7e14a4822:120", -// - "ModTime": "0", -// - "OwnerID": "f6dbf411da22e67d74cd7ddba6a76cd7e14a4822:107", -// + "ModTime": "134", -// + "OwnerID": "f6dbf411da22e67d74cd7ddba6a76cd7e14a4822:134", -// "RefCount": "1" -// }, -// "Value": { -// c[f6dbf411da22e67d74cd7ddba6a76cd7e14a4822:136]={ -// "Fields": [ -// { -// "T": { -// "@type": "/gno.PrimitiveType", -// "value": "16" -// }, -// "V": { -// "@type": "/gno.StringValue", -// "value": "0000000004" -// } -// }, -// { -// "T": { -// "@type": "/gno.PointerType", -// "Elt": { -// "@type": "/gno.RefType", -// "ID": "gno.land/r/demo/boards.Post" -// } -// }, -// "V": { -// "@type": "/gno.PointerValue", -// "Base": { -// "@type": "/gno.RefValue", -// "Escaped": true, -// "ObjectID": "f6dbf411da22e67d74cd7ddba6a76cd7e14a4822:126" -// }, -// "Index": "0", -// "TV": null -// } -// }, -// { -// "T": { -// "@type": "/gno.PrimitiveType", -// "value": "64" -// } -// }, -// { -// "N": "AQAAAAAAAAA=", -// "T": { -// "@type": "/gno.PrimitiveType", -// "value": "32" -// } -// }, -// { -// "T": { -// "@type": "/gno.PointerType", -// "Elt": { -// "@type": "/gno.RefType", -// "ID": "gno.land/p/demo/avl.Node" -// } -// } -// }, -// { -// "T": { -// "@type": "/gno.PointerType", -// "Elt": { -// "@type": "/gno.RefType", -// "ID": "gno.land/p/demo/avl.Node" -// } -// } -// } -// ], -// "ObjectInfo": { -// "ID": "f6dbf411da22e67d74cd7ddba6a76cd7e14a4822:136", -// "ModTime": "0", -// "OwnerID": "f6dbf411da22e67d74cd7ddba6a76cd7e14a4822:135", -// "RefCount": "1" -// } -// } -// c[f6dbf411da22e67d74cd7ddba6a76cd7e14a4822:135]={ -// "ObjectInfo": { -// "ID": "f6dbf411da22e67d74cd7ddba6a76cd7e14a4822:135", -// "ModTime": "0", -// "OwnerID": "f6dbf411da22e67d74cd7ddba6a76cd7e14a4822:134", -// "RefCount": "1" -// }, -// "Value": { -// "T": { -// "@type": "/gno.RefType", -// "ID": "gno.land/p/demo/avl.Node" -// }, -// "V": { -// "@type": "/gno.RefValue", -// "Hash": "96b86b4585c7f1075d7794180a5581f72733a7ab", -// "ObjectID": "f6dbf411da22e67d74cd7ddba6a76cd7e14a4822:136" -// } -// } -// } -// c[f6dbf411da22e67d74cd7ddba6a76cd7e14a4822:134]={ -// "Fields": [ -// { -// "T": { -// "@type": "/gno.PrimitiveType", -// "value": "16" -// }, -// "V": { -// "@type": "/gno.StringValue", -// "value": "0000000004" -// } -// }, -// {}, -// { -// "N": "AQAAAAAAAAA=", -// "T": { -// "@type": "/gno.PrimitiveType", -// "value": "64" -// } -// }, -// { -// "N": "AgAAAAAAAAA=", -// "T": { -// "@type": "/gno.PrimitiveType", -// "value": "32" -// } -// }, -// { -// "T": { -// "@type": "/gno.PointerType", -// "Elt": { -// "@type": "/gno.RefType", -// "ID": "gno.land/p/demo/avl.Node" -// } -// }, -// "V": { -// "@type": "/gno.PointerValue", -// "Base": { -// "@type": "/gno.RefValue", -// "Hash": "32274e1f28fb2b97d67a1262afd362d370de7faa", -// "ObjectID": "f6dbf411da22e67d74cd7ddba6a76cd7e14a4822:120" -// }, -// "Index": "0", -// "TV": null -// } -// }, -// { -// "T": { -// "@type": "/gno.PointerType", -// "Elt": { -// "@type": "/gno.RefType", -// "ID": "gno.land/p/demo/avl.Node" -// } -// }, -// "V": { -// "@type": "/gno.PointerValue", -// "Base": { -// "@type": "/gno.RefValue", -// "Hash": "c2cfd6aec36a462f35bf02e5bf4a127aa1bb7ac2", -// "ObjectID": "f6dbf411da22e67d74cd7ddba6a76cd7e14a4822:135" -// }, -// "Index": "0", -// "TV": null -// } -// } -// ], -// "ObjectInfo": { -// "ID": "f6dbf411da22e67d74cd7ddba6a76cd7e14a4822:134", -// "ModTime": "0", -// "OwnerID": "f6dbf411da22e67d74cd7ddba6a76cd7e14a4822:133", -// "RefCount": "1" -// } -// } -// c[f6dbf411da22e67d74cd7ddba6a76cd7e14a4822:133]={ -// "ObjectInfo": { -// "ID": "f6dbf411da22e67d74cd7ddba6a76cd7e14a4822:133", -// "ModTime": "0", -// "OwnerID": "f6dbf411da22e67d74cd7ddba6a76cd7e14a4822:107", -// "RefCount": "1" -// }, -// "Value": { -// "T": { -// "@type": "/gno.RefType", -// "ID": "gno.land/p/demo/avl.Node" -// }, -// "V": { -// "@type": "/gno.RefValue", -// "Hash": "5cb875179e86d32c517322af7a323b2a5f3e6cc5", -// "ObjectID": "f6dbf411da22e67d74cd7ddba6a76cd7e14a4822:134" -// } -// } -// } -// u[f6dbf411da22e67d74cd7ddba6a76cd7e14a4822:85]= -// @@ -49,7 +49,7 @@ -// } -// }, -// { -// - "N": "AwAAAAAAAAA=", -// + "N": "BAAAAAAAAAA=", -// "T": { -// "@type": "/gno.PrimitiveType", -// "value": "65536" -// @@ -80,7 +80,7 @@ -// ], -// "ObjectInfo": { -// "ID": "f6dbf411da22e67d74cd7ddba6a76cd7e14a4822:85", -// - "ModTime": "110", -// + "ModTime": "121", -// "OwnerID": "f6dbf411da22e67d74cd7ddba6a76cd7e14a4822:84", -// "RefCount": "1" -// } -// u[f6dbf411da22e67d74cd7ddba6a76cd7e14a4822:106]= -// @@ -12,8 +12,8 @@ -// "@type": "/gno.PointerValue", -// "Base": { -// "@type": "/gno.RefValue", -// - "Hash": "3d6aa1e96f126aba3cfd48f0203b85a287a6f1c0", -// - "ObjectID": "f6dbf411da22e67d74cd7ddba6a76cd7e14a4822:111" -// + "Hash": "9809329dc1ddc5d3556f7a8fa3c2cebcbf65560b", -// + "ObjectID": "f6dbf411da22e67d74cd7ddba6a76cd7e14a4822:122" -// }, -// "Index": "0", -// "TV": null -// @@ -22,7 +22,7 @@ -// ], -// "ObjectInfo": { -// "ID": "f6dbf411da22e67d74cd7ddba6a76cd7e14a4822:106", -// - "ModTime": "110", -// + "ModTime": "121", -// "OwnerID": "f6dbf411da22e67d74cd7ddba6a76cd7e14a4822:105", -// "RefCount": "1" -// } -// u[f6dbf411da22e67d74cd7ddba6a76cd7e14a4822:107]= -// @@ -12,8 +12,8 @@ -// "@type": "/gno.PointerValue", -// "Base": { -// "@type": "/gno.RefValue", -// - "Hash": "96a7d0b7b5bf5d366d10c559464ba56a50f78bbc", -// - "ObjectID": "f6dbf411da22e67d74cd7ddba6a76cd7e14a4822:120" -// + "Hash": "ceae9a1c4ed28bb51062e6ccdccfad0caafd1c4f", -// + "ObjectID": "f6dbf411da22e67d74cd7ddba6a76cd7e14a4822:133" -// }, -// "Index": "0", -// "TV": null -// @@ -22,7 +22,7 @@ -// ], -// "ObjectInfo": { -// "ID": "f6dbf411da22e67d74cd7ddba6a76cd7e14a4822:107", -// - "ModTime": "110", -// + "ModTime": "121", -// "OwnerID": "f6dbf411da22e67d74cd7ddba6a76cd7e14a4822:105", -// "RefCount": "1" -// } -// u[f6dbf411da22e67d74cd7ddba6a76cd7e14a4822:84]= -// @@ -2,8 +2,8 @@ -// "ObjectInfo": { -// "ID": "f6dbf411da22e67d74cd7ddba6a76cd7e14a4822:84", -// "IsEscaped": true, -// - "ModTime": "114", -// - "RefCount": "5" -// + "ModTime": "127", -// + "RefCount": "6" -// }, -// "Value": { -// "T": { -// @@ -12,7 +12,7 @@ -// }, -// "V": { -// "@type": "/gno.RefValue", -// - "Hash": "058a49e6ee26f75cc44901754d4c298fd1a1655c", -// + "Hash": "a88a9b837af217656ee27084309f7cd02cd94cb3", -// "ObjectID": "f6dbf411da22e67d74cd7ddba6a76cd7e14a4822:85" -// } -// } -// u[336074805fc853987abe6f7fe3ad97a6a6f3077a:2]= -// @@ -3,8 +3,8 @@ -// "ObjectInfo": { -// "ID": "336074805fc853987abe6f7fe3ad97a6a6f3077a:2", -// "IsEscaped": true, -// - "ModTime": "118", -// - "RefCount": "11" -// + "ModTime": "131", -// + "RefCount": "12" -// }, -// "Parent": null, -// "Source": { -// finalizerealm["gno.land/r/demo/boards"] -// finalizerealm["gno.land/r/sys/users"] -// finalizerealm["gno.land/r/sys/users"] -// finalizerealm["gno.land/r/sys/users"] -// finalizerealm["gno.land/r/sys/users"] -// finalizerealm["gno.land/r/sys/users"] -// finalizerealm["gno.land/r/sys/users"] -// finalizerealm["gno.land/r/sys/users"] -// finalizerealm["gno.land/r/sys/users"] -// finalizerealm["gno.land/r/sys/users"] -// finalizerealm["gno.land/r/demo/boards"] -// finalizerealm["gno.land/r/demo/boards_test"] diff --git a/examples/gno.land/r/demo/boards/z_5_b_filetest.gno b/examples/gno.land/r/demo/boards/z_5_b_filetest.gno index 1d08ff01afa..5f2671ab381 100644 --- a/examples/gno.land/r/demo/boards/z_5_b_filetest.gno +++ b/examples/gno.land/r/demo/boards/z_5_b_filetest.gno @@ -16,16 +16,16 @@ const admin = std.Address("g1us8428u2a5satrlxzagqqa5m6vmuze025anjlj") func main() { testing.SetRealm(std.NewUserRealm(std.Address("g1wymu47drhr0kuq2098m792lytgtj2nyx77yrsm"))) // so that CurrentRealm.Addr() matches OrigCaller - users.Register("gnouser123") + cross(users.Register)("gnouser123") // create board via registered user - bid := boards.CreateBoard("test_board") + bid := cross(boards.CreateBoard)("test_board") // create post via anon user test2 := testutils.TestAddress("test2") testing.SetOriginCaller(test2) testing.SetOriginSend(std.Coins{{"ugnot", 9000000}}) - pid := boards.CreateThread(bid, "First Post (title)", "Body of the first post. (body)") + pid := cross(boards.CreateThread)(bid, "First Post (title)", "Body of the first post. (body)") println(boards.Render("test_board/" + strconv.Itoa(int(pid)))) } diff --git a/examples/gno.land/r/demo/boards/z_5_c_filetest.gno b/examples/gno.land/r/demo/boards/z_5_c_filetest.gno index 3b0d1ca7f4b..ae2ff00efe4 100644 --- a/examples/gno.land/r/demo/boards/z_5_c_filetest.gno +++ b/examples/gno.land/r/demo/boards/z_5_c_filetest.gno @@ -16,17 +16,17 @@ const admin = std.Address("g1us8428u2a5satrlxzagqqa5m6vmuze025anjlj") func main() { testing.SetRealm(std.NewUserRealm(std.Address("g1wymu47drhr0kuq2098m792lytgtj2nyx77yrsm"))) // so that CurrentRealm.Addr() matches OrigCaller - users.Register("gnouser123") + cross(users.Register)("gnouser123") // create board via registered user - bid := boards.CreateBoard("test_board") + bid := cross(boards.CreateBoard)("test_board") // create post via anon user test2 := testutils.TestAddress("test2") testing.SetOriginCaller(test2) testing.SetOriginSend(std.Coins{{"ugnot", 101000000}}) - pid := boards.CreateThread(bid, "First Post (title)", "Body of the first post. (body)") - boards.CreateReply(bid, pid, pid, "Reply of the first post") + pid := cross(boards.CreateThread)(bid, "First Post (title)", "Body of the first post. (body)") + cross(boards.CreateReply)(bid, pid, pid, "Reply of the first post") println(boards.Render("test_board/" + strconv.Itoa(int(pid)))) } diff --git a/examples/gno.land/r/demo/boards/z_5_d_filetest.gno b/examples/gno.land/r/demo/boards/z_5_d_filetest.gno index 20cff9cdf55..2512cfe2297 100644 --- a/examples/gno.land/r/demo/boards/z_5_d_filetest.gno +++ b/examples/gno.land/r/demo/boards/z_5_d_filetest.gno @@ -16,16 +16,16 @@ const admin = std.Address("g1us8428u2a5satrlxzagqqa5m6vmuze025anjlj") func main() { testing.SetRealm(std.NewUserRealm(std.Address("g1wymu47drhr0kuq2098m792lytgtj2nyx77yrsm"))) // so that CurrentRealm.Addr() matches OrigCaller - users.Register("gnouser123") + cross(users.Register)("gnouser123") // create board via registered user - bid := boards.CreateBoard("test_board") - pid := boards.CreateThread(bid, "First Post (title)", "Body of the first post. (body)") + bid := cross(boards.CreateBoard)("test_board") + pid := cross(boards.CreateThread)(bid, "First Post (title)", "Body of the first post. (body)") // create reply via anon user test2 := testutils.TestAddress("test2") testing.SetOriginCaller(test2) testing.SetOriginSend(std.Coins{{"ugnot", 9000000}}) - boards.CreateReply(bid, pid, pid, "Reply of the first post") + cross(boards.CreateReply)(bid, pid, pid, "Reply of the first post") println(boards.Render("test_board/" + strconv.Itoa(int(pid)))) } diff --git a/examples/gno.land/r/demo/boards/z_5_filetest.gno b/examples/gno.land/r/demo/boards/z_5_filetest.gno index b1efd57550f..6eae728b28b 100644 --- a/examples/gno.land/r/demo/boards/z_5_filetest.gno +++ b/examples/gno.land/r/demo/boards/z_5_filetest.gno @@ -1,5 +1,4 @@ -// PKGPATH: gno.land/r/demo/boards_test -package boards_test +package main // SEND: 1000000ugnot @@ -19,17 +18,17 @@ var ( func init() { testing.SetRealm(std.NewUserRealm(std.Address("g1wymu47drhr0kuq2098m792lytgtj2nyx77yrsm"))) // so that CurrentRealm.Addr() matches OrigCaller - users.Register("gnouser123") + cross(users.Register)("gnouser123") - bid = boards.CreateBoard("test_board") - boards.CreateThread(bid, "First Post (title)", "Body of the first post. (body)") - pid = boards.CreateThread(bid, "Second Post (title)", "Body of the second post. (body)") - rid := boards.CreateReply(bid, pid, pid, "Reply of the second post") + bid = cross(boards.CreateBoard)("test_board") + cross(boards.CreateThread)(bid, "First Post (title)", "Body of the first post. (body)") + pid = cross(boards.CreateThread)(bid, "Second Post (title)", "Body of the second post. (body)") + rid := cross(boards.CreateReply)(bid, pid, pid, "Reply of the second post") } func main() { testing.SetRealm(std.NewUserRealm(std.Address("g1wymu47drhr0kuq2098m792lytgtj2nyx77yrsm"))) - rid2 := boards.CreateReply(bid, pid, pid, "Second reply of the second post\n") + rid2 := cross(boards.CreateReply)(bid, pid, pid, "Second reply of the second post\n") println(boards.Render("test_board/" + strconv.Itoa(int(pid)))) } @@ -43,6 +42,6 @@ func main() { // > \- [@gnouser123](/u/gnouser123), [2009-02-13 11:31pm (UTC)](/r/demo/boards:test_board/2/3) \[[reply](/r/demo/boards$help&func=CreateReply&bid=1&postid=3&threadid=2)] \[[x](/r/demo/boards$help&func=DeletePost&bid=1&postid=3&threadid=2)] // // > Second reply of the second post -// > +// > // > \- [@gnouser123](/u/gnouser123), [2009-02-13 11:31pm (UTC)](/r/demo/boards:test_board/2/4) \[[reply](/r/demo/boards$help&func=CreateReply&bid=1&postid=4&threadid=2)] \[[x](/r/demo/boards$help&func=DeletePost&bid=1&postid=4&threadid=2)] // diff --git a/examples/gno.land/r/demo/boards/z_6_filetest.gno b/examples/gno.land/r/demo/boards/z_6_filetest.gno index 82d21de4ad3..0b13ec5547e 100644 --- a/examples/gno.land/r/demo/boards/z_6_filetest.gno +++ b/examples/gno.land/r/demo/boards/z_6_filetest.gno @@ -1,5 +1,4 @@ -// PKGPATH: gno.land/r/demo/boards_test -package boards_test +package main // SEND: 1000000ugnot @@ -20,18 +19,18 @@ var ( func init() { testing.SetRealm(std.NewUserRealm(std.Address("g1wymu47drhr0kuq2098m792lytgtj2nyx77yrsm"))) // so that CurrentRealm.Addr() matches OrigCaller - users.Register("gnouser123") + cross(users.Register)("gnouser123") - bid = boards.CreateBoard("test_board") - boards.CreateThread(bid, "First Post (title)", "Body of the first post. (body)") - pid = boards.CreateThread(bid, "Second Post (title)", "Body of the second post. (body)") - rid = boards.CreateReply(bid, pid, pid, "Reply of the second post") + bid = cross(boards.CreateBoard)("test_board") + cross(boards.CreateThread)(bid, "First Post (title)", "Body of the first post. (body)") + pid = cross(boards.CreateThread)(bid, "Second Post (title)", "Body of the second post. (body)") + rid = cross(boards.CreateReply)(bid, pid, pid, "Reply of the second post") } func main() { testing.SetRealm(std.NewUserRealm(std.Address("g1wymu47drhr0kuq2098m792lytgtj2nyx77yrsm"))) - boards.CreateReply(bid, pid, pid, "Second reply of the second post\n") - boards.CreateReply(bid, pid, rid, "First reply of the first reply\n") + cross(boards.CreateReply)(bid, pid, pid, "Second reply of the second post\n") + cross(boards.CreateReply)(bid, pid, rid, "First reply of the first reply\n") println(boards.Render("test_board/" + strconv.Itoa(int(pid)))) } @@ -43,12 +42,12 @@ func main() { // // > Reply of the second post // > \- [@gnouser123](/u/gnouser123), [2009-02-13 11:31pm (UTC)](/r/demo/boards:test_board/2/3) \[[reply](/r/demo/boards$help&func=CreateReply&bid=1&postid=3&threadid=2)] \[[x](/r/demo/boards$help&func=DeletePost&bid=1&postid=3&threadid=2)] -// > +// > // > > First reply of the first reply -// > > +// > > // > > \- [@gnouser123](/u/gnouser123), [2009-02-13 11:31pm (UTC)](/r/demo/boards:test_board/2/5) \[[reply](/r/demo/boards$help&func=CreateReply&bid=1&postid=5&threadid=2)] \[[x](/r/demo/boards$help&func=DeletePost&bid=1&postid=5&threadid=2)] // // > Second reply of the second post -// > +// > // > \- [@gnouser123](/u/gnouser123), [2009-02-13 11:31pm (UTC)](/r/demo/boards:test_board/2/4) \[[reply](/r/demo/boards$help&func=CreateReply&bid=1&postid=4&threadid=2)] \[[x](/r/demo/boards$help&func=DeletePost&bid=1&postid=4&threadid=2)] // diff --git a/examples/gno.land/r/demo/boards/z_7_filetest.gno b/examples/gno.land/r/demo/boards/z_7_filetest.gno index 4de9268b5dd..020b0cea4ce 100644 --- a/examples/gno.land/r/demo/boards/z_7_filetest.gno +++ b/examples/gno.land/r/demo/boards/z_7_filetest.gno @@ -1,5 +1,4 @@ -// PKGPATH: gno.land/r/demo/boards_test -package boards_test +package main // SEND: 1000000ugnot @@ -14,11 +13,11 @@ import ( func init() { // register testing.SetRealm(std.NewUserRealm(std.Address("g1wymu47drhr0kuq2098m792lytgtj2nyx77yrsm"))) // so that CurrentRealm.Addr() matches OrigCaller - users.Register("gnouser123") + cross(users.Register)("gnouser123") // create board and post - bid := boards.CreateBoard("test_board") - boards.CreateThread(bid, "First Post (title)", "Body of the first post. (body)") + bid := cross(boards.CreateBoard)("test_board") + cross(boards.CreateThread)(bid, "First Post (title)", "Body of the first post. (body)") } func main() { diff --git a/examples/gno.land/r/demo/boards/z_8_filetest.gno b/examples/gno.land/r/demo/boards/z_8_filetest.gno index fc3b696cfa7..7dd2182af40 100644 --- a/examples/gno.land/r/demo/boards/z_8_filetest.gno +++ b/examples/gno.land/r/demo/boards/z_8_filetest.gno @@ -1,5 +1,4 @@ -// PKGPATH: gno.land/r/demo/boards_test -package boards_test +package main // SEND: 1000000ugnot @@ -20,18 +19,18 @@ var ( func init() { testing.SetRealm(std.NewUserRealm(std.Address("g1wymu47drhr0kuq2098m792lytgtj2nyx77yrsm"))) // so that CurrentRealm.Addr() matches OrigCaller - users.Register("gnouser123") + cross(users.Register)("gnouser123") - bid = boards.CreateBoard("test_board") - boards.CreateThread(bid, "First Post (title)", "Body of the first post. (body)") - pid = boards.CreateThread(bid, "Second Post (title)", "Body of the second post. (body)") - rid = boards.CreateReply(bid, pid, pid, "Reply of the second post") + bid = cross(boards.CreateBoard)("test_board") + cross(boards.CreateThread)(bid, "First Post (title)", "Body of the first post. (body)") + pid = cross(boards.CreateThread)(bid, "Second Post (title)", "Body of the second post. (body)") + rid = cross(boards.CreateReply)(bid, pid, pid, "Reply of the second post") } func main() { testing.SetRealm(std.NewUserRealm(std.Address("g1wymu47drhr0kuq2098m792lytgtj2nyx77yrsm"))) - boards.CreateReply(bid, pid, pid, "Second reply of the second post\n") - rid2 := boards.CreateReply(bid, pid, rid, "First reply of the first reply\n") + cross(boards.CreateReply)(bid, pid, pid, "Second reply of the second post\n") + rid2 := cross(boards.CreateReply)(bid, pid, rid, "First reply of the first reply\n") println(boards.Render("test_board/" + strconv.Itoa(int(pid)) + "/" + strconv.Itoa(int(rid2)))) } @@ -44,6 +43,6 @@ func main() { // _[see all 1 replies](/r/demo/boards:test_board/2/3)_ // // > First reply of the first reply -// > +// > // > \- [@gnouser123](/u/gnouser123), [2009-02-13 11:31pm (UTC)](/r/demo/boards:test_board/2/5) \[[reply](/r/demo/boards$help&func=CreateReply&bid=1&postid=5&threadid=2)] \[[x](/r/demo/boards$help&func=DeletePost&bid=1&postid=5&threadid=2)] // diff --git a/examples/gno.land/r/demo/boards/z_9_a_filetest.gno b/examples/gno.land/r/demo/boards/z_9_a_filetest.gno index af19b6a2831..df0f3a2c500 100644 --- a/examples/gno.land/r/demo/boards/z_9_a_filetest.gno +++ b/examples/gno.land/r/demo/boards/z_9_a_filetest.gno @@ -1,5 +1,4 @@ -// PKGPATH: gno.land/r/demo/boards_test -package boards_test +package main // SEND: 1000000ugnot @@ -15,14 +14,13 @@ var dstBoard boards.BoardID func init() { testing.SetRealm(std.NewUserRealm(std.Address("g1wymu47drhr0kuq2098m792lytgtj2nyx77yrsm"))) // so that CurrentRealm.Addr() matches OrigCaller - users.Register("gnouser123") + cross(users.Register)("gnouser123") - dstBoard = boards.CreateBoard("dst_board") - - boards.CreateRepost(0, 0, "First Post in (title)", "Body of the first post. (body)", dstBoard) + dstBoard = cross(boards.CreateBoard)("dst_board") } func main() { + cross(boards.CreateRepost)(0, 0, "First Post in (title)", "Body of the first post. (body)", dstBoard) } // Error: diff --git a/examples/gno.land/r/demo/boards/z_9_b_filetest.gno b/examples/gno.land/r/demo/boards/z_9_b_filetest.gno index 5e6461bac29..d15d3772fde 100644 --- a/examples/gno.land/r/demo/boards/z_9_b_filetest.gno +++ b/examples/gno.land/r/demo/boards/z_9_b_filetest.gno @@ -1,5 +1,4 @@ -// PKGPATH: gno.land/r/demo/boards_test -package boards_test +package main // SEND: 1000000ugnot @@ -18,15 +17,14 @@ var ( func init() { testing.SetRealm(std.NewUserRealm(std.Address("g1wymu47drhr0kuq2098m792lytgtj2nyx77yrsm"))) // so that CurrentRealm.Addr() matches OrigCaller - users.Register("gnouser123") + cross(users.Register)("gnouser123") - srcBoard = boards.CreateBoard("first_board") - pid = boards.CreateThread(srcBoard, "First Post in (title)", "Body of the first post. (body)") - - boards.CreateRepost(srcBoard, pid, "First Post in (title)", "Body of the first post. (body)", 0) + srcBoard = cross(boards.CreateBoard)("first_board") + pid = cross(boards.CreateThread)(srcBoard, "First Post in (title)", "Body of the first post. (body)") } func main() { + cross(boards.CreateRepost)(srcBoard, pid, "First Post in (title)", "Body of the first post. (body)", 0) } // Error: diff --git a/examples/gno.land/r/demo/boards/z_9_filetest.gno b/examples/gno.land/r/demo/boards/z_9_filetest.gno index 4633b49058e..331d43517d0 100644 --- a/examples/gno.land/r/demo/boards/z_9_filetest.gno +++ b/examples/gno.land/r/demo/boards/z_9_filetest.gno @@ -1,5 +1,4 @@ -// PKGPATH: gno.land/r/demo/boards_test -package boards_test +package main // SEND: 1000000ugnot @@ -20,13 +19,13 @@ var ( func init() { testing.SetRealm(std.NewUserRealm(std.Address("g1wymu47drhr0kuq2098m792lytgtj2nyx77yrsm"))) // so that CurrentRealm.Addr() matches OrigCaller - users.Register("gnouser123") + cross(users.Register)("gnouser123") - firstBoard = boards.CreateBoard("first_board") - secondBoard = boards.CreateBoard("second_board") - pid = boards.CreateThread(firstBoard, "First Post in (title)", "Body of the first post. (body)") + firstBoard = cross(boards.CreateBoard)("first_board") + secondBoard = cross(boards.CreateBoard)("second_board") + pid = cross(boards.CreateThread)(firstBoard, "First Post in (title)", "Body of the first post. (body)") - boards.CreateRepost(firstBoard, pid, "First Post in (title)", "Body of the first post. (body)", secondBoard) + cross(boards.CreateRepost)(firstBoard, pid, "First Post in (title)", "Body of the first post. (body)", secondBoard) } func main() { diff --git a/examples/gno.land/r/demo/echo/echo.gno b/examples/gno.land/r/demo/echo/echo.gno index 8feee6e46a6..d9933ab2355 100644 --- a/examples/gno.land/r/demo/echo/echo.gno +++ b/examples/gno.land/r/demo/echo/echo.gno @@ -9,7 +9,5 @@ package echo * See also r/demo/print (to print various thing like user address) */ func Render(path string) string { - crossing() - return path } diff --git a/examples/gno.land/r/demo/emit/z1_filetest.gno b/examples/gno.land/r/demo/emit/z1_filetest.gno index 7dcdbf8e0a3..10e6a165c84 100644 --- a/examples/gno.land/r/demo/emit/z1_filetest.gno +++ b/examples/gno.land/r/demo/emit/z1_filetest.gno @@ -17,8 +17,7 @@ func main() { // "value": "foo" // } // ], -// "pkg_path": "gno.land/r/demo/emit", -// "func": "Emit" +// "pkg_path": "gno.land/r/demo/emit" // }, // { // "type": "EventName", @@ -28,7 +27,6 @@ func main() { // "value": "bar" // } // ], -// "pkg_path": "gno.land/r/demo/emit", -// "func": "Emit" +// "pkg_path": "gno.land/r/demo/emit" // } // ] diff --git a/examples/gno.land/r/demo/grc20factory/grc20factory.gno b/examples/gno.land/r/demo/grc20factory/grc20factory.gno index 6206fffa85b..d15074e9350 100644 --- a/examples/gno.land/r/demo/grc20factory/grc20factory.gno +++ b/examples/gno.land/r/demo/grc20factory/grc20factory.gno @@ -21,11 +21,13 @@ type instance struct { } func New(name, symbol string, decimals uint, initialMint, faucet uint64) { - caller := std.PreviousRealm().Address() + caller := std.OriginCaller() NewWithAdmin(name, symbol, decimals, initialMint, faucet, caller) } func NewWithAdmin(name, symbol string, decimals uint, initialMint, faucet uint64, admin std.Address) { + crossing() + exists := instances.Has(symbol) if exists { panic("token already exists") @@ -43,7 +45,7 @@ func NewWithAdmin(name, symbol string, decimals uint, initialMint, faucet uint64 faucet: faucet, } instances.Set(symbol, &inst) - grc20reg.Register(token.Getter(), symbol) + cross(grc20reg.Register)(token.Getter(), symbol) } func (inst instance) Token() *grc20.Token { @@ -75,6 +77,8 @@ func Allowance(symbol string, owner, spender std.Address) uint64 { } func Transfer(symbol string, to std.Address, amount uint64) { + crossing() + inst := mustGetInstance(symbol) caller := std.PreviousRealm().Address() teller := inst.ledger.ImpersonateTeller(caller) @@ -82,6 +86,8 @@ func Transfer(symbol string, to std.Address, amount uint64) { } func Approve(symbol string, spender std.Address, amount uint64) { + crossing() + inst := mustGetInstance(symbol) caller := std.PreviousRealm().Address() teller := inst.ledger.ImpersonateTeller(caller) @@ -89,6 +95,8 @@ func Approve(symbol string, spender std.Address, amount uint64) { } func TransferFrom(symbol string, from, to std.Address, amount uint64) { + crossing() + inst := mustGetInstance(symbol) caller := std.PreviousRealm().Address() teller := inst.ledger.ImpersonateTeller(caller) @@ -97,6 +105,8 @@ func TransferFrom(symbol string, from, to std.Address, amount uint64) { // faucet. func Faucet(symbol string) { + crossing() + inst := mustGetInstance(symbol) if inst.faucet == 0 { panic("faucet disabled for this token") @@ -108,12 +118,16 @@ func Faucet(symbol string) { } func Mint(symbol string, to std.Address, amount uint64) { + crossing() + inst := mustGetInstance(symbol) inst.admin.AssertOwnedByPrevious() checkErr(inst.ledger.Mint(to, amount)) } func Burn(symbol string, from std.Address, amount uint64) { + crossing() + inst := mustGetInstance(symbol) inst.admin.AssertOwnedByPrevious() checkErr(inst.ledger.Burn(from, amount)) @@ -121,11 +135,15 @@ func Burn(symbol string, from std.Address, amount uint64) { // instance admin functionality func DropInstanceOwnership(symbol string) { + crossing() + inst := mustGetInstance(symbol) checkErr(inst.admin.DropOwnership()) } func TransferInstanceOwnership(symbol string, newOwner std.Address) { + crossing() + inst := mustGetInstance(symbol) checkErr(inst.admin.TransferOwnership(newOwner)) } diff --git a/examples/gno.land/r/demo/grc20factory/grc20factory_test.gno b/examples/gno.land/r/demo/grc20factory/grc20factory_test.gno index 8825f448a98..1e7b3f93250 100644 --- a/examples/gno.land/r/demo/grc20factory/grc20factory_test.gno +++ b/examples/gno.land/r/demo/grc20factory/grc20factory_test.gno @@ -35,8 +35,8 @@ func TestReadOnlyPublicMethods(t *testing.T) { // admin creates FOO and BAR. testing.SetOriginCaller(admin) - NewWithAdmin("Foo", "FOO", 3, 1_111_111_000, 5_555, admin) - NewWithAdmin("Bar", "BAR", 3, 2_222_000, 6_666, admin) + cross(NewWithAdmin)("Foo", "FOO", 3, 1_111_111_000, 5_555, admin) + cross(NewWithAdmin)("Bar", "BAR", 3, 2_222_000, 6_666, admin) checkBalances("step1", 1_111_111_000, 1_111_111_000, 0, 0, 0) // admin mints to bob. @@ -45,21 +45,21 @@ func TestReadOnlyPublicMethods(t *testing.T) { // carl uses the faucet. testing.SetOriginCaller(carl) - Faucet("FOO") + cross(Faucet)("FOO") checkBalances("step3", 1_444_449_555, 1_111_111_000, 333_333_000, 0, 5_555) // admin gives to bob some allowance. testing.SetOriginCaller(admin) - Approve("FOO", bob, 1_000_000) + cross(Approve)("FOO", bob, 1_000_000) checkBalances("step4", 1_444_449_555, 1_111_111_000, 333_333_000, 1_000_000, 5_555) // bob uses a part of the allowance. testing.SetOriginCaller(bob) - TransferFrom("FOO", admin, carl, 400_000) + cross(TransferFrom)("FOO", admin, carl, 400_000) checkBalances("step5", 1_444_449_555, 1_110_711_000, 333_333_000, 600_000, 405_555) // bob uses a part of the allowance. testing.SetOriginCaller(bob) - TransferFrom("FOO", admin, carl, 600_000) + cross(TransferFrom)("FOO", admin, carl, 600_000) checkBalances("step6", 1_444_449_555, 1_110_111_000, 333_333_000, 0, 1_005_555) } diff --git a/examples/gno.land/r/demo/nft/z_4_filetest.gno b/examples/gno.land/r/demo/nft/z_4_filetest.gno index 3a167f3c87b..4eb2c1fb8e9 100644 --- a/examples/gno.land/r/demo/nft/z_4_filetest.gno +++ b/examples/gno.land/r/demo/nft/z_4_filetest.gno @@ -23,4 +23,7 @@ func main() { } // Error: -// unauthorized +// gno.land/r/demo/nft_test/z_4.gno:12:12: name CallerAt not declared + +// TypeCheckError: +// gno.land/r/demo/nft_test/z_4.gno:12:16: undefined: std.CallerAt diff --git a/examples/gno.land/r/demo/profile/profile.gno b/examples/gno.land/r/demo/profile/profile.gno index 6e0baa10929..d5df78054d0 100644 --- a/examples/gno.land/r/demo/profile/profile.gno +++ b/examples/gno.land/r/demo/profile/profile.gno @@ -70,6 +70,8 @@ var boolFields = map[string]bool{ // Setters func SetStringField(field, value string) bool { + crossing() + addr := std.PreviousRealm().Address() key := addr.String() + ":" + field updated := fields.Set(key, value) @@ -85,6 +87,8 @@ func SetStringField(field, value string) bool { } func SetIntField(field string, value int) bool { + crossing() + addr := std.PreviousRealm().Address() key := addr.String() + ":" + field updated := fields.Set(key, value) @@ -100,6 +104,8 @@ func SetIntField(field string, value int) bool { } func SetBoolField(field string, value bool) bool { + crossing() + addr := std.PreviousRealm().Address() key := addr.String() + ":" + field updated := fields.Set(key, value) diff --git a/examples/gno.land/r/demo/profile/profile_test.gno b/examples/gno.land/r/demo/profile/profile_test.gno index 9b207214bd1..2019584303b 100644 --- a/examples/gno.land/r/demo/profile/profile_test.gno +++ b/examples/gno.land/r/demo/profile/profile_test.gno @@ -28,13 +28,13 @@ func TestStringFields(t *testing.T) { uassert.Equal(t, "anon", name) // Set new key - updated := SetStringField(DisplayName, "Alice foo") + updated := cross(SetStringField)(DisplayName, "Alice foo") uassert.Equal(t, updated, false) - updated = SetStringField(Homepage, "https://example.com") + updated = cross(SetStringField)(Homepage, "https://example.com") uassert.Equal(t, updated, false) // Update the key - updated = SetStringField(DisplayName, "Alice foo") + updated = cross(SetStringField)(DisplayName, "Alice foo") uassert.Equal(t, updated, true) // Get after setting @@ -55,11 +55,11 @@ func TestIntFields(t *testing.T) { uassert.Equal(t, 25, age) // Set new key - updated := SetIntField(Age, 30) + updated := cross(SetIntField)(Age, 30) uassert.Equal(t, updated, false) // Update the key - updated = SetIntField(Age, 30) + updated = cross(SetIntField)(Age, 30) uassert.Equal(t, updated, true) // Get after setting @@ -75,11 +75,11 @@ func TestBoolFields(t *testing.T) { uassert.Equal(t, false, hiring) // Set - updated := SetBoolField(AvailableForHiring, true) + updated := cross(SetBoolField)(AvailableForHiring, true) uassert.Equal(t, updated, false) // Update the key - updated = SetBoolField(AvailableForHiring, true) + updated = cross(SetBoolField)(AvailableForHiring, true) uassert.Equal(t, updated, true) // Get after setting @@ -90,12 +90,12 @@ func TestBoolFields(t *testing.T) { func TestMultipleProfiles(t *testing.T) { // Set profile for user1 testing.SetRealm(std.NewUserRealm(user1)) - updated := SetStringField(DisplayName, "User One") + updated := cross(SetStringField)(DisplayName, "User One") uassert.Equal(t, updated, false) // Set profile for user2 testing.SetRealm(std.NewUserRealm(user2)) - updated = SetStringField(DisplayName, "User Two") + updated = cross(SetStringField)(DisplayName, "User Two") uassert.Equal(t, updated, false) // Get profiles @@ -112,7 +112,7 @@ func TestArbitraryStringField(t *testing.T) { testing.SetRealm(std.NewUserRealm(user1)) // Set arbitrary string field - updated := SetStringField("MyEmail", "my@email.com") + updated := cross(SetStringField)("MyEmail", "my@email.com") uassert.Equal(t, updated, false) val := GetStringField(user1, "MyEmail", "") @@ -123,7 +123,7 @@ func TestArbitraryIntField(t *testing.T) { testing.SetRealm(std.NewUserRealm(user1)) // Set arbitrary int field - updated := SetIntField("MyIncome", 100_000) + updated := cross(SetIntField)("MyIncome", 100_000) uassert.Equal(t, updated, false) val := GetIntField(user1, "MyIncome", 0) @@ -133,8 +133,8 @@ func TestArbitraryIntField(t *testing.T) { func TestArbitraryBoolField(t *testing.T) { testing.SetRealm(std.NewUserRealm(user1)) - // Set arbitrary int field - updated := SetBoolField("IsWinner", true) + // Set arbitrary bool field + updated := cross(SetBoolField)("IsWinner", true) uassert.Equal(t, updated, false) val := GetBoolField(user1, "IsWinner", false) diff --git a/examples/gno.land/r/demo/tests/crossrealm/crossrealm.gno b/examples/gno.land/r/demo/tests/crossrealm/crossrealm.gno index d3c2ec54026..0ef0e46507e 100644 --- a/examples/gno.land/r/demo/tests/crossrealm/crossrealm.gno +++ b/examples/gno.land/r/demo/tests/crossrealm/crossrealm.gno @@ -1,6 +1,9 @@ package crossrealm import ( + "std" + + "gno.land/p/demo/ownable" "gno.land/p/demo/tests/p_crossrealm" "gno.land/p/demo/ufmt" ) @@ -109,3 +112,46 @@ func SetObject(x any) { func GetObject() any { return Object } + +func EntryPoint() (noCros *ownable.Ownable) { + println("crossrealm EntryPoint: " + std.PreviousRealm().PkgPath()) + println("crossrealm EntryPoint: " + std.PreviousRealm().Address()) + println() + return PrevRealmNoCrossing() +} + +func EntryPointWithCrossing() (withCros *ownable.Ownable) { + return cross(PrevRealmCrossing)() +} + +func PrevRealmNoCrossing() *ownable.Ownable { + println("crossrealm PreviousRealm no crossing: " + std.PreviousRealm().PkgPath()) + println("crossrealm PreviousRealm no crossing: " + std.PreviousRealm().Address()) + return ownable.New() +} + +func PrevRealmCrossing() *ownable.Ownable { + crossing() + println("crossrealm PreviousRealm with crossing: " + std.PreviousRealm().PkgPath()) + println("crossrealm PreviousRealm with crossing: " + std.PreviousRealm().Address()) + return ownable.New() +} + +func CurRealmNoCrossing() std.Realm { + return std.CurrentRealm() +} +func CurRealmWithCrossing() std.Realm { + crossing() + return std.CurrentRealm() +} + +// call the package that returns current realm +func PkgCurRealmNoCrossing() std.Realm { + return p_crossrealm.CurrentRealm() +} + +// call the package that returns current realm +func PkgCurRealmWithCrossing() std.Realm { + crossing() + return std.CurrentRealm() +} diff --git a/examples/gno.land/r/demo/tests/crossrealm_c/crossrealm.gno b/examples/gno.land/r/demo/tests/crossrealm_c/crossrealm.gno new file mode 100644 index 00000000000..5bc20cd189e --- /dev/null +++ b/examples/gno.land/r/demo/tests/crossrealm_c/crossrealm.gno @@ -0,0 +1,40 @@ +package crossrealm_c + +import ( + "gno.land/p/demo/tests/p_crossrealm" + "gno.land/r/demo/tests/crossrealm" + "std" +) + +func EntryPoint() { + println("crossrealm_c EntryPoint: " + std.PreviousRealm().PkgPath()) + println("crossrealm_c EntryPoint: " + std.PreviousRealm().Address()) + println(" ") + passThrough() + +} + +func passThrough() { + owner := crossrealm.EntryPoint().Owner() + println("Owner from crossrealm EntryPoint no crossing: " + owner) + println() + owner2 := crossrealm.EntryPointWithCrossing().Owner() + println("Owner from crossrealm EntryPoint with crossing: " + owner2) + println() + owner = crossrealm.PrevRealmNoCrossing().Owner() + println("Owner from crossrealm PrevRealmNoCrossing: " + owner) + println() + owner = cross(crossrealm.PrevRealmCrossing)().Owner() + println("Owner from crossrealm PrevRealmCrossing: " + owner) +} + +func CurRealmEntryPoint() { + + println("crossrealm CurRealmWithCrossing: " + cross(crossrealm.CurRealmWithCrossing)().Address()) + println("crossrealm CurRealmNoCrossing: " + crossrealm.CurRealmNoCrossing().Address()) + + println("p_crossrealm CurRealm: " + p_crossrealm.CurrentRealm().Address()) + println("crossrealm PkgCurRealmWithCrossing: " + cross(crossrealm.PkgCurRealmWithCrossing)().Address()) + println("crossrealm PkgCurRealmNoCrossing: " + crossrealm.PkgCurRealmNoCrossing().Address()) + +} diff --git a/examples/gno.land/r/demo/tests/crossrealm_c/gno.mod b/examples/gno.land/r/demo/tests/crossrealm_c/gno.mod new file mode 100644 index 00000000000..5ea5a8c246d --- /dev/null +++ b/examples/gno.land/r/demo/tests/crossrealm_c/gno.mod @@ -0,0 +1 @@ +module gno.land/r/demo/tests/crossrealm_c diff --git a/examples/gno.land/r/demo/wugnot/wugnot.gno b/examples/gno.land/r/demo/wugnot/wugnot.gno index 5c32d5c3012..5d86e44f4f7 100644 --- a/examples/gno.land/r/demo/wugnot/wugnot.gno +++ b/examples/gno.land/r/demo/wugnot/wugnot.gno @@ -50,8 +50,6 @@ func Withdraw(amount uint64) { } func Render(path string) string { - crossing() - parts := strings.Split(path, "/") c := len(parts) diff --git a/examples/gno.land/r/gnoland/faucet/z0_filetest.gno b/examples/gno.land/r/gnoland/faucet/z0_filetest.gno index 5e169f0a81f..f913de85c82 100644 --- a/examples/gno.land/r/gnoland/faucet/z0_filetest.gno +++ b/examples/gno.land/r/gnoland/faucet/z0_filetest.gno @@ -22,10 +22,10 @@ func main() { // # Community Faucet. // // Status: active. -// Balance: 200000000ugnot. +// Balance: . // Total transfers: (in 0 times). // -// Package address: g1ttrq7mp4zy6dssnmgyyktnn4hcj3ys8xhju0n7 +// Package address: g1wymu47drhr0kuq2098m792lytgtj2nyx77yrsm // // Admin: g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5 // @@ -34,5 +34,3 @@ func main() { // // // Per request limit: 350000000ugnot -// -// diff --git a/examples/gno.land/r/gnoland/faucet/z1_filetest.gno b/examples/gno.land/r/gnoland/faucet/z1_filetest.gno index 15c83c66e14..56b39cff359 100644 --- a/examples/gno.land/r/gnoland/faucet/z1_filetest.gno +++ b/examples/gno.land/r/gnoland/faucet/z1_filetest.gno @@ -22,10 +22,10 @@ func main() { // # Community Faucet. // // Status: active. -// Balance: 200000000ugnot. +// Balance: . // Total transfers: (in 0 times). // -// Package address: g1ttrq7mp4zy6dssnmgyyktnn4hcj3ys8xhju0n7 +// Package address: g1wymu47drhr0kuq2098m792lytgtj2nyx77yrsm // // Admin: g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5 // @@ -34,5 +34,3 @@ func main() { // // // Per request limit: 350000000ugnot -// -// diff --git a/examples/gno.land/r/gnoland/faucet/z2_filetest.gno b/examples/gno.land/r/gnoland/faucet/z2_filetest.gno index 7282adcb372..8cb4733c975 100644 --- a/examples/gno.land/r/gnoland/faucet/z2_filetest.gno +++ b/examples/gno.land/r/gnoland/faucet/z2_filetest.gno @@ -37,10 +37,10 @@ func main() { // # Community Faucet. // // Status: active. -// Balance: 200000000ugnot. +// Balance: . // Total transfers: (in 0 times). // -// Package address: g1ttrq7mp4zy6dssnmgyyktnn4hcj3ys8xhju0n7 +// Package address: g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5 // // Admin: g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5 // @@ -49,5 +49,3 @@ func main() { // g1vdhkuarjdakxcetjx9047h6lta047h6lsdacav g1vdhkuarjdakxcetjxf047h6lta047h6lnrev3v // // Per request limit: 350000000ugnot -// -// diff --git a/examples/gno.land/r/gnoland/ghverify/contract.gno b/examples/gno.land/r/gnoland/ghverify/contract.gno index 1eb59c2d31b..f52f0a6ad0b 100644 --- a/examples/gno.land/r/gnoland/ghverify/contract.gno +++ b/examples/gno.land/r/gnoland/ghverify/contract.gno @@ -142,8 +142,6 @@ func GetAddressByHandle(handle string) string { // Render returns a json object string will all verified handle -> address mappings. func Render(_ string) string { - crossing() - result := "{" var appendComma bool handleToAddressMap.Iterate("", "", func(handle string, address any) bool { diff --git a/examples/gno.land/r/gnoland/home/home_filetest.gno b/examples/gno.land/r/gnoland/home/home_filetest.gno index 2973cf76693..da3bb300293 100644 --- a/examples/gno.land/r/gnoland/home/home_filetest.gno +++ b/examples/gno.land/r/gnoland/home/home_filetest.gno @@ -19,7 +19,7 @@ func main() { // // Intuitive and easy to use, gno.land lowers the barrier to web3 and makes // censorship-resistant platforms accessible to everyone. If you want to help lay -// the foundations of a fairer and freer world, join us today. +// the foundations of a fairer and freer world, join us today. // // ## Learn about gno.land // @@ -137,4 +137,3 @@ func main() { // // **This is a testnet.** // Package names are not guaranteed to be available for production. -// diff --git a/examples/gno.land/r/gnoland/monit/monit.gno b/examples/gno.land/r/gnoland/monit/monit.gno index d8e0e5d89b7..1031565fd08 100644 --- a/examples/gno.land/r/gnoland/monit/monit.gno +++ b/examples/gno.land/r/gnoland/monit/monit.gno @@ -20,7 +20,7 @@ var ( lastUpdate time.Time lastCaller std.Address wd = watchdog.Watchdog{Duration: 5 * time.Minute} - Ownable = ownable.New() // TODO: replace with -> ownable.NewWithAddress... + Ownable = ownable.NewWithOrigin() watchdogDuration = 5 * time.Minute ) diff --git a/examples/gno.land/r/morgan/guestbook/admin.gno b/examples/gno.land/r/morgan/guestbook/admin.gno index 47e912d78a4..907585c63a7 100644 --- a/examples/gno.land/r/morgan/guestbook/admin.gno +++ b/examples/gno.land/r/morgan/guestbook/admin.gno @@ -5,7 +5,7 @@ import ( "gno.land/p/demo/seqid" ) -var owner = ownable.New() +var owner = ownable.NewWithOrigin() // AdminDelete removes the guestbook message with the given ID. // The user will still be marked as having submitted a message, so they diff --git a/examples/gno.land/r/moul/present/present.gno b/examples/gno.land/r/moul/present/present.gno index 377af1896e5..3d7925bff00 100644 --- a/examples/gno.land/r/moul/present/present.gno +++ b/examples/gno.land/r/moul/present/present.gno @@ -55,7 +55,7 @@ func init() { return v.(*Presentation).Title }, collection.DefaultIndex) - Ownable = ownable.New() + Ownable = ownable.NewWithOrigin() } // Render handles the realm's rendering logic diff --git a/examples/gno.land/r/stefann/fomo3d/fomo3d.gno b/examples/gno.land/r/stefann/fomo3d/fomo3d.gno index a194b383be6..2dc2920ebc8 100644 --- a/examples/gno.land/r/stefann/fomo3d/fomo3d.gno +++ b/examples/gno.land/r/stefann/fomo3d/fomo3d.gno @@ -70,7 +70,7 @@ var ( ) func init() { - Ownable = ownable.New() + Ownable = ownable.NewWithOrigin() players = avl.NewTree() gameState.Ended = true hor.Register("FOMO3D Game!", "") diff --git a/examples/gno.land/r/stefann/fomo3d/fomo3d_test.gno b/examples/gno.land/r/stefann/fomo3d/fomo3d_test.gno index 72de1d8870a..789afe7b996 100644 --- a/examples/gno.land/r/stefann/fomo3d/fomo3d_test.gno +++ b/examples/gno.land/r/stefann/fomo3d/fomo3d_test.gno @@ -27,7 +27,7 @@ func setupTestGame(t *testing.T) { OwnerFee: 0, } players = avl.NewTree() - Ownable = ownable.New() + Ownable = ownable.NewWithOrigin() } // Test ownership functionality diff --git a/examples/gno.land/r/sys/users/store.gno b/examples/gno.land/r/sys/users/store.gno index 2d6418969b4..07d351684f8 100644 --- a/examples/gno.land/r/sys/users/store.gno +++ b/examples/gno.land/r/sys/users/store.gno @@ -113,7 +113,7 @@ func (u *UserData) UpdateName(newName string) error { } // Validate caller - if !controllers.Has(std.PreviousRealm().Address()) { + if !controllers.Has(std.CurrentRealm().Address()) { return ErrNotWhitelisted } @@ -144,7 +144,7 @@ func (u *UserData) Delete() error { } // Validate caller - if !controllers.Has(std.PreviousRealm().Address()) { + if !controllers.Has(std.CurrentRealm().Address()) { return ErrNotWhitelisted } diff --git a/examples/gno.land/r/sys/users/store_test.gno b/examples/gno.land/r/sys/users/store_test.gno index 17bdbe221d5..6174f739af7 100644 --- a/examples/gno.land/r/sys/users/store_test.gno +++ b/examples/gno.land/r/sys/users/store_test.gno @@ -23,6 +23,7 @@ func TestRegister(t *testing.T) { testing.SetOriginCaller(whitelistedCallerAddr) t.Run("valid_registration", func(t *testing.T) { + testing.SetRealm(std.NewCodeRealm("gno.land/r/sys/users")) urequire.NoError(t, RegisterUser(alice, aliceAddr)) res, isLatest := ResolveName(alice) @@ -34,6 +35,7 @@ func TestRegister(t *testing.T) { }) t.Run("invalid_inputs", func(t *testing.T) { + testing.SetRealm(std.NewCodeRealm("gno.land/r/sys/users")) cleanStore(t) uassert.ErrorContains(t, RegisterUser("", aliceAddr), ErrEmptyUsername.Error()) @@ -48,6 +50,7 @@ func TestRegister(t *testing.T) { }) t.Run("addr_already_registered", func(t *testing.T) { + testing.SetRealm(std.NewCodeRealm("gno.land/r/sys/users")) cleanStore(t) urequire.NoError(t, RegisterUser(alice, aliceAddr)) @@ -57,6 +60,7 @@ func TestRegister(t *testing.T) { }) t.Run("name_taken", func(t *testing.T) { + testing.SetRealm(std.NewCodeRealm("gno.land/r/sys/users")) cleanStore(t) urequire.NoError(t, RegisterUser(alice, aliceAddr)) @@ -66,17 +70,23 @@ func TestRegister(t *testing.T) { }) t.Run("user_deleted", func(t *testing.T) { + testing.SetRealm(std.NewCodeRealm("gno.land/r/sys/users")) cleanStore(t) urequire.NoError(t, RegisterUser(alice, aliceAddr)) data := ResolveAddress(aliceAddr) - urequire.NoError(t, data.Delete()) + { + testing.SetOriginCaller(whitelistedCallerAddr) + urequire.NoError(t, data.Delete()) + testing.SetRealm(std.NewCodeRealm("gno.land/r/sys/users")) + } // Try re-registering after deletion uassert.ErrorContains(t, RegisterUser("newname", aliceAddr), ErrDeletedUser.Error()) }) t.Run("address_lookalike", func(t *testing.T) { + testing.SetRealm(std.NewCodeRealm("gno.land/r/sys/users")) cleanStore(t) // Address as username @@ -90,24 +100,35 @@ func TestRegister(t *testing.T) { func TestUpdateName(t *testing.T) { testing.SetOriginCaller(whitelistedCallerAddr) t.Run("valid_direct_alias", func(t *testing.T) { + testing.SetRealm(std.NewCodeRealm("gno.land/r/sys/users")) cleanStore(t) urequire.NoError(t, RegisterUser(alice, aliceAddr)) data := ResolveAddress(aliceAddr) - uassert.NoError(t, data.UpdateName("alice1")) + { + testing.SetOriginCaller(whitelistedCallerAddr) + uassert.NoError(t, data.UpdateName("alice1")) + testing.SetRealm(std.NewCodeRealm("gno.land/r/sys/users")) + } }) t.Run("valid_double_alias", func(t *testing.T) { + testing.SetRealm(std.NewCodeRealm("gno.land/r/sys/users")) cleanStore(t) urequire.NoError(t, RegisterUser(alice, aliceAddr)) data := ResolveAddress(aliceAddr) - uassert.NoError(t, data.UpdateName("alice2")) - uassert.NoError(t, data.UpdateName("alice3")) + { + testing.SetOriginCaller(whitelistedCallerAddr) + uassert.NoError(t, data.UpdateName("alice2")) + uassert.NoError(t, data.UpdateName("alice3")) + testing.SetRealm(std.NewCodeRealm("gno.land/r/sys/users")) + } uassert.Equal(t, ResolveAddress(aliceAddr).username, "alice3") }) t.Run("name_taken", func(t *testing.T) { + testing.SetRealm(std.NewCodeRealm("gno.land/r/sys/users")) cleanStore(t) urequire.NoError(t, RegisterUser(alice, aliceAddr)) @@ -117,6 +138,7 @@ func TestUpdateName(t *testing.T) { }) t.Run("alias_before_name", func(t *testing.T) { + testing.SetRealm(std.NewCodeRealm("gno.land/r/sys/users")) cleanStore(t) data := ResolveAddress(aliceAddr) // not registered @@ -124,41 +146,59 @@ func TestUpdateName(t *testing.T) { }) t.Run("alias_after_delete", func(t *testing.T) { + testing.SetRealm(std.NewCodeRealm("gno.land/r/sys/users")) cleanStore(t) urequire.NoError(t, RegisterUser(alice, aliceAddr)) data := ResolveAddress(aliceAddr) - urequire.NoError(t, data.Delete()) + { + testing.SetOriginCaller(whitelistedCallerAddr) + urequire.NoError(t, data.Delete()) + testing.SetRealm(std.NewCodeRealm("gno.land/r/sys/users")) + } data = ResolveAddress(aliceAddr) - uassert.ErrorContains(t, data.UpdateName("newalice"), ErrUserNotExistOrDeleted.Error()) + { + testing.SetOriginCaller(whitelistedCallerAddr) + uassert.ErrorContains(t, data.UpdateName("newalice"), ErrUserNotExistOrDeleted.Error()) + testing.SetRealm(std.NewCodeRealm("gno.land/r/sys/users")) + } }) t.Run("invalid_inputs", func(t *testing.T) { + testing.SetRealm(std.NewCodeRealm("gno.land/r/sys/users")) cleanStore(t) urequire.NoError(t, RegisterUser(alice, aliceAddr)) data := ResolveAddress(aliceAddr) - - uassert.ErrorContains(t, data.UpdateName(""), ErrEmptyUsername.Error()) - uassert.ErrorContains(t, data.UpdateName("username with a space"), ErrInvalidUsername.Error()) - uassert.ErrorContains(t, - data.UpdateName("verylongusernameverylongusernameverylongusernameverylongusername1"), - ErrInvalidUsername.Error()) - uassert.ErrorContains(t, data.UpdateName("namewith^&()"), ErrInvalidUsername.Error()) + { + testing.SetOriginCaller(whitelistedCallerAddr) + uassert.ErrorContains(t, data.UpdateName(""), ErrEmptyUsername.Error()) + uassert.ErrorContains(t, data.UpdateName("username with a space"), ErrInvalidUsername.Error()) + uassert.ErrorContains(t, + data.UpdateName("verylongusernameverylongusernameverylongusernameverylongusername1"), + ErrInvalidUsername.Error()) + uassert.ErrorContains(t, data.UpdateName("namewith^&()"), ErrInvalidUsername.Error()) + testing.SetRealm(std.NewCodeRealm("gno.land/r/sys/users")) + } }) t.Run("address_lookalike", func(t *testing.T) { + testing.SetRealm(std.NewCodeRealm("gno.land/r/sys/users")) cleanStore(t) urequire.NoError(t, RegisterUser(alice, aliceAddr)) data := ResolveAddress(aliceAddr) - // Address as username - uassert.ErrorContains(t, data.UpdateName("g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5"), ErrNameLikeAddress.Error()) - // Beginning of address as username - uassert.ErrorContains(t, data.UpdateName("g1jg8mtutu9khhfwc4nxmu"), ErrNameLikeAddress.Error()) - uassert.NoError(t, data.UpdateName("g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5longerthananaddress")) + { + testing.SetOriginCaller(whitelistedCallerAddr) + // Address as username + uassert.ErrorContains(t, data.UpdateName("g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5"), ErrNameLikeAddress.Error()) + // Beginning of address as username + uassert.ErrorContains(t, data.UpdateName("g1jg8mtutu9khhfwc4nxmu"), ErrNameLikeAddress.Error()) + uassert.NoError(t, data.UpdateName("g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5longerthananaddress")) + testing.SetRealm(std.NewCodeRealm("gno.land/r/sys/users")) + } }) } @@ -166,6 +206,7 @@ func TestDelete(t *testing.T) { testing.SetOriginCaller(whitelistedCallerAddr) t.Run("non_existent_user", func(t *testing.T) { + testing.SetRealm(std.NewCodeRealm("gno.land/r/sys/users")) cleanStore(t) data := ResolveAddress(testutils.TestAddress("unregistered")) @@ -173,6 +214,7 @@ func TestDelete(t *testing.T) { }) t.Run("double_delete", func(t *testing.T) { + testing.SetRealm(std.NewCodeRealm("gno.land/r/sys/users")) cleanStore(t) urequire.NoError(t, RegisterUser(alice, aliceAddr)) @@ -183,6 +225,7 @@ func TestDelete(t *testing.T) { }) t.Run("valid_delete", func(t *testing.T) { + testing.SetRealm(std.NewCodeRealm("gno.land/r/sys/users")) cleanStore(t) urequire.NoError(t, RegisterUser(alice, aliceAddr)) diff --git a/examples/gno.land/r/x/jeronimo_render_proxy/home/home.gno b/examples/gno.land/r/x/jeronimo_render_proxy/home/home.gno index 92b277d1b9c..4958cff130f 100644 --- a/examples/gno.land/r/x/jeronimo_render_proxy/home/home.gno +++ b/examples/gno.land/r/x/jeronimo_render_proxy/home/home.gno @@ -8,10 +8,17 @@ import ( // RenderFn defines the type for the render function of realms. type RenderFn func(string) string -var current = struct { - realmPath string - renderFn RenderFn -}{} +var ( + proxyRealmPath string + current = struct { + realmPath string + renderFn RenderFn + }{} +) + +func init() { + proxyRealmPath = std.CurrentRealm().PkgPath() +} // CurrentRealmPath returns the path of the realm that is currently registered. func CurrentRealmPath() string { @@ -20,14 +27,19 @@ func CurrentRealmPath() string { // Register registers a render function of a realm. func Register(fn RenderFn) { + crossing() + if fn == nil { panic("render function must not be nil") } - proxyPath := std.CurrentRealm().PkgPath() + if std.PreviousRealm().IsUser() { + panic("register must be called by a realm") + } + callerPath := std.PreviousRealm().PkgPath() - if !strings.HasPrefix(callerPath, proxyPath+"/") { - panic("caller realm path must start with " + proxyPath) + if !strings.HasPrefix(callerPath, proxyRealmPath+"/") { + panic("caller realm path must start with " + proxyRealmPath) } current.renderFn = fn @@ -36,7 +48,7 @@ func Register(fn RenderFn) { // URL returns a URL that links to the proxy realm. func URL(renderPath string) string { - url := "http://" + std.CurrentRealm().PkgPath() + url := "http://" + proxyRealmPath if renderPath != "" { url += ":" + renderPath } diff --git a/examples/gno.land/r/x/jeronimo_render_proxy/home/v1/v1.gno b/examples/gno.land/r/x/jeronimo_render_proxy/home/v1/v1.gno index 8698998577c..78ffa0261cc 100644 --- a/examples/gno.land/r/x/jeronimo_render_proxy/home/v1/v1.gno +++ b/examples/gno.land/r/x/jeronimo_render_proxy/home/v1/v1.gno @@ -4,7 +4,7 @@ import "gno.land/r/x/jeronimo_render_proxy/home" func init() { // Register the private render function with the render proxy - home.Register(render) + cross(home.Register)(render) } func render(string) string { diff --git a/examples/gno.land/r/x/jeronimo_render_proxy/home/v1/z_filetest.gno b/examples/gno.land/r/x/jeronimo_render_proxy/home/v1/z_filetest.gno index cdb765c131a..2f33594826a 100644 --- a/examples/gno.land/r/x/jeronimo_render_proxy/home/v1/z_filetest.gno +++ b/examples/gno.land/r/x/jeronimo_render_proxy/home/v1/z_filetest.gno @@ -1,6 +1,8 @@ package main -import v1 "gno.land/r/x/jeronimo_render_proxy/home/v1" +import ( + v1 "gno.land/r/x/jeronimo_render_proxy/home/v1" +) func main() { println(v1.Render("")) diff --git a/examples/gno.land/r/x/jeronimo_render_proxy/home/v2/v2.gno b/examples/gno.land/r/x/jeronimo_render_proxy/home/v2/v2.gno index 031f8568441..6af10585dff 100644 --- a/examples/gno.land/r/x/jeronimo_render_proxy/home/v2/v2.gno +++ b/examples/gno.land/r/x/jeronimo_render_proxy/home/v2/v2.gno @@ -4,7 +4,7 @@ import "gno.land/r/x/jeronimo_render_proxy/home" func init() { // Register the private render function with the render proxy - home.Register(render) + cross(home.Register)(render) } func render(string) string { diff --git a/examples/gno.land/r/x/jeronimo_render_proxy/home/v2/z_filetest.gno b/examples/gno.land/r/x/jeronimo_render_proxy/home/v2/z_filetest.gno index 52f3f5958f8..b0889d81da4 100644 --- a/examples/gno.land/r/x/jeronimo_render_proxy/home/v2/z_filetest.gno +++ b/examples/gno.land/r/x/jeronimo_render_proxy/home/v2/z_filetest.gno @@ -1,6 +1,8 @@ package main -import v2 "gno.land/r/x/jeronimo_render_proxy/home/v2" +import ( + v2 "gno.land/r/x/jeronimo_render_proxy/home/v2" +) func main() { println(v2.Render("")) diff --git a/gno.land/Makefile b/gno.land/Makefile index 90ba7451c35..a69022a49a0 100644 --- a/gno.land/Makefile +++ b/gno.land/Makefile @@ -80,8 +80,10 @@ imports: ######################################## # Test suite .PHONY: test -test: _test.gnoland _test.gnoweb _test.gnokey _test.pkgs +test: _test.help _test.gnoland _test.gnoweb _test.gnokey _test.pkgs +_test.help: + @echo "run \`INMEMORY_TS=true make test\` if you encounter 'context deadline exceeded' for non-parallel testing" _test.gnoland:; go test $(GOTEST_FLAGS) ./cmd/gnoland _test.gnoweb:; go test $(GOTEST_FLAGS) ./cmd/gnoweb _test.gnokey:; go test $(GOTEST_FLAGS) ./cmd/gnokey diff --git a/gno.land/pkg/integration/testdata/addpkg_namespace.txtar b/gno.land/pkg/integration/testdata/addpkg_namespace.txtar index 50346e16782..f66f51ade46 100644 --- a/gno.land/pkg/integration/testdata/addpkg_namespace.txtar +++ b/gno.land/pkg/integration/testdata/addpkg_namespace.txtar @@ -57,7 +57,7 @@ stderr 'is not authorized to deploy packages to namespace' # test gui register namespace # gui call -> gnoland/users/v1.Register -gnokey maketx call -pkgpath gno.land/r/gnoland/users/v1 -func Register -send "1000000ugnot" -gas-fee 1000000ugnot -gas-wanted 12000000 -broadcast -chainid=tendermint_test -args 'guigui123' gui +gnokey maketx call -pkgpath gno.land/r/gnoland/users/v1 -func Register -send "1000000ugnot" -gas-fee 1000000ugnot -gas-wanted 13000000 -broadcast -chainid=tendermint_test -args 'guigui123' gui stdout 'OK!' # Test gui publishing on guigui123/one diff --git a/gno.land/pkg/integration/testdata/append.txtar b/gno.land/pkg/integration/testdata/append.txtar index 55a57bb9a7e..2e3dd048181 100644 --- a/gno.land/pkg/integration/testdata/append.txtar +++ b/gno.land/pkg/integration/testdata/append.txtar @@ -22,27 +22,23 @@ gnokey maketx call -pkgpath gno.land/r/append -func Append -gas-fee 1000000ugnot stdout OK! # Call render -gnokey maketx call -pkgpath gno.land/r/append -func Render -gas-fee 1000000ugnot -gas-wanted 3000000 -args '' -broadcast -chainid=tendermint_test test1 -stdout '("1-2-3-" string)' -stdout OK! +gnokey query vm/qrender --data 'gno.land/r/append:' +stdout '1-2-3-' # Call Pop gnokey maketx call -pkgpath gno.land/r/append -func Pop -gas-fee 1000000ugnot -gas-wanted 300000 -broadcast -chainid=tendermint_test test1 -stdout OK! # Call render -gnokey maketx call -pkgpath gno.land/r/append -func Render -gas-fee 1000000ugnot -gas-wanted 3000000 -args '' -broadcast -chainid=tendermint_test test1 -stdout '("2-3-" string)' -stdout OK! +gnokey query vm/qrender --data 'gno.land/r/append:' +stdout '2-3-' # Call Append 42 gnokey maketx call -pkgpath gno.land/r/append -func Append -gas-fee 1000000ugnot -gas-wanted 300000 -args '42' -broadcast -chainid=tendermint_test test1 stdout OK! # Call render -gnokey maketx call -pkgpath gno.land/r/append -func Render -gas-fee 1000000ugnot -gas-wanted 3000000 -args '' -broadcast -chainid=tendermint_test test1 -stdout '("2-3-42-" string)' -stdout OK! +gnokey query vm/qrender --data 'gno.land/r/append:' +stdout '2-3-42-' gnokey maketx call -pkgpath gno.land/r/append -func CopyAppend -gas-fee 1000000ugnot -gas-wanted 300000 -broadcast -chainid=tendermint_test test1 stdout OK! @@ -51,9 +47,8 @@ gnokey maketx call -pkgpath gno.land/r/append -func PopB -gas-fee 1000000ugnot - stdout OK! # Call render -gnokey maketx call -pkgpath gno.land/r/append -func Render -gas-fee 1000000ugnot -gas-wanted 3000000 -args '' -broadcast -chainid=tendermint_test test1 -stdout '("2-3-42-" string)' -stdout OK! +gnokey query vm/qrender --data 'gno.land/r/append:' +stdout '2-3-42-' gnokey maketx call -pkgpath gno.land/r/append -func AppendMoreAndC -gas-fee 1000000ugnot -gas-wanted 350000 -broadcast -chainid=tendermint_test test1 stdout OK! @@ -61,13 +56,11 @@ stdout OK! gnokey maketx call -pkgpath gno.land/r/append -func ReassignC -gas-fee 1000000ugnot -gas-wanted 350000 -broadcast -chainid=tendermint_test test1 stdout OK! -gnokey maketx call -pkgpath gno.land/r/append -func Render -gas-fee 1000000ugnot -gas-wanted 3000000 -args '' -broadcast -chainid=tendermint_test test1 -stdout '("2-3-42-70-100-" string)' -stdout OK! +gnokey query vm/qrender --data 'gno.land/r/append:' +stdout '2-3-42-70-100-' -gnokey maketx call -pkgpath gno.land/r/append -func Render -gas-fee 1000000ugnot -gas-wanted 3000000 -args 'd' -broadcast -chainid=tendermint_test test1 -stdout '("1-" string)' -stdout OK! +gnokey query vm/qrender --data 'gno.land/r/append:d' +stdout '1-' -- append.gno -- package append @@ -132,8 +125,6 @@ func AppendNil() { } func Render(path string) string { - crossing() - source := a if path == "d" { source = d diff --git a/gno.land/pkg/integration/testdata/assertorigincall.txtar b/gno.land/pkg/integration/testdata/assertorigincall.txtar index f6893bd5ca6..f75eabacb5b 100644 --- a/gno.land/pkg/integration/testdata/assertorigincall.txtar +++ b/gno.land/pkg/integration/testdata/assertorigincall.txtar @@ -29,6 +29,7 @@ loadpkg gno.land/r/myrlm $WORK/r/myrlm loadpkg gno.land/r/foo $WORK/r/foo loadpkg gno.land/p/demo/bar $WORK/p/demo/bar + gnoland start # The PANIC is expected to fail at the transaction simulation stage, which is why we set gas-wanted to 1. @@ -84,7 +85,7 @@ stdout 'OK!' stderr 'invalid non-origin call' ## 13. MsgRun -> run.main -> foo.A: PANIC -! gnokey maketx run -gas-fee 100000ugnot -gas-wanted 10_000_000 -broadcast -chainid tendermint_test test1 $WORK/run/fooA.gno +! gnokey maketx run -gas-fee 100000ugnot -gas-wanted 15_000_000 -broadcast -chainid tendermint_test test1 $WORK/run/fooA.gno stderr 'invalid non-origin call' ## 14. MsgRun -> run.main -> foo.B: PASS @@ -92,11 +93,11 @@ gnokey maketx run -gas-fee 100000ugnot -gas-wanted 10_000_000 -broadcast -chaini stdout 'OK!' ## 15. MsgRun -> run.main -> foo.C: PANIC -! gnokey maketx run -gas-fee 100000ugnot -gas-wanted 10_000_000 -broadcast -chainid tendermint_test test1 $WORK/run/fooC.gno +! gnokey maketx run -gas-fee 100000ugnot -gas-wanted 15_000_000 -broadcast -chainid tendermint_test test1 $WORK/run/fooC.gno stderr 'invalid non-origin call' ## 16. MsgRun -> run.main -> bar.A: PANIC -! gnokey maketx run -gas-fee 100000ugnot -gas-wanted 10_000_000 -broadcast -chainid tendermint_test test1 $WORK/run/barA.gno +! gnokey maketx run -gas-fee 100000ugnot -gas-wanted 15_000_000 -broadcast -chainid tendermint_test test1 $WORK/run/barA.gno stderr 'invalid non-origin call' ## 17. MsgRun -> run.main -> bar.B: PASS @@ -123,16 +124,22 @@ package myrlm import "std" func A() { + crossing() + C() } func B() { + crossing() + if false { C() } } func C() { + crossing() + std.AssertOriginCall() } -- r/foo/foo.gno -- @@ -141,15 +148,21 @@ package foo import "gno.land/r/myrlm" func A() { - myrlm.A() + crossing() + + cross(myrlm.A)() } func B() { - myrlm.B() + crossing() + + cross(myrlm.B)() } func C() { - myrlm.C() + crossing() + + cross(myrlm.C)() } -- p/demo/bar/bar.gno -- package bar @@ -174,7 +187,9 @@ package main import myrlm "gno.land/r/myrlm" func main() { - myrlm.A() + crossing() + + cross(myrlm.A)() } -- run/myrlmB.gno -- package main @@ -182,7 +197,9 @@ package main import "gno.land/r/myrlm" func main() { - myrlm.B() + crossing() + + cross(myrlm.B)() } -- run/myrlmC.gno -- package main @@ -190,7 +207,9 @@ package main import "gno.land/r/myrlm" func main() { - myrlm.C() + crossing() + + cross(myrlm.C)() } -- run/fooA.gno -- package main @@ -198,7 +217,9 @@ package main import "gno.land/r/foo" func main() { - foo.A() + crossing() + + cross(foo.A)() } -- run/fooB.gno -- package main @@ -206,7 +227,9 @@ package main import "gno.land/r/foo" func main() { - foo.B() + crossing() + + cross(foo.B)() } -- run/fooC.gno -- package main @@ -214,7 +237,9 @@ package main import "gno.land/r/foo" func main() { - foo.C() + crossing() + + cross(foo.C)() } -- run/barA.gno -- package main @@ -222,6 +247,8 @@ package main import "gno.land/p/demo/bar" func main() { + crossing() + bar.A() } -- run/barB.gno -- @@ -230,6 +257,8 @@ package main import "gno.land/p/demo/bar" func main() { + crossing() + bar.B() } -- run/barC.gno -- @@ -238,6 +267,8 @@ package main import "gno.land/p/demo/bar" func main() { + crossing() + bar.C() } -- run/baz.gno -- @@ -246,5 +277,7 @@ package main import "std" func main() { + crossing() + std.AssertOriginCall() } diff --git a/gno.land/pkg/integration/testdata/atomicswap.txtar b/gno.land/pkg/integration/testdata/atomicswap.txtar index 0dd2340ed9d..b2d65ad358d 100644 --- a/gno.land/pkg/integration/testdata/atomicswap.txtar +++ b/gno.land/pkg/integration/testdata/atomicswap.txtar @@ -24,11 +24,10 @@ stdout '(1 int)' stdout ".*$test2_user_addr.*$test3_user_addr.*12345ugnot.*" stdout 'OK!' -gnokey maketx call -pkgpath gno.land/r/demo/atomicswap -func Render -gas-fee 1000000ugnot -gas-wanted 10000000 -args '' -broadcast -chainid=tendermint_test test2 -stdout 'OK!' +gnokey query vm/qrender --data 'gno.land/r/demo/atomicswap:' gnokey query auth/accounts/$test2_user_addr -stdout 'coins.*:.*1007987655ugnot' +stdout 'coins.*:.*1008987655ugnot' gnokey query auth/accounts/$test3_user_addr stdout 'coins.*:.*1010000000ugnot' @@ -36,6 +35,6 @@ gnokey maketx call -pkgpath gno.land/r/demo/atomicswap -func Claim -gas-fee 1000 stdout 'OK!' gnokey query auth/accounts/$test2_user_addr -stdout 'coins.*:.*1007987655ugnot' +stdout 'coins.*:.*1008987655ugnot' gnokey query auth/accounts/$test3_user_addr stdout 'coins.*:.*1009012345ugnot' diff --git a/gno.land/pkg/integration/testdata/ghverify.txtar b/gno.land/pkg/integration/testdata/ghverify.txtar index 2277ab20890..482ffd33322 100644 --- a/gno.land/pkg/integration/testdata/ghverify.txtar +++ b/gno.land/pkg/integration/testdata/ghverify.txtar @@ -35,5 +35,5 @@ stdout "deelawn" gnokey maketx call -pkgpath gno.land/r/gnoland/ghverify -func GetAddressByHandle -args 'deelawn' -gas-fee 1000000ugnot -gas-wanted 800000 -broadcast -chainid=tendermint_test test1 stdout "g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5" -gnokey maketx call -pkgpath gno.land/r/gnoland/ghverify -func Render -args '' -gas-fee 1000000ugnot -gas-wanted 800000 -broadcast -chainid=tendermint_test test1 -stdout '\("\{\\"deelawn\\": \\"g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5\\"\}" string\)' +gnokey query vm/qrender --data 'gno.land/r/gnoland/ghverify:' +stdout '{"deelawn": "g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5"}' diff --git a/gno.land/pkg/integration/testdata/gnoweb_airgapped.txtar b/gno.land/pkg/integration/testdata/gnoweb_airgapped.txtar index c4d0e6bcdf8..46cc21dd08f 100644 --- a/gno.land/pkg/integration/testdata/gnoweb_airgapped.txtar +++ b/gno.land/pkg/integration/testdata/gnoweb_airgapped.txtar @@ -2,7 +2,7 @@ # help page, work as intended. # load the package from $WORK directory -loadpkg gno.land/r/demo/echo +loadpkg gno.land/r/realm $WORK/realm # add a random user adduserfrom user1 'lamp any denial pulse used shoot gap error denial mansion hurry foot solution grab winner congress drastic cat bamboo chicken color digital coffee unknown' @@ -26,7 +26,7 @@ stdout '}' ! stderr '.+' # empty # Create transaction -gnokey maketx call -pkgpath "gno.land/r/demo/echo" -func "Render" -gas-fee 1000000ugnot -gas-wanted 2000000 -send "" -args "HELLO" user1 +gnokey maketx call -pkgpath "gno.land/r/realm" -func "SetName" -gas-fee 1000000ugnot -gas-wanted 2000000 -send "" -args "foo" user1 cp stdout call.tx # Sign @@ -34,9 +34,27 @@ gnokey sign -tx-path $WORK/call.tx -chainid "tendermint_test" -account-number 58 cmpenv stdout sign.stdout.golden gnokey broadcast $WORK/call.tx -stdout '("HELLO" string)' +stdout '("foo" string)' stdout 'GAS WANTED: 2000000' +gnokey query vm/qrender --data '"gno.land/r/realm":' +stdout '# HELLO foo' + -- sign.stdout.golden -- Tx successfully signed and saved to $WORK/call.tx +-- realm/realm.gno -- +package name + +var name string + +func SetName(s string) string { + crossing() + + name = s + return name +} + +func Render(_ string) string { + return "# HELLO "+name +} diff --git a/gno.land/pkg/integration/testdata/import.txtar b/gno.land/pkg/integration/testdata/import.txtar index 34cd6bbeceb..ea4350f77a4 100644 --- a/gno.land/pkg/integration/testdata/import.txtar +++ b/gno.land/pkg/integration/testdata/import.txtar @@ -6,9 +6,8 @@ loadpkg $WORK gnoland start ## execute Render -gnokey maketx call -pkgpath gno.land/r/importtest -func Render -gas-fee 1000000ugnot -gas-wanted 3000000 -args '' -broadcast -chainid=tendermint_test test1 -stdout '("92054" string)' -stdout OK! +gnokey query vm/qrender --data 'gno.land/r/importtest:' +stdout '92054' -- gno.mod -- module gno.land/r/importtest @@ -21,7 +20,5 @@ import ( ) func Render(_ string) string { - crossing() - return ufmt.Sprintf("%d", 92054) } diff --git a/gno.land/pkg/integration/testdata/infinite_loop.txtar b/gno.land/pkg/integration/testdata/infinite_loop.txtar index d05442e62d0..0b9c8483c82 100644 --- a/gno.land/pkg/integration/testdata/infinite_loop.txtar +++ b/gno.land/pkg/integration/testdata/infinite_loop.txtar @@ -38,11 +38,11 @@ stderr 'out of gas.* location: CPUCycles' stderr 'out of gas.* location: CPUCycles' # call on the render function -! gnokey maketx call -pkgpath gno.land/r/demo/r2 -func Render -args '' -simulate skip -gas-fee 100000ugnot -gas-wanted 1000000 -broadcast -chainid tendermint_test test1 +! gnokey query vm/qrender --data 'gno.land/r/demo/r2:' stderr 'out of gas.* location: CPUCycles' # simulated call on the render function -! gnokey maketx call -pkgpath gno.land/r/demo/r2 -func Render -args '' -simulate only -gas-fee 100000ugnot -gas-wanted 1000000 -broadcast -chainid tendermint_test test1 +! gnokey query vm/qrender --data 'gno.land/r/demo/r2:' stderr 'out of gas.* location: CPUCycles' -- run.gno -- @@ -67,9 +67,7 @@ func init() { for {} } -func main() { - crossing() -} +func main() {} -- r2/gno.mod -- module gno.land/r/demo/r2 @@ -79,8 +77,6 @@ module gno.land/r/demo/r2 package r2 func Render(s string) string { - crossing() - for {} return "hello world!" diff --git a/gno.land/pkg/integration/testdata/initctx.txtar b/gno.land/pkg/integration/testdata/initctx.txtar index d5793f4007b..a986c8bbf81 100644 --- a/gno.land/pkg/integration/testdata/initctx.txtar +++ b/gno.land/pkg/integration/testdata/initctx.txtar @@ -6,10 +6,8 @@ loadpkg gno.land/r/foobar/bar $WORK/bar gnoland start # execute Render -gnokey maketx call -pkgpath gno.land/r/foobar/bar -func Render -args X -gas-fee 1000000ugnot -gas-wanted 2000000 -broadcast -chainid=tendermint_test test1 -stdout OK! -stdout '(" orig=g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5 prev=g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5" string)' -stdout 'OK!' +gnokey query vm/qrender --data='gno.land/r/foobar/bar:X' +stdout ' orig=g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5 prev=g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5' -- bar/bar.gno -- package bar diff --git a/gno.land/pkg/integration/testdata/issue_1167.txtar b/gno.land/pkg/integration/testdata/issue_1167.txtar index 10f445de864..c8f821b6d83 100644 --- a/gno.land/pkg/integration/testdata/issue_1167.txtar +++ b/gno.land/pkg/integration/testdata/issue_1167.txtar @@ -14,30 +14,25 @@ stdout OK! # execute Delta for the first time gnokey maketx call -pkgpath gno.land/r/demo/xx -func Delta -args X -gas-fee 1000000ugnot -gas-wanted 2500000 -broadcast -chainid=tendermint_test test1 stdout OK! -stdout '"1,1,1;" string' +stdout '"1,1,1;' # execute Delta for the second time gnokey maketx call -pkgpath gno.land/r/demo/xx -func Delta -args X -gas-fee 1000000ugnot -gas-wanted 2500000 -broadcast -chainid=tendermint_test test1 stdout OK! -stdout '1,1,1;2,2,2;" string' +stdout '1,1,1;2,2,2;' # execute Delta for the third time gnokey maketx call -pkgpath gno.land/r/demo/xx -func Delta -args X -gas-fee 1000000ugnot -gas-wanted 2500000 -broadcast -chainid=tendermint_test test1 stdout OK! -stdout '1,1,1;2,2,2;3,3,3;" string' +stdout '1,1,1;2,2,2;3,3,3;' # execute Render -gnokey maketx call -pkgpath gno.land/r/demo/xx -func Render -args X -gas-fee 1000000ugnot -gas-wanted 2500000 -broadcast -chainid=tendermint_test test1 -stdout OK! -stdout '1,1,1;2,2,2;3,3,3;" string' +gnokey query vm/qrender --data "gno.land/r/demo/xx:X" +stdout '1,1,1;2,2,2;3,3,3;' -- gno.mod -- module gno.land/r/demo/xx -require ( - gno.land/p/demo/avl v0.0.0-latest -) - -- realm.gno -- package xx @@ -102,8 +97,6 @@ func Delta(s string) string { } func Render(s string) string { - crossing() - v, _ := games.Get(s) g, ok := v.(*Game) if !ok { diff --git a/gno.land/pkg/integration/testdata/issue_1543.txtar b/gno.land/pkg/integration/testdata/issue_1543.txtar index 388f126fcda..90de76e6bd8 100644 --- a/gno.land/pkg/integration/testdata/issue_1543.txtar +++ b/gno.land/pkg/integration/testdata/issue_1543.txtar @@ -1,16 +1,14 @@ -# test issue +# test issue loadpkg gno.land/r/demo/realm $WORK # start a new node gnoland start - gnokey maketx call -pkgpath gno.land/r/demo/realm --func Fill --args 0 --gas-fee 1000000ugnot --gas-wanted 2000000 --broadcast -chainid=tendermint_test test1 gnokey maketx call -pkgpath gno.land/r/demo/realm --func UnFill --args 0 --gas-fee 1000000ugnot --gas-wanted 2000000 --broadcast -chainid=tendermint_test test1 gnokey maketx call -pkgpath gno.land/r/demo/realm --func Fill --args 0 --gas-fee 1000000ugnot --gas-wanted 2000000 --broadcast -chainid=tendermint_test test1 - -- realm.gno -- package main @@ -28,7 +26,9 @@ var ( ) func Fill(i int) { - c := B{ + crossing() + + c := B{ A: a, B: "", } @@ -36,6 +36,7 @@ func Fill(i int) { } func UnFill(i int) { + crossing() + b[i] = nil } - diff --git a/gno.land/pkg/integration/testdata/issue_1786.txtar b/gno.land/pkg/integration/testdata/issue_1786.txtar index 2aa33f6a6be..08b28a17da6 100644 --- a/gno.land/pkg/integration/testdata/issue_1786.txtar +++ b/gno.land/pkg/integration/testdata/issue_1786.txtar @@ -64,13 +64,15 @@ func ProxyWrap() { wugnotAddr := std.DerivePkgAddr("gno.land/r/demo/wugnot") banker := std.NewBanker(std.BankerTypeRealmSend) banker.SendCoins(std.CurrentRealm().Address(), wugnotAddr, std.Coins{{"ugnot", int64(ugnotSent)}}) - wugnot.Deposit() // `proxywugnot` has ugnot + cross(wugnot.Deposit)() // `proxywugnot` has ugnot // SEND WUGNOT: PROXY_WUGNOT -> USER - wugnot.Transfer(std.OriginCaller(), ugnotSent) + cross(wugnot.Transfer)(std.OriginCaller(), ugnotSent) } func ProxyUnwrap(wugnotAmount uint64) { + crossing() + if wugnotAmount == 0 { return } diff --git a/gno.land/pkg/integration/testdata/issue_2266.txtar b/gno.land/pkg/integration/testdata/issue_2266.txtar index 046f57802e3..6da89c52f6e 100644 --- a/gno.land/pkg/integration/testdata/issue_2266.txtar +++ b/gno.land/pkg/integration/testdata/issue_2266.txtar @@ -1,4 +1,4 @@ -# test issue +# test issue loadpkg gno.land/r/demo/realm $WORK @@ -28,7 +28,9 @@ var ( ) func Fill(i int) { - c := B{ + crossing() + + c := B{ A: a, B: "", } @@ -36,7 +38,8 @@ func Fill(i int) { } func UnFill() { + crossing() + b[0] = nil b[1] = nil } - diff --git a/gno.land/pkg/integration/testdata/issue_gnochess_97.txtar b/gno.land/pkg/integration/testdata/issue_gnochess_97.txtar index 89406d328d4..868e3b07536 100644 --- a/gno.land/pkg/integration/testdata/issue_gnochess_97.txtar +++ b/gno.land/pkg/integration/testdata/issue_gnochess_97.txtar @@ -31,10 +31,14 @@ func NewS() S { var s S func RealmCall1() { + crossing() + s = NewS() } func RealmCall2() { + crossing() + arr2 := s.Arr arr2[0] = 8 s = S{Arr: arr2} diff --git a/gno.land/pkg/integration/testdata/loadpkg_example.txtar b/gno.land/pkg/integration/testdata/loadpkg_example.txtar index f7be500f3b6..505832962fc 100644 --- a/gno.land/pkg/integration/testdata/loadpkg_example.txtar +++ b/gno.land/pkg/integration/testdata/loadpkg_example.txtar @@ -8,9 +8,8 @@ gnokey maketx addpkg -pkgdir $WORK -pkgpath gno.land/r/importtest -gas-fee 10000 stdout OK! ## execute Render -gnokey maketx call -pkgpath gno.land/r/importtest -func Render -gas-fee 1000000ugnot -gas-wanted 10000000 -args '' -broadcast -chainid=tendermint_test test1 -stdout '("92054" string)' -stdout OK! +gnokey query vm/qrender --data 'gno.land/r/importtest:' +stdout '92054' -- gno.mod -- module gno.land/r/importtest diff --git a/gno.land/pkg/integration/testdata/loadpkg_example_and_work.txtar b/gno.land/pkg/integration/testdata/loadpkg_example_and_work.txtar index 27e357fece4..4ee4994eeab 100644 --- a/gno.land/pkg/integration/testdata/loadpkg_example_and_work.txtar +++ b/gno.land/pkg/integration/testdata/loadpkg_example_and_work.txtar @@ -6,9 +6,8 @@ loadpkg gno.land/r/importtest $WORK gnoland start ## execute Render -gnokey maketx call -pkgpath gno.land/r/importtest -func Render -gas-fee 1000000ugnot -gas-wanted 2000000 -args '' -broadcast -chainid=tendermint_test test1 -stdout '("92054" string)' -stdout OK! +gnokey query vm/qrender --data 'gno.land/r/importtest:' +stdout '92054' -- import.gno -- package importtest @@ -20,4 +19,3 @@ import ( func Render(_ string) string { return ufmt.Sprintf("%d", 92054) } - diff --git a/gno.land/pkg/integration/testdata/loadpkg_work.txtar b/gno.land/pkg/integration/testdata/loadpkg_work.txtar index e789c171dc2..c23b8fc920b 100644 --- a/gno.land/pkg/integration/testdata/loadpkg_work.txtar +++ b/gno.land/pkg/integration/testdata/loadpkg_work.txtar @@ -27,5 +27,7 @@ package main import "gno.land/r/foobar/bar" func main() { + crossing() + println("main: ---", bar.Render(""), "---") } diff --git a/gno.land/pkg/integration/testdata/maketx_call_pure.txtar b/gno.land/pkg/integration/testdata/maketx_call_pure.txtar index e3231eccc01..27f0a0aeb64 100644 --- a/gno.land/pkg/integration/testdata/maketx_call_pure.txtar +++ b/gno.land/pkg/integration/testdata/maketx_call_pure.txtar @@ -1,26 +1,34 @@ # load the package -loadpkg gno.land/p/foo/call_package $WORK/package +loadpkg gno.land/p/foo/call_pure $WORK/pure loadpkg gno.land/r/foo/call_realm $WORK/realm # start a new node gnoland start -# 1. call to package ERROR -! gnokey maketx call -pkgpath gno.land/p/foo/call_package -func Render -gas-fee 1000000ugnot -gas-wanted 2000000 -broadcast -chainid=tendermint_test test1 +# 1. eval to pure package SUCCESS +gnokey query vm/qeval --data 'gno.land/p/foo/call_pure.Hello()' +stdout 'notok' + +# 2. call to pure package ERROR +! gnokey maketx call -pkgpath gno.land/p/foo/call_pure -func Hello -gas-fee 1000000ugnot -gas-wanted 2000000 -broadcast -chainid=tendermint_test test1 stderr '"gnokey" error: --= Error =--\nData: invalid package path' -# 2. call to stdlibs ERROR +# 3. call to stdlibs ERROR ! gnokey maketx call -pkgpath strconv -func Itoa -args 11 -gas-fee 1000000ugnot -gas-wanted 2000000 -broadcast -chainid=tendermint_test test1 stderr '"gnokey" error: --= Error =--\nData: invalid package path' -# 3. normal call to realm PASS -gnokey maketx call -pkgpath gno.land/r/foo/call_realm -func Render -gas-fee 1000000ugnot -gas-wanted 2000000 -broadcast -chainid=tendermint_test test1 -stdout OK! +# 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 'missing crossing\(\) after cross call in Render from to gno.land/r/foo/call_realm' --- package/package.gno -- -package call_package +# 5. normal eval realm SUCCESS +gnokey query vm/qeval --data 'gno.land/r/foo/call_realm.Render()' +stdout 'ok' -func Render() string { +-- pure/package.gno -- +package call_pure + +func Hello() string { return "notok" } diff --git a/gno.land/pkg/integration/testdata/params_sysparams1.txtar b/gno.land/pkg/integration/testdata/params_sysparams1.txtar index 6800cf18ccb..ffb54b345c4 100644 --- a/gno.land/pkg/integration/testdata/params_sysparams1.txtar +++ b/gno.land/pkg/integration/testdata/params_sysparams1.txtar @@ -37,4 +37,7 @@ import ( ) // This should succeed if it is called from gno.land/r/sys/params -func SetLockTransfer(denom string) { params.SetSysParamStrings("bank","p", "restricted_denoms", []string{denom}) } +func SetLockTransfer(denom string) { + crossing() + params.SetSysParamStrings("bank","p", "restricted_denoms", []string{denom}) +} diff --git a/gno.land/pkg/integration/testdata/params_sysparams2.txtar b/gno.land/pkg/integration/testdata/params_sysparams2.txtar index 054c2c5e5d3..156000a0f47 100644 --- a/gno.land/pkg/integration/testdata/params_sysparams2.txtar +++ b/gno.land/pkg/integration/testdata/params_sysparams2.txtar @@ -77,21 +77,49 @@ import ( ) // This should succeed if it is called from gno.land/r/sys/params -func SetLockTransfer(denom string) { params.SetSysParamStrings("bank","p", "restricted_denoms", []string{denom}) } +func SetLockTransfer(denom string) { + crossing() + params.SetSysParamStrings("bank","p", "restricted_denoms", []string{denom}) +} // # XXX test setting the wrong type, like SetSysParamString() instead of Strings(), and make it error for special case of "p". // # func SetLockTransfer(denom string) { params.SetSysParamString("bank","p", "restricted_denoms", denom) } // This should fail because the parameter does not exist -func SetBankArbitrary(value string) { params.SetSysParamString("bank","p", "newkey", value) } +func SetBankArbitrary(value string) { + crossing() + params.SetSysParamString("bank","p", "newkey", value) +} // SetSysParamXXX must be called from gno.land/r/sys/params; otherwise it panics // This should fail because the key "bank:restricted_denoms" is not valid -func SetInvalidKey(denom string) { params.SetSysParamString("bank", "p", "bank:restricted_denoms", "ugnot") } - -func SetSysParamString(s string) { params.SetSysParamString("bank","p", "foo", s) } -func SetSysParamBool(b bool) { params.SetSysParamBool("bank","p", "bar", b) } -func SetSysParamInt64(i int64) { params.SetSysParamInt64("bank","p", "baz", i) } -func SetSysParamUint64(u uint64) { params.SetSysParamUint64("bank","p", "baz", u) } -func SetSysParamBytes() { params.SetSysParamBytes("bank","p", "baz", []byte{255,255}) } +func SetInvalidKey(denom string) { + crossing() + params.SetSysParamString("bank", "p", "bank:restricted_denoms", "ugnot") +} + +func SetSysParamString(s string) { + crossing() + params.SetSysParamString("bank","p", "foo", s) +} + +func SetSysParamBool(b bool) { + crossing() + params.SetSysParamBool("bank","p", "bar", b) +} + +func SetSysParamInt64(i int64) { + crossing() + params.SetSysParamInt64("bank","p", "baz", i) +} + +func SetSysParamUint64(u uint64) { + crossing() + params.SetSysParamUint64("bank","p", "baz", u) +} + +func SetSysParamBytes() { + crossing() + params.SetSysParamBytes("bank","p", "baz", []byte{255,255}) +} diff --git a/gno.land/pkg/integration/testdata/patchpkg.txtar b/gno.land/pkg/integration/testdata/patchpkg.txtar index 58fed49bc2e..da86a0bf482 100644 --- a/gno.land/pkg/integration/testdata/patchpkg.txtar +++ b/gno.land/pkg/integration/testdata/patchpkg.txtar @@ -6,7 +6,7 @@ patchpkg "g1abcde" $dev_user_addr gnoland start -gnokey maketx call -pkgpath gno.land/r/dev/admin -func Render -gas-fee 1000000ugnot -gas-wanted 2000000 -args '' -broadcast -chainid=tendermint_test test1 +gnokey query vm/qrender --data 'gno.land/r/dev/admin:' ! stdout g1abcde stdout $dev_user_addr @@ -16,7 +16,5 @@ package admin var admin = "g1abcde" func Render(path string) string { - crossing() - return "# Hello "+admin } diff --git a/gno.land/pkg/integration/testdata/prevrealm.txtar b/gno.land/pkg/integration/testdata/prevrealm.txtar index fd3aa59d68e..bf03deefd30 100644 --- a/gno.land/pkg/integration/testdata/prevrealm.txtar +++ b/gno.land/pkg/integration/testdata/prevrealm.txtar @@ -31,7 +31,6 @@ loadpkg gno.land/p/demo/bar $WORK/p/demo/bar gnoland start env RFOO_USER_ADDR=g1evezrh92xaucffmtgsaa3rvmz5s8kedffsg469 -env R_UNKNOWN_ADDR=g1a9r05e34s7dxe7wh8v00lnewnxtfnfq02gn5ws # XXX: temp # Test cases ## 1. MsgCall -> myrlm.A: user address @@ -69,30 +68,29 @@ stdout ${test1_user_addr} ## 9. MsgRun -> r/foo.A -> myrlm.A: r/foo gnokey maketx run -gas-fee 100000ugnot -gas-wanted 12000000 -broadcast -chainid tendermint_test test1 $WORK/run/fooA.gno -stdout ${test1_user_addr} +stdout ${RFOO_USER_ADDR} ## 10. MsgRun -> r/foo.B -> myrlm.B -> r/foo.A: r/foo gnokey maketx run -gas-fee 100000ugnot -gas-wanted 12000000 -broadcast -chainid tendermint_test test1 $WORK/run/fooB.gno -stdout ${test1_user_addr} +stdout ${RFOO_USER_ADDR} ## 11. MsgRun -> p/demo/bar.A -> myrlm.A: user address -## crossing call only allowed in realm packages, doesn't work -gnokey maketx run -gas-fee 100000ugnot -gas-wanted 12000000 -broadcast -chainid tendermint_test test1 $WORK/run/barA.gno +## XXX: crossing call only allowed in realm packages, doesn't work +! gnokey maketx run -gas-fee 100000ugnot -gas-wanted 12000000 -broadcast -chainid tendermint_test test1 $WORK/run/barA.gno stderr 'crossing' ## 12. MsgRun -> p/demo/bar.B -> myrlm.B -> r/foo.A: user address -## crossing call only allowed in realm packages, doesn't work -gnokey maketx run -gas-fee 100000ugnot -gas-wanted 12000000 -broadcast -chainid tendermint_test test1 $WORK/run/barB.gno +## XXX: crossing call only allowed in realm packages, doesn't work +! gnokey maketx run -gas-fee 100000ugnot -gas-wanted 12000000 -broadcast -chainid tendermint_test test1 $WORK/run/barB.gno stderr 'crossing' ## 13. MsgCall -> std.PreviousRealm(): user address -gnokey maketx call -pkgpath std -func PreviousRealm -gas-fee 100000ugnot -gas-wanted 4000000 -broadcast -chainid tendermint_test test1 -stderr 'crossing' +## gnokey maketx call -pkgpath std -func PreviousRealm -gas-fee 100000ugnot -gas-wanted 4000000 -broadcast -chainid tendermint_test test1 +## stdout ${test1_user_addr} ## 14. MsgRun -> std.PreviousRealm(): user address -## PreviousRealm() not possible in run + main: frame not found -! gnokey maketx run -gas-fee 100000ugnot -gas-wanted 12000000 -broadcast -chainid tendermint_test test1 $WORK/run/baz.gno -stderr 'crossing' +gnokey maketx run -gas-fee 100000ugnot -gas-wanted 12000000 -broadcast -chainid tendermint_test test1 $WORK/run/baz.gno +stdout ${test1_user_addr} -- r/myrlm/myrlm.gno -- package myrlm diff --git a/gno.land/pkg/integration/testdata/realm_banker_issued_coin_denom.txtar b/gno.land/pkg/integration/testdata/realm_banker_issued_coin_denom.txtar index 26f643bd420..34aa84c8187 100644 --- a/gno.land/pkg/integration/testdata/realm_banker_issued_coin_denom.txtar +++ b/gno.land/pkg/integration/testdata/realm_banker_issued_coin_denom.txtar @@ -79,11 +79,15 @@ import ( ) func Mint(addr std.Address, denom string, amount int64) { + crossing() + banker := std.NewBanker(std.BankerTypeRealmIssue) banker.IssueCoin(addr, std.CurrentRealm().CoinDenom(denom), amount) } func Burn(addr std.Address, denom string, amount int64) { + crossing() + banker := std.NewBanker(std.BankerTypeRealmIssue) banker.RemoveCoin(addr, std.CurrentRealm().CoinDenom(denom), amount) } @@ -97,11 +101,15 @@ import ( ) func Mint(addr std.Address, denom string, amount int64) { + crossing() + banker := std.NewBanker(std.BankerTypeRealmIssue) banker.IssueCoin(addr, std.CurrentRealm().CoinDenom(denom), amount) } func Burn(addr std.Address, denom string, amount int64) { + crossing() + banker := std.NewBanker(std.BankerTypeRealmIssue) banker.RemoveCoin(addr, std.CurrentRealm().CoinDenom(denom), amount) } @@ -114,11 +122,15 @@ import ( ) func Mint(addr std.Address, denom string, amount int64) { + crossing() + banker := std.NewBanker(std.BankerTypeRealmIssue) banker.IssueCoin(addr, denom, amount) } func Burn(addr std.Address, denom string, amount int64) { + crossing() + banker := std.NewBanker(std.BankerTypeRealmIssue) banker.RemoveCoin(addr, denom, amount) } diff --git a/gno.land/pkg/integration/testdata/transfer_lock.txtar b/gno.land/pkg/integration/testdata/transfer_lock.txtar index 5fcea46c01f..bc6c80ec3bb 100644 --- a/gno.land/pkg/integration/testdata/transfer_lock.txtar +++ b/gno.land/pkg/integration/testdata/transfer_lock.txtar @@ -37,7 +37,7 @@ gnokey maketx addpkg -pkgdir $WORK -pkgpath gno.land/r/bank -gas-fee 1000000ugno stdout 'OK!' ## paying gas fees to call a realm function is acceptable. -gnokey maketx call -pkgpath gno.land/r/demo/echo -func Render -args "Hello!" -gas-fee 1000000ugnot -gas-wanted 12500000 -broadcast -chainid=tendermint_test regular1 +gnokey query vm/qrender --data 'gno.land/r/demo/echo:Hello!' stdout 'Hello!' -- bank.gno -- diff --git a/gno.land/pkg/integration/testdata/wugnot.txtar b/gno.land/pkg/integration/testdata/wugnot.txtar index aa8354a1085..d06c31e7fd8 100644 --- a/gno.land/pkg/integration/testdata/wugnot.txtar +++ b/gno.land/pkg/integration/testdata/wugnot.txtar @@ -2,44 +2,39 @@ loadpkg gno.land/r/demo/wugnot gnoland start -gnokey maketx call -pkgpath gno.land/r/demo/wugnot -func Render -gas-fee 10000000ugnot -gas-wanted 6000000 -args '' -broadcast -chainid=tendermint_test test1 +gnokey query vm/qrender --data "gno.land/r/demo/wugnot:" stdout '# wrapped GNOT \(\$wugnot\)' stdout 'Decimals..: 0' stdout 'Total supply..: 0' stdout 'Known accounts..: 0' -stdout 'OK!' gnokey maketx call -pkgpath gno.land/r/demo/wugnot -func Deposit -send 12345678ugnot -gas-fee 1000000ugnot -gas-wanted 50000000 -broadcast -chainid=tendermint_test test1 stdout 'OK!' -gnokey maketx call -pkgpath gno.land/r/demo/wugnot -func Render -gas-fee 1000000ugnot -gas-wanted 6000000 -args '' -broadcast -chainid=tendermint_test test1 +gnokey query vm/qrender --data "gno.land/r/demo/wugnot:" stdout 'Total supply..: 12345678' stdout 'Known accounts..: 1' -stdout 'OK!' # XXX: use test2 instead (depends on https://github.com/gnolang/gno/issues/1269#issuecomment-1806386069) gnokey maketx call -pkgpath gno.land/r/demo/wugnot -func Deposit -send 12345678ugnot -gas-fee 1000000ugnot -gas-wanted 100000000 -broadcast -chainid=tendermint_test test1 stdout 'OK!' -gnokey maketx call -pkgpath gno.land/r/demo/wugnot -func Render -gas-fee 1000000ugnot -gas-wanted 6000000 -args '' -broadcast -chainid=tendermint_test test1 +gnokey query vm/qrender --data "gno.land/r/demo/wugnot:" stdout 'Total supply..: 24691356' stdout 'Known accounts..: 1' # should be 2 once we can use test2 -stdout 'OK!' # XXX: replace hardcoded address with test3 gnokey maketx call -pkgpath gno.land/r/demo/wugnot -func Transfer -gas-fee 1000000ugnot -gas-wanted 100000000 -args 'g1u7y667z64x2h7vc6fmpcprgey4ck233jaww9zq' -args '10000000' -broadcast -chainid=tendermint_test test1 stdout 'OK!' -gnokey maketx call -pkgpath gno.land/r/demo/wugnot -func Render -gas-fee 1000000ugnot -gas-wanted 6000000 -args '' -broadcast -chainid=tendermint_test test1 +gnokey query vm/qrender --data "gno.land/r/demo/wugnot:" stdout 'Total supply..: 24691356' stdout 'Known accounts..: 2' # should be 3 once we can use test2 -stdout 'OK!' # XXX: use test3 instead (depends on https://github.com/gnolang/gno/issues/1269#issuecomment-1806386069) gnokey maketx call -pkgpath gno.land/r/demo/wugnot -func Withdraw -args 10000000 -gas-fee 1000000ugnot -gas-wanted 100000000 -broadcast -chainid=tendermint_test test1 stdout 'OK!' -gnokey maketx call -pkgpath gno.land/r/demo/wugnot -func Render -gas-fee 1000000ugnot -gas-wanted 100000000 -args '' -broadcast -chainid=tendermint_test test1 +gnokey query vm/qrender --data "gno.land/r/demo/wugnot:" stdout 'Total supply..: 14691356' stdout 'Known accounts..: 2' # should be 3 once we can use test2 -stdout 'OK!' diff --git a/gno.land/pkg/sdk/vm/handler_test.go b/gno.land/pkg/sdk/vm/handler_test.go index 6ca649f76a3..87047fad0e4 100644 --- a/gno.land/pkg/sdk/vm/handler_test.go +++ b/gno.land/pkg/sdk/vm/handler_test.go @@ -81,7 +81,7 @@ func TestVmHandlerQuery_Eval(t *testing.T) { {input: []byte(`gno.land/r/hello.float64(1337)`), expectedResult: `(1337 float64)`}, {input: []byte(`gno.land/r/hello.myStructInst`), expectedResult: `(struct{(1000 int)} gno.land/r/hello.myStruct)`}, {input: []byte(`gno.land/r/hello.myStructInst.Foo()`), expectedResult: `("myStruct.Foo" string)`}, - {input: []byte(`gno.land/r/hello.myStruct`), expectedResultMatch: `\(typeval{gno.land/r/hello.myStruct \(0x.*\)} type{}\)`}, + {input: []byte(`gno.land/r/hello.myStruct`), expectedResultMatch: `\(typeval{gno.land/r/hello.myStruct} type{}\)`}, {input: []byte(`gno.land/r/hello.Inc`), expectedResult: `(Inc func() int)`}, {input: []byte(`gno.land/r/hello.fn()("hi")`), expectedResult: `("echo:hi" string)`}, {input: []byte(`gno.land/r/hello.sl`), expectedResultMatch: `(slice[ref(.*)] []int)`}, // XXX: should return the actual value diff --git a/gno.land/pkg/sdk/vm/keeper.go b/gno.land/pkg/sdk/vm/keeper.go index fcc82efedeb..edbf7ee21bc 100644 --- a/gno.land/pkg/sdk/vm/keeper.go +++ b/gno.land/pkg/sdk/vm/keeper.go @@ -423,7 +423,7 @@ func (vm *VMKeeper) Call(ctx sdk.Context, msg MsgCall) (res string, err error) { pn := gnostore.GetBlockNode(pl).(*gno.PackageNode) ft := pn.GetStaticTypeOf(gnostore, gno.Name(fnc)).(*gno.FuncType) // Make main Package with imports. - mpn := gno.NewPackageNode("main", "main", nil) + mpn := gno.NewPackageNode("main", "", nil) mpn.Define("pkg", gno.TypedValue{T: &gno.PackageType{}, V: pv}) mpv := mpn.NewPackage() // Parse expression. @@ -625,7 +625,6 @@ func (vm *VMKeeper) Run(ctx sdk.Context, msg MsgRun) (res string, err error) { Context: msgCtx, GasMeter: ctx.GasMeter(), }) - // XXX MsgRun does not have pkgPath. How do we find it on chain? defer m.Release() defer doRecover(m, &err) diff --git a/gnovm/cmd/gno/testdata/test/error_correct.txtar b/gnovm/cmd/gno/testdata/test/error_correct.txtar index bcd2c87da5c..642227fb56a 100644 --- a/gnovm/cmd/gno/testdata/test/error_correct.txtar +++ b/gnovm/cmd/gno/testdata/test/error_correct.txtar @@ -2,8 +2,8 @@ gno test -v . -stderr '=== RUN file/x_filetest.gno' -stderr '--- PASS: file/x_filetest.gno \(\d+\.\d\ds\)' +stderr '=== RUN ./x_filetest.gno' +stderr '--- PASS: ./x_filetest.gno \(\d+\.\d\ds\)' stderr 'ok \. \d+\.\d\ds' -- x_filetest.gno -- diff --git a/gnovm/cmd/gno/testdata/test/error_incorrect.txtar b/gnovm/cmd/gno/testdata/test/error_incorrect.txtar index 621397d8d1f..a89221c37af 100644 --- a/gnovm/cmd/gno/testdata/test/error_incorrect.txtar +++ b/gnovm/cmd/gno/testdata/test/error_incorrect.txtar @@ -2,7 +2,7 @@ ! gno test -v . -stderr '=== RUN file/x_filetest.gno' +stderr '=== RUN ./x_filetest.gno' stderr 'Error diff:' stderr '-xxx' stderr '\+oups' diff --git a/gnovm/cmd/gno/testdata/test/error_sync.txtar b/gnovm/cmd/gno/testdata/test/error_sync.txtar index 067489c41f2..22cb25c2657 100644 --- a/gnovm/cmd/gno/testdata/test/error_sync.txtar +++ b/gnovm/cmd/gno/testdata/test/error_sync.txtar @@ -6,7 +6,7 @@ gno test -update-golden-tests -v . ! stdout .+ -stderr '=== RUN file/x_filetest.gno' +stderr '=== RUN ./x_filetest.gno' cmp x_filetest.gno x_filetest.gno.golden diff --git a/gnovm/cmd/gno/testdata/test/failing_filetest.txtar b/gnovm/cmd/gno/testdata/test/failing_filetest.txtar index 7b57729ee91..1517188a290 100644 --- a/gnovm/cmd/gno/testdata/test/failing_filetest.txtar +++ b/gnovm/cmd/gno/testdata/test/failing_filetest.txtar @@ -2,7 +2,7 @@ ! gno test -v . -stderr '=== RUN file/failing_filetest.gno' +stderr '=== RUN ./failing_filetest.gno' stderr 'unexpected panic: beep boop' -- failing.gno -- diff --git a/gnovm/cmd/gno/testdata/test/filetest_events.txtar b/gnovm/cmd/gno/testdata/test/filetest_events.txtar index 157cb811402..4b1c17126f5 100644 --- a/gnovm/cmd/gno/testdata/test/filetest_events.txtar +++ b/gnovm/cmd/gno/testdata/test/filetest_events.txtar @@ -8,8 +8,8 @@ stderr 'ok \. \d+\.\d\ds' gno test -print-events -v . stdout 'test' -stderr '=== RUN file/valid_filetest.gno' -stderr '--- PASS: file/valid_filetest.gno \(\d+\.\d\ds\)' +stderr '=== RUN ./valid_filetest.gno' +stderr '--- PASS: ./valid_filetest.gno \(\d+\.\d\ds\)' stderr 'ok \. \d+\.\d\ds' -- valid.gno -- diff --git a/gnovm/cmd/gno/testdata/test/origin_caller.txtar b/gnovm/cmd/gno/testdata/test/origin_caller.txtar new file mode 100644 index 00000000000..bc358bccf32 --- /dev/null +++ b/gnovm/cmd/gno/testdata/test/origin_caller.txtar @@ -0,0 +1,23 @@ +# Test with a _test.gno file calling std.OriginCaller() + + gno test . + +! stdout .+ +stderr 'ok \. \d+\.\d\ds' + +-- gno.mod -- +module gno.land/r/origin_caller + +-- origin_caller_test.gno -- +package origin_caller + +import ( + "testing" + "std" +) + +func TestOriginCaller(t *testing.T) { + if std.OriginCaller().IsValid() { + t.Error("std.OriginCaller() from (non-filetest) test cases should not return a valid address") + } +} diff --git a/gnovm/cmd/gno/testdata/test/output_correct.txtar b/gnovm/cmd/gno/testdata/test/output_correct.txtar index 3a829e66bee..2133f158d52 100644 --- a/gnovm/cmd/gno/testdata/test/output_correct.txtar +++ b/gnovm/cmd/gno/testdata/test/output_correct.txtar @@ -4,8 +4,8 @@ gno test -v . stdout 'hey' stdout 'hru?' -stderr '=== RUN file/x_filetest.gno' -stderr '--- PASS: file/x_filetest.gno \(\d+\.\d\ds\)' +stderr '=== RUN ./x_filetest.gno' +stderr '--- PASS: ./x_filetest.gno \(\d+\.\d\ds\)' stderr 'ok \. \d+\.\d\ds' -- x_filetest.gno -- diff --git a/gnovm/cmd/gno/testdata/test/output_incorrect.txtar b/gnovm/cmd/gno/testdata/test/output_incorrect.txtar index 8d74bcc0858..3daddcbdbeb 100644 --- a/gnovm/cmd/gno/testdata/test/output_incorrect.txtar +++ b/gnovm/cmd/gno/testdata/test/output_incorrect.txtar @@ -5,7 +5,7 @@ stdout 'hey' -stderr '=== RUN file/x_filetest.gno' +stderr '=== RUN ./x_filetest.gno' stderr '--- Expected' stderr '\+\+\+ Actual' stderr '@@ -1,2 \+1 @@' diff --git a/gnovm/cmd/gno/testdata/test/output_sync.txtar b/gnovm/cmd/gno/testdata/test/output_sync.txtar index 1d701cc1c7f..14d7d0ee1e7 100644 --- a/gnovm/cmd/gno/testdata/test/output_sync.txtar +++ b/gnovm/cmd/gno/testdata/test/output_sync.txtar @@ -5,8 +5,8 @@ gno test -v . -update-golden-tests stdout 'hey' stdout '^hru\?' -stderr '=== RUN file/x_filetest.gno' -stderr '--- PASS: file/x_filetest.gno \(\d+\.\d\ds\)' +stderr '=== RUN ./x_filetest.gno' +stderr '--- PASS: ./x_filetest.gno \(\d+\.\d\ds\)' stderr 'ok \. \d+\.\d\ds' cmp x_filetest.gno x_filetest.gno.golden diff --git a/gnovm/cmd/gno/testdata/test/pkg_underscore_test.txtar b/gnovm/cmd/gno/testdata/test/pkg_underscore_test.txtar index f1eb6e19af5..3fa88527b44 100644 --- a/gnovm/cmd/gno/testdata/test/pkg_underscore_test.txtar +++ b/gnovm/cmd/gno/testdata/test/pkg_underscore_test.txtar @@ -14,7 +14,7 @@ stderr '--- PASS: TestHello.*' stderr '=== RUN TestHullo' stderr '--- PASS: TestHullo.*' -stderr '=== RUN file/z0_filetest.*' +stderr '=== RUN ./examples/gno.land/p/demo/hello/z0_filetest.*' -- examples/gno.land/p/demo/hello/gno.mod -- module gno.land/p/demo/hello diff --git a/gnovm/cmd/gno/testdata/test/realm_boundmethod.txtar b/gnovm/cmd/gno/testdata/test/realm_boundmethod.txtar index 273b1809f93..99b5a7418b4 100644 --- a/gnovm/cmd/gno/testdata/test/realm_boundmethod.txtar +++ b/gnovm/cmd/gno/testdata/test/realm_boundmethod.txtar @@ -9,8 +9,8 @@ gno test -v ./examples/gno.land/r/demo/realm2 stderr '=== RUN TestDo' stderr '--- PASS: TestDo.*' -stderr '=== RUN file/realm2_filetest.gno' -stderr '--- PASS: file/realm2_filetest.*' +stderr '=== RUN ./examples/gno.land/r/demo/realm2/realm2_filetest.gno' +stderr '--- PASS: ./examples/gno.land/r/demo/realm2/realm2_filetest.*' -- examples/gno.land/p/demo/counter/gno.mod -- module gno.land/p/demo/counter diff --git a/gnovm/cmd/gno/testdata/test/realm_correct.txtar b/gnovm/cmd/gno/testdata/test/realm_correct.txtar index a8862783525..a427b804095 100644 --- a/gnovm/cmd/gno/testdata/test/realm_correct.txtar +++ b/gnovm/cmd/gno/testdata/test/realm_correct.txtar @@ -3,8 +3,8 @@ gno test -v . ! stdout .+ # stdout should be empty -stderr '=== RUN file/x_filetest.gno' -stderr '--- PASS: file/x_filetest.gno \(\d+\.\d\ds\)' +stderr '=== RUN ./x_filetest.gno' +stderr '--- PASS: ./x_filetest.gno \(\d+\.\d\ds\)' stderr 'ok \. \d+\.\d\ds' -- x_filetest.gno -- diff --git a/gnovm/cmd/gno/testdata/test/realm_incorrect.txtar b/gnovm/cmd/gno/testdata/test/realm_incorrect.txtar index f2d29429446..10e600a30d8 100644 --- a/gnovm/cmd/gno/testdata/test/realm_incorrect.txtar +++ b/gnovm/cmd/gno/testdata/test/realm_incorrect.txtar @@ -3,7 +3,7 @@ ! gno test -v . ! stdout .+ # stdout should be empty -stderr '=== RUN file/x_filetest.gno' +stderr '=== RUN ./x_filetest.gno' stderr 'Realm diff:' stderr '--- Expected' stderr '-xxxx' diff --git a/gnovm/cmd/gno/testdata/test/realm_sync.txtar b/gnovm/cmd/gno/testdata/test/realm_sync.txtar index bc380fa328e..f1c6f56a0af 100644 --- a/gnovm/cmd/gno/testdata/test/realm_sync.txtar +++ b/gnovm/cmd/gno/testdata/test/realm_sync.txtar @@ -3,8 +3,8 @@ gno test -v . -update-golden-tests ! stdout .+ # stdout should be empty -stderr '=== RUN file/x_filetest.gno' -stderr '--- PASS: file/x_filetest.gno \(\d+\.\d\ds\)' +stderr '=== RUN ./x_filetest.gno' +stderr '--- PASS: ./x_filetest.gno \(\d+\.\d\ds\)' stderr 'ok \. \d+\.\d\ds' cmp x_filetest.gno x_filetest.gno.golden diff --git a/gnovm/cmd/gno/testdata/test/valid_filetest.txtar b/gnovm/cmd/gno/testdata/test/valid_filetest.txtar index bd73ce3dc99..216119ed4f6 100644 --- a/gnovm/cmd/gno/testdata/test/valid_filetest.txtar +++ b/gnovm/cmd/gno/testdata/test/valid_filetest.txtar @@ -8,8 +8,8 @@ stderr 'ok \. \d+\.\d\ds' gno test -v . stdout 'test' -stderr '=== RUN file/valid_filetest.gno' -stderr '--- PASS: file/valid_filetest.gno \(\d+\.\d\ds\)' +stderr '=== RUN ./valid_filetest.gno' +stderr '--- PASS: ./valid_filetest.gno \(\d+\.\d\ds\)' stderr 'ok \. \d+\.\d\ds' -- valid.gno -- diff --git a/gnovm/pkg/gnolang/machine.go b/gnovm/pkg/gnolang/machine.go index 4569e70f264..116694e4bd0 100644 --- a/gnovm/pkg/gnolang/machine.go +++ b/gnovm/pkg/gnolang/machine.go @@ -709,7 +709,7 @@ func (m *Machine) runFunc(st Stage, fn Name, withCross bool) { } func (m *Machine) RunMain() { - m.runFunc(StageRun, "main", m.Package.IsRealm()) + m.runFunc(StageRun, "main", false) } // Evaluate throwaway expression in new block scope. @@ -1828,7 +1828,7 @@ func (m *Machine) PushFrameCall(cx *CallExpr, fv *FuncValue, recv TypedValue, is if withCross { if !fv.IsCrossing() { panic(fmt.Sprintf( - "missing crossing() after cross call in %v from %s to %s", + "missing crossing() after cross call to %v from %s to %s", fv.String(), m.Realm.GetPath(), pv.Realm.Path, @@ -1877,10 +1877,12 @@ func (m *Machine) PushFrameCall(cx *CallExpr, fv *FuncValue, recv TypedValue, is rlm = objpv.GetRealm() m.Realm = rlm // DO NOT set DidCross here. Make DidCross only - // happen upon explicit cross(fn)(...) calls to - // avoid user confusion. Otherwise whether - // DidCross happened or not depends on where - // the receiver resides, which isn't explicit + // happen upon explicit cross(fn)(...) calls + // and subsequent calls to crossing functions + // from the same realm, to avoid user + // confusion. Otherwise whether DidCross + // happened or not depends on where the + // receiver resides, which isn't explicit // enough to avoid confusion. // fr.DidCross = true return diff --git a/gnovm/pkg/gnolang/misc.go b/gnovm/pkg/gnolang/misc.go index 7367a955632..04d27e5cc77 100644 --- a/gnovm/pkg/gnolang/misc.go +++ b/gnovm/pkg/gnolang/misc.go @@ -174,6 +174,9 @@ func DerivePkgCryptoAddr(pkgPath string) crypto.Address { } func DerivePkgBech32Addr(pkgPath string) crypto.Bech32Address { + if pkgPath == "" { + panic("pkgpath cannot be empty") + } b32addr, ok := IsGnoRunPath(pkgPath) if ok { return crypto.Bech32Address(b32addr) diff --git a/gnovm/pkg/gnolang/nodes.go b/gnovm/pkg/gnolang/nodes.go index c8888a78c8d..6463a264dc5 100644 --- a/gnovm/pkg/gnolang/nodes.go +++ b/gnovm/pkg/gnolang/nodes.go @@ -1456,11 +1456,6 @@ func (x *PackageNode) NewPackage() *PackageValue { // NOTE: declared methods do not get their closures set here. See // *DeclaredType.GetValueAt() which returns a filled copy. func (x *PackageNode) PrepareNewValues(pv *PackageValue) []TypedValue { - if pv.PkgPath == "" { - // nothing to prepare for throwaway packages. - // TODO: double check to see if still relevant. - return nil - } // should already exist. block := pv.Block.(*Block) if block.Source != x { @@ -1748,6 +1743,7 @@ func (sb *StaticBlock) GetParentNode(store Store) BlockNode { // Implements BlockNode. // As a side effect, notes externally defined names. +// Slow, for precompile only. func (sb *StaticBlock) GetPathForName(store Store, n Name) ValuePath { if n == blankIdentifier { return NewValuePathBlock(0, 0, blankIdentifier) @@ -1768,26 +1764,26 @@ func (sb *StaticBlock) GetPathForName(store Store, n Name) ValuePath { } // Check ancestors. gen++ - faux := 0 - sn = sn.GetParentNode(store) - if fauxBlockNode(sn) { - faux++ + fauxChild := 0 + if fauxChildBlockNode(sn) { + fauxChild++ } + sn = sn.GetParentNode(store) for sn != nil { if idx, ok := sn.GetLocalIndex(n); ok { - return NewValuePathBlock(uint8(gen-faux), idx, n) + if 0xff < (gen - fauxChild) { + panic("value path depth overflow") + } + return NewValuePathBlock(uint8(gen-fauxChild), idx, n) } else { if !isFile(sn) { sn.GetStaticBlock().addExternName(n) } gen++ - sn = sn.GetParentNode(store) - if fauxBlockNode(sn) { - faux++ - } - if 0xff < gen { - panic("value path depth overflow") + if fauxChildBlockNode(sn) { + fauxChild++ } + sn = sn.GetParentNode(store) } } // Finally, check uverse. @@ -1799,6 +1795,7 @@ func (sb *StaticBlock) GetPathForName(store Store, n Name) ValuePath { } // Get the containing block node for node with path relative to this containing block. +// Slow, for precompile only. func (sb *StaticBlock) GetBlockNodeForPath(store Store, path ValuePath) BlockNode { if path.Type != VPBlock { panic("expected block type value path but got " + path.Type.String()) @@ -1807,13 +1804,13 @@ func (sb *StaticBlock) GetBlockNodeForPath(store Store, path ValuePath) BlockNod // NOTE: path.Depth == 1 means it's in bn. bn := sb.GetSource(store) for i := 1; i < int(path.Depth); i++ { - bn = bn.GetParentNode(store) - if fauxBlockNode(bn) { + if fauxChildBlockNode(bn) { bn = bn.GetParentNode(store) } + bn = bn.GetParentNode(store) } - // If bn is a faux block node, check also its parent. + // If bn is a faux child block node, check also its faux parent. switch bn := bn.(type) { case *IfCaseStmt, *SwitchClauseStmt: pn := bn.GetParentNode(store) diff --git a/gnovm/pkg/gnolang/nodes_string.go b/gnovm/pkg/gnolang/nodes_string.go index a3294ab2ec6..d577b0b1d84 100644 --- a/gnovm/pkg/gnolang/nodes_string.go +++ b/gnovm/pkg/gnolang/nodes_string.go @@ -542,7 +542,11 @@ func (ds Decls) String() string { } func (x ConstExpr) String() string { - return fmt.Sprintf("(const %s)", x.TypedValue.String()) + if x.TypedValue.HasKind(TypeKind) { + return x.TypedValue.V.String() + } else { + return fmt.Sprintf("(const %s)", x.TypedValue.String()) + } } func (x constTypeExpr) String() string { diff --git a/gnovm/pkg/gnolang/preprocess.go b/gnovm/pkg/gnolang/preprocess.go index 52d1d6ee40c..c1f5fdd7776 100644 --- a/gnovm/pkg/gnolang/preprocess.go +++ b/gnovm/pkg/gnolang/preprocess.go @@ -210,7 +210,7 @@ func initStaticBlocks(store Store, ctx BlockNode, bn BlockNode) { last2 := skipFile(last) nx := &n.NameExpr nx.Type = NameExprTypeDefine - last2.Predefine(false, n.Name) + last2.Predefine(true, n.Name) case *FuncDecl: if n.IsMethod { if n.Recv.Name == "" || n.Recv.Name == blankIdentifier { @@ -747,11 +747,13 @@ func preprocess1(store Store, ctx BlockNode, n Node) Node { store, last, cx).(Expr) var ct Type if cxx, ok := cx.(*ConstExpr); ok { - if !cxx.IsUndefined() { - panic("should not happen") + if cxx.IsUndefined() { + // TODO: shouldn't cxx.T be TypeType? + // Don't change cxx.GetType() for defensiveness. + ct = nil + } else { + ct = cxx.GetType() } - // only in type switch cases, nil type allowed. - ct = nil } else { ct = evalStaticType(store, last, cx) } @@ -977,7 +979,7 @@ func preprocess1(store Store, ctx BlockNode, n Node) Node { panic(fmt.Sprintf( "should not happen: name %q is reserved", n.Name)) } - // special case if struct composite key. + // Special case if struct composite key. if ftype == TRANS_COMPOSITE_KEY { clx := ns[len(ns)-1].(*CompositeLitExpr) clt := evalStaticType(store, last, clx.Type) @@ -2258,7 +2260,7 @@ func preprocess1(store Store, ctx BlockNode, n Node) Node { *dst = *(tmp.(*StructType)) case *DeclaredType: // if store has this type, use that. - tid := DeclaredTypeID(lastpn.PkgPath, n.Name) + tid := DeclaredTypeID(lastpn.PkgPath, last.GetLocation(), n.Name) exists := false if dt := store.GetTypeSafe(tid); dt != nil { dst = dt.(*DeclaredType) @@ -2270,7 +2272,7 @@ func preprocess1(store Store, ctx BlockNode, n Node) Node { // NOTE: this is where declared types are // actually instantiated, not in // machine.go:runDeclaration(). - dt2 := declareWith(lastpn.PkgPath, n.Name, tmp) + dt2 := declareWith(lastpn.PkgPath, last, n.Name, tmp) // if !n.IsAlias { // not sure why this was here. dt2.Seal() // } @@ -2775,6 +2777,13 @@ func findHeapDefinesByUse(ctx BlockNode, bn BlockNode) { return n, TRANS_CONTINUE } } + // Ignore type declaration names. + // Types cannot be passed ergo cannot be captured. + // (revisit when types become first class objects) + st := dbn.GetStaticTypeOf(nil, n.Name) + if st.Kind() == TypeKind { + return n, TRANS_CONTINUE + } // Found a heap item closure capture. addAttrHeapUse(dbn, n.Name) @@ -2869,7 +2878,7 @@ func addHeapCapture(dbn BlockNode, fle *FuncLitExpr, depth int, nx *NameExpr) (i // returns the depth of first closure, 1 if stop itself is a closure, // or 0 if not found. func findFirstClosure(stack []BlockNode, stop BlockNode) (fle *FuncLitExpr, depth int, found bool) { - redundant := 0 // count faux block + faux := 0 // count faux block for i := len(stack) - 1; i >= 0; i-- { stbn := stack[i] switch stbn := stbn.(type) { @@ -2878,16 +2887,14 @@ func findFirstClosure(stack []BlockNode, stop BlockNode) (fle *FuncLitExpr, dept return } fle = stbn - depth = len(stack) - 1 - redundant - i + 1 // +1 since 1 is lowest. + depth = len(stack) - 1 - faux - i + 1 // +1 since 1 is lowest. found = true // even if found, continue iteration in case // an earlier *FuncLitExpr is found. - case *IfCaseStmt, *SwitchClauseStmt: - if stbn == stop { - return - } - redundant++ default: + if fauxChildBlockNode(stbn) { + faux++ + } if stbn == stop { return } @@ -3435,7 +3442,7 @@ func findBranchLabel(last BlockNode, label Name) ( ) { for { switch cbn := last.(type) { - case *BlockStmt, *ForStmt, *IfCaseStmt, *RangeStmt, *SelectCaseStmt, *SwitchClauseStmt, *SwitchStmt: + case *BlockStmt, *ForStmt, *IfCaseStmt, *RangeStmt, *SelectCaseStmt, *SwitchClauseStmt: lbl := cbn.GetLabel() if label == lbl { bn = cbn @@ -3443,7 +3450,7 @@ func findBranchLabel(last BlockNode, label Name) ( } last = skipFaux(cbn.GetParentNode(nil)) depth += 1 - case *IfStmt: + case *IfStmt, *SwitchStmt: // These are faux blocks -- shouldn't happen. panic("unexpected faux blocknode") case *FileNode: @@ -4904,10 +4911,12 @@ func tryPredefine(store Store, pkg *PackageNode, last BlockNode, d Decl) (un Nam } else { // create new declared type. pn := packageOf(last) - t = declareWith(pn.PkgPath, d.Name, t) + dt := declareWith(pn.PkgPath, last, d.Name, t) + t = dt } // fill in later. - last2.Define(d.Name, asValue(t)) + // last2.Define(d.Name, asValue(t)) + last2.Define2(true, d.Name, t, asValue(t)) d.Path = last.GetPathForName(store, d.Name) } // after predefinitions, return any undefined dependencies. @@ -5025,6 +5034,14 @@ func fauxBlockNode(bn BlockNode) bool { return false } +func fauxChildBlockNode(bn BlockNode) bool { + switch bn.(type) { + case *IfCaseStmt, *SwitchClauseStmt: + return true + } + return false +} + func fillNameExprPath(last BlockNode, nx *NameExpr, isDefineLHS bool) { if nx.Name == blankIdentifier { // Blank name has no path; caller error. @@ -5039,13 +5056,13 @@ func fillNameExprPath(last BlockNode, nx *NameExpr, isDefineLHS bool) { // and declared variables. See tests/files/define1.go for test case. var path ValuePath var i int = 0 - var faux int = 0 + var fauxChild int = 0 for { i++ - last = last.GetParentNode(nil) - if fauxBlockNode(last) { - faux++ + if fauxChildBlockNode(last) { + fauxChild++ } + last = last.GetParentNode(nil) if last == nil { if isUverseName(nx.Name) { idx, ok := UverseNode().GetLocalIndex(nx.Name) @@ -5069,7 +5086,7 @@ func fillNameExprPath(last BlockNode, nx *NameExpr, isDefineLHS bool) { break } } - path.SetDepth(path.Depth + uint8(i) - uint8(faux)) + path.SetDepth(path.Depth + uint8(i) - uint8(fauxChild)) path.Validate() nx.Path = path return diff --git a/gnovm/pkg/gnolang/types.go b/gnovm/pkg/gnolang/types.go index dc1e5e102da..c102c033aeb 100644 --- a/gnovm/pkg/gnolang/types.go +++ b/gnovm/pkg/gnolang/types.go @@ -1408,7 +1408,8 @@ func (tt *TypeType) IsNamed() bool { type DeclaredType struct { PkgPath string - Name Name + Name Name // name of declaration + Loc Location // declaration location for disambiguation Base Type // not a DeclaredType Methods []TypedValue // {T:*FuncType,V:*FuncValue}... @@ -1416,12 +1417,23 @@ type DeclaredType struct { sealed bool // for ensuring correctness with recursive types. } -// returns an unsealed *DeclaredType. -// do not use for aliases. -func declareWith(pkgPath string, name Name, b Type) *DeclaredType { +// Returns an unsealed *DeclaredType. +// parent is the block node in which it is declared. +// Do not use for aliases. +func declareWith(pkgPath string, parent BlockNode, name Name, b Type) *DeclaredType { + loc := Location{} + switch parent.(type) { + case *PackageNode, *FileNode: + // leave aero + case *FuncDecl, *FuncLitExpr: + loc = parent.GetLocation() + default: + panic("should not happen") + } dt := &DeclaredType{ PkgPath: pkgPath, Name: name, + Loc: loc, Base: baseOf(b), sealed: false, } @@ -1471,17 +1483,25 @@ func (dt *DeclaredType) checkSeal() { func (dt *DeclaredType) TypeID() TypeID { if dt.typeid.IsZero() { - dt.typeid = DeclaredTypeID(dt.PkgPath, dt.Name) + dt.typeid = DeclaredTypeID(dt.PkgPath, dt.Loc, dt.Name) } return dt.typeid } -func DeclaredTypeID(pkgPath string, name Name) TypeID { - return typeidf("%s.%s", pkgPath, name) +func DeclaredTypeID(pkgPath string, loc Location, name Name) TypeID { + if loc.IsZero() { // package/file decl + return typeidf("%s.%s", pkgPath, name) + } else { + return typeidf("%s[%s].%s", pkgPath, loc.String(), name) + } } func (dt *DeclaredType) String() string { - return fmt.Sprintf("%s.%s", dt.PkgPath, dt.Name) + if dt.Loc.IsZero() { + return fmt.Sprintf("%s.%s", dt.PkgPath, dt.Name) + } else { + return fmt.Sprintf("%s[%s].%s", dt.PkgPath, dt.Loc.String(), dt.Name) + } } func (dt *DeclaredType) Elem() Type { diff --git a/gnovm/pkg/gnolang/uverse.go b/gnovm/pkg/gnolang/uverse.go index 8276ed3d459..b63ae9fb1d3 100644 --- a/gnovm/pkg/gnolang/uverse.go +++ b/gnovm/pkg/gnolang/uverse.go @@ -772,7 +772,20 @@ func makeUverseNode() { for i := 1 + 1; ; i++ { fri := m.PeekCallFrame(i) if fri == nil { - panic("crossing could not find corresponding cross(fn)(...) call") + // For stage add, meaning init() AND + // global var decls inherit a faux + // frame of index -1 which crossed from + // the package deployer. + // For stage run, main() does the same, + // so main() can be crossing or not, it + // doesn't matter. This applies for + // MsgRun() as well as tests. MsgCall() + // runs like cross(fn)(...) which + // meains fri.WithCross would have been + // found below. + fr2 := m.PeekCallFrame(2) + fr2.SetDidCross() + return } if fri.WithCross || fri.DidCross { // NOTE: fri.DidCross implies diff --git a/gnovm/pkg/gnolang/values_string.go b/gnovm/pkg/gnolang/values_string.go index 68b9621d8d4..4a75de5f1c0 100644 --- a/gnovm/pkg/gnolang/values_string.go +++ b/gnovm/pkg/gnolang/values_string.go @@ -238,18 +238,8 @@ func (mv *MapValue) ProtectedString(seen *seenValues) string { } func (tv TypeValue) String() string { - ptr := "" - if reflect.TypeOf(tv.Type).Kind() == reflect.Ptr { - ptr = fmt.Sprintf(" (%p)", tv.Type) - } - /* - mthds := "" - if d, ok := tv.Type.(*DeclaredType); ok { - mthds = fmt.Sprintf(" %v", d.Methods) - } - */ - return fmt.Sprintf("typeval{%s%s}", - tv.Type.String(), ptr) + return fmt.Sprintf("typeval{%s}", + tv.Type.String()) } func (pv *PackageValue) String() string { diff --git a/gnovm/pkg/test/filetest.go b/gnovm/pkg/test/filetest.go index ef529c76622..a9502952ab3 100644 --- a/gnovm/pkg/test/filetest.go +++ b/gnovm/pkg/test/filetest.go @@ -128,7 +128,7 @@ func (opts *TestOptions) runFiletest(filename string, source []byte) (string, er if !strings.HasSuffix(result.Output, "\n") { result.Output += "\n" } - match(dir, result.Output) + match(dir, trimTrailingSpaces(result.Output)) case DirectiveRealm: res := opslog.(*bytes.Buffer).String() match(dir, res) @@ -168,6 +168,15 @@ func (opts *TestOptions) runFiletest(filename string, source []byte) (string, er return "", returnErr } +func trimTrailingSpaces(in string) string { + lines := strings.Split(in, "\n") + for i, line := range lines { + line = strings.TrimRight(line, " ") + lines[i] = line + } + return strings.Join(lines, "\n") +} + func unifiedDiff(wanted, actual string) string { diff, err := difflib.GetUnifiedDiffString(difflib.UnifiedDiff{ A: difflib.SplitLines(wanted), @@ -315,7 +324,7 @@ func (opts *TestOptions) runTest(m *gno.Machine, pkgPath, filename string, conte // Call main() like withrealm(main)(). // This will switch the realm to the package. // main() must start with crossing(). - m.RunStatement(gno.StageRun, gno.S(gno.Call(gno.Call(gno.X("cross"), gno.X("main"))))) // switch realm. + m.RunMain() } return runResult{ @@ -426,7 +435,7 @@ var reDirectiveLine = regexp.MustCompile("^(?:([A-Za-z]*):|([A-Z]+): ?(.*))$") func ParseDirectives(source io.Reader) (Directives, error) { sc := bufio.NewScanner(source) parsed := make(Directives, 0, 8) - parsed = append(parsed, Directive{Complete: true}) // faux directive. + parsed = append(parsed, Directive{LastLine: "// FAUX: faux directive", Complete: true}) // faux directive. for sc.Scan() { last := &parsed[len(parsed)-1] txt := sc.Text() diff --git a/gnovm/pkg/test/test.go b/gnovm/pkg/test/test.go index 86d25ac030d..150daae1a3b 100644 --- a/gnovm/pkg/test/test.go +++ b/gnovm/pkg/test/test.go @@ -264,7 +264,9 @@ func Test(memPkg *gnovm.MemPackage, fsDir string, opts *TestOptions) error { for _, testFile := range ftfiles { testFileName := testFile.Name testFilePath := filepath.Join(fsDir, testFileName) - testName := "file/" + testFileName + // XXX consider this + testName := fsDir + "/" + testFileName + // testName := "file/" + testFileName if !shouldRun(filter, testName) { continue } @@ -383,6 +385,8 @@ func (opts *TestOptions) runTestFiles( &gno.CompositeLitExpr{ // Third param, the testing.InternalTest Type: gno.Sel(testingcx, "InternalTest"), Elts: gno.KeyValueExprs{ + // XXX Consider this. + // {Key: gno.X("Name"), Value: gno.Str(memPkg.Path + "/" + tf.Filename + "." + tf.Name)}, {Key: gno.X("Name"), Value: gno.Str(tf.Name)}, {Key: gno.X("F"), Value: gno.Nx(tf.Name)}, }, @@ -453,8 +457,9 @@ type report struct { } type testFunc struct { - Package string - Name string + Package string + Name string + Filename string } func loadTestFuncs(pkgName string, tfiles *gno.FileSet) (rt []testFunc) { @@ -464,8 +469,9 @@ func loadTestFuncs(pkgName string, tfiles *gno.FileSet) (rt []testFunc) { fname := string(fd.Name) if strings.HasPrefix(fname, "Test") { tf := testFunc{ - Package: pkgName, - Name: fname, + Package: pkgName, + Name: fname, + Filename: string(tf.Name), } rt = append(rt, tf) } diff --git a/gnovm/stdlibs/std/native.go b/gnovm/stdlibs/std/native.go index 8ae606184f0..0b17a54f0b4 100644 --- a/gnovm/stdlibs/std/native.go +++ b/gnovm/stdlibs/std/native.go @@ -122,6 +122,16 @@ func X_getRealm(m *gno.Machine, height int) (address, pkgPath string) { case gno.StageRun: switch height { case crosses: + fr := m.Frames[0] + path := fr.LastPackage.PkgPath + if path == "" { + // e.g. MsgCall, cross-call a public realm function + return string(ctx.OriginCaller), "" + } else { + // e.g. MsgRun, non-cross-call main() + return string(gno.DerivePkgBech32Addr(path)), path + } + case crosses + 1: return string(ctx.OriginCaller), "" default: m.Panic(typedString("frame not found")) diff --git a/gnovm/tests/files/const39.gno b/gnovm/tests/files/const39.gno index 21d8badab8e..f180cb669a9 100644 --- a/gnovm/tests/files/const39.gno +++ b/gnovm/tests/files/const39.gno @@ -11,7 +11,9 @@ func main() { } // Error: -// main/files/const39.gno:10:8: T.Mv (variable of type func(main.T, int) int) is not constant +// main/files/const39.gno:10:8: typeval{main.T}.Mv (variable of type func(main.T, int) int) is not constant + + // TypeCheckError: // main/files/const39.gno:10:12: T.Mv (value of type func(tv T, a int) int) is not constant diff --git a/gnovm/tests/files/const45_b.gno b/gnovm/tests/files/const45_b.gno index 6273d826d8e..de235999591 100644 --- a/gnovm/tests/files/const45_b.gno +++ b/gnovm/tests/files/const45_b.gno @@ -11,7 +11,9 @@ func main() { } // Error: -// main/files/const45_b.gno:7:7: MyStruct{arr: [](const-type int){(const (1 int)), (const (2 int))}}.arr (variable of type []int) is not constant +// main/files/const45_b.gno:7:7: typeval{main.MyStruct}{arr: [](const-type int){(const (1 int)), (const (2 int))}}.arr (variable of type []int) is not constant + + // TypeCheckError: // main/files/const45_b.gno:7:11: len(MyStruct{…}.arr) (value of type int) is not constant diff --git a/gnovm/tests/files/fun29.gno b/gnovm/tests/files/fun29.gno new file mode 100644 index 00000000000..b0b766de757 --- /dev/null +++ b/gnovm/tests/files/fun29.gno @@ -0,0 +1,17 @@ +package main + +import ( + "errors" +) + +func main() { + if func() bool { + println(errors.New("imported").Error()) + return false + }() { + return + } +} + +// Output: +// imported diff --git a/gnovm/tests/files/fun9.gno b/gnovm/tests/files/fun9.gno index 18c49a3a226..11e3c033d89 100644 --- a/gnovm/tests/files/fun9.gno +++ b/gnovm/tests/files/fun9.gno @@ -9,4 +9,4 @@ func main() { } // Output: -// (1 main.myint) +// (1 main[main/files/fun9.gno:5:1].myint) diff --git a/gnovm/tests/files/goto7.gno b/gnovm/tests/files/goto7.gno new file mode 100644 index 00000000000..c1056be0090 --- /dev/null +++ b/gnovm/tests/files/goto7.gno @@ -0,0 +1,23 @@ +package main + +import "fmt" + +func main() { + counter := 0 + for { + LABEL: + if true { + if counter == 3 { + break + } + counter++ + fmt.Println("true") + goto LABEL + } + } +} + +// Output: +// true +// true +// true diff --git a/gnovm/tests/files/heap_alloc_forloop1a.gno b/gnovm/tests/files/heap_alloc_forloop1a.gno index bcbd7d4ce6b..a2d4ca6890e 100644 --- a/gnovm/tests/files/heap_alloc_forloop1a.gno +++ b/gnovm/tests/files/heap_alloc_forloop1a.gno @@ -29,7 +29,9 @@ func main() { // go 1.22 loop var is not supported for now. // Preprocessed: -// file{ package main; import fmt fmt; type Int (const-type main.Int); var s1 []*(Int); func inc2(j *(Int)) { *(j) = *(j) + (const (2 main.Int)) }; func forLoopRef() { defer func func(){ for i, e := range (const (ref(main) package{})).s1 { (const (ref(fmt) package{})).Printf((const ("s1[%d] is: %d\n" string)), i, *(e)) } }(); for i := (const (0 main.Int)); i<~VPBlock(1,0)> < (const (10 main.Int)); inc2(&(i<~VPBlock(1,0)>)) { s1<~VPBlock(4,1)> = (const (append func([]*main.Int, ...*main.Int) []*main.Int))(s1<~VPBlock(4,1)>, &(i<~VPBlock(1,0)>)) } }; func main() { forLoopRef() } } +// file{ package main; import fmt fmt; type Int (const-type main.Int); var s1 []*(typeval{main.Int}); func inc2(j *(typeval{main.Int})) { *(j) = *(j) + (const (2 main.Int)) }; func forLoopRef() { defer func func(){ for i, e := range (const (ref(main) package{})).s1 { (const (ref(fmt) package{})).Printf((const ("s1[%d] is: %d\n" string)), i, *(e)) } }(); for i := (const (0 main.Int)); i<~VPBlock(1,0)> < (const (10 main.Int)); inc2(&(i<~VPBlock(1,0)>)) { s1<~VPBlock(4,1)> = (const (append func([]*main.Int, ...*main.Int) []*main.Int))(s1<~VPBlock(4,1)>, &(i<~VPBlock(1,0)>)) } }; func main() { forLoopRef() } } + + // Output: // s1[0] is: 10 diff --git a/gnovm/tests/files/heap_alloc_forloop3.gno b/gnovm/tests/files/heap_alloc_forloop3.gno index 939fa9785fb..a5b7ad5c2ab 100644 --- a/gnovm/tests/files/heap_alloc_forloop3.gno +++ b/gnovm/tests/files/heap_alloc_forloop3.gno @@ -25,7 +25,9 @@ func main() { // You can tell by the preprocess printout of z and z<()~...>. // Preprocessed: -// file{ package main; type f (const-type main.f); var fs []f; func forLoopClosure() { defer func func(){ for _, f := range (const (ref(main) package{})).fs { f() } }(); for i := (const (0 int)); i < (const (3 int)); i++ { z := i; fs<~VPBlock(4,1)> = (const (append func([]main.f, ...main.f) []main.f))(fs<~VPBlock(4,1)>, (const-type main.f)(func func(){ (const (println func(...interface {})))(z<~VPBlock(1,0)>) }>)) } }; func main() { forLoopClosure() } } +// file{ package main; type f (const-type main.f); var fs []typeval{main.f}; func forLoopClosure() { defer func func(){ for _, f := range (const (ref(main) package{})).fs { f() } }(); for i := (const (0 int)); i < (const (3 int)); i++ { z := i; fs<~VPBlock(4,1)> = (const (append func([]main.f, ...main.f) []main.f))(fs<~VPBlock(4,1)>, (const-type main.f)(func func(){ (const (println func(...interface {})))(z<~VPBlock(1,0)>) }>)) } }; func main() { forLoopClosure() } } + + // Output: // 0 diff --git a/gnovm/tests/files/heap_alloc_forloop3a.gno b/gnovm/tests/files/heap_alloc_forloop3a.gno index 5b5b2309e7b..fde49bec058 100644 --- a/gnovm/tests/files/heap_alloc_forloop3a.gno +++ b/gnovm/tests/files/heap_alloc_forloop3a.gno @@ -27,7 +27,9 @@ func main() { // You can tell by the preprocess printout of z and z<()~...>. // Preprocessed: -// file{ package main; type f (const-type main.f); var fs []f; func forLoopClosure() { defer func func(){ for _, f := range (const (ref(main) package{})).fs { f() } }(); for i := (const (0 int)); i < (const (3 int)); i++ { x := i; (const (println func(...interface {})))(x); z := i; fs<~VPBlock(4,1)> = (const (append func([]main.f, ...main.f) []main.f))(fs<~VPBlock(4,1)>, (const-type main.f)(func func(){ (const (println func(...interface {})))(z<~VPBlock(1,0)>) }>)) } }; func main() { forLoopClosure() } } +// file{ package main; type f (const-type main.f); var fs []typeval{main.f}; func forLoopClosure() { defer func func(){ for _, f := range (const (ref(main) package{})).fs { f() } }(); for i := (const (0 int)); i < (const (3 int)); i++ { x := i; (const (println func(...interface {})))(x); z := i; fs<~VPBlock(4,1)> = (const (append func([]main.f, ...main.f) []main.f))(fs<~VPBlock(4,1)>, (const-type main.f)(func func(){ (const (println func(...interface {})))(z<~VPBlock(1,0)>) }>)) } }; func main() { forLoopClosure() } } + + // Output: // 0 diff --git a/gnovm/tests/files/heap_alloc_forloop4.gno b/gnovm/tests/files/heap_alloc_forloop4.gno index 33aad1e2fac..f61dfe7f2e5 100644 --- a/gnovm/tests/files/heap_alloc_forloop4.gno +++ b/gnovm/tests/files/heap_alloc_forloop4.gno @@ -23,7 +23,9 @@ func main() { // go 1.22 loop var is not supported for now. // Preprocessed: -// file{ package main; type f (const-type main.f); var fs []f; func forLoopClosure() { defer func func(){ for _, f := range (const (ref(main) package{})).fs { f() } }(); for i := (const (0 int)); i<~VPBlock(1,0)> < (const (3 int)); i<~VPBlock(1,0)>++ { fs<~VPBlock(4,1)> = (const (append func([]main.f, ...main.f) []main.f))(fs<~VPBlock(4,1)>, (const-type main.f)(func func(){ (const (println func(...interface {})))(i<~VPBlock(1,0)>) }>)) } }; func main() { forLoopClosure() } } +// file{ package main; type f (const-type main.f); var fs []typeval{main.f}; func forLoopClosure() { defer func func(){ for _, f := range (const (ref(main) package{})).fs { f() } }(); for i := (const (0 int)); i<~VPBlock(1,0)> < (const (3 int)); i<~VPBlock(1,0)>++ { fs<~VPBlock(4,1)> = (const (append func([]main.f, ...main.f) []main.f))(fs<~VPBlock(4,1)>, (const-type main.f)(func func(){ (const (println func(...interface {})))(i<~VPBlock(1,0)>) }>)) } }; func main() { forLoopClosure() } } + + // Output: // 3 diff --git a/gnovm/tests/files/heap_alloc_forloop5.gno b/gnovm/tests/files/heap_alloc_forloop5.gno index 373b88ff8b2..ef9be0a76ed 100644 --- a/gnovm/tests/files/heap_alloc_forloop5.gno +++ b/gnovm/tests/files/heap_alloc_forloop5.gno @@ -24,7 +24,9 @@ func main() { } // Preprocessed: -// file{ package main; type f (const-type main.f); var fs []f; func forLoopClosure() { defer func func(){ for _, f := range (const (ref(main) package{})).fs { f() } }(); for i := (const (0 int)); i<~VPBlock(1,0)> < (const (3 int)); i<~VPBlock(1,0)>++ { fs<~VPBlock(4,1)> = (const (append func([]main.f, ...main.f) []main.f))(fs<~VPBlock(4,1)>, (const-type main.f)(func func(){ z := i<~VPBlock(1,1)>; (const (println func(...interface {})))(z) }>)) } }; func main() { forLoopClosure() } } +// file{ package main; type f (const-type main.f); var fs []typeval{main.f}; func forLoopClosure() { defer func func(){ for _, f := range (const (ref(main) package{})).fs { f() } }(); for i := (const (0 int)); i<~VPBlock(1,0)> < (const (3 int)); i<~VPBlock(1,0)>++ { fs<~VPBlock(4,1)> = (const (append func([]main.f, ...main.f) []main.f))(fs<~VPBlock(4,1)>, (const-type main.f)(func func(){ z := i<~VPBlock(1,1)>; (const (println func(...interface {})))(z) }>)) } }; func main() { forLoopClosure() } } + + // Output: // 3 diff --git a/gnovm/tests/files/heap_alloc_forloop5a.gno b/gnovm/tests/files/heap_alloc_forloop5a.gno index 110dd83541e..b2f10bd56c9 100644 --- a/gnovm/tests/files/heap_alloc_forloop5a.gno +++ b/gnovm/tests/files/heap_alloc_forloop5a.gno @@ -25,7 +25,9 @@ func main() { } // Preprocessed: -// file{ package main; type f (const-type main.f); var fs []f; func forLoopClosure() { defer func func(){ for _, f := range (const (ref(main) package{})).fs { f() } }(); for i := (const (0 int)); i < (const (3 int)); i++ { x := i; fs<~VPBlock(4,1)> = (const (append func([]main.f, ...main.f) []main.f))(fs<~VPBlock(4,1)>, (const-type main.f)(func func(){ z := x<~VPBlock(1,1)>; (const (println func(...interface {})))(z) }>)) } }; func main() { forLoopClosure() } } +// file{ package main; type f (const-type main.f); var fs []typeval{main.f}; func forLoopClosure() { defer func func(){ for _, f := range (const (ref(main) package{})).fs { f() } }(); for i := (const (0 int)); i < (const (3 int)); i++ { x := i; fs<~VPBlock(4,1)> = (const (append func([]main.f, ...main.f) []main.f))(fs<~VPBlock(4,1)>, (const-type main.f)(func func(){ z := x<~VPBlock(1,1)>; (const (println func(...interface {})))(z) }>)) } }; func main() { forLoopClosure() } } + + // Output: // 0 diff --git a/gnovm/tests/files/issue_1096.gno b/gnovm/tests/files/issue_1096.gno index 38411e6571d..86ae2820319 100644 --- a/gnovm/tests/files/issue_1096.gno +++ b/gnovm/tests/files/issue_1096.gno @@ -278,7 +278,7 @@ func (_ Z) manip2(xs ...X) { // 0 // 0 // false -// ----- x direct +// ----- x direct // 888 // 0 // false diff --git a/gnovm/tests/files/panic0a.gno b/gnovm/tests/files/panic0a.gno index 242457d445e..5adfc8a1465 100644 --- a/gnovm/tests/files/panic0a.gno +++ b/gnovm/tests/files/panic0a.gno @@ -36,7 +36,7 @@ func main() { // Stacktrace: // panic: wtf -// f(v.((const-type int)),lit[0],*pit,&vit<~VPBlock(1,0)>,!b,[](const-type string),S,map[(const-type string)] (const-type string),func(s (const-type string)) .res.0 (const-type string){ ... }) +// f(v.((const-type int)),lit[0],*pit,&vit<~VPBlock(1,0)>,!b,[](const-type string),typeval{main.S},map[(const-type string)] (const-type string),func(s (const-type string)) .res.0 (const-type string){ ... }) // main/files/panic0a.gno:9 // main() // main/files/panic0a.gno:22 diff --git a/gnovm/tests/files/std10.gno b/gnovm/tests/files/std10.gno index 32b831b540c..89a838711e4 100644 --- a/gnovm/tests/files/std10.gno +++ b/gnovm/tests/files/std10.gno @@ -4,11 +4,12 @@ import "std" func main() { defer func() { - // assert panic is recoverable + // assert no panic println(recover()) }() - std.PreviousRealm() + println(std.PreviousRealm()) } // Output: -// frame not found +// (struct{("g1wymu47drhr0kuq2098m792lytgtj2nyx77yrsm" std.Address),("" string)} std.Realm) +// undefined diff --git a/gnovm/tests/files/std4.gno b/gnovm/tests/files/std4.gno index 6a7b9f46b51..6fc4464b1a8 100644 --- a/gnovm/tests/files/std4.gno +++ b/gnovm/tests/files/std4.gno @@ -10,4 +10,4 @@ func main() { } // Output: -// (struct{("g1wymu47drhr0kuq2098m792lytgtj2nyx77yrsm" std.Address),("" string)} std.Realm) +// (struct{("g17rgsdnfxzza0sdfsdma37sdwxagsz378833ca4" std.Address),("main" string)} std.Realm) diff --git a/gnovm/tests/files/std5.gno b/gnovm/tests/files/std5.gno index 5d9877e262d..573468ed823 100644 --- a/gnovm/tests/files/std5.gno +++ b/gnovm/tests/files/std5.gno @@ -11,14 +11,6 @@ func main() { println(realm2) } -// Stacktrace: -// panic: frame not found -// getRealm(1) -// gonative:std/std.gno -// ref(std).PreviousRealm() -// std/native.gno:32 -// main() -// main/files/std5.gno:10 - -// Error: -// frame not found +// Output: +// (struct{("g17rgsdnfxzza0sdfsdma37sdwxagsz378833ca4" std.Address),("main" string)} std.Realm) +// (struct{("g1wymu47drhr0kuq2098m792lytgtj2nyx77yrsm" std.Address),("" string)} std.Realm) diff --git a/gnovm/tests/files/std6.gno b/gnovm/tests/files/std6.gno index 1e2eb9699ba..985697d3f68 100644 --- a/gnovm/tests/files/std6.gno +++ b/gnovm/tests/files/std6.gno @@ -13,16 +13,6 @@ func main() { inner() } -// Stacktrace: -// panic: frame not found -// getRealm(1) -// gonative:std/std.gno -// ref(std).PreviousRealm() -// std/native.gno:32 -// inner() -// main/files/std6.gno:8 -// main() -// main/files/std6.gno:13 - -// Error: -// frame not found +// Output: +// (struct{("g17rgsdnfxzza0sdfsdma37sdwxagsz378833ca4" std.Address),("main" string)} std.Realm) +// (struct{("g1wymu47drhr0kuq2098m792lytgtj2nyx77yrsm" std.Address),("" string)} std.Realm) diff --git a/gnovm/tests/files/std7.gno b/gnovm/tests/files/std7.gno index 7e0d97d0394..c68272e35c3 100644 --- a/gnovm/tests/files/std7.gno +++ b/gnovm/tests/files/std7.gno @@ -18,7 +18,10 @@ func main() { } // Output: +// (struct{("g17rgsdnfxzza0sdfsdma37sdwxagsz378833ca4" std.Address),("main" string)} std.Realm) // (struct{("g1wymu47drhr0kuq2098m792lytgtj2nyx77yrsm" std.Address),("" string)} std.Realm) + + // Error: // frame not found diff --git a/gnovm/tests/files/std8.gno b/gnovm/tests/files/std8.gno index 7b6205f3ed8..3bcbd352857 100644 --- a/gnovm/tests/files/std8.gno +++ b/gnovm/tests/files/std8.gno @@ -18,20 +18,15 @@ func main() { } // Output: +// (struct{("g17rgsdnfxzza0sdfsdma37sdwxagsz378833ca4" std.Address),("main" string)} std.Realm) // (struct{("g1wymu47drhr0kuq2098m792lytgtj2nyx77yrsm" std.Address),("" string)} std.Realm) + + // Stacktrace: -// panic: frame not found -// getRealm(1) -// gonative:std/std.gno -// ref(std).PreviousRealm() -// std/native.gno:32 -// fn() -// main/files/std8.gno:12 -// ref(gno.land/p/demo/testutils).WrapCall(inner) -// gno.land/p/demo/testutils/misc.gno:5 -// main() -// main/files/std8.gno:17 +// + + // Error: // frame not found diff --git a/gnovm/tests/files/type42.gno b/gnovm/tests/files/type42.gno new file mode 100644 index 00000000000..f7ee84682d0 --- /dev/null +++ b/gnovm/tests/files/type42.gno @@ -0,0 +1,16 @@ +package main + +type A int + +func main() { + println(A(1)) + type A string + println(A("a")) +} + +// Output: +// (1 main.A) +// ("a" main[main/files/type42.gno:5:1].A) + +// Preprocessed: +// file{ package main; type A (const-type main.A); func main() { (const (println func(...interface {})))((const (1 main.A))); type A (const-type main[main/files/type42.gno:5:1].A); (const (println func(...interface {})))((const ("a" main[main/files/type42.gno:5:1].A))) } } diff --git a/gnovm/tests/files/zrealm_crossrealm13.gno b/gnovm/tests/files/zrealm_crossrealm13.gno index 9c5440f26ef..293a327e6e7 100644 --- a/gnovm/tests/files/zrealm_crossrealm13.gno +++ b/gnovm/tests/files/zrealm_crossrealm13.gno @@ -6,19 +6,25 @@ import ( ) func main() { - // Need this as base frame because main2 calls PreviousRealm. - testing.SetRealm(std.NewUserRealm("g1wymu47drhr0kuq2098m792lytgtj2nyx77yrsm")) - main2() -} - -func main2() { + println("From main:") PrintRealm() println(pad("CurrentRealm:"), std.CurrentRealm()) println(pad("PreviousRealm:"), std.PreviousRealm()) + println("") + + println("From g1user origin:") testing.SetRealm(std.NewUserRealm("g1user")) - PrintRealm() println(pad("CurrentRealm:"), std.CurrentRealm()) - println(pad("PreviousRealm:"), std.PreviousRealm()) + func() { + defer func() { + r := recover() + println(pad("PreviousRealm:"), r) + }() + println(pad("PreviousRealm:"), std.PreviousRealm()) + }() + println("") + + println("From gno.land/r/sys/users realm:") testing.SetRealm(std.NewCodeRealm("gno.land/r/sys/users")) PrintRealm() println(pad("CurrentRealm:"), std.CurrentRealm()) @@ -33,20 +39,23 @@ func pad(s string) string { } func PrintRealm() { - println(pad("PrintRealm: CurrentRealm:"), std.CurrentRealm()) - println(pad("PrintRealm: PreviousRealm:"), std.PreviousRealm()) + println(pad("PR() CurrentRealm:"), std.CurrentRealm()) + println(pad("PR() PreviousRealm:"), std.PreviousRealm()) } // Output: -// PrintRealm: CurrentRealm: (struct{("g1wymu47drhr0kuq2098m792lytgtj2nyx77yrsm" std.Address),("" string)} std.Realm) -// PrintRealm: PreviousRealm: (struct{("g1wymu47drhr0kuq2098m792lytgtj2nyx77yrsm" std.Address),("" string)} std.Realm) -// CurrentRealm: (struct{("g1wymu47drhr0kuq2098m792lytgtj2nyx77yrsm" std.Address),("" string)} std.Realm) +// From main: +// PR() CurrentRealm: (struct{("g17rgsdnfxzza0sdfsdma37sdwxagsz378833ca4" std.Address),("main" string)} std.Realm) +// PR() PreviousRealm: (struct{("g1wymu47drhr0kuq2098m792lytgtj2nyx77yrsm" std.Address),("" string)} std.Realm) +// CurrentRealm: (struct{("g17rgsdnfxzza0sdfsdma37sdwxagsz378833ca4" std.Address),("main" string)} std.Realm) // PreviousRealm: (struct{("g1wymu47drhr0kuq2098m792lytgtj2nyx77yrsm" std.Address),("" string)} std.Realm) -// PrintRealm: CurrentRealm: (struct{("g1user" std.Address),("" string)} std.Realm) -// PrintRealm: PreviousRealm: (struct{("g1wymu47drhr0kuq2098m792lytgtj2nyx77yrsm" std.Address),("" string)} std.Realm) +// +// From g1user origin: // CurrentRealm: (struct{("g1user" std.Address),("" string)} std.Realm) -// PreviousRealm: (struct{("g1wymu47drhr0kuq2098m792lytgtj2nyx77yrsm" std.Address),("" string)} std.Realm) -// PrintRealm: CurrentRealm: (struct{("g1njxh4leja7h52ea0lnq9crx3j6782g77nc7yd4" std.Address),("gno.land/r/sys/users" string)} std.Realm) -// PrintRealm: PreviousRealm: (struct{("g1wymu47drhr0kuq2098m792lytgtj2nyx77yrsm" std.Address),("" string)} std.Realm) +// PreviousRealm: frame not found: cannot seek beyond origin caller override +// +// From gno.land/r/sys/users realm: +// PR() CurrentRealm: (struct{("g1njxh4leja7h52ea0lnq9crx3j6782g77nc7yd4" std.Address),("gno.land/r/sys/users" string)} std.Realm) +// PR() PreviousRealm: (struct{("g17rgsdnfxzza0sdfsdma37sdwxagsz378833ca4" std.Address),("main" string)} std.Realm) // CurrentRealm: (struct{("g1njxh4leja7h52ea0lnq9crx3j6782g77nc7yd4" std.Address),("gno.land/r/sys/users" string)} std.Realm) -// PreviousRealm: (struct{("g1wymu47drhr0kuq2098m792lytgtj2nyx77yrsm" std.Address),("" string)} std.Realm) +// PreviousRealm: (struct{("g17rgsdnfxzza0sdfsdma37sdwxagsz378833ca4" std.Address),("main" string)} std.Realm) diff --git a/gnovm/tests/files/zrealm_crossrealm13a.gno b/gnovm/tests/files/zrealm_crossrealm13a.gno index 08ed6b214b6..bf250baece4 100644 --- a/gnovm/tests/files/zrealm_crossrealm13a.gno +++ b/gnovm/tests/files/zrealm_crossrealm13a.gno @@ -9,13 +9,27 @@ import ( func main() { crossing() + println("From main:") PrintRealm() + cross(PrintRealm)() println(pad("CurrentRealm:"), std.CurrentRealm()) println(pad("PreviousRealm:"), std.PreviousRealm()) + println("") + + println("From g1user origin:") testing.SetRealm(std.NewUserRealm("g1user")) cross(PrintRealm)() println(pad("CurrentRealm:"), std.CurrentRealm()) - println(pad("PreviousRealm:"), std.PreviousRealm()) + func() { + defer func() { + r := recover() + println(pad("PreviousRealm:"), r) + }() + println(pad("PreviousRealm:"), std.PreviousRealm()) + }() + println("") + + println("From gno.land/r/sys/users realm:") testing.SetRealm(std.NewCodeRealm("gno.land/r/sys/users")) cross(PrintRealm)() println(pad("CurrentRealm:"), std.CurrentRealm()) @@ -37,15 +51,22 @@ func PrintRealm() { } // Output: +// From main: // PrintRealm: CurrentRealm: (struct{("g1r0mlnkc05z0fv49km99z60qnp95tengyqfdr02" std.Address),("gno.land/r/demo/groups" string)} std.Realm) // PrintRealm: PreviousRealm: (struct{("g1wymu47drhr0kuq2098m792lytgtj2nyx77yrsm" std.Address),("" string)} std.Realm) +// PrintRealm: CurrentRealm: (struct{("g1r0mlnkc05z0fv49km99z60qnp95tengyqfdr02" std.Address),("gno.land/r/demo/groups" string)} std.Realm) +// PrintRealm: PreviousRealm: (struct{("g1r0mlnkc05z0fv49km99z60qnp95tengyqfdr02" std.Address),("gno.land/r/demo/groups" string)} std.Realm) // CurrentRealm: (struct{("g1r0mlnkc05z0fv49km99z60qnp95tengyqfdr02" std.Address),("gno.land/r/demo/groups" string)} std.Realm) // PreviousRealm: (struct{("g1wymu47drhr0kuq2098m792lytgtj2nyx77yrsm" std.Address),("" string)} std.Realm) +// +// From g1user origin: // PrintRealm: CurrentRealm: (struct{("g1r0mlnkc05z0fv49km99z60qnp95tengyqfdr02" std.Address),("gno.land/r/demo/groups" string)} std.Realm) // PrintRealm: PreviousRealm: (struct{("g1user" std.Address),("" string)} std.Realm) // CurrentRealm: (struct{("g1user" std.Address),("" string)} std.Realm) -// PreviousRealm: (struct{("g1wymu47drhr0kuq2098m792lytgtj2nyx77yrsm" std.Address),("" string)} std.Realm) +// PreviousRealm: frame not found: cannot seek beyond origin caller override +// +// From gno.land/r/sys/users realm: // PrintRealm: CurrentRealm: (struct{("g1r0mlnkc05z0fv49km99z60qnp95tengyqfdr02" std.Address),("gno.land/r/demo/groups" string)} std.Realm) // PrintRealm: PreviousRealm: (struct{("g1njxh4leja7h52ea0lnq9crx3j6782g77nc7yd4" std.Address),("gno.land/r/sys/users" string)} std.Realm) // CurrentRealm: (struct{("g1njxh4leja7h52ea0lnq9crx3j6782g77nc7yd4" std.Address),("gno.land/r/sys/users" string)} std.Realm) -// PreviousRealm: (struct{("g1wymu47drhr0kuq2098m792lytgtj2nyx77yrsm" std.Address),("" string)} std.Realm) +// PreviousRealm: (struct{("g1r0mlnkc05z0fv49km99z60qnp95tengyqfdr02" std.Address),("gno.land/r/demo/groups" string)} std.Realm) diff --git a/gnovm/tests/files/zrealm_crossrealm21.gno b/gnovm/tests/files/zrealm_crossrealm21.gno index 2b44d7e5cd3..8ab268cd5ac 100644 --- a/gnovm/tests/files/zrealm_crossrealm21.gno +++ b/gnovm/tests/files/zrealm_crossrealm21.gno @@ -22,6 +22,8 @@ func main() { // hello B cur=gno.land/r/demo/tests/crossrealm_b prev=gno.land/r/demo/tests/crossrealm // . + + // Realm: // finalizerealm["gno.land/r/demo/tests/crossrealm"] // u[1712ac7adcfdc8e58a67e5615e20fb312394c4df:7]= @@ -30,7 +32,7 @@ func main() { // "ObjectInfo": { // "ID": "1712ac7adcfdc8e58a67e5615e20fb312394c4df:7", // - "ModTime": "0", -// + "ModTime": "27", +// + "ModTime": "35", // "OwnerID": "1712ac7adcfdc8e58a67e5615e20fb312394c4df:2", // "RefCount": "1" // }, @@ -62,7 +64,7 @@ func main() { // "ID": "0edc46caf30c00efd87b6c272673239eafbd051e:4", // - "ModTime": "0", // + "IsEscaped": true, -// + "ModTime": "27", +// + "ModTime": "35", // "OwnerID": "0edc46caf30c00efd87b6c272673239eafbd051e:3", // - "RefCount": "1" // + "RefCount": "2" diff --git a/gnovm/tests/files/zrealm_crossrealm22.gno b/gnovm/tests/files/zrealm_crossrealm22.gno index 51d2f4a9ffa..3e9008e97c4 100644 --- a/gnovm/tests/files/zrealm_crossrealm22.gno +++ b/gnovm/tests/files/zrealm_crossrealm22.gno @@ -40,11 +40,11 @@ func main() { // Realm: // finalizerealm["gno.land/r/demo/tests/crossrealm"] -// c[1712ac7adcfdc8e58a67e5615e20fb312394c4df:29]={ +// c[1712ac7adcfdc8e58a67e5615e20fb312394c4df:37]={ // "ObjectInfo": { -// "ID": "1712ac7adcfdc8e58a67e5615e20fb312394c4df:29", +// "ID": "1712ac7adcfdc8e58a67e5615e20fb312394c4df:37", // "ModTime": "0", -// "OwnerID": "1712ac7adcfdc8e58a67e5615e20fb312394c4df:28", +// "OwnerID": "1712ac7adcfdc8e58a67e5615e20fb312394c4df:36", // "RefCount": "1" // }, // "Value": { @@ -67,7 +67,7 @@ func main() { // } // } // } -// c[1712ac7adcfdc8e58a67e5615e20fb312394c4df:28]={ +// c[1712ac7adcfdc8e58a67e5615e20fb312394c4df:36]={ // "Captures": [ // { // "T": { @@ -75,8 +75,8 @@ func main() { // }, // "V": { // "@type": "/gno.RefValue", -// "Hash": "3149f32e902d2cb3fb2913334a4472280aecf1f1", -// "ObjectID": "1712ac7adcfdc8e58a67e5615e20fb312394c4df:29" +// "Hash": "be376ecae5370ffc9b531703d1dabb784f53752b", +// "ObjectID": "1712ac7adcfdc8e58a67e5615e20fb312394c4df:37" // } // } // ], @@ -88,7 +88,7 @@ func main() { // "NativeName": "", // "NativePkg": "", // "ObjectInfo": { -// "ID": "1712ac7adcfdc8e58a67e5615e20fb312394c4df:28", +// "ID": "1712ac7adcfdc8e58a67e5615e20fb312394c4df:36", // "ModTime": "0", // "OwnerID": "1712ac7adcfdc8e58a67e5615e20fb312394c4df:13", // "RefCount": "1" @@ -127,7 +127,7 @@ func main() { // "ObjectInfo": { // "ID": "1712ac7adcfdc8e58a67e5615e20fb312394c4df:13", // - "ModTime": "0", -// + "ModTime": "27", +// + "ModTime": "35", // "OwnerID": "1712ac7adcfdc8e58a67e5615e20fb312394c4df:2", // "RefCount": "1" // }, @@ -138,8 +138,8 @@ func main() { // + }, // + "V": { // + "@type": "/gno.RefValue", -// + "Hash": "96fa7ba7744e6e490ac43c0d656e11e09f3e9450", -// + "ObjectID": "1712ac7adcfdc8e58a67e5615e20fb312394c4df:28" +// + "Hash": "496beec28378b765d658286561b08be89e32efee", +// + "ObjectID": "1712ac7adcfdc8e58a67e5615e20fb312394c4df:36" // } // } // } @@ -150,7 +150,7 @@ func main() { // "ID": "0edc46caf30c00efd87b6c272673239eafbd051e:4", // - "ModTime": "0", // + "IsEscaped": true, -// + "ModTime": "29", +// + "ModTime": "37", // "OwnerID": "0edc46caf30c00efd87b6c272673239eafbd051e:3", // - "RefCount": "1" // + "RefCount": "2" @@ -196,8 +196,8 @@ func main() { // { // "ObjectInfo": { // "ID": "1712ac7adcfdc8e58a67e5615e20fb312394c4df:13", -// - "ModTime": "27", -// + "ModTime": "29", +// - "ModTime": "35", +// + "ModTime": "37", // "OwnerID": "1712ac7adcfdc8e58a67e5615e20fb312394c4df:2", // "RefCount": "1" // }, @@ -205,8 +205,8 @@ func main() { // }, // "V": { // "@type": "/gno.RefValue", -// - "Hash": "96fa7ba7744e6e490ac43c0d656e11e09f3e9450", -// - "ObjectID": "1712ac7adcfdc8e58a67e5615e20fb312394c4df:28" +// - "Hash": "496beec28378b765d658286561b08be89e32efee", +// - "ObjectID": "1712ac7adcfdc8e58a67e5615e20fb312394c4df:36" // + "Escaped": true, // + "ObjectID": "0edc46caf30c00efd87b6c272673239eafbd051e:7" // } @@ -219,7 +219,7 @@ func main() { // "ID": "0edc46caf30c00efd87b6c272673239eafbd051e:7", // - "ModTime": "0", // + "IsEscaped": true, -// + "ModTime": "29", +// + "ModTime": "37", // "OwnerID": "0edc46caf30c00efd87b6c272673239eafbd051e:6", // - "RefCount": "1" // + "RefCount": "2" @@ -229,7 +229,7 @@ func main() { // u[0edc46caf30c00efd87b6c272673239eafbd051e:4]= // @@ -4,7 +4,7 @@ // "IsEscaped": true, -// "ModTime": "29", +// "ModTime": "37", // "OwnerID": "0edc46caf30c00efd87b6c272673239eafbd051e:3", // - "RefCount": "2" // + "RefCount": "1" @@ -245,8 +245,8 @@ func main() { // "ObjectID": "0edc46caf30c00efd87b6c272673239eafbd051e:5" // } // } -// d[1712ac7adcfdc8e58a67e5615e20fb312394c4df:28] -// d[1712ac7adcfdc8e58a67e5615e20fb312394c4df:29] +// d[1712ac7adcfdc8e58a67e5615e20fb312394c4df:36] +// d[1712ac7adcfdc8e58a67e5615e20fb312394c4df:37] // finalizerealm["gno.land/r/demo/tests/crossrealm_b"] // finalizerealm["gno.land/r/demo/tests/crossrealm"] // finalizerealm["gno.land/r/demo/tests/crossrealm_b"] @@ -261,7 +261,7 @@ func main() { // } // ], // finalizerealm["gno.land/r/demo/tests/crossrealm"] -// c[1712ac7adcfdc8e58a67e5615e20fb312394c4df:30]={ +// c[1712ac7adcfdc8e58a67e5615e20fb312394c4df:38]={ // "Crossing": false, // "FileName": "", // "IsClosure": false, @@ -270,7 +270,7 @@ func main() { // "NativeName": "", // "NativePkg": "", // "ObjectInfo": { -// "ID": "1712ac7adcfdc8e58a67e5615e20fb312394c4df:30", +// "ID": "1712ac7adcfdc8e58a67e5615e20fb312394c4df:38", // "ModTime": "0", // "OwnerID": "1712ac7adcfdc8e58a67e5615e20fb312394c4df:13", // "RefCount": "1" @@ -310,15 +310,15 @@ func main() { // "@type": "/gno.RefValue", // - "Escaped": true, // - "ObjectID": "0edc46caf30c00efd87b6c272673239eafbd051e:7" -// + "Hash": "d55f6f80443199ddb7062c89a2ec81bc3dd60113", -// + "ObjectID": "1712ac7adcfdc8e58a67e5615e20fb312394c4df:30" +// + "Hash": "6a8bf31929a4f73151f3b404c376f279bacd9c81", +// + "ObjectID": "1712ac7adcfdc8e58a67e5615e20fb312394c4df:38" // } // } // } // u[0edc46caf30c00efd87b6c272673239eafbd051e:7]= // @@ -11,7 +11,7 @@ // "IsEscaped": true, -// "ModTime": "29", +// "ModTime": "37", // "OwnerID": "0edc46caf30c00efd87b6c272673239eafbd051e:6", // - "RefCount": "2" // + "RefCount": "1" diff --git a/gnovm/tests/files/zrealm_crossrealm27.gno b/gnovm/tests/files/zrealm_crossrealm27.gno index b9c905102bb..7931f2241bd 100644 --- a/gnovm/tests/files/zrealm_crossrealm27.gno +++ b/gnovm/tests/files/zrealm_crossrealm27.gno @@ -27,5 +27,7 @@ func main() { // Error: // cannot modify external-realm or non-realm object + + // Preprocessed: -// file{ package crossrealm_test; import crossrealm_b gno.land/r/demo/tests/crossrealm_b; type Struct (const-type gno.land/r/crossrealm_test.Struct); var s *(Struct); func init.2() { s2 := &(Struct{A: (const (100 int))}); (const (cross func(func(interface {})) func(interface {})))((const (ref(gno.land/r/demo/tests/crossrealm_b) package{})).SetObject)(func func(){ (const (println func(...interface {})))(&(s2<~VPBlock(1,0)>.A)) }>); s<~VPBlock(3,1)> = s2<~VPBlock(1,0)> }; func main() { (const (crossing func()))(); s<~VPBlock(3,1)>.A = (const (123 int)); (const (println func(...interface {})))(s<~VPBlock(3,1)>) } } +// file{ package crossrealm_test; import crossrealm_b gno.land/r/demo/tests/crossrealm_b; type Struct (const-type gno.land/r/crossrealm_test.Struct); var s *(typeval{gno.land/r/crossrealm_test.Struct}); func init.2() { s2 := &(typeval{gno.land/r/crossrealm_test.Struct}{A: (const (100 int))}); (const (cross func(func(interface {})) func(interface {})))((const (ref(gno.land/r/demo/tests/crossrealm_b) package{})).SetObject)(func func(){ (const (println func(...interface {})))(&(s2<~VPBlock(1,0)>.A)) }>); s<~VPBlock(3,1)> = s2<~VPBlock(1,0)> }; func main() { (const (crossing func()))(); s<~VPBlock(3,1)>.A = (const (123 int)); (const (println func(...interface {})))(s<~VPBlock(3,1)>) } } diff --git a/gnovm/tests/files/zrealm_crossrealm28.gno b/gnovm/tests/files/zrealm_crossrealm28.gno index 768bb99b45e..8c0ff2f70d9 100644 --- a/gnovm/tests/files/zrealm_crossrealm28.gno +++ b/gnovm/tests/files/zrealm_crossrealm28.gno @@ -31,7 +31,7 @@ func main() { // Preprocessed: -// file{ package crossrealm_test; import crossrealm_b gno.land/r/demo/tests/crossrealm_b; type Struct (const-type gno.land/r/crossrealm_test.Struct); var s *(Struct); func init.2() { s<~VPBlock(3,1)> = &(Struct{A: (const (100 int))}); (const (cross func(func(interface {})) func(interface {})))((const (ref(gno.land/r/demo/tests/crossrealm_b) package{})).SetObject)(func func(){ (const (println func(...interface {})))(&((const (ref(gno.land/r/crossrealm_test) package{})).s.A)) }) }; func main() { (const (crossing func()))(); (const (cross func(func(interface {})) func(interface {})))((const (ref(gno.land/r/demo/tests/crossrealm_b) package{})).SetObject)((const (123 int))); s<~VPBlock(3,1)>.A = (const (123 int)); (const (println func(...interface {})))(s<~VPBlock(3,1)>) } } +// file{ package crossrealm_test; import crossrealm_b gno.land/r/demo/tests/crossrealm_b; type Struct (const-type gno.land/r/crossrealm_test.Struct); var s *(typeval{gno.land/r/crossrealm_test.Struct}); func init.2() { s<~VPBlock(3,1)> = &(typeval{gno.land/r/crossrealm_test.Struct}{A: (const (100 int))}); (const (cross func(func(interface {})) func(interface {})))((const (ref(gno.land/r/demo/tests/crossrealm_b) package{})).SetObject)(func func(){ (const (println func(...interface {})))(&((const (ref(gno.land/r/crossrealm_test) package{})).s.A)) }) }; func main() { (const (crossing func()))(); (const (cross func(func(interface {})) func(interface {})))((const (ref(gno.land/r/demo/tests/crossrealm_b) package{})).SetObject)((const (123 int))); s<~VPBlock(3,1)>.A = (const (123 int)); (const (println func(...interface {})))(s<~VPBlock(3,1)>) } } diff --git a/gnovm/tests/files/zrealm_crossrealm29.gno b/gnovm/tests/files/zrealm_crossrealm29.gno index de15e58b4dc..be573d81300 100644 --- a/gnovm/tests/files/zrealm_crossrealm29.gno +++ b/gnovm/tests/files/zrealm_crossrealm29.gno @@ -31,5 +31,7 @@ func main() { // Output: // &(struct{(123 int)} gno.land/r/crossrealm_test.Struct) + + // Preprocessed: -// file{ package crossrealm_test; import crossrealm_b gno.land/r/demo/tests/crossrealm_b; type Struct (const-type gno.land/r/crossrealm_test.Struct); var s *(Struct); func init.2() { s<~VPBlock(3,1)> = &(Struct{A: (const (100 int))}); (const (cross func(func(interface {})) func(interface {})))((const (ref(gno.land/r/demo/tests/crossrealm_b) package{})).SetObject)(func func(){ (const (println func(...interface {})))(&((const (ref(gno.land/r/crossrealm_test) package{})).s.A)) }) }; func main() { (const (crossing func()))(); s<~VPBlock(3,1)>.A = (const (123 int)); (const (println func(...interface {})))(s<~VPBlock(3,1)>) } } +// file{ package crossrealm_test; import crossrealm_b gno.land/r/demo/tests/crossrealm_b; type Struct (const-type gno.land/r/crossrealm_test.Struct); var s *(typeval{gno.land/r/crossrealm_test.Struct}); func init.2() { s<~VPBlock(3,1)> = &(typeval{gno.land/r/crossrealm_test.Struct}{A: (const (100 int))}); (const (cross func(func(interface {})) func(interface {})))((const (ref(gno.land/r/demo/tests/crossrealm_b) package{})).SetObject)(func func(){ (const (println func(...interface {})))(&((const (ref(gno.land/r/crossrealm_test) package{})).s.A)) }) }; func main() { (const (crossing func()))(); s<~VPBlock(3,1)>.A = (const (123 int)); (const (println func(...interface {})))(s<~VPBlock(3,1)>) } } diff --git a/gnovm/tests/files/zrealm_panic.gno b/gnovm/tests/files/zrealm_panic.gno index 0176655b1ef..c7a9ddd6f8d 100644 --- a/gnovm/tests/files/zrealm_panic.gno +++ b/gnovm/tests/files/zrealm_panic.gno @@ -17,9 +17,11 @@ func main() { // Error: // panic + + // Stacktrace: // panic: panic // ms.Panic() // gno.land/r/test/files/zrealm_panic.gno:7 -// cross(main)() +// main() // gno.land/r/test/files/zrealm_panic.gno:14 diff --git a/gnovm/tests/stdlibs/fmt/fmt_test.gno b/gnovm/tests/stdlibs/fmt/fmt_test.gno index df6e527afd0..8220ebf9b4c 100644 --- a/gnovm/tests/stdlibs/fmt/fmt_test.gno +++ b/gnovm/tests/stdlibs/fmt/fmt_test.gno @@ -1328,7 +1328,7 @@ func TestStructPrinter(t *testing.T) { }{ {"%v", "{abc def 123}"}, {"%+v", "{a:abc b:def c:123}"}, - {"%#v", `fmt_test.T{a:"abc", b:"def", c:123}`}, + {"%#v", `fmt_test[fmt_test/fmt_test.gno:1315:1].T{a:"abc", b:"def", c:123}`}, } for _, tt := range tests { out := fmt.Sprintf(tt.fmt, s) @@ -1591,7 +1591,7 @@ func TestNilDoesNotBecomeTyped(t *testing.T) { var a *A = nil var b B = B{} got := fmt.Sprintf(hideFromVet("%s %s %s %s %s"), nil, a, nil, b, nil) - const expect = "%!s() %!s(*fmt_test.A=) %!s() {} %!s()" + const expect = "%!s() %!s(*fmt_test[fmt_test/fmt_test.gno:1588:1].A=) %!s() {} %!s()" if got != expect { t.Errorf("expected:\n\t%q\ngot:\n\t%q", expect, got) } diff --git a/gnovm/tests/stdlibs/std/std.go b/gnovm/tests/stdlibs/std/std.go index 1e442a8c63f..27524ab2b12 100644 --- a/gnovm/tests/stdlibs/std/std.go +++ b/gnovm/tests/stdlibs/std/std.go @@ -87,6 +87,16 @@ func X_callerAt(m *gno.Machine, n int) string { } */ +func getOverride(m *gno.Machine, i int) (RealmOverride, bool) { + fr := &m.Frames[i] + ctx := m.Context.(*TestExecContext) + override, overridden := ctx.RealmFrames[i] + if overridden && !fr.TestOverridden { + return RealmOverride{}, false // override was replaced + } + return override, overridden +} + func X_getRealm(m *gno.Machine, height int) (address string, pkgPath string) { // NOTE: keep in sync with stdlibs/std.getRealm @@ -100,10 +110,11 @@ func X_getRealm(m *gno.Machine, height int) (address string, pkgPath string) { fr := &m.Frames[i] // Skip over (non-realm) non-crosses. - // Override implies cross. - override, overridden := ctx.RealmFrames[i] - if overridden && !fr.TestOverridden { - overridden = false // overridden frame was replaced. + override, overridden := getOverride(m, i) + if overridden { + if override.PkgPath == "" && crosses < height { + m.Panic(typedString("frame not found: cannot seek beyond origin caller override")) + } } if !overridden { if !fr.IsCall() { @@ -155,6 +166,17 @@ func X_getRealm(m *gno.Machine, height int) (address string, pkgPath string) { case gno.StageRun: switch height { case crosses: + fr := m.Frames[0] + path := fr.LastPackage.PkgPath + if path == "" { + // Not sure what would cause this. + panic("should not happen") + } else { + // e.g. TestFoo(t *testing.Test) in *_test.gno + // or main() in *_filetest.gno + return string(gno.DerivePkgBech32Addr(path)), path + } + case crosses + 1: return string(ctx.OriginCaller), "" default: m.Panic(typedString("frame not found")) diff --git a/gnovm/tests/stdlibs/testing/context_testing.gno b/gnovm/tests/stdlibs/testing/context_testing.gno index 72bd6533981..a197cdf971d 100644 --- a/gnovm/tests/stdlibs/testing/context_testing.gno +++ b/gnovm/tests/stdlibs/testing/context_testing.gno @@ -64,6 +64,7 @@ func testIssueCoins(addr string, denom []string, amt []int64) func SetOriginCaller(origCaller std.Address) { ctx := GetContext() ctx.OriginCaller = origCaller + ctx.CurrentRealm = std.NewUserRealm(origCaller) SetContext(ctx) } @@ -88,9 +89,15 @@ func SetHeight(height int64) { // SetRealm sets the realm for the current frame. // After calling SetRealm, calling CurrentRealm() in the test function will yield the value of // rlm, while if a realm function is called, using PreviousRealm() will yield rlm. +// If rlm.PkgPath() is "", implies rlm.Address() is the user address. +// OriginCaller will also be set. This is identical to calling +// ctx.SetOriginCaller(userAddress) func SetRealm(rlm std.Realm) { ctx := GetContext() ctx.CurrentRealm = rlm + if rlm.PkgPath() == "" { + ctx.OriginCaller = rlm.Address() + } SetContext(ctx) }