Skip to content

Commit

Permalink
feat: inject ParamsKeeper in VMKeeper
Browse files Browse the repository at this point in the history
Signed-off-by: moul <94029+moul@users.noreply.github.com>
  • Loading branch information
moul committed Oct 10, 2024
1 parent c177c69 commit 2a5b678
Show file tree
Hide file tree
Showing 12 changed files with 328 additions and 4 deletions.
50 changes: 50 additions & 0 deletions gno.land/pkg/sdk/vm/builtins.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package vm
import (
"github.com/gnolang/gno/tm2/pkg/crypto"
"github.com/gnolang/gno/tm2/pkg/sdk"
"github.com/gnolang/gno/tm2/pkg/sdk/params"
"github.com/gnolang/gno/tm2/pkg/std"
)

Expand Down Expand Up @@ -55,3 +56,52 @@ func (bnk *SDKBanker) RemoveCoin(b32addr crypto.Bech32Address, denom string, amo
panic(err)
}
}

// ----------------------------------------
// SDKParams

type SDKParams struct {
vmk *VMKeeper
ctx sdk.Context
}

func NewSDKParams(vmk *VMKeeper, ctx sdk.Context) *SDKParams {
return &SDKParams{
vmk: vmk,
ctx: ctx,
}
}

// SetXXX helpers:
// - dynamically register a new key with the corresponding type in the paramset table (only once).
// - set the value.

func (prm *SDKParams) SetString(key, value string) {
if !prm.vmk.prmk.Has(prm.ctx, key) {
prm.vmk.prmk.RegisterType(params.NewParamSetPair(key, "", validateNoOp))
}
prm.vmk.prmk.Set(prm.ctx, key, value)
}

func (prm *SDKParams) SetBool(key string, value bool) {
if !prm.vmk.prmk.Has(prm.ctx, key) {
prm.vmk.prmk.RegisterType(params.NewParamSetPair(key, true, validateNoOp))
}
prm.vmk.prmk.Set(prm.ctx, key, value)
}

func (prm *SDKParams) SetInt64(key string, value int64) {
if !prm.vmk.prmk.Has(prm.ctx, key) {
prm.vmk.prmk.RegisterType(params.NewParamSetPair(key, int64(0), validateNoOp))
}
prm.vmk.prmk.Set(prm.ctx, key, value)
}

func (prm *SDKParams) SetUint64(key string, value uint64) {
if !prm.vmk.prmk.Has(prm.ctx, key) {
prm.vmk.prmk.RegisterType(params.NewParamSetPair(key, uint64(0), validateNoOp))
}
prm.vmk.prmk.Set(prm.ctx, key, value)
}

