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

[Hotfix] prevent huge gas tx #462

Merged
merged 2 commits into from
Mar 18, 2021
Merged
Show file tree
Hide file tree
Changes from all 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
17 changes: 16 additions & 1 deletion app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (

treasuryclient "github.com/terra-project/core/x/treasury/client"

core "github.com/terra-project/core/types"
"github.com/terra-project/core/x/auth"
"github.com/terra-project/core/x/auth/ante"
"github.com/terra-project/core/x/auth/vesting"
Expand Down Expand Up @@ -367,7 +368,21 @@ func (app *TerraApp) BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock) a

// EndBlocker defines application updates at every end block
func (app *TerraApp) EndBlocker(ctx sdk.Context, req abci.RequestEndBlock) abci.ResponseEndBlock {
return app.mm.EndBlock(ctx, req)
res := app.mm.EndBlock(ctx, req)
if core.IsSoftforkHeight(ctx, 3) {
return abci.ResponseEndBlock{
ConsensusParamUpdates: &abci.ConsensusParams{
Block: &abci.BlockParams{
MaxBytes: 1000000,
MaxGas: 30000000,
},
},
ValidatorUpdates: res.ValidatorUpdates,
Events: res.Events,
}
}

return res
}

// InitChainer defines application update at chain initialization
Expand Down
71 changes: 55 additions & 16 deletions types/util/softfork.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,64 @@ import sdk "github.com/cosmos/cosmos-sdk/types"

