parent
273c5253fd
commit
120e08f12d
|
@ -0,0 +1 @@
|
||||||
|
#3463 Revert bank module handler fork (re-enables transfers)
|
|
@ -11,9 +11,6 @@ import (
|
||||||
dbm "github.com/tendermint/tendermint/libs/db"
|
dbm "github.com/tendermint/tendermint/libs/db"
|
||||||
"github.com/tendermint/tendermint/libs/log"
|
"github.com/tendermint/tendermint/libs/log"
|
||||||
|
|
||||||
// TODO: Remove once transfers are enabled.
|
|
||||||
gaiabank "github.com/cosmos/cosmos-sdk/cmd/gaia/app/x/bank"
|
|
||||||
|
|
||||||
bam "github.com/cosmos/cosmos-sdk/baseapp"
|
bam "github.com/cosmos/cosmos-sdk/baseapp"
|
||||||
"github.com/cosmos/cosmos-sdk/codec"
|
"github.com/cosmos/cosmos-sdk/codec"
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
|
@ -169,10 +166,8 @@ func NewGaiaApp(logger log.Logger, db dbm.DB, traceStore io.Writer, loadLatest,
|
||||||
staking.RegisterInvariants(&app.crisisKeeper, app.stakingKeeper, app.feeCollectionKeeper, app.distrKeeper, app.accountKeeper)
|
staking.RegisterInvariants(&app.crisisKeeper, app.stakingKeeper, app.feeCollectionKeeper, app.distrKeeper, app.accountKeeper)
|
||||||
|
|
||||||
// register message routes
|
// register message routes
|
||||||
//
|
|
||||||
// TODO: Use standard bank router once transfers are enabled.
|
|
||||||
app.Router().
|
app.Router().
|
||||||
AddRoute(bank.RouterKey, gaiabank.NewHandler(app.bankKeeper)).
|
AddRoute(bank.RouterKey, bank.NewHandler(app.bankKeeper)).
|
||||||
AddRoute(staking.RouterKey, staking.NewHandler(app.stakingKeeper)).
|
AddRoute(staking.RouterKey, staking.NewHandler(app.stakingKeeper)).
|
||||||
AddRoute(distr.RouterKey, distr.NewHandler(app.distrKeeper)).
|
AddRoute(distr.RouterKey, distr.NewHandler(app.distrKeeper)).
|
||||||
AddRoute(slashing.RouterKey, slashing.NewHandler(app.slashingKeeper)).
|
AddRoute(slashing.RouterKey, slashing.NewHandler(app.slashingKeeper)).
|
||||||
|
|
|
@ -1,100 +0,0 @@
|
||||||
// Package bank contains a forked version of the bank module. It only contains
|
|
||||||
// a modified message handler to support a very limited form of transfers during
|
|
||||||
// mainnet launch -- MsgMultiSend messages.
|
|
||||||
//
|
|
||||||
// NOTE: This fork should be removed entirely once transfers are enabled and
|
|
||||||
// the Gaia router should be reset to using the original bank module handler.
|
|
||||||
package bank
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/tendermint/tendermint/crypto"
|
|
||||||
|
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
|
||||||
"github.com/cosmos/cosmos-sdk/x/bank"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
uatomDenom = "uatom"
|
|
||||||
atomsToUatoms = int64(1000000)
|
|
||||||
|
|
||||||
// BurnedCoinsAccAddr represents the burn account address used for
|
|
||||||
// MsgMultiSend message during the period for which transfers are disabled.
|
|
||||||
// Its Bech32 address is cosmos1x4p90uuy63fqzsheamn48vq88q3eusykf0a69v.
|
|
||||||
BurnedCoinsAccAddr = sdk.AccAddress(crypto.AddressHash([]byte("bankBurnedCoins")))
|
|
||||||
)
|
|
||||||
|
|
||||||
// NewHandler returns a handler for "bank" type messages.
|
|
||||||
func NewHandler(k bank.Keeper) sdk.Handler {
|
|
||||||
return func(ctx sdk.Context, msg sdk.Msg) sdk.Result {
|
|
||||||
switch msg := msg.(type) {
|
|
||||||
case bank.MsgSend:
|
|
||||||
return handleMsgSend(ctx, k, msg)
|
|
||||||
|
|
||||||
case bank.MsgMultiSend:
|
|
||||||
return handleMsgMultiSend(ctx, k, msg)
|
|
||||||
|
|
||||||
default:
|
|
||||||
errMsg := "Unrecognized bank Msg type: %s" + msg.Type()
|
|
||||||
return sdk.ErrUnknownRequest(errMsg).Result()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// handleMsgSend implements a MsgSend message handler. It operates no differently
|
|
||||||
// than the standard bank module MsgSend message handler in that it transfers
|
|
||||||
// an amount from one account to another under the condition of transfers being
|
|
||||||
// enabled.
|
|
||||||
func handleMsgSend(ctx sdk.Context, k bank.Keeper, msg bank.MsgSend) sdk.Result {
|
|
||||||
// No need to modify handleMsgSend as the forked module requires no changes,
|
|
||||||
// so we can just call the standard bank modules handleMsgSend since we know
|
|
||||||
// the message is of type MsgSend.
|
|
||||||
return bank.NewHandler(k)(ctx, msg)
|
|
||||||
}
|
|
||||||
|
|
||||||
// handleMsgMultiSend implements a modified forked version of a MsgMultiSend
|
|
||||||
// message handler. If transfers are disabled, a modified version of MsgMultiSend
|
|
||||||
// is allowed where there must be a single input and only two outputs. The first
|
|
||||||
// of the two outputs must be to a specific burn address defined by
|
|
||||||
// burnedCoinsAccAddr. In addition, the output amounts must be of 9atom and
|
|
||||||
// 1uatom respectively.
|
|
||||||
func handleMsgMultiSend(ctx sdk.Context, k bank.Keeper, msg bank.MsgMultiSend) sdk.Result {
|
|
||||||
// NOTE: totalIn == totalOut should already have been checked
|
|
||||||
if !k.GetSendEnabled(ctx) {
|
|
||||||
if !validateMultiSendTransfersDisabled(msg) {
|
|
||||||
return bank.ErrSendDisabled(k.Codespace()).Result()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
tags, err := k.InputOutputCoins(ctx, msg.Inputs, msg.Outputs)
|
|
||||||
if err != nil {
|
|
||||||
return err.Result()
|
|
||||||
}
|
|
||||||
|
|
||||||
return sdk.Result{
|
|
||||||
Tags: tags,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func validateMultiSendTransfersDisabled(msg bank.MsgMultiSend) bool {
|
|
||||||
nineAtoms := sdk.Coins{sdk.NewInt64Coin(uatomDenom, 9*atomsToUatoms)}
|
|
||||||
oneAtom := sdk.Coins{sdk.NewInt64Coin(uatomDenom, 1*atomsToUatoms)}
|
|
||||||
|
|
||||||
if len(msg.Inputs) != 1 {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if len(msg.Outputs) != 2 {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
if !msg.Outputs[0].Address.Equals(BurnedCoinsAccAddr) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if !msg.Outputs[0].Coins.IsEqual(nineAtoms) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if !msg.Outputs[1].Coins.IsEqual(oneAtom) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
|
|
@ -1,216 +0,0 @@
|
||||||
package bank
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
abci "github.com/tendermint/tendermint/abci/types"
|
|
||||||
"github.com/tendermint/tendermint/crypto/secp256k1"
|
|
||||||
dbm "github.com/tendermint/tendermint/libs/db"
|
|
||||||
"github.com/tendermint/tendermint/libs/log"
|
|
||||||
|
|
||||||
"github.com/cosmos/cosmos-sdk/codec"
|
|
||||||
"github.com/cosmos/cosmos-sdk/store"
|
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
|
||||||
"github.com/cosmos/cosmos-sdk/x/auth"
|
|
||||||
"github.com/cosmos/cosmos-sdk/x/bank"
|
|
||||||
"github.com/cosmos/cosmos-sdk/x/params"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
addrs = []sdk.AccAddress{
|
|
||||||
sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()),
|
|
||||||
sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()),
|
|
||||||
sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()),
|
|
||||||
}
|
|
||||||
|
|
||||||
initAmt = sdk.NewInt(atomsToUatoms * 100)
|
|
||||||
)
|
|
||||||
|
|
||||||
type testInput struct {
|
|
||||||
ctx sdk.Context
|
|
||||||
accKeeper auth.AccountKeeper
|
|
||||||
bankKeeper bank.Keeper
|
|
||||||
}
|
|
||||||
|
|
||||||
func newTestCodec() *codec.Codec {
|
|
||||||
cdc := codec.New()
|
|
||||||
|
|
||||||
bank.RegisterCodec(cdc)
|
|
||||||
auth.RegisterCodec(cdc)
|
|
||||||
sdk.RegisterCodec(cdc)
|
|
||||||
codec.RegisterCrypto(cdc)
|
|
||||||
|
|
||||||
return cdc
|
|
||||||
}
|
|
||||||
|
|
||||||
func createTestInput(t *testing.T) testInput {
|
|
||||||
keyAcc := sdk.NewKVStoreKey(auth.StoreKey)
|
|
||||||
keyParams := sdk.NewKVStoreKey(params.StoreKey)
|
|
||||||
tKeyParams := sdk.NewTransientStoreKey(params.TStoreKey)
|
|
||||||
|
|
||||||
cdc := newTestCodec()
|
|
||||||
db := dbm.NewMemDB()
|
|
||||||
ms := store.NewCommitMultiStore(db)
|
|
||||||
ctx := sdk.NewContext(ms, abci.Header{Time: time.Now().UTC()}, false, log.NewNopLogger())
|
|
||||||
|
|
||||||
ms.MountStoreWithDB(keyAcc, sdk.StoreTypeIAVL, db)
|
|
||||||
ms.MountStoreWithDB(tKeyParams, sdk.StoreTypeTransient, db)
|
|
||||||
ms.MountStoreWithDB(keyParams, sdk.StoreTypeIAVL, db)
|
|
||||||
|
|
||||||
require.NoError(t, ms.LoadLatestVersion())
|
|
||||||
|
|
||||||
paramsKeeper := params.NewKeeper(cdc, keyParams, tKeyParams)
|
|
||||||
accKeeper := auth.NewAccountKeeper(
|
|
||||||
cdc,
|
|
||||||
keyAcc,
|
|
||||||
paramsKeeper.Subspace(auth.DefaultParamspace),
|
|
||||||
auth.ProtoBaseAccount,
|
|
||||||
)
|
|
||||||
|
|
||||||
bankKeeper := bank.NewBaseKeeper(
|
|
||||||
accKeeper,
|
|
||||||
paramsKeeper.Subspace(bank.DefaultParamspace),
|
|
||||||
bank.DefaultCodespace,
|
|
||||||
)
|
|
||||||
|
|
||||||
for _, addr := range addrs {
|
|
||||||
_, _, err := bankKeeper.AddCoins(ctx, addr, sdk.Coins{sdk.NewCoin(uatomDenom, initAmt)})
|
|
||||||
require.NoError(t, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return testInput{ctx, accKeeper, bankKeeper}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestHandlerMsgSendTransfersDisabled(t *testing.T) {
|
|
||||||
input := createTestInput(t)
|
|
||||||
input.bankKeeper.SetSendEnabled(input.ctx, false)
|
|
||||||
|
|
||||||
handler := NewHandler(input.bankKeeper)
|
|
||||||
amt := sdk.NewInt(atomsToUatoms * 5)
|
|
||||||
msg := bank.NewMsgSend(addrs[0], addrs[1], sdk.Coins{sdk.NewCoin(uatomDenom, amt)})
|
|
||||||
|
|
||||||
res := handler(input.ctx, msg)
|
|
||||||
require.False(t, res.IsOK(), "expected failed message execution: %v", res.Log)
|
|
||||||
|
|
||||||
from := input.accKeeper.GetAccount(input.ctx, addrs[0])
|
|
||||||
require.Equal(t, from.GetCoins(), sdk.Coins{sdk.NewCoin(uatomDenom, initAmt)})
|
|
||||||
|
|
||||||
to := input.accKeeper.GetAccount(input.ctx, addrs[1])
|
|
||||||
require.Equal(t, to.GetCoins(), sdk.Coins{sdk.NewCoin(uatomDenom, initAmt)})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestHandlerMsgSendTransfersEnabled(t *testing.T) {
|
|
||||||
input := createTestInput(t)
|
|
||||||
input.bankKeeper.SetSendEnabled(input.ctx, true)
|
|
||||||
|
|
||||||
handler := NewHandler(input.bankKeeper)
|
|
||||||
amt := sdk.NewInt(atomsToUatoms * 5)
|
|
||||||
msg := bank.NewMsgSend(addrs[0], addrs[1], sdk.Coins{sdk.NewCoin(uatomDenom, amt)})
|
|
||||||
|
|
||||||
res := handler(input.ctx, msg)
|
|
||||||
require.True(t, res.IsOK(), "expected successful message execution: %v", res.Log)
|
|
||||||
|
|
||||||
from := input.accKeeper.GetAccount(input.ctx, addrs[0])
|
|
||||||
balance := initAmt.Sub(amt)
|
|
||||||
require.Equal(t, from.GetCoins(), sdk.Coins{sdk.NewCoin(uatomDenom, balance)})
|
|
||||||
|
|
||||||
to := input.accKeeper.GetAccount(input.ctx, addrs[1])
|
|
||||||
balance = initAmt.Add(amt)
|
|
||||||
require.Equal(t, to.GetCoins(), sdk.Coins{sdk.NewCoin(uatomDenom, balance)})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestHandlerMsgMultiSendTransfersDisabledBurn(t *testing.T) {
|
|
||||||
input := createTestInput(t)
|
|
||||||
input.bankKeeper.SetSendEnabled(input.ctx, false)
|
|
||||||
|
|
||||||
handler := NewHandler(input.bankKeeper)
|
|
||||||
totalAmt := sdk.NewInt(10 * atomsToUatoms)
|
|
||||||
burnAmt := sdk.NewInt(9 * atomsToUatoms)
|
|
||||||
transAmt := sdk.NewInt(1 * atomsToUatoms)
|
|
||||||
msg := bank.NewMsgMultiSend(
|
|
||||||
[]bank.Input{
|
|
||||||
bank.NewInput(addrs[0], sdk.Coins{sdk.NewCoin(uatomDenom, totalAmt)}),
|
|
||||||
},
|
|
||||||
[]bank.Output{
|
|
||||||
bank.NewOutput(BurnedCoinsAccAddr, sdk.Coins{sdk.NewCoin(uatomDenom, burnAmt)}),
|
|
||||||
bank.NewOutput(addrs[1], sdk.Coins{sdk.NewCoin(uatomDenom, transAmt)}),
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
res := handler(input.ctx, msg)
|
|
||||||
require.True(t, res.IsOK(), "expected successful message execution: %v", res.Log)
|
|
||||||
|
|
||||||
from := input.accKeeper.GetAccount(input.ctx, addrs[0])
|
|
||||||
balance := initAmt.Sub(totalAmt)
|
|
||||||
require.Equal(t, from.GetCoins(), sdk.Coins{sdk.NewCoin(uatomDenom, balance)})
|
|
||||||
|
|
||||||
to := input.accKeeper.GetAccount(input.ctx, addrs[1])
|
|
||||||
balance = initAmt.Add(transAmt)
|
|
||||||
require.Equal(t, to.GetCoins(), sdk.Coins{sdk.NewCoin(uatomDenom, balance)})
|
|
||||||
|
|
||||||
burn := input.accKeeper.GetAccount(input.ctx, BurnedCoinsAccAddr)
|
|
||||||
require.Equal(t, burn.GetCoins(), sdk.Coins{sdk.NewCoin(uatomDenom, burnAmt)})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestHandlerMsgMultiSendTransfersDisabledInvalidBurn(t *testing.T) {
|
|
||||||
input := createTestInput(t)
|
|
||||||
input.bankKeeper.SetSendEnabled(input.ctx, false)
|
|
||||||
|
|
||||||
handler := NewHandler(input.bankKeeper)
|
|
||||||
totalAmt := sdk.NewInt(15 * atomsToUatoms)
|
|
||||||
burnAmt := sdk.NewInt(10 * atomsToUatoms)
|
|
||||||
transAmt := sdk.NewInt(5 * atomsToUatoms)
|
|
||||||
msg := bank.NewMsgMultiSend(
|
|
||||||
[]bank.Input{
|
|
||||||
bank.NewInput(addrs[0], sdk.Coins{sdk.NewCoin(uatomDenom, totalAmt)}),
|
|
||||||
},
|
|
||||||
[]bank.Output{
|
|
||||||
bank.NewOutput(BurnedCoinsAccAddr, sdk.Coins{sdk.NewCoin(uatomDenom, burnAmt)}),
|
|
||||||
bank.NewOutput(addrs[1], sdk.Coins{sdk.NewCoin(uatomDenom, transAmt)}),
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
res := handler(input.ctx, msg)
|
|
||||||
require.False(t, res.IsOK(), "expected failed message execution: %v", res.Log)
|
|
||||||
|
|
||||||
from := input.accKeeper.GetAccount(input.ctx, addrs[0])
|
|
||||||
require.Equal(t, from.GetCoins(), sdk.Coins{sdk.NewCoin(uatomDenom, initAmt)})
|
|
||||||
|
|
||||||
to := input.accKeeper.GetAccount(input.ctx, addrs[1])
|
|
||||||
require.Equal(t, to.GetCoins(), sdk.Coins{sdk.NewCoin(uatomDenom, initAmt)})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestHandlerMsgMultiSendTransfersEnabled(t *testing.T) {
|
|
||||||
input := createTestInput(t)
|
|
||||||
input.bankKeeper.SetSendEnabled(input.ctx, true)
|
|
||||||
|
|
||||||
handler := NewHandler(input.bankKeeper)
|
|
||||||
totalAmt := sdk.NewInt(10 * atomsToUatoms)
|
|
||||||
outAmt := sdk.NewInt(5 * atomsToUatoms)
|
|
||||||
msg := bank.NewMsgMultiSend(
|
|
||||||
[]bank.Input{
|
|
||||||
bank.NewInput(addrs[0], sdk.Coins{sdk.NewCoin(uatomDenom, totalAmt)}),
|
|
||||||
},
|
|
||||||
[]bank.Output{
|
|
||||||
bank.NewOutput(addrs[1], sdk.Coins{sdk.NewCoin(uatomDenom, outAmt)}),
|
|
||||||
bank.NewOutput(addrs[2], sdk.Coins{sdk.NewCoin(uatomDenom, outAmt)}),
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
res := handler(input.ctx, msg)
|
|
||||||
require.True(t, res.IsOK(), "expected successful message execution: %v", res.Log)
|
|
||||||
|
|
||||||
from := input.accKeeper.GetAccount(input.ctx, addrs[0])
|
|
||||||
balance := initAmt.Sub(totalAmt)
|
|
||||||
require.Equal(t, from.GetCoins(), sdk.Coins{sdk.NewCoin(uatomDenom, balance)})
|
|
||||||
|
|
||||||
out1 := input.accKeeper.GetAccount(input.ctx, addrs[1])
|
|
||||||
balance = initAmt.Add(outAmt)
|
|
||||||
require.Equal(t, out1.GetCoins(), sdk.Coins{sdk.NewCoin(uatomDenom, balance)})
|
|
||||||
|
|
||||||
out2 := input.accKeeper.GetAccount(input.ctx, addrs[2])
|
|
||||||
balance = initAmt.Add(outAmt)
|
|
||||||
require.Equal(t, out2.GetCoins(), sdk.Coins{sdk.NewCoin(uatomDenom, balance)})
|
|
||||||
}
|
|
Loading…
Reference in New Issue