Skip to content

Commit

Permalink
Merge pull request #260 from persistenceOne/ajeet/prepare-v10.2.0
Browse files Browse the repository at this point in the history
tx fee denom whiltelist + PFM ViperStrike patch
  • Loading branch information
ajeet97 authored Dec 10, 2023
2 parents 78140b1 + 37c0c43 commit b19c04c
Show file tree
Hide file tree
Showing 8 changed files with 210 additions and 7 deletions.
3 changes: 3 additions & 0 deletions app/ante_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ type HandlerOptions struct {
TxDecoder sdk.TxDecoder
TxEncoder sdk.TxEncoder
BuilderKeeper *builderkeeper.Keeper

FeeDenomsWhitelist []string
}

func NewAnteHandler(options HandlerOptions) (sdk.AnteHandler, error) {
Expand Down Expand Up @@ -57,6 +59,7 @@ func NewAnteHandler(options HandlerOptions) (sdk.AnteHandler, error) {
ante.NewTxTimeoutHeightDecorator(),
ante.NewValidateMemoDecorator(options.AccountKeeper),
ante.NewConsumeGasForTxSizeDecorator(options.AccountKeeper),
NewFeeDenomWhitelistDecorator(options.FeeDenomsWhitelist),
ante.NewDeductFeeDecorator(options.AccountKeeper, options.BankKeeper, options.FeegrantKeeper, options.TxFeeChecker),
// SetPubKeyDecorator must be called before all signature verification decorators
ante.NewSetPubKeyDecorator(options.AccountKeeper),
Expand Down
14 changes: 14 additions & 0 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,8 @@ func (app *Application) setupPOBAndAnteHandler(wasmConfig wasmtypes.WasmConfig)
Mempool: mempool,
TxDecoder: app.txConfig.TxDecoder(),
TxEncoder: app.txConfig.TxEncoder(),

FeeDenomsWhitelist: app.GetFeeDenomsWhitelist(),
}
anteHandler, err := NewAnteHandler(anteOptions)
if err != nil {
Expand Down Expand Up @@ -340,6 +342,18 @@ func (app *Application) GetChainBondDenom() string {
return "stake"
}

func (app *Application) GetFeeDenomsWhitelist() []string {
chainID := app.ChainID()

if strings.HasPrefix(chainID, "core-") {
return FeeDenomsWhitelistMainnet
} else if strings.HasPrefix(chainID, "test-core-") {
return FeeDenomsWhitelistTestnet
}

return []string{"stake"}
}

// CheckTx will check the transaction with the provided checkTxHandler. We override the default
// handler so that we can verify bid transactions before they are inserted into the mempool.
// With the POB CheckTx, we can verify the bid transaction and all of the bundled transactions
Expand Down
16 changes: 16 additions & 0 deletions app/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,19 @@ const (
Bech32PrefixConsAddr = Bech32MainPrefix + sdk.PrefixValidator + sdk.PrefixConsensus
Bech32PrefixConsPub = Bech32MainPrefix + sdk.PrefixValidator + sdk.PrefixConsensus + sdk.PrefixPublic
)

var (
FeeDenomsWhitelistMainnet = []string{
BondDenom, // XPRT
"ibc/C8A74ABBE2AF892E15680D916A7C22130585CE5704F9B17A10F184A90D53BECA", // ATOM
"ibc/A6E3AF63B3C906416A9AF7A556C59EA4BD50E617EFFE6299B99700CCB780E444", // pSTAKE
"ibc/646315E3B0461F5FA4C5C8968A88FC45D4D5D04A45B98F1B8294DD82F386DD85", // OSMO
"stk/uatom", // stkATOM
"stk/uosmo", // stkOSMO
}

FeeDenomsWhitelistTestnet = []string{
BondDenom, // XPRT
"ibc/C4CFF46FD6DE35CA4CF4CE031E643C8FDC9BA4B99AE598E9B0ED98FE3A2319F9", // ATOM
}
)
53 changes: 53 additions & 0 deletions app/fee_denom_whitelist_decorator.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package app

import (
"fmt"
"strings"

errorsmod "cosmossdk.io/errors"

sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
)

type FeeDenomWhitelistDecorator struct {
whitelistMap map[string]struct{}
whitelistStr string // this is used for err msg only
}

func NewFeeDenomWhitelistDecorator(denomsWhitelist []string) *FeeDenomWhitelistDecorator {
if len(denomsWhitelist) == 0 {
panic("at least one fee denom must be whitelisted")
}

whitelistMap := map[string]struct{}{}
for _, denom := range denomsWhitelist {
// must be valid denom
if err := sdk.ValidateDenom(denom); err != nil {
panic(fmt.Sprintf("invalid denoms whiltelist; err: %v", err))
}
whitelistMap[denom] = struct{}{}
}

return &FeeDenomWhitelistDecorator{
whitelistMap: whitelistMap,
whitelistStr: strings.Join(denomsWhitelist, ","),
}
}

func (fdd *FeeDenomWhitelistDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (newCtx sdk.Context, err error) {
feeTx, ok := tx.(sdk.FeeTx)
if !ok {
return ctx, errorsmod.Wrap(sdkerrors.ErrTxDecode, "Tx must be a FeeTx")
}

feeCoins := feeTx.GetFee()
for _, coin := range feeCoins {
if _, found := fdd.whitelistMap[coin.Denom]; !found {
return ctx, errorsmod.Wrapf(sdkerrors.ErrInvalidCoins,
"fee denom is not allowed; got: %v, allowed: %v",
coin.Denom, fdd.whitelistStr)
}
}
return next(ctx, tx, simulate)
}
117 changes: 117 additions & 0 deletions app/fee_denom_whitelist_decorator_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
package app

import (
"testing"

"cosmossdk.io/math"
"github.com/stretchr/testify/require"

"github.com/cometbft/cometbft/libs/log"
tmtypes "github.com/cometbft/cometbft/proto/tendermint/types"
sdk "github.com/cosmos/cosmos-sdk/types"
)

func TestFeeDenomWhiltelistDecorator(t *testing.T) {
testDenomsWhitelist := []string{
"uxprt",
"ibc/C8A74ABBE2AF892E15680D916A7C22130585CE5704F9B17A10F184A90D53BECA",
}

testcases := []struct {
name string
txFee sdk.Coins
denomsWhitelist []string
expectedErr string
panics bool
}{
{
name: "empty denoms list",
txFee: coins(),
denomsWhitelist: []string{},
expectedErr: "at least one fee denom must be whitelisted",
panics: true,
},
{
name: "invalid denoms list",
txFee: coins(),
denomsWhitelist: []string{"a"},
expectedErr: "invalid denoms whiltelist; err: invalid denom: a",
panics: true,
},
{
name: "valid denoms - valid fee",
txFee: coins(10, "uxprt"),
denomsWhitelist: testDenomsWhitelist,
expectedErr: "",
},
{
name: "valid denoms - multiple valid fees",
txFee: coins(10, testDenomsWhitelist[1], 10, "uxprt"),
denomsWhitelist: testDenomsWhitelist,
expectedErr: "",
},
{
name: "valid denoms - invalid fee",
txFee: coins(10, "abcd"),
denomsWhitelist: testDenomsWhitelist,
expectedErr: "fee denom is not allowed; got: abcd, allowed: uxprt,ibc/C8A74ABBE2AF892E15680D916A7C22130585CE5704F9B17A10F184A90D53BECA: invalid coins",
},
{
name: "valid denoms - multiple invalid fee",
txFee: coins(10, "uxprt", 10, "xyz"),
denomsWhitelist: testDenomsWhitelist,
expectedErr: "fee denom is not allowed; got: xyz, allowed: uxprt,ibc/C8A74ABBE2AF892E15680D916A7C22130585CE5704F9B17A10F184A90D53BECA: invalid coins",
},
}

isCheckTx := false
ctx := sdk.NewContext(nil, tmtypes.Header{}, isCheckTx, log.NewNopLogger())
for _, tc := range testcases {
t.Run(tc.name, func(t *testing.T) {
defer func() {
r := recover()
if tc.panics {
require.Equal(t, r, tc.expectedErr)
} else {
require.Nil(t, r, "Test did not panic")
}
}()

fdd := NewFeeDenomWhitelistDecorator(tc.denomsWhitelist)
antehandlerFFD := sdk.ChainAnteDecorators(fdd)
tx := &mockFeeTx{fee: tc.txFee}

_, err := antehandlerFFD(ctx, tx, false)

if tc.expectedErr == "" {
require.NoError(t, err)
} else {
require.EqualError(t, err, tc.expectedErr)
}
})
}
}

func coins(amountDenomPairs ...interface{}) sdk.Coins {
coins := sdk.Coins{}
for i := 0; i < len(amountDenomPairs); i += 2 {
coins = append(coins, sdk.Coin{
Amount: math.NewInt(int64(amountDenomPairs[i].(int))),
Denom: amountDenomPairs[i+1].(string),
})
}
return coins
}

var _ sdk.Tx = (*mockFeeTx)(nil)
var _ sdk.FeeTx = (*mockFeeTx)(nil)

type mockFeeTx struct{ fee sdk.Coins }

func (m *mockFeeTx) GetFee() sdk.Coins { return m.fee }
func (m *mockFeeTx) GetGas() uint64 { return 1 }

func (*mockFeeTx) FeeGranter() sdk.AccAddress { return nil }
func (*mockFeeTx) FeePayer() sdk.AccAddress { return nil }
func (*mockFeeTx) GetMsgs() []sdk.Msg { return nil }
func (*mockFeeTx) ValidateBasic() error { return nil }
2 changes: 1 addition & 1 deletion docker/persistencecore/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ WORKDIR /usr/local/app
COPY . .

# Force it to use static lib (from above) not standard libgo_cosmwasm.so file
RUN LEDGER_ENABLED=false BUILD_TAGS="muslc linkstatic" make build
RUN LEDGER_ENABLED=true BUILD_TAGS="muslc linkstatic" LDFLAGS='-linkmode external -extldflags "-static"' make build
RUN echo "Ensuring binary is statically linked ..." \
&& (file /usr/local/app/bin/persistenceCore | grep "statically linked")

Expand Down
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -203,8 +203,8 @@ replace (
replace (
github.com/CosmWasm/wasmd => github.com/persistenceOne/wasmd v0.40.2-lsm3
github.com/cosmos/cosmos-sdk => github.com/persistenceOne/cosmos-sdk v0.47.3-lsm5
github.com/cosmos/ibc-apps/middleware/packet-forward-middleware/v7 => github.com/persistenceOne/ibc-apps/middleware/packet-forward-middleware/v7 v7.0.0-20231013113028-ed5200e45b3f
github.com/cosmos/ibc-apps/modules/ibc-hooks/v7 => github.com/persistenceOne/ibc-apps/modules/ibc-hooks/v7 v7.0.0-20231013113028-ed5200e45b3f
github.com/cosmos/ibc-apps/middleware/packet-forward-middleware/v7 => github.com/persistenceOne/ibc-apps/middleware/packet-forward-middleware/v7 v7.0.0-20231208060526-73231b958bd4
github.com/cosmos/ibc-apps/modules/ibc-hooks/v7 => github.com/persistenceOne/ibc-apps/modules/ibc-hooks/v7 v7.0.0-20231208060526-73231b958bd4
github.com/cosmos/ibc-go/v7 => github.com/persistenceOne/ibc-go/v7 v7.2.0-lsm3
github.com/skip-mev/pob => github.com/persistenceOne/pob v1.0.3-lsm3
)
8 changes: 4 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -1011,10 +1011,10 @@ github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNc
github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac=
github.com/persistenceOne/cosmos-sdk v0.47.3-lsm5 h1:z5k9M81ogHgaMyLck7GVzfdNYvn03ZTXsCpQDzy69eQ=
github.com/persistenceOne/cosmos-sdk v0.47.3-lsm5/go.mod h1:4oxikyyHyEe1wlYQFMGITfW/r01wYtfj8yjwru7bSWE=
github.com/persistenceOne/ibc-apps/middleware/packet-forward-middleware/v7 v7.0.0-20231013113028-ed5200e45b3f h1:rBSSzxpWmrv0wcBL8StKY+SskBwjSm0GVQKbOoBN5gs=
github.com/persistenceOne/ibc-apps/middleware/packet-forward-middleware/v7 v7.0.0-20231013113028-ed5200e45b3f/go.mod h1:v+x4hTcShRZylXZNsK5zXFQ8QMV448rbIY4e9HDXBkY=
github.com/persistenceOne/ibc-apps/modules/ibc-hooks/v7 v7.0.0-20231013113028-ed5200e45b3f h1:7ifIPNlYNFey0DTRMLSc3b3TwSy0Gia/HQ3SVhfum+E=
github.com/persistenceOne/ibc-apps/modules/ibc-hooks/v7 v7.0.0-20231013113028-ed5200e45b3f/go.mod h1:fbwFAk6oxuKiFvp5SLCItT34A1+F5LjGcMNOTuU8h4c=
github.com/persistenceOne/ibc-apps/middleware/packet-forward-middleware/v7 v7.0.0-20231208060526-73231b958bd4 h1:7HGqX27LtoKrbOHTI1ymyT0fAHHoSd+xfxGuI8KFJ2Y=
github.com/persistenceOne/ibc-apps/middleware/packet-forward-middleware/v7 v7.0.0-20231208060526-73231b958bd4/go.mod h1:v+x4hTcShRZylXZNsK5zXFQ8QMV448rbIY4e9HDXBkY=
github.com/persistenceOne/ibc-apps/modules/ibc-hooks/v7 v7.0.0-20231208060526-73231b958bd4 h1:vxJTAcApUh/pizcdEj6KFI5dv9KeiM2RGOggJz6y3k4=
github.com/persistenceOne/ibc-apps/modules/ibc-hooks/v7 v7.0.0-20231208060526-73231b958bd4/go.mod h1:fbwFAk6oxuKiFvp5SLCItT34A1+F5LjGcMNOTuU8h4c=
github.com/persistenceOne/ibc-go/v7 v7.2.0-lsm3 h1:U4NsRXpg9VHCFVyrk1JfG+sIA3frtZIWbtNmmumjta8=
github.com/persistenceOne/ibc-go/v7 v7.2.0-lsm3/go.mod h1:PDvFOPEd8Fz25qBmhX7KXSPX4COyGnytKweRdEP1yfA=
github.com/persistenceOne/persistence-sdk/v2 v2.1.1 h1:fo8Og2QkjsqqhH/wiEiOSB99M2Jr0kLqirU2xhJRZfQ=
Expand Down

0 comments on commit b19c04c

Please sign in to comment.