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: custom bank hooks #201

Merged
merged 6 commits into from
Nov 2, 2023
Merged
Show file tree
Hide file tree
Changes from 3 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
33 changes: 0 additions & 33 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (
"os"
"path/filepath"
"reflect" // #nosec G702
"strings"

authsims "github.com/cosmos/cosmos-sdk/x/auth/simulation"

Expand Down Expand Up @@ -174,33 +173,6 @@ import (
_ "github.com/terra-money/core/v2/client/docs/statik"
)

var (
// If EnabledSpecificProposals is "", and this is "true", then enable all x/wasm proposals.
// If EnabledSpecificProposals is "", and this is not "true", then disable all x/wasm proposals.
ProposalsEnabled = "true"
// If set to non-empty string it must be comma-separated list of values that are all a subset
// of "EnableAllProposals" (takes precedence over ProposalsEnabled)
// https://github.com/CosmWasm/wasmd/blob/02a54d33ff2c064f3539ae12d75d027d9c665f05/x/wasm/internal/types/proposal.go#L28-L34
EnableSpecificProposals = ""
)

// GetEnabledProposals parses the ProposalsEnabled / EnableSpecificProposals values to
// produce a list of enabled proposals to pass into wasmd app.
func GetEnabledProposals() []wasmtypes.ProposalType {
if EnableSpecificProposals == "" {
if ProposalsEnabled == "true" {
return wasmtypes.EnableAllProposals
}
return wasmtypes.DisableAllProposals
}
chunks := strings.Split(EnableSpecificProposals, ",")
proposals, err := wasmtypes.ConvertToProposals(chunks)
if err != nil {
panic(err)
}
return proposals
}

// GetWasmOpts build wasm options
func GetWasmOpts(app *TerraApp, appOpts servertypes.AppOptions) []wasmkeeper.Option {
var wasmOpts []wasmkeeper.Option
Expand Down Expand Up @@ -692,11 +664,6 @@ func NewTerraApp(
app.TokenFactoryKeeper.Hooks(),
),
)
// register wasm gov proposal types
enabledProposals := GetEnabledProposals()
if len(enabledProposals) != 0 {
govRouter.AddRoute(wasmtypes.RouterKey, wasmkeeper.NewWasmProposalHandler(app.WasmKeeper, enabledProposals))
}

// Create fee enabled wasm ibc Stack
var wasmStack porttypes.IBCModule
Expand Down
94 changes: 89 additions & 5 deletions custom/bank/keeper/keeper.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
package keeper

import (
"sort"

"github.com/cosmos/cosmos-sdk/codec"
storetypes "github.com/cosmos/cosmos-sdk/store/types"
sdk "github.com/cosmos/cosmos-sdk/types"
accountkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper"
bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"

sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
errorsmod "cosmossdk.io/errors"
custombankkeeper "github.com/terra-money/alliance/custom/bank/keeper"
customterratypes "github.com/terra-money/core/v2/custom/bank/types"
)
Expand Down Expand Up @@ -50,7 +53,6 @@ func (k *Keeper) SetHooks(bh customterratypes.BankHooks) *Keeper {
// SendCoins transfers amt coins from a sending account to a receiving account.
// An error is returned upon failure.
func (k Keeper) SendCoins(ctx sdk.Context, fromAddr sdk.AccAddress, toAddr sdk.AccAddress, amt sdk.Coins) error {
// BlockBeforeSend hook should always be called before the TrackBeforeSend hook.
err := k.BlockBeforeSend(ctx, fromAddr, toAddr, amt)
if err != nil {
return err
Expand All @@ -66,13 +68,95 @@ func (k Keeper) SendCoins(ctx sdk.Context, fromAddr sdk.AccAddress, toAddr sdk.A
func (k Keeper) SendCoinsFromModuleToModule(ctx sdk.Context, senderModule, recipientModule string, amt sdk.Coins) error {
senderAddr := k.ak.GetModuleAddress(senderModule)
if senderAddr == nil {
panic(sdkerrors.Wrapf(sdkerrors.ErrUnknownAddress, "module account %s does not exist", senderModule))
panic(errorsmod.Wrapf(customterratypes.ErrUnknownAddress, "senderModule address %s is nil", senderModule))
}

recipientAcc := k.ak.GetModuleAccount(ctx, recipientModule)
if recipientAcc == nil {
panic(sdkerrors.Wrapf(sdkerrors.ErrUnknownAddress, "module account %s does not exist", recipientModule))
panic(errorsmod.Wrapf(customterratypes.ErrUnknownAddress, "recipientModule address %s is nil", recipientModule))
}

return k.Keeper.SendCoins(ctx, senderAddr, recipientAcc.GetAddress(), amt)
}

// UndelegateCoins performs undelegation by crediting amt coins to an account with
// address addr. For vesting accounts, undelegation amounts are tracked for both
// vesting and vested coins. The coins are then transferred from a ModuleAccount
// address to the delegator address. If any of the undelegation amounts are
// negative, an error is returned.
func (k Keeper) UndelegateCoins(ctx sdk.Context, moduleAccAddr, delegatorAddr sdk.AccAddress, amt sdk.Coins) error {
err := k.BlockBeforeSend(ctx, moduleAccAddr, delegatorAddr, amt)
if err != nil {
return err
}
k.TrackBeforeSend(ctx, moduleAccAddr, delegatorAddr, amt)

return k.Keeper.UndelegateCoins(ctx, moduleAccAddr, delegatorAddr, amt)
}

// DelegateCoins performs delegation by deducting amt coins from an account with
// address addr. For vesting accounts, delegations amounts are tracked for both
// vesting and vested coins. The coins are then transferred from the delegator
// address to a ModuleAccount address. If any of the delegation amounts are negative,
// an error is returned.
func (k Keeper) DelegateCoins(ctx sdk.Context, delegatorAddr, moduleAccAddr sdk.AccAddress, amt sdk.Coins) error {
err := k.BlockBeforeSend(ctx, delegatorAddr, moduleAccAddr, amt)
if err != nil {
return err
}
k.TrackBeforeSend(ctx, delegatorAddr, moduleAccAddr, amt)

return k.Keeper.DelegateCoins(ctx, delegatorAddr, moduleAccAddr, amt)
}

// InputOutputCoins performs multi-send functionality. It accepts a series of
// inputs that correspond to a series of outputs. It returns an error if the
// inputs and outputs don't line up or if any single transfer of tokens fails.
func (k Keeper) InputOutputCoins(ctx sdk.Context, inputs []banktypes.Input, outputs []banktypes.Output) error {
emidev98 marked this conversation as resolved.
Show resolved Hide resolved
// ValidateInputsOutputs is executed in the k.Keeper.InputOutputCoins
// but we execute it here too just to avoid unnecessary computation
// if the inputs and outputs are invalid, that way we can assume things like
// the addreeses being valid and the inputs and outputs match balances
if err := banktypes.ValidateInputsOutputs(inputs, outputs); err != nil {
emidev98 marked this conversation as resolved.
Show resolved Hide resolved
return err
}

// Create a slice to hold OutputCoin structs
// to be sorted so the output is deterministic
var outputCoinSlice customterratypes.OutputCoinSlice

// Populate the slice with outputs and corresponding
// coins to decrease the algorithm complexity.
for _, output := range outputs {
for _, coin := range output.Coins {
outputCoinSlice = append(outputCoinSlice, customterratypes.OutputCoin{Output: output, Coin: coin})
}
}

// Sort the slice based on denomination
sort.Sort(outputCoinSlice)

// Iterate through all inputs
for _, input := range inputs {
// Iterate through all coins in the current input
for _, inputCoin := range input.Coins {
// Use binary search to find matching outputs
index := sort.Search(len(outputCoinSlice), func(i int) bool { return outputCoinSlice[i].Coin.Denom >= inputCoin.Denom })

for index < len(outputCoinSlice) && outputCoinSlice[index].Coin.Denom == inputCoin.Denom {

fromAddr := sdk.MustAccAddressFromBech32(input.Address)
toAddr := sdk.MustAccAddressFromBech32(outputCoinSlice[index].Output.Address)
coins := sdk.NewCoins(inputCoin)

err := k.BlockBeforeSend(ctx, fromAddr, toAddr, coins)
if err != nil {
return err
}
k.TrackBeforeSend(ctx, fromAddr, toAddr, coins)
index++
}
}
}

return k.Keeper.InputOutputCoins(ctx, inputs, outputs)
}
12 changes: 12 additions & 0 deletions custom/bank/types/errors.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package types

// DONTCOVER

import (
sdkerrors "cosmossdk.io/errors"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
)

var (
ErrUnknownAddress = sdkerrors.Register(banktypes.ModuleName, 383838, "module account does not exist")
)
19 changes: 19 additions & 0 deletions custom/bank/types/output_coin_slice.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package types

import (
sdk "github.com/cosmos/cosmos-sdk/types"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
)

// Define a custom type to hold Output and Coin together for sorting
type OutputCoin struct {
Output banktypes.Output
Coin sdk.Coin
}

// Define a slice of OutputCoin and implement sort.Interface
type OutputCoinSlice []OutputCoin

func (o OutputCoinSlice) Len() int { return len(o) }
func (o OutputCoinSlice) Less(i, j int) bool { return o[i].Coin.Denom < o[j].Coin.Denom }
func (o OutputCoinSlice) Swap(i, j int) { o[i], o[j] = o[j], o[i] }
6 changes: 3 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ require (
cosmossdk.io/errors v1.0.0
cosmossdk.io/math v1.1.2
cosmossdk.io/tools/rosetta v0.2.1
github.com/CosmWasm/wasmd v0.41.0
github.com/CosmWasm/wasmvm v1.3.0
github.com/CosmWasm/wasmd v0.43.0
github.com/CosmWasm/wasmvm v1.4.1
github.com/cometbft/cometbft v0.37.2
github.com/cometbft/cometbft-db v0.8.0
github.com/cosmos/cosmos-proto v1.0.0-beta.3
Expand Down Expand Up @@ -66,7 +66,7 @@ require (
github.com/confio/ics23/go v0.9.0 // indirect
github.com/cosmos/btcutil v1.0.5 // indirect
github.com/cosmos/gogogateway v1.2.0 // indirect
github.com/cosmos/iavl v0.20.0 // indirect
github.com/cosmos/iavl v0.20.1 // indirect
github.com/cosmos/ics23/go v0.10.0 // indirect
github.com/cosmos/ledger-cosmos-go v0.12.2 // indirect
github.com/cosmos/ledger-go v0.9.3 // indirect
Expand Down
12 changes: 6 additions & 6 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -223,10 +223,10 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d h1:nalkkPQcITbvhmL4+C4cKA87NW0tfm3Kl9VXRoPywFg=
github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d/go.mod h1:URdX5+vg25ts3aCh8H5IFZybJYKWhJHYMTnf+ULtoC4=
github.com/CosmWasm/wasmd v0.41.0 h1:fmwxSbwb50zZDcBaayYFRLIaSFca+EFld1WOaQi49jg=
github.com/CosmWasm/wasmd v0.41.0/go.mod h1:0Sds1q2IsPaTN1gHa3BNOYcUFgtGvxH7CXEXPgoihns=
github.com/CosmWasm/wasmvm v1.3.0 h1:x12X4bKlUPS7TT9QQP45+fJo2sp30GEbiSSgb9jsec8=
github.com/CosmWasm/wasmvm v1.3.0/go.mod h1:vW/E3h8j9xBQs9bCoijDuawKo9kCtxOaS8N8J7KFtkc=
github.com/CosmWasm/wasmd v0.43.0 h1:4xQAiNf6Ej+TuYe4PXwrtVJ9C+xyFrbsdqHH/kU9Vxk=
github.com/CosmWasm/wasmd v0.43.0/go.mod h1:gpri8YvkRErBz+qDme5jOThGZmSlHfyN532bWibXOl4=
github.com/CosmWasm/wasmvm v1.4.1 h1:YgodVlBrXa2HJZzOXjWDH0EIRwQzK3zuA73dDPRRLS4=
github.com/CosmWasm/wasmvm v1.4.1/go.mod h1:fXB+m2gyh4v9839zlIXdMZGeLAxqUdYdFQqYsTha2hc=
github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
github.com/DataDog/zstd v1.5.0/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw=
Expand Down Expand Up @@ -398,8 +398,8 @@ github.com/cosmos/gogogateway v1.2.0/go.mod h1:iQpLkGWxYcnCdz5iAdLcRBSw3h7NXeOkZ
github.com/cosmos/gogoproto v1.4.2/go.mod h1:cLxOsn1ljAHSV527CHOtaIP91kK6cCrZETRBrkzItWU=
github.com/cosmos/gogoproto v1.4.10 h1:QH/yT8X+c0F4ZDacDv3z+xE3WU1P1Z3wQoLMBRJoKuI=
github.com/cosmos/gogoproto v1.4.10/go.mod h1:3aAZzeRWpAwr+SS/LLkICX2/kDFyaYVzckBDzygIxek=
github.com/cosmos/iavl v0.20.0 h1:fTVznVlepH0KK8NyKq8w+U7c2L6jofa27aFX6YGlm38=
github.com/cosmos/iavl v0.20.0/go.mod h1:WO7FyvaZJoH65+HFOsDir7xU9FWk2w9cHXNW1XHcl7A=
github.com/cosmos/iavl v0.20.1 h1:rM1kqeG3/HBT85vsZdoSNsehciqUQPWrR4BYmqE2+zg=
github.com/cosmos/iavl v0.20.1/go.mod h1:WO7FyvaZJoH65+HFOsDir7xU9FWk2w9cHXNW1XHcl7A=
github.com/cosmos/ibc-apps/middleware/packet-forward-middleware/v7 v7.0.1-0.20231012160012-d0f49580a238 h1:vc9zQUjiYctU3q4uF5usbl2JUqaa3F6bEyboNKOKyBk=
github.com/cosmos/ibc-apps/middleware/packet-forward-middleware/v7 v7.0.1-0.20231012160012-d0f49580a238/go.mod h1:WO/xWf+I8m+9PZsBkwZkEREZIW24j90Sz2yOsXU3B9U=
github.com/cosmos/ibc-apps/modules/ibc-hooks/v7 v7.0.0-20230803181732-7c8f814d3b79 h1:pCxyhIxgWTabAQC5UerkITraHG3SwajdLKKMCFDWCv4=
Expand Down
Loading