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: restrict sending gnot by default #2667

Closed
wants to merge 16 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 4 additions & 0 deletions gno.land/cmd/gnoland/dylan/send.txtar
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
gnoland start --ugnot-locked

! gnokey maketx send -send "9999999ugnot" -to g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5 -gas-fee 1ugnot -gas-wanted 10000000 -broadcast -chainid=tendermint_test test1
stderr 'account is locked'
Copy link
Member

@moul moul Aug 29, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"ugnot transfer is locked for this account or globally" (the account it not locked)

17 changes: 16 additions & 1 deletion gno.land/cmd/gnoland/genesis_generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
blockMaxDataBytes int64
blockMaxGas int64
blockTimeIota int64
ugnotUnrestricted bool
}

// newGenerateCmd creates the genesis generate subcommand
Expand Down Expand Up @@ -89,6 +90,13 @@
types.BlockTimeIotaMS,
"the block time iota (in ms)",
)

fs.BoolVar(
&c.ugnotUnrestricted,
"ugnot-unrestricted",
false,
"allow sending of ugnot from locked accounts",
)
}

func execGenerate(cfg *generateCfg, io commands.IO) error {
Expand Down Expand Up @@ -125,6 +133,10 @@
genesis.ConsensusParams.Block.TimeIotaMS = cfg.blockTimeIota
}

if cfg.ugnotUnrestricted {
genesis.ConsensusParams.Account.RestrictedDenoms = []string{}

Check warning on line 137 in gno.land/cmd/gnoland/genesis_generate.go

View check run for this annotation

Codecov / codecov/patch

gno.land/cmd/gnoland/genesis_generate.go#L137

Added line #L137 was not covered by tests
}

// Validate the genesis
if validateErr := genesis.ValidateAndComplete(); validateErr != nil {
return fmt.Errorf("unable to validate genesis, %w", validateErr)
Expand All @@ -145,9 +157,12 @@

// getDefaultGenesis returns the default genesis config
func getDefaultGenesis() *types.GenesisDoc {
return &types.GenesisDoc{
genDoc := &types.GenesisDoc{
GenesisTime: time.Now(),
ChainID: defaultChainID,
ConsensusParams: types.DefaultConsensusParams(),
}

genDoc.ConsensusParams.Account.RestrictedDenoms = []string{"ugnot"}
return genDoc
}
41 changes: 30 additions & 11 deletions gno.land/cmd/gnoland/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,17 +43,18 @@
`, "'", "`")

type startCfg struct {
gnoRootDir string // TODO: remove as part of https://github.com/gnolang/gno/issues/1952
skipFailingGenesisTxs bool // TODO: remove as part of https://github.com/gnolang/gno/issues/1952
genesisBalancesFile string // TODO: remove as part of https://github.com/gnolang/gno/issues/1952
genesisTxsFile string // TODO: remove as part of https://github.com/gnolang/gno/issues/1952
genesisRemote string // TODO: remove as part of https://github.com/gnolang/gno/issues/1952
genesisFile string
chainID string
dataDir string
genesisMaxVMCycles int64
config string
lazyInit bool
gnoRootDir string // TODO: remove as part of https://github.com/gnolang/gno/issues/1952
skipFailingGenesisTxs bool // TODO: remove as part of https://github.com/gnolang/gno/issues/1952
genesisBalancesFile string // TODO: remove as part of https://github.com/gnolang/gno/issues/1952
genesisTxsFile string // TODO: remove as part of https://github.com/gnolang/gno/issues/1952
genesisRemote string // TODO: remove as part of https://github.com/gnolang/gno/issues/1952
genesisFile string
chainID string
dataDir string
genesisMaxVMCycles int64
config string
lazyInit bool
disableUGNOTRestrictions bool

logLevel string
logFormat string
Expand Down Expand Up @@ -171,6 +172,13 @@
false,
"flag indicating if lazy init is enabled. Generates the node secrets, configuration, and genesis.json",
)

fs.BoolVar(
&c.disableUGNOTRestrictions,
"disable-ugnot-restrictions",
false,
"if true and genesis file is not provided, disables ugnot sending restrictions",
)
}

func execStart(ctx context.Context, c *startCfg, io commands.IO) error {
Expand Down Expand Up @@ -228,6 +236,10 @@
if err := lazyInitGenesis(io, c, genesisPath, privateKey.GetPubKey()); err != nil {
return fmt.Errorf("unable to initialize genesis.json, %w", err)
}
} else if c.disableUGNOTRestrictions {

Check warning on line 239 in gno.land/cmd/gnoland/start.go

View check run for this annotation

Codecov / codecov/patch

gno.land/cmd/gnoland/start.go#L239

Added line #L239 was not covered by tests
// Clearly return an error in this case so the user isn't left wondering why
// the restrictions weren't disabled.
return errors.New("cannot disable ugnot restrictions when genesis file is provided")

Check warning on line 242 in gno.land/cmd/gnoland/start.go

View check run for this annotation

Codecov / codecov/patch

gno.land/cmd/gnoland/start.go#L242

Added line #L242 was not covered by tests
}

// Initialize telemetry
Expand Down Expand Up @@ -385,6 +397,13 @@
MaxGas: 100_000_000, // 100M gas
TimeIotaMS: 100, // 100ms
},
Account: &abci.AccountParams{
RestrictedDenoms: []string{"ugnot"},
},
}

