Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

feat: support custom VM domain #2911

Open
wants to merge 36 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
9afb088
chore: make tm2/telemetry less aware of gno.land
moul Oct 5, 2024
f5d6d84
chore: fixup
moul Oct 5, 2024
ec39ada
chore: fixup
moul Oct 5, 2024
75a1f88
chore: fixup
moul Oct 5, 2024
e982dc1
chore: fixup
moul Oct 5, 2024
46530c9
chore: fixup
moul Oct 5, 2024
588b219
chore: fixup
moul Oct 5, 2024
f81ced5
chore: fixup
moul Oct 5, 2024
0b58baa
chore: fixup
moul Oct 5, 2024
302d730
chore: fixup
moul Oct 5, 2024
f6dd011
chore: fixup
moul Oct 5, 2024
6a75067
chore: fixup
moul Oct 5, 2024
b5b17d1
chore: fixup
moul Oct 5, 2024
b2f90b4
chore: fixup
moul Oct 5, 2024
8a444b4
chore: fixup
moul Oct 5, 2024
5b72ed7
chore: fixup
moul Oct 5, 2024
57b2983
chore: fixup
moul Oct 5, 2024
1ff1d4c
chore: fixup
moul Oct 5, 2024
7353989
Merge branch 'master' into dev/moul/gno-domain
moul Oct 6, 2024
448e962
chore: fixup
moul Oct 6, 2024
4f03186
chore: fixup
moul Oct 6, 2024
f0b41df
Update gno.land/pkg/sdk/vm/keeper.go
moul Oct 6, 2024
9d73f9d
Merge remote-tracking branch 'origin/master' into dev/moul/gno-domain
moul Oct 22, 2024
af82c24
Merge remote-tracking branch 'origin/master' into dev/moul/gno-domain
moul Nov 13, 2024
4633be4
chore: fixup
moul Nov 13, 2024
6fcbd1c
chore: fixup
moul Nov 13, 2024
c874441
chore: fixup
moul Nov 14, 2024
f6e3a5d
chore: fixup
moul Nov 14, 2024
c403e23
chore: fixup
moul Nov 14, 2024
a1c2ddb
chore: fixup
moul Nov 14, 2024
f90c32f
Merge branch 'master' into dev/moul/gno-domain
moul Nov 15, 2024
c9f2292
chore: fixup
moul Nov 15, 2024
9d97f31
Merge remote-tracking branch 'origin/master' into dev/moul/gno-domain
moul Nov 28, 2024
8445d8c
chore: fixup
moul Nov 28, 2024
29e0e2e
Update gno.land/pkg/sdk/vm/params.go
moul Nov 28, 2024
a41f9b5
Merge branch 'master' into dev/moul/gno-domain
moul Nov 28, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 17 additions & 8 deletions contribs/gnodev/cmd/gnodev/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,18 +61,20 @@ type devCfg struct {
webRemoteHelperAddr string

// Node Configuration
minimal bool
verbose bool
noWatch bool
noReplay bool
maxGas int64
chainId string
serverMode bool
unsafeAPI bool
minimal bool
verbose bool
noWatch bool
noReplay bool
maxGas int64
chainId string
chainDomain string
serverMode bool
unsafeAPI bool
}

