Skip to content

Commit

Permalink
feat(stdlibs): add std.GetCaller
Browse files Browse the repository at this point in the history
  • Loading branch information
albttx committed Apr 3, 2023
1 parent 98cc986 commit a70e880
Show file tree
Hide file tree
Showing 13 changed files with 450 additions and 5 deletions.
17 changes: 17 additions & 0 deletions examples/gno.land/p/demo/tests/subtests/subtests.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package subtests

import (
"std"
)

func CurrentRealmPath() string {
return std.CurrentRealmPath()
}

func GetCaller() std.Address {
return std.GetCaller()
}

func Exec(fn func()) {
fn()
}
24 changes: 23 additions & 1 deletion examples/gno.land/p/demo/tests/tests.gno
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
package tests

import "std"
import (
"std"

psubtests "gno.land/p/demo/tests/subtests"
)

func CurrentRealmPath() string {
return std.CurrentRealmPath()
Expand Down Expand Up @@ -40,3 +44,21 @@ func ModifyTestRealmObject2b() {
func ModifyTestRealmObject2c() {
SomeValue3.Field = "modified"
}

func GetCaller() std.Address {
return std.GetCaller()
}

func GetSubtestsCaller() std.Address {
return psubtests.GetCaller()
}

func PrintCallers() {
println("p/TEST : ORIGCALL:", std.GetOrigCaller())
println("p/TEST : PKG ADDR:", std.GetOrigPkgAddr())
println("p/TEST : CALLER :", std.GetCaller())
}

func Exec(fn func()) {
fn()
}
122 changes: 122 additions & 0 deletions examples/gno.land/r/demo/tests/fake20/fake20.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
package fake20

import (
"std"
"strings"

"gno.land/p/demo/grc/grc20"
"gno.land/p/demo/ufmt"
)

var (
foo *grc20.AdminToken
admin std.Address = "g1us8428u2a5satrlxzagqqa5m6vmuze025anjlj" // TODO: helper to change admin
)

func Init() {
foo = grc20.NewAdminToken("Fake", "FAKE", 4)
foo.Mint(admin, 1000000*10000) // @administrator (1M)
foo.Mint("g1u7y667z64x2h7vc6fmpcprgey4ck233jaww9zq", 10000*10000) // @manfred (10k)
foo.Mint("g1lpnflsxpr84dsqkznw85yd5wdzenkj89vsptmf", 10000*10000) // @gno.land/r/demo/tests/unsaferealm
}

func init() {
Init()
}


// method proxies as public functions.
//

// getters.

func GetCaller() std.Address {
return std.GetCallerAt(1)
// return std.GetOrigPkgAddr()
}

func TotalSupply() uint64 {
return foo.TotalSupply()
}

func BalanceOf(owner std.Address) uint64 {
balance, err := foo.BalanceOf(owner)
if err != nil {
panic(err)
}
return balance
}

func Allowance(owner, spender std.Address) uint64 {
allowance, err := foo.Allowance(owner, spender)
if err != nil {
panic(err)
}
return allowance
}

// setters.

func Transfer(to std.Address, amount uint64) {
caller := std.GetCaller()
println("transfering", amount, "from:", caller, "to:", to)
foo.Transfer(caller, to, amount)
}

func Approve(spender std.Address, amount uint64) {
caller := std.GetCaller()
foo.Approve(caller, spender, amount)
}

func TransferFrom(from, to std.Address, amount uint64) {
caller := std.GetCaller()
foo.TransferFrom(caller, from, to, amount)
}

// faucet.

func Faucet() {
// FIXME: add limits?
// FIXME: add payment in gnot?
caller := std.GetCaller()
foo.Mint(caller, 1000*10000) // 1k
}

// administration.

func Mint(address std.Address, amount uint64) {
caller := std.GetCaller()
assertIsAdmin(caller)
foo.Mint(address, amount)
}

func Burn(address std.Address, amount uint64) {
caller := std.GetCaller()
assertIsAdmin(caller)
foo.Burn(address, amount)
}

// render.
//

func Render(path string) string {
parts := strings.Split(path, "/")
c := len(parts)

switch {
case path == "":
return foo.RenderHome()
case c == 2 && parts[0] == "balance":
owner := std.Address(parts[1])
balance, _ := foo.BalanceOf(owner)
return ufmt.Sprintf("%d\n", balance)
default:
return "404\n"
}
}

func assertIsAdmin(address std.Address) {
if address != admin {
panic("restricted access")
}
}
4 changes: 4 additions & 0 deletions examples/gno.land/r/demo/tests/phishing/phishing.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package phising

func GetMillionaire() {
}
17 changes: 17 additions & 0 deletions examples/gno.land/r/demo/tests/subtests/subtests.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package subtests

import (
"std"
)

func CurrentRealmPath() string {
return std.CurrentRealmPath()
}

func GetCaller() std.Address {
return std.GetCaller()
}

func Exec(fn func()) {
fn()
}
30 changes: 29 additions & 1 deletion examples/gno.land/r/demo/tests/tests.gno
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
package tests

import "std"
import (
"std"

"gno.land/r/demo/tests/subtests"
)

func CurrentRealmPath() string {
return std.CurrentRealmPath()
Expand Down Expand Up @@ -51,3 +55,27 @@ func ModTestNodes() {
func PrintTestNodes() {
println(gTestNode2.Child.Name)
}

func GetCaller() std.Address {
return std.GetCaller()
}

func GetSubtestsCaller() std.Address {
return subtests.GetCaller()
}

func ExecFromTest() {
Exec(func() {
println("xxx -> r/demo/tests -> r/demo/tests.Exec:", std.GetCaller())
})
}

func Exec(fn func()) {
fn()
}

func PrintCallers() {
println("p/TEST : ORIGCALL:", std.GetOrigCaller())
println("p/TEST : PKG ADDR:", std.GetOrigPkgAddr())
println("p/TEST : CALLER :", std.GetCaller())
}
52 changes: 52 additions & 0 deletions examples/gno.land/r/demo/tests/unsaferealm/unsaferealm.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package unsaferealm

import (
"std"

"gno.land/p/demo/grc/grc20"
)

var (
foo *grc20.AdminToken
Owner = std.Address("g1lpnflsxpr84dsqkznw85yd5wdzenkj89vsptmf")
)

func init() {
foo = grc20.NewAdminToken("Fake", "FAKE", 4)

// std.TestDerivePkgAddr("gno.land/r/demo/tests/unsaferealm")
// foo.Mint("g1lpnflsxpr84dsqkznw85yd5wdzenkj89vsptmf", 1000000*10000)
foo.Mint(Owner, 1000000*10000)
// foo.Mint(std.GetOrigPkgAddr(), 1000000*10000)
}

/*
** Some grc20 functions
*/

func GetCaller() std.Address {
return std.GetCallerAt(1)
}

func BalanceOf(owner std.Address) uint64 {
balance, err := foo.BalanceOf(owner)
if err != nil {
panic(err)
}

return balance
}

func Transfer(to std.Address, amount uint64) {
caller := std.GetCaller()
println("transfering", amount, "from:", caller, "to:", to)
foo.Transfer(caller, to, amount)
}

/*
** Realm unsafe functions
*/

func Do(fn func()) {
fn()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package unsaferealm

import (
"testing"
)

func TestUnsafeRealm(t *testing.T) {
println("Hello")
}
4 changes: 3 additions & 1 deletion gnovm/pkg/gnolang/frame.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package gnolang

import "fmt"
import (
"fmt"
)

//----------------------------------------
// (runtime) Frame
Expand Down
38 changes: 38 additions & 0 deletions gnovm/stdlibs/stdlibs.go
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,44 @@ func InjectPackage(store gno.Store, pn *gno.PackageNode) {
m.PushValue(res0)
},
)
pn.DefineNative("GetCaller",
gno.Flds( // params
),
gno.Flds( // results
"", "Address",
),
func(m *gno.Machine) {
ctx := m.Context.(ExecContext)

lastCaller := ctx.OrigCaller

if m.NumFrames() <= 2 {
lastCaller = ctx.OrigCaller
} else {

for i := m.NumFrames() - 1; i > 0; i-- {
frameA := m.Frames[i]
frameB := m.Frames[i-1]
if !frameB.LastPackage.IsRealm() {
continue
}
if !frameA.LastPackage.IsRealm() && !frameB.LastPackage.IsRealm() {
continue
}
lastCaller = frameB.LastPackage.GetPkgAddr().Bech32()
break
}
}
res0 := gno.Go2GnoValue(
m.Alloc,
m.Store,
reflect.ValueOf(lastCaller),
)
addrT := store.GetType(gno.DeclaredTypeID("std", "Address"))
res0.T = addrT
m.PushValue(res0)
},
)
pn.DefineNative("GetOrigPkgAddr",
gno.Flds( // params
),
Expand Down
5 changes: 3 additions & 2 deletions gnovm/tests/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ func TestMachine(store gno.Store, stdout io.Writer, pkgPath string) *gno.Machine
func testMachineCustom(store gno.Store, pkgPath string, stdout io.Writer, maxAlloc int64, send std.Coins) *gno.Machine {
// FIXME: create a better package to manage this, with custom constructors
pkgAddr := gno.DerivePkgAddr(pkgPath) // the addr of the pkgPath called.
caller := gno.DerivePkgAddr(pkgPath) // NOTE: for the purpose of testing, the caller is generally the "main" package, same as pkgAddr.
caller := gno.DerivePkgAddr("user1.gno") // NOTE: for the purpose of testing, the caller is generally the "main" package, same as pkgAddr.
pkgCoins := std.MustParseCoins("200000000ugnot").Add(send) // >= send.
banker := newTestBanker(pkgAddr.Bech32(), pkgCoins)
ctx := stdlibs.ExecContext{
Expand Down Expand Up @@ -295,7 +295,8 @@ func RunFileTest(rootDir string, path string, opts ...RunFileTestOption) error {
if resWanted == "" {
panic(fmt.Sprintf("fail on %s: got unexpected output: %s", path, res))
} else {
panic(fmt.Sprintf("fail on %s: got:\n%s\n\nwant:\n%s\n", path, res, resWanted))
fmt.Printf("fail on %s: got:\n%s\n\nwant:\n%s\n", path, res, resWanted)
os.Exit(1)
}
}
}
Expand Down
Loading

0 comments on commit a70e880

Please sign in to comment.