if c.disableUGNOTRestrictions {
gen.ConsensusParams.Account.RestrictedDenoms = nil

Check warning on line 406 in gno.land/cmd/gnoland/start.go

View check run for this annotation

Codecov / codecov/patch

gno.land/cmd/gnoland/start.go#L406

Added line #L406 was not covered by tests
}

gen.Validators = []bft.GenesisValidator{
Expand Down
20 changes: 19 additions & 1 deletion gno.land/pkg/gnoland/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"log/slog"
"path/filepath"
"strconv"
"strings"

"github.com/gnolang/gno/gno.land/pkg/sdk/vm"
"github.com/gnolang/gno/gnovm/pkg/gnoenv"
Expand All @@ -28,6 +29,8 @@
"github.com/gnolang/gno/tm2/pkg/db/memdb"
)

var restrictedDenomsKey = []byte("restricted_denoms")

type AppOptions struct {
DB dbm.DB
// `gnoRootDir` should point to the local location of the gno repository.
Expand Down Expand Up @@ -89,12 +92,18 @@
acctKpr := auth.NewAccountKeeper(mainKey, ProtoGnoAccount)
bankKpr := bank.NewBankKeeper(acctKpr)

// If this isn't genesis, then there might be restricted denominations in the database.
if rawDenoms := cfg.DB.Get(restrictedDenomsKey); len(rawDenoms) != 0 {
denomList := strings.Split(string(rawDenoms), ",")
bankKpr.SetRestrictedDenoms(denomList...)

Check warning on line 98 in gno.land/pkg/gnoland/app.go

View check run for this annotation

Codecov / codecov/patch

gno.land/pkg/gnoland/app.go#L96-L98

Added lines #L96 - L98 were not covered by tests
}

// XXX: Embed this ?
stdlibsDir := filepath.Join(cfg.GnoRootDir, "gnovm", "stdlibs")
vmk := vm.NewVMKeeper(baseKey, mainKey, acctKpr, bankKpr, stdlibsDir, cfg.MaxCycles)

// Set InitChainer
baseApp.SetInitChainer(InitChainer(baseApp, acctKpr, bankKpr, cfg.GenesisTxHandler))
baseApp.SetInitChainer(InitChainer(baseApp, acctKpr, bankKpr, cfg.GenesisTxHandler, cfg.DB))

Check warning on line 106 in gno.land/pkg/gnoland/app.go

View check run for this annotation

Codecov / codecov/patch

gno.land/pkg/gnoland/app.go#L106

Added line #L106 was not covered by tests

// Set AnteHandler
authOptions := auth.AnteOptions{
Expand Down Expand Up @@ -191,6 +200,7 @@
acctKpr auth.AccountKeeperI,
bankKpr bank.BankKeeperI,
resHandler GenesisTxHandler,
db dbm.DB,
) func(sdk.Context, abci.RequestInitChain) abci.ResponseInitChain {
return func(ctx sdk.Context, req abci.RequestInitChain) abci.ResponseInitChain {
txResponses := []abci.ResponseDeliverTx{}
Expand Down Expand Up @@ -229,6 +239,14 @@

resHandler(ctx, tx, res)
}

if denoms := req.ConsensusParams.Account.RestrictedDenoms; len(denoms) != 0 {

Check warning on line 243 in gno.land/pkg/gnoland/app.go

View check run for this annotation

Codecov / codecov/patch

gno.land/pkg/gnoland/app.go#L243

Added line #L243 was not covered by tests
// Set the bank's restricted denominations AFTER executing any genesis transactions.
bankKpr.SetRestrictedDenoms(denoms...)

Check warning on line 245 in gno.land/pkg/gnoland/app.go

View check run for this annotation

Codecov / codecov/patch

gno.land/pkg/gnoland/app.go#L245

Added line #L245 was not covered by tests

// Put the restricted denominations in the database so they are available on restart.
db.SetSync(restrictedDenomsKey, []byte(strings.Join(denoms, ",")))

Check warning on line 248 in gno.land/pkg/gnoland/app.go

View check run for this annotation

Codecov / codecov/patch

gno.land/pkg/gnoland/app.go#L248

Added line #L248 was not covered by tests
}
}

// Done!
Expand Down
5 changes: 5 additions & 0 deletions gno.land/pkg/integration/testing_integration.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"log/slog"
"os"
"path/filepath"
"slices"
"strconv"
"strings"
"testing"
Expand Down Expand Up @@ -183,6 +184,10 @@

// Generate config and node
cfg := TestingMinimalNodeConfig(t, gnoRootDir)
if slices.Contains[[]string, string](args, "--ugnot-locked") {
cfg.Genesis.ConsensusParams.Account.RestrictedDenoms = []string{"ugnot"}

Check warning on line 188 in gno.land/pkg/integration/testing_integration.go

View check run for this annotation

Codecov / codecov/patch

gno.land/pkg/integration/testing_integration.go#L188

Added line #L188 was not covered by tests
}

genesis := ts.Value(envKeyGenesis).(*gnoland.GnoGenesisState)
genesis.Txs = append(pkgsTxs, genesis.Txs...)

Expand Down
1 change: 1 addition & 0 deletions gno.land/pkg/integration/testing_node.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ func DefaultTestingGenesisConfig(t TestingTS, gnoroot string, self crypto.PubKey
MaxGas: 100_000_000, // 100M gas
TimeIotaMS: 100, // 100ms
},
Account: new(abci.AccountParams),
},
Validators: []bft.GenesisValidator{
{
Expand Down
5 changes: 5 additions & 0 deletions tm2/pkg/bft/abci/types/abci.proto
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ message StringError {
message ConsensusParams {
BlockParams block = 1 [json_name = "Block"];
ValidatorParams validator = 2 [json_name = "Validator"];
AccountParams account = 3 [json_name = "Account"];
}

message BlockParams {
Expand All @@ -177,6 +178,10 @@ message ValidatorUpdate {
sint64 power = 3 [json_name = "Power"];
}

message AccountParams {
repeated string restricted_denoms = 1 [json_name = "RestrictedDenoms"];
}

message LastCommitInfo {
sint32 round = 1 [json_name = "Round"];
repeated VoteInfo votes = 2 [json_name = "Votes"];
Expand Down
5 changes: 5 additions & 0 deletions tm2/pkg/bft/abci/types/params.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,14 @@ func (params ConsensusParams) Update(params2 ConsensusParams) ConsensusParams {
if params2.Block != nil {
res.Block = amino.DeepCopy(params2.Block).(*BlockParams)
}

if params2.Validator != nil {
res.Validator = amino.DeepCopy(params2.Validator).(*ValidatorParams)
}

if params2.Account != nil {
res.Account = amino.DeepCopy(params2.Account).(*AccountParams)
}

return res
}
5 changes: 5 additions & 0 deletions tm2/pkg/bft/abci/types/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,7 @@ func (err EventString) Event() string {
type ConsensusParams struct {
Block *BlockParams
Validator *ValidatorParams
Account *AccountParams
}

type BlockParams struct {
Expand All @@ -265,6 +266,10 @@ type ValidatorUpdate struct {
Power int64
}

type AccountParams struct {
RestrictedDenoms []string
}

type LastCommitInfo struct {
Round int32
Votes []VoteInfo
Expand Down
11 changes: 6 additions & 5 deletions tm2/pkg/bft/types/params.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,9 @@ var validatorPubKeyTypeURLs = map[string]struct{}{

func DefaultConsensusParams() abci.ConsensusParams {
return abci.ConsensusParams{
DefaultBlockParams(),
DefaultValidatorParams(),
Block: DefaultBlockParams(),
Validator: DefaultValidatorParams(),
Account: &abci.AccountParams{},
}
}

Expand All @@ -51,9 +52,9 @@ func DefaultBlockParams() *abci.BlockParams {
}

func DefaultValidatorParams() *abci.ValidatorParams {
return &abci.ValidatorParams{[]string{
amino.GetTypeURL(ed25519.PubKeyEd25519{}),
}}
return &abci.ValidatorParams{
PubKeyTypeURLs: []string{amino.GetTypeURL(ed25519.PubKeyEd25519{})},
}
}

func ValidateConsensusParams(params abci.ConsensusParams) error {
Expand Down
4 changes: 3 additions & 1 deletion tm2/pkg/sdk/auth/ante.go
Original file line number Diff line number Diff line change
Expand Up @@ -363,7 +363,9 @@ func DeductFees(bank BankKeeperI, ctx sdk.Context, acc std.Account, fees std.Coi
))
}

err := bank.SendCoins(ctx, acc.GetAddress(), FeeCollectorAddress(), fees)
// Sending coins is unrestricted to pay for gas fees, meaning locked accounts can only
// send restricted coins to pay for gas.
err := bank.SendCoinsUnrestricted(ctx, acc.GetAddress(), FeeCollectorAddress(), fees)
if err != nil {
return abciResult(err)
}
Expand Down
4 changes: 4 additions & 0 deletions tm2/pkg/sdk/auth/test_common.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,3 +84,7 @@ func (bank DummyBankKeeper) SendCoins(ctx sdk.Context, fromAddr crypto.Address,

return nil
}

func (bank DummyBankKeeper) SendCoinsUnrestricted(ctx sdk.Context, fromAddr crypto.Address, toAddr crypto.Address, amt std.Coins) error {
return bank.SendCoins(ctx, fromAddr, toAddr, amt)
}
1 change: 1 addition & 0 deletions tm2/pkg/sdk/auth/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,5 @@ var _ AccountKeeperI = AccountKeeper{}
// Limited interface only needed for auth.
type BankKeeperI interface {
SendCoins(ctx sdk.Context, fromAddr crypto.Address, toAddr crypto.Address, amt std.Coins) error
SendCoinsUnrestricted(ctx sdk.Context, fromAddr crypto.Address, toAddr crypto.Address, amt std.Coins) error
}
Loading
Loading