diff --git a/contribs/gnodev/cmd/gnodev/main.go b/contribs/gnodev/cmd/gnodev/main.go index 2c694b608bb..c9d6487d753 100644 --- a/contribs/gnodev/cmd/gnodev/main.go +++ b/contribs/gnodev/cmd/gnodev/main.go @@ -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", @@ -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", diff --git a/contribs/gnodev/cmd/gnodev/setup_node.go b/contribs/gnodev/cmd/gnodev/setup_node.go index 578cf525751..f671a3daa1f 100644 --- a/contribs/gnodev/cmd/gnodev/setup_node.go +++ b/contribs/gnodev/cmd/gnodev/setup_node.go @@ -51,7 +51,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 diff --git a/contribs/gnodev/pkg/dev/node.go b/contribs/gnodev/pkg/dev/node.go index c3e70366fb2..c748c56661b 100644 --- a/contribs/gnodev/pkg/dev/node.go +++ b/contribs/gnodev/pkg/dev/node.go @@ -41,9 +41,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 @@ -63,6 +64,7 @@ func DefaultNodeConfig(rootdir string) *NodeConfig { DefaultDeployer: defaultDeployer, BalancesList: balances, ChainID: tmc.ChainID(), + ChainDomain: domain, TMConfig: tmc, SkipFailingGenesisTxs: true, MaxGasPerBlock: 10_000_000_000, @@ -468,7 +470,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 @@ -547,7 +549,7 @@ 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) @@ -564,10 +566,12 @@ func newNodeConfig(tmc *tmcfg.Config, chainid string, appstate gnoland.GnoGenesi }, } - return &gnoland.InMemoryNodeConfig{ + cfg := &gnoland.InMemoryNodeConfig{ PrivValidator: pv, TMConfig: tmc, Genesis: genesis, GenesisMaxVMCycles: 100_000_000, } + cfg.InitChainerConfig.ChainDomain = chaindomain + return cfg } diff --git a/contribs/gnodev/pkg/dev/node_test.go b/contribs/gnodev/pkg/dev/node_test.go index 11b0a2090d7..14b719319c2 100644 --- a/contribs/gnodev/pkg/dev/node_test.go +++ b/contribs/gnodev/pkg/dev/node_test.go @@ -34,7 +34,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) @@ -62,7 +62,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) @@ -295,7 +295,7 @@ func newTestingDevNode(t *testing.T, pkgslist ...PackagePath) (*Node, *mock.Serv emitter := &mock.ServerEmitter{} // Call NewDevNode with no package should work - cfg := DefaultNodeConfig(gnoenv.RootDir()) + cfg := DefaultNodeConfig(gnoenv.RootDir(), "gno.land") cfg.PackagesPathList = pkgslist cfg.Emitter = emitter cfg.Logger = logger diff --git a/gno.land/cmd/gnoland/start.go b/gno.land/cmd/gnoland/start.go index 21f0cb4b1a6..32f3dd37493 100644 --- a/gno.land/cmd/gnoland/start.go +++ b/gno.land/cmd/gnoland/start.go @@ -50,8 +50,8 @@ type startCfg struct { genesisRemote string // TODO: remove as part of https://github.com/gnolang/gno/issues/1952 genesisFile string chainID string + chainDomain string dataDir string - genesisMaxVMCycles int64 config string lazyInit bool @@ -116,6 +116,13 @@ func (c *startCfg) RegisterFlags(fs *flag.FlagSet) { "the ID of the chain", ) + fs.StringVar( + &c.chainDomain, + "chaindomain", + "gno.land", + "the domain of the chain for packages", + ) + fs.StringVar( &c.gnoRootDir, "gnoroot-dir", @@ -137,13 +144,6 @@ func (c *startCfg) RegisterFlags(fs *flag.FlagSet) { "replacement for '%%REMOTE%%' in genesis", ) - fs.Int64Var( - &c.genesisMaxVMCycles, - "genesis-max-vm-cycles", - 100_000_000, - "set maximum allowed vm cycles per operation. Zero means no limit.", - ) - fs.StringVar( &c.config, flagConfigFlag, diff --git a/gno.land/cmd/gnoland/testdata/addpkg_domain.txtar b/gno.land/cmd/gnoland/testdata/addpkg_domain.txtar new file mode 100644 index 00000000000..25e4fe0d3a3 --- /dev/null +++ b/gno.land/cmd/gnoland/testdata/addpkg_domain.txtar @@ -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" } diff --git a/gno.land/pkg/gnoland/app.go b/gno.land/pkg/gnoland/app.go index 2380658c6e9..6d2fb0b2aee 100644 --- a/gno.land/pkg/gnoland/app.go +++ b/gno.land/pkg/gnoland/app.go @@ -49,6 +49,7 @@ func TestAppOptions(db dbm.DB) *AppOptions { GenesisTxResultHandler: PanicOnFailingTxResultHandler, StdlibDir: filepath.Join(gnoenv.RootDir(), "gnovm", "stdlibs"), CacheStdlibLoad: true, + ChainDomain: "gno.land", }, } } @@ -88,7 +89,7 @@ func NewAppWithOptions(cfg *AppOptions) (abci.Application, error) { // Construct keepers. acctKpr := auth.NewAccountKeeper(mainKey, ProtoGnoAccount) bankKpr := bank.NewBankKeeper(acctKpr) - vmk := vm.NewVMKeeper(baseKey, mainKey, acctKpr, bankKpr, cfg.MaxCycles) + vmk := vm.NewVMKeeper(baseKey, mainKey, acctKpr, bankKpr, cfg.ChainDomain, cfg.MaxCycles) // Set InitChainer icc := cfg.InitChainerConfig @@ -223,6 +224,9 @@ type InitChainerConfig struct { // called several times. CacheStdlibLoad bool + // ChainDomain is the primary domain name for the chain and its packages. + ChainDomain string + // These fields are passed directly by NewAppWithOptions, and should not be // configurable by end-users. baseApp *sdk.BaseApp diff --git a/gno.land/pkg/integration/testing_node.go b/gno.land/pkg/integration/testing_node.go index 5e9e2272049..2c34f62ade3 100644 --- a/gno.land/pkg/integration/testing_node.go +++ b/gno.land/pkg/integration/testing_node.go @@ -90,6 +90,7 @@ func TestingMinimalNodeConfig(t TestingTS, gnoroot string) *gnoland.InMemoryNode InitChainerConfig: gnoland.InitChainerConfig{ GenesisTxResultHandler: gnoland.PanicOnFailingTxResultHandler, CacheStdlibLoad: true, + ChainDomain: "gno.land", }, } } diff --git a/gno.land/pkg/sdk/vm/common_test.go b/gno.land/pkg/sdk/vm/common_test.go index 43a8fe1fbec..c7725fd94b5 100644 --- a/gno.land/pkg/sdk/vm/common_test.go +++ b/gno.land/pkg/sdk/vm/common_test.go @@ -47,7 +47,8 @@ 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) + chainDomain := "gno.land" + vmk := NewVMKeeper(baseCapKey, iavlCapKey, acck, bank, chainDomain, 100_000_000) mcw := ms.MultiCacheWrap() vmk.Initialize(log.NewNoopLogger(), mcw) diff --git a/gno.land/pkg/sdk/vm/keeper.go b/gno.land/pkg/sdk/vm/keeper.go index 365473b3e7a..2ff162df9bf 100644 --- a/gno.land/pkg/sdk/vm/keeper.go +++ b/gno.land/pkg/sdk/vm/keeper.go @@ -63,7 +63,11 @@ type VMKeeper struct { // cached, the DeliverTx persistent state. gnoStore gno.Store - maxCycles int64 // max allowed cylces on VM executions + domain string // chain domain + maxCycles int64 // max allowed cylces on VM executions + + // internal + reNamespace *regexp.Regexp } // NewVMKeeper returns a new VMKeeper. @@ -72,6 +76,7 @@ func NewVMKeeper( iavlKey store.StoreKey, acck auth.AccountKeeper, bank bank.BankKeeper, + chainDomain string, maxCycles int64, ) *VMKeeper { // TODO: create an Options struct to avoid too many constructor parameters @@ -80,8 +85,12 @@ func NewVMKeeper( iavlKey: iavlKey, acck: acck, bank: bank, + domain: chainDomain, maxCycles: maxCycles, } + + // Namespace can be either a user or crypto address. + vmk.reNamespace = regexp.MustCompile(`^` + regexp.QuoteMeta(chainDomain) + `/(?:r|p)/([\.~_a-zA-Z0-9]+)`) return vmk } @@ -189,6 +198,7 @@ func loadStdlibPackage(pkgPath, stdlibDir string, store gno.Store) { } m := gno.NewMachineWithOptions(gno.MachineOptions{ + // XXX: gno.land, vm.domain, other? PkgPath: "gno.land/r/stdlibs/" + pkgPath, // PkgPath: pkgPath, XXX why? Output: os.Stdout, @@ -223,16 +233,13 @@ func (vm *VMKeeper) getGnoTransactionStore(ctx sdk.Context) gno.TransactionStore return txStore } -// Namespace can be either a user or crypto address. -var reNamespace = regexp.MustCompile(`^gno.land/(?: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 { - const sysUsersPkg = "gno.land/r/sys/users" + sysUsersPkg := vm.domain + "/r/sys/users" // configurable through sys/params store := vm.getGnoTransactionStore(ctx) - match := reNamespace.FindStringSubmatch(pkgPath) + match := vm.reNamespace.FindStringSubmatch(pkgPath) switch len(match) { case 0: return ErrInvalidPkgPath(pkgPath) // no match @@ -255,6 +262,7 @@ func (vm *VMKeeper) checkNamespacePermission(ctx sdk.Context, creator crypto.Add pkgAddr := gno.DerivePkgAddr(pkgPath) msgCtx := stdlibs.ExecContext{ ChainID: ctx.ChainID(), + ChainDomain: vm.domain, Height: ctx.BlockHeight(), Timestamp: ctx.BlockTime().Unix(), OrigCaller: creator.Bech32(), @@ -324,6 +332,9 @@ func (vm *VMKeeper) AddPackage(ctx sdk.Context, msg MsgAddPackage) (err error) { if err := msg.Package.Validate(); err != nil { return ErrInvalidPkgPath(err.Error()) } + if !strings.HasPrefix(pkgPath, vm.domain+"/") { + return ErrInvalidPkgPath("invalid domain: " + pkgPath) + } if pv := gnostore.GetPackage(pkgPath, false); pv != nil { return ErrPkgAlreadyExists("package already exists: " + pkgPath) } @@ -529,7 +540,7 @@ func (vm *VMKeeper) Run(ctx sdk.Context, msg MsgRun) (res string, err error) { // 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 = vm.domain + "/r/" + msg.Caller.String() + "/run" // Validate arguments. callerAcc := vm.acck.GetAccount(ctx, caller) @@ -555,6 +566,7 @@ func (vm *VMKeeper) Run(ctx sdk.Context, msg MsgRun) (res string, err error) { // Parse and run the files, construct *PV. msgCtx := stdlibs.ExecContext{ ChainID: ctx.ChainID(), + ChainDomain: vm.domain, Height: ctx.BlockHeight(), Timestamp: ctx.BlockTime().Unix(), Msg: msg, diff --git a/gno.land/pkg/sdk/vm/keeper_test.go b/gno.land/pkg/sdk/vm/keeper_test.go index 9257da2ddaf..a1c301ecc16 100644 --- a/gno.land/pkg/sdk/vm/keeper_test.go +++ b/gno.land/pkg/sdk/vm/keeper_test.go @@ -21,7 +21,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() @@ -67,6 +67,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 := []*std.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() diff --git a/gno.land/pkg/sdk/vm/msgs.go b/gno.land/pkg/sdk/vm/msgs.go index d650c23f382..2c7d7752427 100644 --- a/gno.land/pkg/sdk/vm/msgs.go +++ b/gno.land/pkg/sdk/vm/msgs.go @@ -185,8 +185,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)) } diff --git a/gnovm/cmd/gno/test.go b/gnovm/cmd/gno/test.go index 5884463a552..d8d569b3337 100644 --- a/gnovm/cmd/gno/test.go +++ b/gnovm/cmd/gno/test.go @@ -258,7 +258,7 @@ func gnoTestPkg( if gnoPkgPath == "" { // unable to read pkgPath from gno.mod, generate a random realm path io.ErrPrintfln("--- WARNING: unable to read package path from gno.mod or gno root directory; try creating a gno.mod file") - gnoPkgPath = gno.RealmPathPrefix + random.RandStr(8) + gnoPkgPath = "gno.land/r/" + random.RandStr(8) // XXX: "gno.land" hardcoded for convenience } } memPkg := gno.ReadMemPackage(pkgPath, gnoPkgPath) diff --git a/gnovm/pkg/gnolang/helpers.go b/gnovm/pkg/gnolang/helpers.go index c6f7e696ea4..dea9f120d02 100644 --- a/gnovm/pkg/gnolang/helpers.go +++ b/gnovm/pkg/gnolang/helpers.go @@ -10,29 +10,31 @@ import ( // ---------------------------------------- // Functions centralizing definitions -// RealmPathPrefix is the prefix used to identify pkgpaths which are meant to +// ReGnoRealmPath is the regex used to identify pkgpaths which are meant to // be realms and as such to have their state persisted. This is used by [IsRealmPath]. -const RealmPathPrefix = "gno.land/r/" +var ReGnoRealmPath = regexp.MustCompile(`^([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.[a-zA-Z]{2,}/r/`) // ReGnoRunPath is the path used for realms executed in maketx run. -// These are not considered realms, as an exception to the RealmPathPrefix rule. -var ReGnoRunPath = regexp.MustCompile(`^gno\.land/r/g[a-z0-9]+/run$`) +// These are not considered realms, as an exception to the ReGnoRealmPath rule. +var ReGnoRunPath = regexp.MustCompile(`^([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.[a-zA-Z]{2,}/r/g[a-z0-9]+/run$`) // IsRealmPath determines whether the given pkgpath is for a realm, and as such // should persist the global state. func IsRealmPath(pkgPath string) bool { - return strings.HasPrefix(pkgPath, RealmPathPrefix) && - // MsgRun pkgPath aren't realms + return ReGnoRealmPath.MatchString(pkgPath) && !ReGnoRunPath.MatchString(pkgPath) } // IsStdlib determines whether s is a pkgpath for a standard library. func IsStdlib(s string) bool { - // NOTE(morgan): this is likely to change in the future as we add support for - // IBC/ICS and we allow import paths to other chains. It might be good to - // (eventually) follow the same rule as Go, which is: does the first - // element of the import path contain a dot? - return !strings.HasPrefix(s, "gno.land/") + parts := strings.Split(s, "/") + if len(parts) > 0 { + // Check if the first part contains a dot + if strings.Contains(parts[0], ".") { + return false // It's a domain, so it's not part of the standard library + } + } + return true } // ---------------------------------------- diff --git a/gnovm/stdlibs/generated.go b/gnovm/stdlibs/generated.go index 4c460e220b7..67b0ef24277 100644 --- a/gnovm/stdlibs/generated.go +++ b/gnovm/stdlibs/generated.go @@ -469,6 +469,26 @@ var nativeFuncs = [...]NativeFunc{ )) }, }, + { + "std", + "GetChainDomain", + []gno.FieldTypeExpr{}, + []gno.FieldTypeExpr{ + {Name: gno.N("r0"), Type: gno.X("string")}, + }, + true, + func(m *gno.Machine) { + r0 := libs_std.GetChainDomain( + m, + ) + + m.PushValue(gno.Go2GnoValue( + m.Alloc, + m.Store, + reflect.ValueOf(&r0).Elem(), + )) + }, + }, { "std", "GetHeight", diff --git a/gnovm/stdlibs/std/context.go b/gnovm/stdlibs/std/context.go index ff5c91a14eb..77c3e047fc4 100644 --- a/gnovm/stdlibs/std/context.go +++ b/gnovm/stdlibs/std/context.go @@ -9,6 +9,7 @@ import ( type ExecContext struct { ChainID string + ChainDomain string Height int64 Timestamp int64 // seconds TimestampNano int64 // nanoseconds, only used for testing. diff --git a/gnovm/stdlibs/std/native.gno b/gnovm/stdlibs/std/native.gno index 22a16fc18d1..d70710b88b2 100644 --- a/gnovm/stdlibs/std/native.gno +++ b/gnovm/stdlibs/std/native.gno @@ -10,8 +10,9 @@ func AssertOriginCall() // injected // MsgRun. func IsOriginCall() bool // injected -func GetChainID() string // injected -func GetHeight() int64 // injected +func GetChainID() string // injected +func GetChainDomain() string // injected +func GetHeight() int64 // injected func GetOrigSend() Coins { den, amt := origSend() diff --git a/gnovm/stdlibs/std/native.go b/gnovm/stdlibs/std/native.go index f185a52f249..04e3195711c 100644 --- a/gnovm/stdlibs/std/native.go +++ b/gnovm/stdlibs/std/native.go @@ -27,6 +27,10 @@ func GetChainID(m *gno.Machine) string { return GetContext(m).ChainID } +func GetChainDomain(m *gno.Machine) string { + return GetContext(m).ChainDomain +} + func GetHeight(m *gno.Machine) int64 { return GetContext(m).Height } diff --git a/gnovm/tests/file.go b/gnovm/tests/file.go index f6bd789f1bf..15bec958bd3 100644 --- a/gnovm/tests/file.go +++ b/gnovm/tests/file.go @@ -58,6 +58,7 @@ func TestContext(pkgPath string, send std.Coins) *teststd.TestExecContext { banker := newTestBanker(pkgAddr.Bech32(), pkgCoins) ctx := stdlibs.ExecContext{ ChainID: "dev", + ChainDomain: "tests.gno.land", Height: 123, Timestamp: 1234567890, Msg: nil, diff --git a/gnovm/tests/files/std5_stdlibs.gno b/gnovm/tests/files/std5_stdlibs.gno index 4afa09da8d3..061df0d6ac0 100644 --- a/gnovm/tests/files/std5_stdlibs.gno +++ b/gnovm/tests/files/std5_stdlibs.gno @@ -13,10 +13,10 @@ func main() { // Stacktrace: // panic: frame not found -// callerAt(n) +// callerAt(n) // gonative:std.callerAt // std.GetCallerAt(2) -// std/native.gno:44 +// std/native.gno:45 // main() // main/files/std5_stdlibs.gno:10 diff --git a/gnovm/tests/files/std8_stdlibs.gno b/gnovm/tests/files/std8_stdlibs.gno index ab5e15bd618..b59a7a59a84 100644 --- a/gnovm/tests/files/std8_stdlibs.gno +++ b/gnovm/tests/files/std8_stdlibs.gno @@ -23,10 +23,10 @@ func main() { // Stacktrace: // panic: frame not found -// callerAt(n) +// callerAt(n) // gonative:std.callerAt // std.GetCallerAt(4) -// std/native.gno:44 +// std/native.gno:45 // fn() // main/files/std8_stdlibs.gno:16 // testutils.WrapCall(inner) diff --git a/gnovm/tests/files/zrealm_natbind1_stdlibs.gno b/gnovm/tests/files/zrealm_natbind1_stdlibs.gno new file mode 100644 index 00000000000..f44b6ab4fcf --- /dev/null +++ b/gnovm/tests/files/zrealm_natbind1_stdlibs.gno @@ -0,0 +1,16 @@ +// PKGPATH: gno.land/r/test +package test + +import ( + "std" +) + +func main() { + println(std.GetChainDomain()) +} + +// Output: +// tests.gno.land + +// Realm: +// switchrealm["gno.land/r/test"] diff --git a/misc/genstd/Makefile b/misc/genstd/Makefile new file mode 100644 index 00000000000..2022a6cc2b4 --- /dev/null +++ b/misc/genstd/Makefile @@ -0,0 +1,6 @@ +run: + cd ../../gnovm/stdlibs && go run ../../misc/genstd + cd ../../gnovm/tests/stdlibs && go run ../../../misc/genstd + +test: + go test -v . diff --git a/tm2/pkg/std/memfile.go b/tm2/pkg/std/memfile.go index 01bc18c1487..539f102a47c 100644 --- a/tm2/pkg/std/memfile.go +++ b/tm2/pkg/std/memfile.go @@ -41,7 +41,7 @@ const pathLengthLimit = 256 var ( rePkgName = regexp.MustCompile(`^[a-z][a-z0-9_]*$`) - rePkgOrRlmPath = regexp.MustCompile(`^gno\.land\/(?:p|r)(?:\/_?[a-z]+[a-z0-9_]*)+$`) + rePkgOrRlmPath = regexp.MustCompile(`^([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.[a-zA-Z]{2,}\/(?:p|r)(?:\/_?[a-z]+[a-z0-9_]*)+$`) reFileName = regexp.MustCompile(`^([a-zA-Z0-9_]*\.[a-z0-9_\.]*|LICENSE|README)$`) ) diff --git a/tm2/pkg/std/memfile_test.go b/tm2/pkg/std/memfile_test.go index 3e1fb49e131..71b0dad8423 100644 --- a/tm2/pkg/std/memfile_test.go +++ b/tm2/pkg/std/memfile_test.go @@ -158,13 +158,13 @@ func TestMemPackage_Validate(t *testing.T) { "invalid package/realm path", }, { - "Invalid path", + "Custom domain", &MemPackage{ Name: "hey", Path: "github.com/p/path/path", Files: []*MemFile{{Name: "a.gno"}}, }, - "invalid package/realm path", + "", }, { "Special character", diff --git a/tm2/pkg/telemetry/config/config.go b/tm2/pkg/telemetry/config/config.go index a9aa24d7848..47fc5666342 100644 --- a/tm2/pkg/telemetry/config/config.go +++ b/tm2/pkg/telemetry/config/config.go @@ -19,9 +19,9 @@ type Config struct { func DefaultTelemetryConfig() *Config { return &Config{ MetricsEnabled: false, - MeterName: "gno.land", - ServiceName: "gno.land", - ServiceInstanceID: "gno-node-1", + MeterName: "tm2", + ServiceName: "tm2", + ServiceInstanceID: "tm2-node-1", ExporterEndpoint: "", } }