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 46 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
2279644
feat: lock token transfer and parameter module
piux2 Nov 21, 2024
c293926
chores: ufmt
piux2 Nov 21, 2024
3591b39
addressed comments
piux2 Dec 9, 2024
c84c819
merge master
piux2 Dec 27, 2024
5cecf36
merge master
piux2 Dec 27, 2024
599e64a
fmt
piux2 Dec 27, 2024
b7f317a
fix test
piux2 Dec 27, 2024
41d1633
lint
piux2 Dec 27, 2024
9fd24d5
fix test
piux2 Dec 27, 2024
9f05d03
gno tidy
piux2 Dec 27, 2024
692bc1d
addressed review comments
piux2 Jan 20, 2025
df5cc2f
fix bugs
piux2 Jan 21, 2025
41378f5
lint
piux2 Jan 21, 2025
f95e945
fix bugs and clean up
piux2 Jan 21, 2025
ad9eb84
Merged master into this branch
piux2 Jan 22, 2025
529bd97
fix test
piux2 Jan 22, 2025
bd27b2e
fix integration test
piux2 Jan 22, 2025
696ab02
refactor the unlocksend proposal
piux2 Jan 22, 2025
52cdd68
remove unnecessary check
piux2 Jan 23, 2025
ba1c49e
refactor gno account attributes
piux2 Jan 25, 2025
0313890
added tests
piux2 Jan 25, 2025
625fa5b
fix test
piux2 Jan 25, 2025
842c80d
cleaned up interfaces and addressed empty genesis state
piux2 Jan 30, 2025
c3c64e1
added setPrefixedXXX, fixed keeper.initGenesis
piux2 Feb 6, 2025
8f93911
updated prefix setters
piux2 Feb 7, 2025
304d56a
refactor SDKParam
piux2 Feb 8, 2025
7c111e8
more tests and clean up
piux2 Feb 10, 2025
6bc4602
merged master to this branch
piux2 Feb 10, 2025
1f6ce70
lint
piux2 Feb 10, 2025
d7aaf22
fix test
piux2 Feb 10, 2025
5f67b6d
fixed merge
piux2 Feb 10, 2025
5812fcc
merged the lastest master
piux2 Feb 10, 2025
d282741
fix tests
piux2 Feb 10, 2025
0459dd8
Merge remote-tracking branch 'origin/master' into feat_lock_transfer
piux2 Feb 10, 2025
ab4a676
remove iavl/testdata
piux2 Feb 10, 2025
6c9da8b
Merge branch 'master' into feat_lock_transfer
moul Feb 11, 2025
fb627fa
updated prefix, validation and tests
piux2 Feb 13, 2025
76fb5ee
merge the Master in this branch
piux2 Feb 13, 2025
cf36f63
Merge branch 'feat_lock_transfer' of https://github.com/piux2/gno int…
piux2 Feb 13, 2025
3002f65
fix test
piux2 Feb 13, 2025
cf9fe49
fix the test
piux2 Feb 14, 2025
bfe737f
lint
piux2 Feb 14, 2025
d98a5d2
fix test
piux2 Feb 14, 2025
8f6b1a8
more testing coverage
piux2 Feb 14, 2025
1c653cc
fix
piux2 Feb 14, 2025
b3ee19f
Merge remote-tracking branch 'origin/master' into feat_lock_transfer
piux2 Feb 14, 2025
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
1 change: 0 additions & 1 deletion contribs/gnodev/pkg/dev/node_state.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,6 @@ func (n *Node) ExportStateAsGenesis(ctx context.Context) (*bft.GenesisDoc, error

// Get current blockstore state
doc := *n.Node.GenesisDoc() // copy doc

genState := doc.AppState.(gnoland.GnoGenesisState)
genState.Balances = n.config.BalancesList
genState.Txs = state
moul marked this conversation as resolved.
Show resolved Hide resolved
Expand Down
31 changes: 31 additions & 0 deletions examples/gno.land/r/sys/params/params.gno
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package params

import (
"std"
prms "sys/params"
piux2 marked this conversation as resolved.
Show resolved Hide resolved

"gno.land/p/demo/dao"
"gno.land/r/gov/dao/bridge"
Expand All @@ -44,6 +45,26 @@ func NewBytesPropExecutor(key string, value []byte) dao.Executor {
return newPropExecutor(key, func() { std.SetParamBytes(key, value) })
}

func NewPrefixedStringPropExecutor(keeperPrefix, key string, value string) dao.Executor {
return newPropExecutor(key, func() { prms.SetPrefixedString(keeperPrefix, key, value) })
}

func NewPrefixedInt64PropExecutor(keeperPrefix, key string, value int64) dao.Executor {
return newPropExecutor(key, func() { prms.SetPrefixedInt64(keeperPrefix, key, value) })
}

func NewPrefixedUint64PropExecutor(keeperPrefix, key string, value uint64) dao.Executor {
return newPropExecutor(key, func() { prms.SetPrefixedUint64(keeperPrefix, key, value) })
}

func NewPrefixedBoolPropExecutor(keeperPrefix, key string, value bool) dao.Executor {
return newPropExecutor(key, func() { prms.SetPrefixedBool(keeperPrefix, key, value) })
}

func NewPrefixedBytesPropExecutor(keeperPrefix, key string, value []byte) dao.Executor {
return newPropExecutor(keeperPrefix+key, func() { prms.SetPrefixedBytes(keeperPrefix, key, value) })
}

func newPropExecutor(key string, fn func()) dao.Executor {
callback := func() error {
fn()
Expand All @@ -52,3 +73,13 @@ func newPropExecutor(key string, fn func()) dao.Executor {
}
return bridge.GovDAO().NewGovDAOExecutor(callback)
}
func propose(exec dao.Executor, title, desc string) uint64 {
// The executor's callback function is executed only after the proposal has been voted on
// and approved by the GovDAO.
prop := dao.ProposalRequest{
Title: title,
Description: desc,
Executor: exec,
}
return bridge.GovDAO().Propose(prop)
}
18 changes: 18 additions & 0 deletions examples/gno.land/r/sys/params/unlock.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package params

const (
bankKeeperPrefix = "bank"
lockTransferKey = "lockTransfer.string"
UnlockTransferTitle = "Proposal to unlock the transfer of ugnot."
LockTransferTitle = "Proposal to lock the transfer of ugnot."
)

func ProposeUnlockTransfer() uint64 {
exe := NewPrefixedStringPropExecutor(bankKeeperPrefix, lockTransferKey, "")
return propose(exe, UnlockTransferTitle, "")
}

func ProposeLockTransfer() uint64 {
exe := NewPrefixedStringPropExecutor(bankKeeperPrefix, lockTransferKey, "ugnot")
return propose(exe, LockTransferTitle, "")
}
52 changes: 52 additions & 0 deletions examples/gno.land/r/sys/params/unlock_test.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package params

import (
"testing"

"gno.land/p/demo/dao"
"gno.land/p/demo/simpledao"
"gno.land/p/demo/urequire"
"gno.land/r/gov/dao/bridge"
)

func TestProUnlockTransfer(t *testing.T) {
govdao := bridge.GovDAO()
id := ProposeUnlockTransfer()
p, err := govdao.GetPropStore().ProposalByID(id)
urequire.NoError(t, err)
urequire.Equal(t, UnlockTransferTitle, p.Title())
}

func TestFailUnlockTransfer(t *testing.T) {
govdao := bridge.GovDAO()
id := ProposeUnlockTransfer()
urequire.PanicsWithMessage(
t,
simpledao.ErrProposalNotAccepted.Error(),
zivkovicmilos marked this conversation as resolved.
Show resolved Hide resolved
func() {
govdao.ExecuteProposal(id)
},
)
}

func TestExeUnlockTransfer(t *testing.T) {
govdao := bridge.GovDAO()
id := ProposeUnlockTransfer()
p, err := govdao.GetPropStore().ProposalByID(id)
urequire.NoError(t, err)
urequire.True(t, dao.Active == p.Status())

govdao.VoteOnProposal(id, dao.YesVote)

urequire.True(t, dao.Accepted == p.Status())

urequire.NotPanics(
t,
func() {
govdao.ExecuteProposal(id)
},
)

urequire.True(t, dao.ExecutionSuccessful == p.Status())

}
20 changes: 12 additions & 8 deletions gno.land/genesis/genesis_params.toml
Original file line number Diff line number Diff line change
@@ -1,27 +1,31 @@

## gno.land
["gno.land/r/sys/params.sys"]
users_pkgpath.string = "gno.land/r/sys/users" # if empty, no namespace support.

# NOTE: These are module parameters actually
#["gno.land/r/sys/params.sys"]
# users_pkgpath.string = "gno.land/r/sys/users" # if empty, no namespace support.
# TODO: validators_pkgpath.string = "gno.land/r/sys/validators"
# TODO: rewards_pkgpath.string = "gno.land/r/sys/rewards"
# TODO: token_lock.bool = true

## gnovm
["gno.land/r/sys/params.vm"]
## gnovm module parameters
["vm"]
chain_domain.string = "gno.land"
sysusers_pkgpath.string= "gno.land/r/sys/users"
# TODO: Leverage toml unmarshaler to extract these into VM Params struct before writing to genesis
# TODO: max_gas.int64 = 100_000_000
# TODO: chain_tz.string = "UTC"
# TODO: default_storage_allowance.string = ""

## tm2
["gno.land/r/sys/params.tm2"]
# ["gno.land/r/sys/params.tm2"]

## misc
["gno.land/r/sys/params.misc"]
# ["gno.land/r/sys/params.misc"]

## testing
## testing arbirary parameters
# do not remove these lines. they are needed for a txtar integration test.
["gno.land/r/sys/params.test"]
["vm:gno.land/r/sys/params.test"]
foo.string = "bar"
foo.int64 = -1337
foo.uint64 = 42
Expand Down
35 changes: 27 additions & 8 deletions gno.land/pkg/gnoland/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,14 +96,18 @@ func NewAppWithOptions(cfg *AppOptions) (abci.Application, error) {
baseApp.MountStoreWithDB(baseKey, dbadapter.StoreConstructor, cfg.DB)

// Construct keepers.
paramsKpr := params.NewParamsKeeper(mainKey, "vm")

paramsKpr := params.NewParamsKeeper(mainKey)
acctKpr := auth.NewAccountKeeper(mainKey, paramsKpr, ProtoGnoAccount)
bankKpr := bank.NewBankKeeper(acctKpr, paramsKpr)
gpKpr := auth.NewGasPriceKeeper(mainKey)
bankKpr := bank.NewBankKeeper(acctKpr)

vmk := vm.NewVMKeeper(baseKey, mainKey, acctKpr, bankKpr, paramsKpr)
vmk.Output = cfg.VMOutput

paramsKpr.Register(acctKpr.GetParamfulKey(), acctKpr)
paramsKpr.Register(bankKpr.GetParamfulKey(), bankKpr)
paramsKpr.Register(vmk.GetParamfulKey(), vmk)

// Set InitChainer
icc := cfg.InitChainerConfig
icc.baseApp = baseApp
Expand All @@ -123,7 +127,6 @@ func NewAppWithOptions(cfg *AppOptions) (abci.Application, error) {
) {
// Add last gas price in the context
ctx = ctx.WithValue(auth.GasPriceContextKey{}, gpKpr.LastGasPrice(ctx))

// Override auth params.
ctx = ctx.WithValue(auth.AuthParamsContextKey{}, acctKpr.GetParams(ctx))
// Continue on with default auth ante handler.
Expand Down Expand Up @@ -325,11 +328,8 @@ func (cfg InitChainerConfig) loadAppState(ctx sdk.Context, appState any) ([]abci
if !ok {
return nil, fmt.Errorf("invalid AppState of type %T", appState)
}
cfg.acctKpr.InitGenesis(ctx, state.Auth)
params := cfg.acctKpr.GetParams(ctx)
ctx = ctx.WithValue(auth.AuthParamsContextKey{}, params)
auth.InitChainer(ctx, cfg.gpKpr.(auth.GasPriceKeeper), params.InitialGasPrice)

cfg.bankKpr.InitGenesis(ctx, state.Bank)
// Apply genesis balances.
for _, bal := range state.Balances {
acc := cfg.acctKpr.NewAccountWithAddress(ctx, bal.Address)
Expand All @@ -344,6 +344,25 @@ func (cfg InitChainerConfig) loadAppState(ctx sdk.Context, appState any) ([]abci
for _, param := range state.Params {
param.register(ctx, cfg.paramsKpr)
}
// The account keeper's initial genesis state must be set after genesis
// accounts are created in account keeeper with genesis balances
cfg.acctKpr.InitGenesis(ctx, state.Auth)

// The unrestricted address must have been created as one of the genesis accounts.
// Otherwise, we cannot verify the unrestricted address in the genesis state.

for _, addr := range state.Auth.Params.UnrestrictedAddrs {
acc := cfg.acctKpr.GetAccount(ctx, addr)
accr := acc.(*GnoAccount)
accr.SetUnrestricted()
cfg.acctKpr.SetAccount(ctx, acc)
}

cfg.vmKpr.InitGenesis(ctx, state.VM)

params := cfg.acctKpr.GetParams(ctx)
ctx = ctx.WithValue(auth.AuthParamsContextKey{}, params)
auth.InitChainer(ctx, cfg.gpKpr, params.InitialGasPrice)

// Replay genesis txs.
txResponses := make([]abci.ResponseDeliverTx, 0, len(state.Txs))
Expand Down
40 changes: 29 additions & 11 deletions gno.land/pkg/gnoland/app_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,12 +108,13 @@ func TestNewAppWithOptions(t *testing.T) {
path string
expectedVal string
}{
{"params/vm/foo.string", `"hello"`},
{"params/vm/foo.int64", `"-42"`},
{"params/vm/foo.uint64", `"1337"`},
{"params/vm/foo.bool", `true`},
{"params/vm/foo.bytes", `"SGkh"`}, // XXX: make this test more readable
{"params/foo.string", `"hello"`},
{"params/foo.int64", `"-42"`},
{"params/foo.uint64", `"1337"`},
{"params/foo.bool", `true`},
{"params/foo.bytes", `"SGkh"`}, // XXX: make this test more readable
}

for _, tc := range tcs {
qres := bapp.Query(abci.RequestQuery{
Path: tc.path,
Expand Down Expand Up @@ -216,12 +217,17 @@ func testInitChainerLoadStdlib(t *testing.T, cached bool) { //nolint:thelper
cfg := InitChainerConfig{
StdlibDir: stdlibDir,
vmKpr: mock,
acctKpr: &mockAuthKeeper{},
bankKpr: &mockBankKeeper{},
paramsKpr: &mockParamsKeeper{},
gpKpr: &mockGasPriceKeeper{},
CacheStdlibLoad: cached,
}
// Construct keepers.
paramsKpr := params.NewParamsKeeper(iavlCapKey, "")
cfg.acctKpr = auth.NewAccountKeeper(iavlCapKey, paramsKpr, ProtoGnoAccount)
cfg.gpKpr = auth.NewGasPriceKeeper(iavlCapKey)
// paramsKpr := params.NewParamsKeeper(iavlCapKey, params.PrefixKeyMapper{})
// cfg.paramsKpr = &mockParamsKeeper{}
// cfg.acctKpr = auth.NewAccountKeeper(iavlCapKey, paramsKpr, ProtoGnoAccount)
// cfg.gpKpr = auth.NewGasPriceKeeper(iavlCapKey)
cfg.InitChainer(testCtx, abci.RequestInitChain{
AppState: DefaultGenState(),
})
Expand Down Expand Up @@ -311,6 +317,9 @@ func TestInitChainer_MetadataTxs(t *testing.T) {
},
// Make sure the deployer account has a balance
Balances: balances,
Auth: auth.DefaultGenesisState(),
Bank: bank.DefaultGenesisState(),
VM: vm.DefaultGenesisState(),
}
}

Expand All @@ -322,6 +331,9 @@ func TestInitChainer_MetadataTxs(t *testing.T) {
},
},
Balances: balances,
Auth: auth.DefaultGenesisState(),
Bank: bank.DefaultGenesisState(),
VM: vm.DefaultGenesisState(),
}
}
)
Expand Down Expand Up @@ -822,12 +834,14 @@ func newGasPriceTestApp(t *testing.T) abci.Application {
baseApp.MountStoreWithDB(baseKey, dbadapter.StoreConstructor, cfg.DB)

// Construct keepers.
paramsKpr := params.NewParamsKeeper(mainKey, "")
paramsKpr := params.NewParamsKeeper(mainKey)
acctKpr := auth.NewAccountKeeper(mainKey, paramsKpr, ProtoGnoAccount)
gpKpr := auth.NewGasPriceKeeper(mainKey)
bankKpr := bank.NewBankKeeper(acctKpr)
bankKpr := bank.NewBankKeeper(acctKpr, paramsKpr)
vmk := vm.NewVMKeeper(baseKey, mainKey, acctKpr, bankKpr, paramsKpr)

paramsKpr.Register(acctKpr.GetParamfulKey(), acctKpr)
paramsKpr.Register(bankKpr.GetParamfulKey(), bankKpr)
paramsKpr.Register(vmk.GetParamfulKey(), vmk)
// Set InitChainer
icc := cfg.InitChainerConfig
icc.baseApp = baseApp
Expand Down Expand Up @@ -950,6 +964,10 @@ func gnoGenesisState(t *testing.T) GnoGenesisState {
}
}`)
err := amino.UnmarshalJSON(genBytes, &gen)

gen.Bank = bank.DefaultGenesisState()
gen.VM = vm.DefaultGenesisState()

if err != nil {
t.Fatalf("failed to create genesis state: %v", err)
}
Expand Down
14 changes: 12 additions & 2 deletions gno.land/pkg/gnoland/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"github.com/gnolang/gno/tm2/pkg/crypto"
osm "github.com/gnolang/gno/tm2/pkg/os"
"github.com/gnolang/gno/tm2/pkg/sdk/auth"
"github.com/gnolang/gno/tm2/pkg/sdk/bank"
"github.com/gnolang/gno/tm2/pkg/std"
"github.com/pelletier/go-toml"
)
Expand Down Expand Up @@ -77,11 +78,19 @@ func LoadGenesisParamsFile(path string) ([]Param, error) {
}

params := make([]Param, 0)
// By default parameters are group by modules. the module seperater is ":"

for category, keys := range m {
separator := ":"
// the category prefixed with "vm:" contains arbirary parameters
if strings.HasPrefix(category, "vm:") {
separator = "."
}
for key, kinds := range keys {
for kind, val := range kinds {
fmt.Println(category)
param := Param{
key: category + "." + key,
key: category + separator + key,
kind: kind,
}
switch kind {
Expand Down Expand Up @@ -200,7 +209,8 @@ func DefaultGenState() GnoGenesisState {
Balances: []Balance{},
Txs: []TxWithMetadata{},
Auth: authGen,
Bank: bank.DefaultGenesisState(),
VM: vmm.DefaultGenesisState(),
}

return gs
}
Loading
Loading