Skip to content

Commit

Permalink
Create the x/hold module. (#1638)
Browse files Browse the repository at this point in the history
* [1607]: Switch to a local sdk version that has the locked coins injectable.

* [1607]: Create initial escrow protos.

* [1607]: Generate stuff from the protos.

* [1607]: Make the genesis escrows nullable, and fix that field's tag.

* [1607]: Change the GetEscrow response field name to amount (from escrow) since it's called amount everywhere else.

* [1607]: Make the AccountEscrow entries nullable in the GetAllEscrow query.

* [1607]: Write the new module.go and build things out enough to compile. Some stuff is still left to be implemented though.

* [1607]: Add the escrow module to the app.

* [1607]: Implement the rest of the keeper functions (and keys stuff). Finish the simulation decoder. Make the GetAllEscrow query pay attention to pagination even though I'll want to refactor it in a bit.

* [1607]: Create the invariant. Add the bypass check to GetLockedCoins. Tweak the errors from ValidateNewEscrow to also make sense from the invariant.

* [1607]: Overhaul the GetAllEscrow query to properly do pagination and entry combination.

* [1607]: Add changelog entry.

* [1607]: Require addresses in the genesis state to be unique.

* [1607]: Change the GetLockedCoins function to just use GetEscrowCoins.

* [1607]: Rename EscrowCoinPrefix to KeyPrefixEscrowCoin since the 'key prefix' part is the key piece of info I'm always looking for with those variables. Also, move the UnmarshalEscrowCoinValue function into keys.go (from keeper.go).

* [1607]: Write unit tests on the types stuff.

* [1607]: Write unit tests on the keys stuff.

* [1607]: Start work on the keeper tests.

* [1607]: Tweak the error message from GetEscrowCoin to have the address also.

* [1607]: Add unit tests for GetEscrowCoin.

* [1607]: add some context to the iterator errors. Remove the panic recovery from GetAllAccountEscrows since it's not actually needed.

* [1607]: Write unit tests for GetEscrowCoins, IterateEscrow, IterateAllEscrow, GetAllAccountEscrows.

* [1607]: Tweak a couple error messages to include extra info.

* [1607]: Write unit tests on AddEscrow and RemoveEscrow.

* [1607]: Add a couple TODOs for events.

* [1607]: Set the bank keeper in the constructor.

* [1607]: Add some panic checking assertion helpers.

* [1607]: Refactor the keeper test stuff a bit to create some helpers to shorten a lot of the common long setup lines. Make all the helper funcs private so that the only public stuff is tests.

* [1607]: Unit tests on InitGenesis and ExportGenesis.

* [1607]: Create a helper to shorten the FundAccount calls.

* [1607]: Tweak the messages from the invariant.

* [1607]: Unit test on the invariant.

* [1607]: Change an error form paginateAllEscrow to match other errors of that type.

* [1607]: Move clearEscrowState and dumpEscrowState into the keeper.go file (from genesis). Switch to a getStore helper func.

* [1607]: Unit tests on the grpc_query funcs.

* [1607]: Add a couple more TODOs about the events.

* [1607]: Fix RandomAccountEscrows to be able to pick up to all of the accounts. Fix RandomizedGenState to correctly update the bank genesis balances.

* [1607]: Simulation unit tests.

* [1607]: Switch to a pseudo-version of the sdk at commit 9d5e97ff8efd. That commit is on the prov/dwedul/bp-577-578-to-0.46 branch which is release-pio/v0.46.x plus a couple backports.

* [1607]: Create a couple typed events.

* [1607]: Add some constructors for the events and unit tests on the constructs and typed event conversion.

* [1607]: Emit the events when adding or removing escrow.

* [1607]: Switch back to a local version of the sdk since the spendable balances cli query.

* [1607]: Add pagination stuff to the GetAllEscrow CLI command.

* [1607]: Unit tests on the cli commands.

* [1607]: Lint fixes.

* [1607]: Comment out the TestEscrowRemovedFromSpendable tests until I can get a more public version of the SDK with that query in it.

* [1607]: Switch back to the pseudo-version of the sdk.

* [1607]: Add some TODOs for a few tests related to the bank keeper.

* [1607]: Rename all the new files from escrow to hold.

* [1607]: Regenerate protos after rename.

* [1607]: Change the names of proto things from escrow to hold.

* [1607]: Fix all the package imports.

* [1607]: Fix the event names.

* [1607]: Fix all uses of the word escrow in the types files.

* [1607]: Fix all uses of the word escrow in the keeper files.

* [1607]: Fix all uses of the word escrow in the cli files.

* [1607]: Fix the last uses of the word escrow in the hold module.

* [1607]: Output the hold gen state and new bank state during RandomizedGenState.

* [1607]: Fix the marker send restriction test that started failing with the change in the SDK to subtract from the account before calling the send restriction.

* [1607]: Unit tests on the GetLockedCoins fn and bank stuff.

* [1607]: Put back import that somehow got deleted.

* [1607]: Update changelog.

* [1607]: Add the hold storkey to the TestAppImportExport.

* [1607]: Switch back to a local version of the sdk that has a fix (hopefully) in it.

* [1607]: Fix the one use of InputOutputCoins that broke when I switched the SDK.

* [1607]: Tweak the hold simulation RandomizedGenState to give some better info to see if I can figure out what's going wrong with the sims.

* [1607]: Add some extra debug output.

* [1607]: Add most of a test looking at vesting and holds over time.

* [1607]: Rename RemoveHold to ReleaseHold since that feels better.

* [1607]: Bring in sdk changes and fix uses of SimulateFromSeed that changed.

* [1607]: Update the simulation genesis tests to reflect recent changes.

* [1607]: Add a count to the printed statement in RandomizedGenState.

* [1607]: Fix the invariant to ignore the vesting locked funds when the block time is zero. Also fix it to properly include all the errors when there's more than two.

* [1607] Switch back to a pseudo-version of the sdk at commit 0194df1aa61d. That commit is on the prov/dwedul/1607-delegate-locked-coins branch which is main-pio plus a couple a fix.

* Change EventHoldRemoved to EventHoldReleased to match the what the keeper calls it and what sounds more accurate to me.

* [1607]: Remove a Printf only added to help with debugging.

* [1607]: Re-enable the TestHoldsNotInFromSpendable test since the sdk has it now.

* [1607]: Finish the TestVestingAndHoldOverTime test.

* [1607]: Add the spec readme and put a TODO in it to finish the rest.

* [1607]: Finish spec docs.

* [1607]: Update marker messages TOC to add missing entry (added automatically with make update-tocs).

* [1607]: go mod tidy since somehow, one of the previous things made a dependency indirect.

* [1607]: make proto-format.

* [1607]: Add a reason field to the EventHoldAdded.

* [1607]: Take in a reason for AddHold and pass it on to the event.

* [1607]: Bump the sdk to v0.46.13-pio-2 (from v0.46.13-pio-1).

* [1607]: Add the reason to the spec doc.

* [1607]: Remove the RandomAccountHolds2 since I decided not to use that version.

* [1607]: Remove the bank balances output when generating randomized genesis state.

* [1607]: Get rid of addrCoinsStringsObjJSON since the only thing that needs it now is holdsString.

* [1607]: 'Both' to 'All' for the EventHoldAdded since it has three attributes.

* [1607]: Create some assertion funcs that I commonly want to use and have been copy/pasting.

* [1607]: Switch to using the new assertion functions I just made.

* [1607]: Move the assertions into their own package and split them into smaller files. This prevents a circular dependency where hold -> testutil -> app -> hold.

* [1607]: Add a mutex to the mockTB so that race tests pass for it. I probably could have norace directived those tests, but this is probably better.

* [1607]: Add some comments to the AssertPanicEquals funcs about how it's different from PanicsWithError and PanicsWithValue.

* [1607]: Add some unit tests on the panic stuff to panic with anonymous structs.

* [1607]: Make the event/attribute to strings functions public and add unit tests on them.

* [1607]: Switch to assertions.AttrsToStrings in TestTypedEventToEvent.

* [1607]: Turn TestHoldsString into a more standard test so I'm not just recreating HoldsString.

* [1607]: Change some finalEsc variables to finalHold since esc was for escrow which this no longer is.

* [1607]: Add some tests for AddHold and ReleaseHold as well as some specific ones for setHoldCoinAmount.
  • Loading branch information
SpicyLemon authored Aug 31, 2023
1 parent 045bca8 commit c63b170
Show file tree
Hide file tree
Showing 64 changed files with 11,511 additions and 26 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ Ref: https://keepachangelog.com/en/1.0.0/
* New `GetByAddr` metadata query [#1443](https://github.com/provenance-io/provenance/issues/1443).
* Add Trigger module queries to stargate whitelist for smart contracts [#1636](https://github.com/provenance-io/provenance/issues/1636)
* Added the saffron upgrade handlers [PR 1648](https://github.com/provenance-io/provenance/pull/1648).
* Create the `x/hold` module which facilitates locking funds in an owners account [#1607](https://github.com/provenance-io/provenance/issues/1607).
Funds with a hold on them cannot be transferred until the hold is removed.
Management of holds is internal, but there are queries for looking up holds on accounts.
Holds are also reflected in the `x/bank` module's `SpendableBalances` query.

### Improvements

Expand Down
16 changes: 16 additions & 0 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,9 @@ import (
attributekeeper "github.com/provenance-io/provenance/x/attribute/keeper"
attributetypes "github.com/provenance-io/provenance/x/attribute/types"
attributewasm "github.com/provenance-io/provenance/x/attribute/wasm"
"github.com/provenance-io/provenance/x/hold"
holdkeeper "github.com/provenance-io/provenance/x/hold/keeper"
holdmodule "github.com/provenance-io/provenance/x/hold/module"
ibchooks "github.com/provenance-io/provenance/x/ibchooks"
ibchookskeeper "github.com/provenance-io/provenance/x/ibchooks/keeper"
ibchookstypes "github.com/provenance-io/provenance/x/ibchooks/types"
Expand Down Expand Up @@ -214,6 +217,7 @@ var (
msgfeesmodule.AppModuleBasic{},
rewardmodule.AppModuleBasic{},
triggermodule.AppModuleBasic{},
holdmodule.AppModuleBasic{},
)

// module account permissions
Expand Down Expand Up @@ -301,6 +305,7 @@ type App struct {
MetadataKeeper metadatakeeper.Keeper
AttributeKeeper attributekeeper.Keeper
NameKeeper namekeeper.Keeper
HoldKeeper holdkeeper.Keeper
WasmKeeper *wasm.Keeper
ContractKeeper *wasmkeeper.PermissionedKeeper

Expand Down Expand Up @@ -377,6 +382,7 @@ func New(
quarantine.StoreKey,
sanction.StoreKey,
triggertypes.StoreKey,
hold.StoreKey,
)
tkeys := sdk.NewTransientStoreKeys(paramstypes.TStoreKey)
memKeys := sdk.NewMemoryStoreKeys(capabilitytypes.MemStoreKey)
Expand Down Expand Up @@ -535,6 +541,10 @@ func New(
app.AttributeKeeper, app.NameKeeper, app.TransferKeeper, markerReqAttrBypassAddrs,
)

app.HoldKeeper = holdkeeper.NewKeeper(
appCodec, keys[hold.StoreKey], app.BankKeeper,
)

pioMessageRouter := MessageRouterFunc(func(msg sdk.Msg) baseapp.MsgServiceHandler {
return pioMsgFeesRouter.Handler(msg)
})
Expand Down Expand Up @@ -689,6 +699,7 @@ func New(
wasm.NewAppModule(appCodec, app.WasmKeeper, app.StakingKeeper, app.AccountKeeper, app.BankKeeper),
rewardmodule.NewAppModule(appCodec, app.RewardKeeper, app.AccountKeeper, app.BankKeeper),
triggermodule.NewAppModule(appCodec, app.TriggerKeeper, app.AccountKeeper, app.BankKeeper),
holdmodule.NewAppModule(appCodec, app.HoldKeeper),

// IBC
ibc.NewAppModule(app.IBCKeeper),
Expand Down Expand Up @@ -735,6 +746,7 @@ func New(
vestingtypes.ModuleName,
quarantine.ModuleName,
sanction.ModuleName,
hold.ModuleName,
)

app.mm.SetOrderEndBlockers(
Expand Down Expand Up @@ -771,6 +783,7 @@ func New(
paramstypes.ModuleName,
quarantine.ModuleName,
sanction.ModuleName,
hold.ModuleName,
)

// NOTE: The genutils module must occur after staking so that pools are
Expand Down Expand Up @@ -801,6 +814,7 @@ func New(
attributetypes.ModuleName,
metadatatypes.ModuleName,
msgfeestypes.ModuleName,
hold.ModuleName,

ibchost.ModuleName,
ibctransfertypes.ModuleName,
Expand Down Expand Up @@ -838,6 +852,7 @@ func New(
vestingtypes.ModuleName,
quarantine.ModuleName,
sanction.ModuleName,
hold.ModuleName,

ibchookstypes.ModuleName,
icatypes.ModuleName,
Expand Down Expand Up @@ -884,6 +899,7 @@ func New(
msgfeesmodule.NewAppModule(appCodec, app.MsgFeesKeeper, app.interfaceRegistry),
rewardmodule.NewAppModule(appCodec, app.RewardKeeper, app.AccountKeeper, app.BankKeeper),
triggermodule.NewAppModule(appCodec, app.TriggerKeeper, app.AccountKeeper, app.BankKeeper),
holdmodule.NewAppModule(appCodec, app.HoldKeeper),
provwasm.NewWrapper(appCodec, app.WasmKeeper, app.StakingKeeper, app.AccountKeeper, app.BankKeeper, app.NameKeeper),

// IBC
Expand Down
6 changes: 3 additions & 3 deletions app/sim_bench_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ func BenchmarkFullAppSimulation(b *testing.B) {
app := New(logger, db, nil, true, map[int64]bool{}, b.TempDir(), sdksim.FlagPeriodValue, MakeEncodingConfig(), sdksim.EmptyAppOptions{}, interBlockCacheOpt())

// run randomized simulation
_, simParams, simErr := simulation.SimulateFromSeed(
_, _, simParams, simErr := simulation.SimulateFromSeed(
b,
os.Stdout,
app.BaseApp,
Expand Down Expand Up @@ -88,7 +88,7 @@ func BenchmarkInvariants(b *testing.B) {
app := New(logger, db, nil, true, map[int64]bool{}, b.TempDir(), sdksim.FlagPeriodValue, MakeEncodingConfig(), sdksim.EmptyAppOptions{}, interBlockCacheOpt())

// run randomized simulation
_, simParams, simErr := simulation.SimulateFromSeed(
_, lastBlockTime, simParams, simErr := simulation.SimulateFromSeed(
b,
os.Stdout,
app.BaseApp,
Expand All @@ -111,7 +111,7 @@ func BenchmarkInvariants(b *testing.B) {

PrintStats(config, db)

ctx := app.NewContext(true, tmproto.Header{Height: app.LastBlockHeight() + 1})
ctx := app.NewContext(true, tmproto.Header{Height: app.LastBlockHeight() + 1, Time: lastBlockTime})

// 3. Benchmark each invariant separately
//
Expand Down
24 changes: 14 additions & 10 deletions app/sim_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ import (
cmdconfig "github.com/provenance-io/provenance/cmd/provenanced/config"
"github.com/provenance-io/provenance/internal/pioconfig"
attributetypes "github.com/provenance-io/provenance/x/attribute/types"
"github.com/provenance-io/provenance/x/hold"
markertypes "github.com/provenance-io/provenance/x/marker/types"
metadatatypes "github.com/provenance-io/provenance/x/metadata/types"
msgfeetype "github.com/provenance-io/provenance/x/msgfees/types"
Expand Down Expand Up @@ -111,10 +112,10 @@ func TestFullAppSimulation(t *testing.T) {
app := New(logger, db, nil, true, map[int64]bool{}, t.TempDir(), sdksim.FlagPeriodValue, MakeEncodingConfig(), sdksim.EmptyAppOptions{}, fauxMerkleModeOpt)
require.Equal(t, "provenanced", app.Name())

fmt.Printf("running provenance full app simulation")
fmt.Printf("running provenance full app simulation\n")

// run randomized simulation
_, simParams, simErr := simulation.SimulateFromSeed(
_, _, simParams, simErr := simulation.SimulateFromSeed(
t,
os.Stdout,
app.BaseApp,
Expand Down Expand Up @@ -151,7 +152,7 @@ func TestSimple(t *testing.T) {
require.Equal(t, "provenanced", app.Name())

// run randomized simulation
_, _, simErr := simulation.SimulateFromSeed(
_, _, _, simErr := simulation.SimulateFromSeed(
t,
os.Stdout,
app.BaseApp,
Expand Down Expand Up @@ -188,10 +189,10 @@ func TestAppImportExport(t *testing.T) {
home := t.TempDir()
app := New(logger, db, nil, true, map[int64]bool{}, home, sdksim.FlagPeriodValue, MakeEncodingConfig(), sdksim.EmptyAppOptions{}, fauxMerkleModeOpt)

fmt.Printf("running provenance test import export")
fmt.Printf("running provenance test import export\n")

// Run randomized simulation
_, simParams, simErr := simulation.SimulateFromSeed(
_, lastBlockTime, simParams, simErr := simulation.SimulateFromSeed(
t,
os.Stdout,
app.BaseApp,
Expand Down Expand Up @@ -242,8 +243,8 @@ func TestAppImportExport(t *testing.T) {
}
}()

ctxA := app.NewContext(true, tmproto.Header{Height: app.LastBlockHeight()})
ctxB := newApp.NewContext(true, tmproto.Header{Height: app.LastBlockHeight()})
ctxA := app.NewContext(true, tmproto.Header{Height: app.LastBlockHeight(), Time: lastBlockTime})
ctxB := newApp.NewContext(true, tmproto.Header{Height: app.LastBlockHeight(), Time: lastBlockTime})
newApp.mm.InitGenesis(ctxB, app.AppCodec(), genesisState)
newApp.StoreConsensusParams(ctxB, exported.ConsensusParams)

Expand Down Expand Up @@ -274,6 +275,7 @@ func TestAppImportExport(t *testing.T) {
{app.keys[nametypes.StoreKey], newApp.keys[nametypes.StoreKey], [][]byte{}},
{app.keys[metadatatypes.StoreKey], newApp.keys[metadatatypes.StoreKey], [][]byte{}},
{app.keys[triggertypes.StoreKey], newApp.keys[triggertypes.StoreKey], [][]byte{}},
{app.keys[hold.StoreKey], newApp.keys[hold.StoreKey], [][]byte{}},
}

for _, skp := range storeKeysPrefixes {
Expand Down Expand Up @@ -305,7 +307,7 @@ func TestAppSimulationAfterImport(t *testing.T) {
app := New(logger, db, nil, true, map[int64]bool{}, home, sdksim.FlagPeriodValue, MakeEncodingConfig(), sdksim.EmptyAppOptions{}, fauxMerkleModeOpt)

// Run randomized simulation
stopEarly, simParams, simErr := simulation.SimulateFromSeed(
stopEarly, lastBlockTime, simParams, simErr := simulation.SimulateFromSeed(
t,
os.Stdout,
app.BaseApp,
Expand Down Expand Up @@ -348,9 +350,11 @@ func TestAppSimulationAfterImport(t *testing.T) {

newApp.InitChain(abci.RequestInitChain{
AppStateBytes: exported.AppState,
Time: lastBlockTime,
})

_, _, err = simulation.SimulateFromSeed(
sdksim.FlagGenesisTimeValue = lastBlockTime.Unix()
_, _, _, err = simulation.SimulateFromSeed(
t,
os.Stdout,
newApp.BaseApp,
Expand Down Expand Up @@ -419,7 +423,7 @@ func TestAppStateDeterminism(t *testing.T) {
config.Seed, i+1, numSeeds, j+1, numTimesToRunPerSeed,
)

_, _, err := simulation.SimulateFromSeed(
_, _, _, err := simulation.SimulateFromSeed(
t,
os.Stdout,
app.BaseApp,
Expand Down
5 changes: 3 additions & 2 deletions app/upgrades.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (

attributekeeper "github.com/provenance-io/provenance/x/attribute/keeper"
attributetypes "github.com/provenance-io/provenance/x/attribute/types"
"github.com/provenance-io/provenance/x/hold"
ibchookstypes "github.com/provenance-io/provenance/x/ibchooks/types"
msgfeetypes "github.com/provenance-io/provenance/x/msgfees/types"
triggertypes "github.com/provenance-io/provenance/x/trigger/types"
Expand Down Expand Up @@ -108,7 +109,7 @@ var upgrades = map[string]appUpgrade{

return vm, nil
},
Added: []string{ibchookstypes.ModuleName},
Added: []string{hold.ModuleName, ibchookstypes.ModuleName},
},
"saffron": { // upgrade for v1.17.0
Handler: func(ctx sdk.Context, app *App, vm module.VersionMap) (module.VersionMap, error) {
Expand All @@ -125,7 +126,7 @@ var upgrades = map[string]appUpgrade{

return vm, nil
},
Added: []string{ibchookstypes.ModuleName},
Added: []string{hold.ModuleName, ibchookstypes.ModuleName},
},
// TODO - Add new upgrade definitions here.
}
Expand Down
7 changes: 3 additions & 4 deletions client/docs/statik/statik.go

Large diffs are not rendered by default.

Loading

0 comments on commit c63b170

Please sign in to comment.