var defaultDevOptions = &devCfg{
chainId: "dev",
chainDomain: "gno.land",
maxGas: 10_000_000_000,
webListenerAddr: "127.0.0.1:8888",
nodeRPCListenerAddr: "127.0.0.1:26657",
Expand Down Expand Up @@ -203,6 +205,13 @@ func (c *devCfg) RegisterFlags(fs *flag.FlagSet) {
"set node ChainID",
)

fs.StringVar(
&c.chainDomain,
"chain-domain",
defaultDevOptions.chainDomain,
"set node ChainDomain",
)

fs.BoolVar(
&c.noWatch,
"no-watch",
Expand Down
2 changes: 1 addition & 1 deletion contribs/gnodev/cmd/gnodev/setup_node.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ func setupDevNodeConfig(
balances gnoland.Balances,
pkgspath []gnodev.PackagePath,
) *gnodev.NodeConfig {
config := gnodev.DefaultNodeConfig(cfg.root)
config := gnodev.DefaultNodeConfig(cfg.root, cfg.chainDomain)

config.Logger = logger
config.Emitter = emitter
Expand Down
13 changes: 8 additions & 5 deletions contribs/gnodev/pkg/dev/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,10 @@ type NodeConfig struct {
NoReplay bool
MaxGasPerBlock int64
ChainID string
ChainDomain string
}

func DefaultNodeConfig(rootdir string) *NodeConfig {
func DefaultNodeConfig(rootdir, domain string) *NodeConfig {
tmc := gnoland.NewDefaultTMConfig(rootdir)
tmc.Consensus.SkipTimeoutCommit = false // avoid time drifting, see issue #1507
tmc.Consensus.WALDisabled = true
Expand All @@ -65,6 +66,7 @@ func DefaultNodeConfig(rootdir string) *NodeConfig {
DefaultDeployer: defaultDeployer,
BalancesList: balances,
ChainID: tmc.ChainID(),
ChainDomain: domain,
TMConfig: tmc,
SkipFailingGenesisTxs: true,
MaxGasPerBlock: 10_000_000_000,
Expand Down Expand Up @@ -487,7 +489,7 @@ func (n *Node) rebuildNode(ctx context.Context, genesis gnoland.GnoGenesisState)
}

// Setup node config
nodeConfig := newNodeConfig(n.config.TMConfig, n.config.ChainID, genesis)
nodeConfig := newNodeConfig(n.config.TMConfig, n.config.ChainID, n.config.ChainDomain, genesis)
nodeConfig.GenesisTxResultHandler = n.genesisTxResultHandler
// Speed up stdlib loading after first start (saves about 2-3 seconds on each reload).
nodeConfig.CacheStdlibLoad = true
Expand Down Expand Up @@ -566,10 +568,10 @@ func (n *Node) genesisTxResultHandler(ctx sdk.Context, tx std.Tx, res sdk.Result
return
}

func newNodeConfig(tmc *tmcfg.Config, chainid string, appstate gnoland.GnoGenesisState) *gnoland.InMemoryNodeConfig {
func newNodeConfig(tmc *tmcfg.Config, chainid, chaindomain string, appstate gnoland.GnoGenesisState) *gnoland.InMemoryNodeConfig {
// Create Mocked Identity
pv := gnoland.NewMockedPrivValidator()
genesis := gnoland.NewDefaultGenesisConfig(chainid)
genesis := gnoland.NewDefaultGenesisConfig(chainid, chaindomain)
genesis.AppState = appstate

// Add self as validator
Expand All @@ -583,10 +585,11 @@ func newNodeConfig(tmc *tmcfg.Config, chainid string, appstate gnoland.GnoGenesi
},
}

return &gnoland.InMemoryNodeConfig{
cfg := &gnoland.InMemoryNodeConfig{
PrivValidator: pv,
TMConfig: tmc,
Genesis: genesis,
VMOutput: os.Stdout,
}
return cfg
}
6 changes: 3 additions & 3 deletions contribs/gnodev/pkg/dev/node_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ func TestNewNode_NoPackages(t *testing.T) {
logger := log.NewTestingLogger(t)

// Call NewDevNode with no package should work
cfg := DefaultNodeConfig(gnoenv.RootDir())
cfg := DefaultNodeConfig(gnoenv.RootDir(), "gno.land")
cfg.Logger = logger
node, err := NewDevNode(ctx, cfg)
require.NoError(t, err)
Expand Down Expand Up @@ -66,7 +66,7 @@ func Render(_ string) string { return "foo" }
logger := log.NewTestingLogger(t)

// Call NewDevNode with no package should work
cfg := DefaultNodeConfig(gnoenv.RootDir())
cfg := DefaultNodeConfig(gnoenv.RootDir(), "gno.land")
cfg.PackagesPathList = []PackagePath{pkgpath}
cfg.Logger = logger
node, err := NewDevNode(ctx, cfg)
Expand Down Expand Up @@ -475,7 +475,7 @@ func generateTestingPackage(t *testing.T, nameFile ...string) PackagePath {
}

func createDefaultTestingNodeConfig(pkgslist ...PackagePath) *NodeConfig {
cfg := DefaultNodeConfig(gnoenv.RootDir())
cfg := DefaultNodeConfig(gnoenv.RootDir(), "gno.land")
cfg.PackagesPathList = pkgslist
return cfg
}
Expand Down
15 changes: 15 additions & 0 deletions gno.land/cmd/gnoland/testdata/addpkg_domain.txtar
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
gnoland start

# addpkg with anotherdomain.land
! gnokey maketx addpkg -pkgdir $WORK -pkgpath anotherdomain.land/r/foobar/bar -gas-fee 1000000ugnot -gas-wanted 2000000 -broadcast -chainid=tendermint_test test1
stdout 'TX HASH:'
stderr 'invalid package path'
stderr 'invalid domain: anotherdomain.land/r/foobar/bar'

# addpkg with gno.land
gnokey maketx addpkg -pkgdir $WORK -pkgpath gno.land/r/foobar/bar -gas-fee 1000000ugnot -gas-wanted 2000000 -broadcast -chainid=tendermint_test test1
stdout 'OK!'

-- bar.gno --
package bar
func Render(path string) string { return "hello" }
18 changes: 16 additions & 2 deletions gno.land/cmd/gnoland/testdata/genesis_params.txtar
Original file line number Diff line number Diff line change
@@ -1,14 +1,28 @@
# test for https://github.com/gnolang/gno/pull/3003
# Test for #3003, #2911.

gnoland start

# Query and validate official parameters.
# These parameters should ideally be tested in a txtar format to ensure that a
# default initialization of "gnoland" provides the expected default values.

# Verify the default chain domain parameter for Gno.land
gnokey query params/vm/gno.land/r/sys/params.vm.chain_domain.string
stdout 'data: "gno.land"$'
moul marked this conversation as resolved.
Show resolved Hide resolved

# Test custom parameters to confirm they return the expected values and types.

gnokey query params/vm/gno.land/r/sys/params.test.foo.string
stdout 'data: "bar"$'

gnokey query params/vm/gno.land/r/sys/params.test.foo.int64
stdout 'data: "-1337"'

gnokey query params/vm/gno.land/r/sys/params.test.foo.uint64
stdout 'data: "42"'

gnokey query params/vm/gno.land/r/sys/params.test.foo.bool
stdout 'data: true'
# XXX: bytes

# TODO: Consider adding a test case for a byte array parameter

2 changes: 1 addition & 1 deletion gno.land/genesis/genesis_params.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

## gnovm
["gno.land/r/sys/params.vm"]
# TODO: chain_domain.string = "gno.land"
chain_domain.string = "gno.land"
moul marked this conversation as resolved.
Show resolved Hide resolved
# TODO: max_gas.int64 = 100_000_000
# TODO: chain_tz.string = "UTC"
# TODO: default_storage_allowance.string = ""
Expand Down
9 changes: 8 additions & 1 deletion gno.land/pkg/gnoland/node_inmemory.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,11 @@
}

// NewDefaultGenesisConfig creates a default configuration for an in-memory node.
func NewDefaultGenesisConfig(chainid string) *bft.GenesisDoc {
func NewDefaultGenesisConfig(chainid, chaindomain string) *bft.GenesisDoc {
// custom chain domain
var domainParam Param
_ = domainParam.Parse("gno.land/r/sys/params.vm.chain_domain.string=" + chaindomain)
moul marked this conversation as resolved.
Show resolved Hide resolved

Check warning on line 43 in gno.land/pkg/gnoland/node_inmemory.go

View check run for this annotation

Codecov / codecov/patch

gno.land/pkg/gnoland/node_inmemory.go#L39-L43

Added lines #L39 - L43 were not covered by tests
return &bft.GenesisDoc{
GenesisTime: time.Now(),
ChainID: chainid,
Expand All @@ -46,6 +50,9 @@
AppState: &GnoGenesisState{
Balances: []Balance{},
Txs: []TxWithMetadata{},
Params: []Param{
domainParam,
},

Check warning on line 55 in gno.land/pkg/gnoland/node_inmemory.go

View check run for this annotation

Codecov / codecov/patch

gno.land/pkg/gnoland/node_inmemory.go#L53-L55

Added lines #L53 - L55 were not covered by tests
},
}
}
Expand Down
4 changes: 2 additions & 2 deletions gno.land/pkg/sdk/vm/gas_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ func TestAddPkgDeliverTx(t *testing.T) {
assert.True(t, res.IsOK())

// NOTE: let's try to keep this bellow 100_000 :)
assert.Equal(t, int64(92825), gasDeliver)
assert.Equal(t, int64(93825), gasDeliver)
}

// Enough gas for a failed transaction.
Expand All @@ -95,7 +95,7 @@ func TestAddPkgDeliverTxFailed(t *testing.T) {
gasDeliver := gctx.GasMeter().GasConsumed()

assert.False(t, res.IsOK())
assert.Equal(t, int64(2231), gasDeliver)
assert.Equal(t, int64(3231), gasDeliver)
}

// Not enough gas for a failed transaction.
Expand Down
26 changes: 17 additions & 9 deletions gno.land/pkg/sdk/vm/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@
bank: bank,
prmk: prmk,
}

return vmk
}

Expand Down Expand Up @@ -192,6 +193,7 @@
}

m := gno.NewMachineWithOptions(gno.MachineOptions{
// XXX: gno.land, vm.domain, other?
PkgPath: "gno.land/r/stdlibs/" + pkgPath,
// PkgPath: pkgPath, XXX why?
Store: store,
Expand Down Expand Up @@ -226,20 +228,22 @@
}

// Namespace can be either a user or crypto address.
var reNamespace = regexp.MustCompile(`^gno.land/(?:r|p)/([\.~_a-zA-Z0-9]+)`)

const sysUsersPkgParamPath = "gno.land/r/sys/params.sys.users_pkgpath.string"
var reNamespace = regexp.MustCompile(`^[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/(?:r|p)/([\.~_a-zA-Z0-9]+)`)

// checkNamespacePermission check if the user as given has correct permssion to on the given pkg path
func (vm *VMKeeper) checkNamespacePermission(ctx sdk.Context, creator crypto.Address, pkgPath string) error {
var sysUsersPkg string
vm.prmk.GetString(ctx, sysUsersPkgParamPath, &sysUsersPkg)
sysUsersPkg := vm.getSysUsersPkgParam(ctx)
if sysUsersPkg == "" {
return nil
}
chainDomain := vm.getChainDomainParam(ctx)

store := vm.getGnoTransactionStore(ctx)

if !strings.HasPrefix(pkgPath, chainDomain+"/") {
return ErrInvalidPkgPath(pkgPath) // no match
}

Check warning on line 245 in gno.land/pkg/sdk/vm/keeper.go

View check run for this annotation

Codecov / codecov/patch

gno.land/pkg/sdk/vm/keeper.go#L244-L245

Added lines #L244 - L245 were not covered by tests

match := reNamespace.FindStringSubmatch(pkgPath)
switch len(match) {
case 0:
Expand All @@ -248,9 +252,6 @@
default:
panic("invalid pattern while matching pkgpath")
}
if len(match) != 2 {
return ErrInvalidPkgPath(pkgPath)
}
username := match[1]

// if `sysUsersPkg` does not exist -> skip validation.
Expand All @@ -263,6 +264,7 @@
pkgAddr := gno.DerivePkgAddr(pkgPath)
msgCtx := stdlibs.ExecContext{
ChainID: ctx.ChainID(),
ChainDomain: chainDomain,
Height: ctx.BlockHeight(),
Timestamp: ctx.BlockTime().Unix(),
OrigCaller: creator.Bech32(),
Expand Down Expand Up @@ -320,6 +322,7 @@
memPkg := msg.Package
deposit := msg.Deposit
gnostore := vm.getGnoTransactionStore(ctx)
chainDomain := vm.getChainDomainParam(ctx)

// Validate arguments.
if creator.IsZero() {
Expand All @@ -332,6 +335,9 @@
if err := msg.Package.Validate(); err != nil {
return ErrInvalidPkgPath(err.Error())
}
if !strings.HasPrefix(pkgPath, chainDomain+"/") {
return ErrInvalidPkgPath("invalid domain: " + pkgPath)
}
if pv := gnostore.GetPackage(pkgPath, false); pv != nil {
return ErrPkgAlreadyExists("package already exists: " + pkgPath)
}
Expand Down Expand Up @@ -531,11 +537,12 @@
gnostore := vm.getGnoTransactionStore(ctx)
send := msg.Send
memPkg := msg.Package
chainDomain := vm.getChainDomainParam(ctx)

// coerce path to right one.
// the path in the message must be "" or the following path.
// this is already checked in MsgRun.ValidateBasic
memPkg.Path = "gno.land/r/" + msg.Caller.String() + "/run"
memPkg.Path = chainDomain + "/r/" + msg.Caller.String() + "/run"

// Validate arguments.
callerAcc := vm.acck.GetAccount(ctx, caller)
Expand All @@ -561,6 +568,7 @@
// Parse and run the files, construct *PV.
msgCtx := stdlibs.ExecContext{
ChainID: ctx.ChainID(),
ChainDomain: chainDomain,
Height: ctx.BlockHeight(),
Timestamp: ctx.BlockTime().Unix(),
OrigCaller: caller.Bech32(),
Expand Down
39 changes: 38 additions & 1 deletion gno.land/pkg/sdk/vm/keeper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import (
"github.com/gnolang/gno/tm2/pkg/store/types"
)

var coinsString = ugnot.ValueString(10000000)
var coinsString = ugnot.ValueString(10_000_000)

func TestVMKeeperAddPackage(t *testing.T) {
env := setupTestEnv()
Expand Down Expand Up @@ -68,6 +68,43 @@ func Echo() string { return "hello world" }
assert.Equal(t, expected, memFile.Body)
}

func TestVMKeeperAddPackage_InvalidDomain(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))
assert.True(t, env.bank.GetCoins(ctx, addr).IsEqual(std.MustParseCoins(coinsString)))

// Create test package.
files := []*gnovm.MemFile{
{
Name: "test.gno",
Body: `package test
func Echo() string {return "hello world"}`,
},
}
pkgPath := "anotherdomain.land/r/test"
msg1 := NewMsgAddPackage(addr, pkgPath, files)
assert.Nil(t, env.vmk.getGnoTransactionStore(ctx).GetPackage(pkgPath, false))

err := env.vmk.AddPackage(ctx, msg1)

assert.Error(t, err, ErrInvalidPkgPath("invalid domain: anotherdomain.land/r/test"))
assert.Nil(t, env.vmk.getGnoTransactionStore(ctx).GetPackage(pkgPath, false))

err = env.vmk.AddPackage(ctx, msg1)
assert.Error(t, err, ErrInvalidPkgPath("invalid domain: anotherdomain.land/r/test"))

// added package is formatted
store := env.vmk.getGnoTransactionStore(ctx)
memFile := store.GetMemFile("gno.land/r/test", "test.gno")
assert.Nil(t, memFile)
}

// Sending total send amount succeeds.
func TestVMKeeperOrigSend1(t *testing.T) {
env := setupTestEnv()
Expand Down
4 changes: 2 additions & 2 deletions gno.land/pkg/sdk/vm/msgs.go
Original file line number Diff line number Diff line change
Expand Up @@ -186,8 +186,8 @@ func (msg MsgRun) ValidateBasic() error {
}

// Force memPkg path to the reserved run path.
wantPath := "gno.land/r/" + msg.Caller.String() + "/run"
if path := msg.Package.Path; path != "" && path != wantPath {
wantSuffix := "/r/" + msg.Caller.String() + "/run"
if path := msg.Package.Path; path != "" && !strings.HasSuffix(path, wantSuffix) {
return ErrInvalidPkgPath(fmt.Sprintf("invalid pkgpath for MsgRun: %q", path))
}

Expand Down
Loading
Loading