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: lock token transfer and parameter module #3176

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

piux2
Copy link
Contributor

@piux2 piux2 commented Nov 21, 2024

Context for Locking Token Transfer

This feature allows us to lock token transfers, except for paying gas fees to add a package or call a contract.
The restriction will be unlocked through GovDAO voting on a proposal.

We also want a few whitelisted, unrestricted accounts to vote on the proposal since a separate fee is required to initiate and vote on proposals.

This implementation manages the lock and unlock settings in r/sys/params, where we change the chain’s parameters.
Calling lock or unlock will automatically submit a proposal to GovDAO. Once GovDAO votes and approves the proposal, the token
transfer restriction will be removed instantly.

All changes to parameters specified in r/sys/params must go through GovDAO voting.

Here are some implementation details

  1. Set a flag in base account to indicate if the account is restricted for token transfer.
  2. Add a restricted Denom list in the bank module
  3. System contract to handle
  4. Verify realm access from r/sys/params for change chain parameters.
  5. Integration test to simulate the end to end unlock process
  6. Load params from genesis and verify the values

Main Idea Behind the Alternative Approach To implement parameter module ( Discussion)

  1. The parameter module is designed to store chain and Cosmos SDK modules' parameters. It is not an arbitrary key-value storage system for Gno contracts.
  2. Parameters are abstracted within each module's genesis state.
  3. Parameters can only be modified through:
    • The genesis state.
    • gno.land/r/sys/gov/dao
  4. The parameter module is intended for managing parameters of other modules, not specifically for the GnoVM.
  5. The parameter module and genesis state support structures, not just primitive types, as parameters.
  6. The ParameterKey prefix is defined in the module's prefix key. This must be registered with the parameter module to prevent conflicts in the parameter store's keyspace.

image

image

Todo: update other params...

Contributors' checklist...
  • Added new tests,
  • Provided an example (e.g. screenshot) to aid review
  • not needed
  • No breaking changes were made,
  • Added references to related issues and PRs
  • Provided any useful hints for running manual tests

@github-actions github-actions bot added 🧾 package/realm Tag used for new Realms or Packages. 📦 🤖 gnovm Issues or PRs gnovm related 📦 🌐 tendermint v2 Issues or PRs tm2 related 📦 ⛰️ gno.land Issues or PRs gno.land package related labels Nov 21, 2024
@Kouteki Kouteki added the in focus Core team is prioritizing this work label Nov 21, 2024
@zivkovicmilos zivkovicmilos added this to the 🚀 Mainnet launch milestone Nov 21, 2024
@Kouteki Kouteki linked an issue Nov 25, 2024 that may be closed by this pull request
Copy link
Member

@zivkovicmilos zivkovicmilos left a comment

Choose a reason for hiding this comment

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

Thank you for pushing this out 🙏

I think the direction is good, but I'd love to discuss more about some implementation details. I'm mostly worried about us having a temporary implementation detail as a permanent state of a core object (check comments).

Pinging @moul to give a review as well.

Please check the CI 🙏

"gno.land/r/gov/dao/bridge"
)

const lockSendKey = "lockSend.bool"
Copy link
Member

Choose a reason for hiding this comment

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

Nitpick: you can group these in a const block

id := ProposeUnlockSend()
urequire.PanicsWithMessage(
t,
simpledao.ErrProposalNotAccepted.Error(),
Copy link
Member

Choose a reason for hiding this comment

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

Do you think we should standardize errors like these, to avoid having to import simpledao?
It would mean that the dao package would need to know about specific implementation details like errors, so I'm not sure if this is the way to go

cc @moul

stdout '(0 uint64)'


## vote unlock proposal with unrestricted account test1
Copy link
Member

Choose a reason for hiding this comment

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

Which accounts are going to be unrestricted in the initial version of the chain?

for _, param := range state.Params {
param.register(ctx, cfg.paramsKpr)
}
// The account keeper's initial genesis state must be set after genesis areccounts are created.
Copy link
Member

Choose a reason for hiding this comment

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

Typo here, accounts

{key: "foo", kind: "bool", value: true},
{key: "foo", kind: "bytes", value: []byte{0x48, 0x69, 0x21}},
},
/*
Copy link
Member

Choose a reason for hiding this comment

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

Leftover?

// Otherwise, we cannot verify the unrestricted address in the genesis state.

for _, addr := range data.Params.UnrestrictedAddrs {
acc := ak.GetAccount(ctx, addr)
Copy link
Member

Choose a reason for hiding this comment

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

There is tight coupling here. The account keeper must have a previously initialized account in order for us to modify it in another func

Can't we keep the store of unrestricted accounts somewhere, instead of keeping the Unrestricted information on the account itself?

My biggest concern is that we're coupling temporary logic (account balance transfer locks) into a structure that will be encoded and saved permanently to disk. Every time we use the account, even in 10 years, we will have to keep track of its "restricted state".

This is why I'm suggesting we go with an approach that isn't so coupled

@@ -67,3 +70,41 @@ func (p Params) String() string {
sb.WriteString(fmt.Sprintf("SigVerifyCostSecp256k1: %d\n", p.SigVerifyCostSecp256k1))
return sb.String()
}

func (p Params) Validate() error {
if p.TxSigLimit == 0 {
Copy link
Member

Choose a reason for hiding this comment

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

All of these should verify <= 0, not just ==

ok, err := ak.paramk.GetParams(ctx, ModuleName, "p", params)

if !ok {
panic("params key " + ModuleName + " does not exist")
Copy link
Member

Choose a reason for hiding this comment

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

Why panic?

TxSizeCostPerByte int64 `json:"tx_size_cost_per_byte" yaml:"tx_size_cost_per_byte"`
SigVerifyCostED25519 int64 `json:"sig_verify_cost_ed25519" yaml:"sig_verify_cost_ed25519"`
SigVerifyCostSecp256k1 int64 `json:"sig_verify_cost_secp256k1" yaml:"sig_verify_cost_secp256k1"`
UnrestrictedAddrs []crypto.Address `json:"unrestricted_addrs" yaml:"unrestricted_addrs"`
Copy link
Member

Choose a reason for hiding this comment

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

Just a note we don't initialize this new field in DefaultParams

TxSizeCostPerByte int64 `json:"tx_size_cost_per_byte" yaml:"tx_size_cost_per_byte"`
SigVerifyCostED25519 int64 `json:"sig_verify_cost_ed25519" yaml:"sig_verify_cost_ed25519"`
SigVerifyCostSecp256k1 int64 `json:"sig_verify_cost_secp256k1" yaml:"sig_verify_cost_secp256k1"`
UnrestrictedAddrs []crypto.Address `json:"unrestricted_addrs" yaml:"unrestricted_addrs"`
}

// NewParams creates a new Params object
Copy link
Member

Choose a reason for hiding this comment

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

This function is unused

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in focus Core team is prioritizing this work 📦 🌐 tendermint v2 Issues or PRs tm2 related 📦 ⛰️ gno.land Issues or PRs gno.land package related 📦 🤖 gnovm Issues or PRs gnovm related 🧾 package/realm Tag used for new Realms or Packages.
Projects
Status: In Review
Development

Successfully merging this pull request may close these issues.

Global GNOT lock
3 participants