func validateNoOp(_ interface{}) error { return nil }
5 changes: 4 additions & 1 deletion gno.land/pkg/sdk/vm/common_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"github.com/gnolang/gno/tm2/pkg/sdk"
authm "github.com/gnolang/gno/tm2/pkg/sdk/auth"
bankm "github.com/gnolang/gno/tm2/pkg/sdk/bank"
paramsm "github.com/gnolang/gno/tm2/pkg/sdk/params"
"github.com/gnolang/gno/tm2/pkg/std"
"github.com/gnolang/gno/tm2/pkg/store"
"github.com/gnolang/gno/tm2/pkg/store/dbadapter"
Expand Down Expand Up @@ -47,7 +48,9 @@ func _setupTestEnv(cacheStdlibs bool) testEnv {
ctx := sdk.NewContext(sdk.RunTxModeDeliver, ms, &bft.Header{ChainID: "test-chain-id"}, log.NewNoopLogger())
acck := authm.NewAccountKeeper(iavlCapKey, std.ProtoBaseAccount)
bank := bankm.NewBankKeeper(acck)
vmk := NewVMKeeper(baseCapKey, iavlCapKey, acck, bank, 100_000_000)
prmk := paramsm.NewParamsKeeper(iavlCapKey, "params")
maxCycles := int64(100_000_000) // XXX: use x/params for 100_000_000
vmk := NewVMKeeper(baseCapKey, iavlCapKey, acck, bank, prmk, maxCycles)

mcw := ms.MultiCacheWrap()
vmk.Initialize(log.NewNoopLogger(), mcw)
Expand Down
11 changes: 10 additions & 1 deletion gno.land/pkg/sdk/vm/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"github.com/gnolang/gno/tm2/pkg/sdk"
"github.com/gnolang/gno/tm2/pkg/sdk/auth"
"github.com/gnolang/gno/tm2/pkg/sdk/bank"
"github.com/gnolang/gno/tm2/pkg/sdk/params"
"github.com/gnolang/gno/tm2/pkg/std"
"github.com/gnolang/gno/tm2/pkg/store"
"github.com/gnolang/gno/tm2/pkg/store/dbadapter"
Expand Down Expand Up @@ -59,6 +60,7 @@ type VMKeeper struct {
iavlKey store.StoreKey
acck auth.AccountKeeper
bank bank.BankKeeper
prmk params.ParamsKeeper

// cached, the DeliverTx persistent state.
gnoStore gno.Store
Expand All @@ -72,14 +74,15 @@ func NewVMKeeper(
iavlKey store.StoreKey,
acck auth.AccountKeeper,
bank bank.BankKeeper,
prmk params.ParamsKeeper,
maxCycles int64,
) *VMKeeper {
// TODO: create an Options struct to avoid too many constructor parameters
vmk := &VMKeeper{
baseKey: baseKey,
iavlKey: iavlKey,
acck: acck,
bank: bank,
prmk: prmk,
maxCycles: maxCycles,
}
return vmk
Expand Down Expand Up @@ -262,6 +265,7 @@ func (vm *VMKeeper) checkNamespacePermission(ctx sdk.Context, creator crypto.Add
OrigPkgAddr: pkgAddr.Bech32(),
// XXX: should we remove the banker ?
Banker: NewSDKBanker(vm, ctx),
Params: NewSDKParams(vm, ctx),
EventLogger: ctx.EventLogger(),
}

Expand Down Expand Up @@ -363,6 +367,7 @@ func (vm *VMKeeper) AddPackage(ctx sdk.Context, msg MsgAddPackage) (err error) {
OrigSendSpent: new(std.Coins),
OrigPkgAddr: pkgAddr.Bech32(),
Banker: NewSDKBanker(vm, ctx),
Params: NewSDKParams(vm, ctx),
EventLogger: ctx.EventLogger(),
}
// Parse and run the files, construct *PV.
Expand Down Expand Up @@ -464,6 +469,7 @@ func (vm *VMKeeper) Call(ctx sdk.Context, msg MsgCall) (res string, err error) {
OrigSendSpent: new(std.Coins),
OrigPkgAddr: pkgAddr.Bech32(),
Banker: NewSDKBanker(vm, ctx),
Params: NewSDKParams(vm, ctx),
EventLogger: ctx.EventLogger(),
}
// Construct machine and evaluate.
Expand Down Expand Up @@ -563,6 +569,7 @@ func (vm *VMKeeper) Run(ctx sdk.Context, msg MsgRun) (res string, err error) {
OrigSendSpent: new(std.Coins),
OrigPkgAddr: pkgAddr.Bech32(),
Banker: NewSDKBanker(vm, ctx),
Params: NewSDKParams(vm, ctx),
EventLogger: ctx.EventLogger(),
}
// Parse and run the files, construct *PV.
Expand Down Expand Up @@ -724,6 +731,7 @@ func (vm *VMKeeper) QueryEval(ctx sdk.Context, pkgPath string, expr string) (res
// OrigSendSpent: nil,
OrigPkgAddr: pkgAddr.Bech32(),
Banker: NewSDKBanker(vm, ctx), // safe as long as ctx is a fork to be discarded.
Params: NewSDKParams(vm, ctx),
EventLogger: ctx.EventLogger(),
}
m := gno.NewMachineWithOptions(
Expand Down Expand Up @@ -791,6 +799,7 @@ func (vm *VMKeeper) QueryEvalString(ctx sdk.Context, pkgPath string, expr string
// OrigSendSpent: nil,
OrigPkgAddr: pkgAddr.Bech32(),
Banker: NewSDKBanker(vm, ctx), // safe as long as ctx is a fork to be discarded.
Params: NewSDKParams(vm, ctx),
EventLogger: ctx.EventLogger(),
}
m := gno.NewMachineWithOptions(
Expand Down
54 changes: 54 additions & 0 deletions gno.land/pkg/sdk/vm/keeper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,60 @@ func Echo(msg string) string {
assert.Error(t, err)
}

// Using x/params from a realm.
func TestVMKeeperParams(t *testing.T) {
env := setupTestEnv()
ctx := env.vmk.MakeGnoTransactionStore(env.ctx)

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

// Create test package.
files := []*std.MemFile{
{"init.gno", `
package test
import "std"
func init() {
std.SetConfig("foo", "foo1")
}
func Do() string {
std.SetConfig("bar", int64(1337))
std.SetConfig("foo", "foo2") // override init
return "XXX" // return std.GetConfig("gno.land/r/test.foo"), if we want to expose std.GetConfig, maybe as a std.TestGetConfig
}`},
}
pkgPath := "gno.land/r/test"
msg1 := NewMsgAddPackage(addr, pkgPath, files)
err := env.vmk.AddPackage(ctx, msg1)
assert.NoError(t, err)

// Run Echo function.
coins := std.MustParseCoins(ugnot.ValueString(9_000_000))
msg2 := NewMsgCall(addr, coins, pkgPath, "Do", []string{})

res, err := env.vmk.Call(ctx, msg2)
assert.NoError(t, err)
_ = res
expected := fmt.Sprintf("(\"%s\" string)\n\n", "XXX") // XXX: return something more useful
assert.Equal(t, expected, res)

var foo string
var bar int64
env.vmk.prmk.Get(ctx, "gno.land/r/test.foo.string", &foo)
env.vmk.prmk.Get(ctx, "gno.land/r/test.bar.int64", &bar)
assert.Equal(t, "foo2", foo)
assert.Equal(t, int64(1337), bar)
}

// Assign admin as OrigCaller on deploying the package.
func TestVMKeeperOrigCallerInit(t *testing.T) {
env := setupTestEnv()
Expand Down
104 changes: 104 additions & 0 deletions gnovm/stdlibs/generated.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions gnovm/stdlibs/std/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ type ExecContext struct {
OrigSend std.Coins
OrigSendSpent *std.Coins // mutable
Banker BankerInterface
Params ParamsInterface
EventLogger *sdk.EventLogger
}

Expand Down
28 changes: 28 additions & 0 deletions gnovm/stdlibs/std/params.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package std

// These are native bindings to the banker's functions.
func setConfigString(key string, val string)
func setConfigBool(key string, val bool)
func setConfigInt64(key string, val int64)
func setConfigUint64(key string, val uint64)

// XXX: add doc
func SetConfig(key string, val interface{}) {
switch v := val.(type) {
case string:
setConfigString(key, v)
case bool:
setConfigBool(key, v)
case int64:
setConfigInt64(key, v)
case uint64:
setConfigUint64(key, v)
default:
panic("unsupported type")
}
}

// XXX: add doc
//func GetConfig(key string) string {
// return getConfig(key)
//}
Loading

0 comments on commit 2a5b678

Please sign in to comment.