// IsWaitingForSoftfork returns whether current block
// height is bigger than reserved softfork block height
func IsWaitingForSoftfork(ctx sdk.Context, _version uint8) bool {
// Expected time:
// MAINNET
// Fri Jan 01 2021 18:00:00 GMT+0900 (KST)
// Fri Jan 01 2021 09:00:00 GMT+0000 (UTC)
// Fri Jan 01 2021 01:00:00 GMT-0800 (PST)
//
// TEQUILA
// Fri Nov 27 2020 12:00:00 GMT+0900 (KST)
// Fri Nov 27 2020 03:00:00 GMT+0000 (UTC)
// Fri Nov 26 2020 19:00:00 GMT-0800 (KST)
func IsWaitingForSoftfork(ctx sdk.Context, version uint8) bool {
if version == 1 {
// Expected time:
// MAINNET
// Fri Jan 01 2021 18:00:00 GMT+0900 (KST)
// Fri Jan 01 2021 09:00:00 GMT+0000 (UTC)
// Fri Jan 01 2021 01:00:00 GMT-0800 (PST)
//
// TEQUILA
// Fri Nov 27 2020 12:00:00 GMT+0900 (KST)
// Fri Nov 27 2020 03:00:00 GMT+0000 (UTC)
// Fri Nov 26 2020 19:00:00 GMT-0800 (KST)

return (ctx.ChainID() == "columbus-4" && ctx.BlockHeight() < 1200000) ||
(ctx.ChainID() == "tequila-0004" && ctx.BlockHeight() < 1350000)
return (ctx.ChainID() == "columbus-4" && ctx.BlockHeight() < 1200000) ||
(ctx.ChainID() == "tequila-0004" && ctx.BlockHeight() < 1350000)
} else if version == 2 {
// Expected time:
// MAINNET
// Tue Mar 30 2021 18:00:00 GMT+0900 (KST)
// Tue Mar 30 2021 09:00:00 GMT+0000 (UTC)
// Tue Mar 30 2021 01:00:00 GMT-0800 (PST)
//
// TEQUILA
// ASAP
return (ctx.ChainID() == "columbus-4" && ctx.BlockHeight() < 2380000) ||
(ctx.ChainID() == "tequila-0004" && ctx.BlockHeight() < 3052265)
} else if version == 3 {
// Expected time:
// MAINNET
// Tue Mar 30 2021 18:00:00 GMT+0900 (KST)
// Tue Mar 30 2021 09:00:00 GMT+0000 (UTC)
// Tue Mar 30 2021 01:00:00 GMT-0800 (PST)
//
// TEQUILA
// Tue Mar 25 2021 18:00:00 GMT+0900 (KST)
// Tue Mar 25 2021 09:00:00 GMT+0000 (UTC)
// Tue Mar 25 2021 01:00:00 GMT-0800 (PST)

return (ctx.ChainID() == "columbus-4" && ctx.BlockHeight() < 2380000) ||
(ctx.ChainID() == "tequila-0004" && ctx.BlockHeight() < 3150000)
}

return false
}

// IsSoftforkHeight return whether current block
// height is the targeted softfork height
func IsSoftforkHeight(ctx sdk.Context, _version uint8) bool {
return (ctx.ChainID() == "columbus-4" && ctx.BlockHeight() == 1200000) ||
(ctx.ChainID() == "tequila-0004" && ctx.BlockHeight() == 1350000)
func IsSoftforkHeight(ctx sdk.Context, version uint8) bool {
if version == 1 {
return (ctx.ChainID() == "columbus-4" && ctx.BlockHeight() == 1200000) ||
(ctx.ChainID() == "tequila-0004" && ctx.BlockHeight() == 1350000)
} else if version == 2 {
return (ctx.ChainID() == "columbus-4" && ctx.BlockHeight() == 2380000) ||
(ctx.ChainID() == "tequila-0004" && ctx.BlockHeight() == 3052265)
} else if version == 3 {
return (ctx.ChainID() == "columbus-4" && ctx.BlockHeight() == 2380000) ||
(ctx.ChainID() == "tequila-0004" && ctx.BlockHeight() == 3150000)
}

return false
}
21 changes: 15 additions & 6 deletions x/auth/ante/spamming_prevention.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@ import (
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
"github.com/spf13/viper"

core "github.com/terra-project/core/types"
)

// FlagTxGasHardLimit defines the hard cap to prevent tx spamming attack
const FlagTxGasHardLimit = "tx-gas-hard-limit"
const transactionGasHardCap = 30000000

// SpammingPreventionDecorator will check if the transaction's gas is smaller than
// configured hard cap
Expand All @@ -21,18 +24,24 @@ func NewSpammingPreventionDecorator() SpammingPreventionDecorator {

// AnteHandle handles msg tax fee checking
func (spd SpammingPreventionDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (newCtx sdk.Context, err error) {
if ctx.IsCheckTx() {
feeTx, ok := tx.(FeeTx)
if !ok {
return ctx, sdkerrors.Wrap(sdkerrors.ErrTxDecode, "Tx must be a FeeTx")
}
feeTx, ok := tx.(FeeTx)
if !ok {
return ctx, sdkerrors.Wrap(sdkerrors.ErrTxDecode, "Tx must be a FeeTx")
}

gas := feeTx.GetGas()
gas := feeTx.GetGas()
if ctx.IsCheckTx() {
gasHardLimit := viper.GetUint64(FlagTxGasHardLimit)
if gas > gasHardLimit {
return ctx, sdkerrors.Wrapf(sdkerrors.ErrOutOfGas, "Tx cannot spend more than %d gas", gasHardLimit)
}
}

if !core.IsWaitingForSoftfork(ctx, 2) {
if gas > transactionGasHardCap {
return ctx, sdkerrors.Wrap(sdkerrors.ErrOutOfGas, "Tx exceed max gas usage")
}
}

return next(ctx, tx, simulate)
}
73 changes: 73 additions & 0 deletions x/auth/ante/spamming_prevention_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package ante_test

import (
"io/ioutil"
"os"
"testing"

"github.com/cosmos/cosmos-sdk/client/flags"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/auth/types"
"github.com/spf13/viper"
"github.com/stretchr/testify/require"
"github.com/tendermint/tendermint/crypto"
"github.com/terra-project/core/x/auth/ante"
)

func TestEnsureSoftforkGasCheck(t *testing.T) {
tempDir, err := ioutil.TempDir("", "wasmtest")
require.NoError(t, err)
defer os.RemoveAll(tempDir)
viper.Set(flags.FlagHome, tempDir)

_, ctx := createTestApp()

// setup
spd := ante.NewSpammingPreventionDecorator()
antehandler := sdk.ChainAnteDecorators(spd)

// keys and addresses
priv1, _, addr1 := types.KeyTestPubAddr()

// msg and signatures
msg1 := types.NewTestMsg(addr1)
fee := types.NewTestStdFee()
fee.Gas = 100000000

msgs := []sdk.Msg{msg1}

privs, accNums, seqs := []crypto.PrivKey{priv1}, []uint64{0}, []uint64{0}
tx := types.NewTestTx(ctx, msgs, privs, accNums, seqs, fee)

// Set IsCheckTx to true
ctx = ctx.WithIsCheckTx(true)

// antehandler errors with insufficient fees
_, err = antehandler(ctx, tx, false)
require.Error(t, err, "Decorator should have errored on too high gas for local gasPrice")

// Set IsCheckTx to false
ctx = ctx.WithIsCheckTx(false)

// antehandler should not error since we do not check minGasPrice in DeliverTx
_, err = antehandler(ctx, tx, false)
require.Error(t, err, "Decorator should have errored on too high gas for local gasPrice")

// Set ChainID to columbus-4 and height to before fork
ctx = ctx.WithChainID("columbus-4")
ctx = ctx.WithBlockHeight(2379999)

_, err = antehandler(ctx, tx, false)
require.NoError(t, err, "SpammingPreventionDecorator returned error in DeliverTx")

// Set height to after fork
ctx = ctx.WithBlockHeight(2380000)

_, err = antehandler(ctx, tx, false)
require.Error(t, err, "Decorator should have errored on high gas than hard cap")

ctx = ctx.WithBlockHeight(2380001)

_, err = antehandler(ctx, tx, false)
require.Error(t, err, "Decorator should have errored on high gas than hard cap")
}