Skip to content
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
7 changes: 7 additions & 0 deletions app/ante/ante.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@ package ante
import (
ibcante "github.com/cosmos/ibc-go/v8/modules/core/ante"
ibckeeper "github.com/cosmos/ibc-go/v8/modules/core/keeper"
"github.com/terra-money/core/v2/app/ante/blacklist"
feesharekeeper "github.com/terra-money/core/v2/x/feeshare/keeper"

corestoretypes "cosmossdk.io/core/store"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
"github.com/cosmos/cosmos-sdk/x/auth/ante"
Expand All @@ -27,6 +29,7 @@ type HandlerOptions struct {
TXCounterStoreService corestoretypes.KVStoreService
NodeConfig wasmTypes.NodeConfig
TxConfig client.TxConfig
Codec codec.Codec
}

// NewAnteHandler returns an AnteHandler that checks and increments sequence
Expand All @@ -44,6 +47,9 @@ func NewAnteHandler(options HandlerOptions) (sdk.AnteHandler, error) {
if options.SignModeHandler == nil {
return nil, sdkerrors.ErrLogic.Wrap("sign mode handler is required for ante builder")
}
if options.Codec == nil {
return nil, sdkerrors.ErrLogic.Wrap("codec is required for ante builder")
}

sigGasConsumer := options.SigGasConsumer
if sigGasConsumer == nil {
Expand All @@ -55,6 +61,7 @@ func NewAnteHandler(options HandlerOptions) (sdk.AnteHandler, error) {
wasmkeeper.NewLimitSimulationGasDecorator(options.NodeConfig.SimulationGasLimit),
wasmkeeper.NewCountTXDecorator(options.TXCounterStoreService),
wasmkeeper.NewTxContractsDecorator(),
blacklist.NewBlacklistDecorator(options.Codec),
ante.NewExtensionOptionsDecorator(options.ExtensionOptionChecker),
ante.NewValidateBasicDecorator(),
ante.NewTxTimeoutHeightDecorator(),
Expand Down
570 changes: 570 additions & 0 deletions app/ante/blacklist/blacklist.go

Large diffs are not rendered by default.

220 changes: 220 additions & 0 deletions app/ante/blacklist/blacklist_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,220 @@
package blacklist

import (
"errors"
"strings"
"testing"

sdk "github.com/cosmos/cosmos-sdk/types"
authsigning "github.com/cosmos/cosmos-sdk/x/auth/signing"
"github.com/cosmos/cosmos-sdk/x/authz"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"

"github.com/terra-money/core/v2/app/params"
)

type testSignedTx struct {
authsigning.SigVerifiableTx
signers [][]byte
msgs []sdk.Msg
err error
}

func (tx testSignedTx) GetSigners() ([][]byte, error) {
return tx.signers, tx.err
}

func (tx testSignedTx) GetMsgs() []sdk.Msg {
return tx.msgs
}

type testUnsignedTx struct {
sdk.Tx
}

func (testUnsignedTx) GetMsgs() []sdk.Msg {
return nil
}

type testFeeTx struct {
sdk.FeeTx
granter []byte
}

func (tx testFeeTx) FeeGranter() []byte {
return tx.granter
}

func (testFeeTx) GetMsgs() []sdk.Msg {
return nil
}

func TestBlacklistDecorator(t *testing.T) {
sdk.GetConfig().SetBech32PrefixForAccount("terra", "terrapub")
addresses := map[string]string{
"victim": "terra1kvwkvurw4xexw69ef772p95jajnjjjsq6d5uca",
"attacker": "terra1agp4wwzgn6fuxqrsqgjvfhvmfqf63ekvn9nvyh",
}
for role, address := range addresses {
if !Blacklist[address] {
t.Fatalf("%s address %s is missing from the blacklist", role, address)
}
}

allowed := sdk.AccAddress(make([]byte, 20))
decorator := NewBlacklistDecorator(params.MakeEncodingConfig().Marshaler)
ctx := sdk.Context{}
called := false
next := func(ctx sdk.Context, tx sdk.Tx, simulate bool) (sdk.Context, error) {
called = true
return ctx, nil
}

for _, address := range addresses {
blocked, err := sdk.AccAddressFromBech32(address)
if err != nil {
t.Fatal(err)
}
called = false
_, err = decorator.AnteHandle(ctx, testSignedTx{signers: [][]byte{allowed, blocked}}, false, next)
if err == nil || !strings.Contains(err.Error(), "is blacklisted") || called {
t.Fatalf("blacklisted signer %s was not rejected: err=%v, next called=%t", address, err, called)
}
}

_, err := decorator.AnteHandle(ctx, testSignedTx{signers: [][]byte{allowed}}, false, next)
if err != nil || !called {
t.Fatalf("allowed signer was not passed to next decorator: err=%v, next called=%t", err, called)
}

called = false
signerErr := errors.New("invalid signers")
_, err = decorator.AnteHandle(ctx, testSignedTx{err: signerErr}, false, next)
if !errors.Is(err, signerErr) || called {
t.Fatalf("signer error was not returned: err=%v, next called=%t", err, called)
}

_, err = decorator.AnteHandle(ctx, testUnsignedTx{}, false, next)
if err != nil || !called {
t.Fatalf("unsigned transaction was not passed to next decorator: err=%v, next called=%t", err, called)
}
}

func TestBlacklistDecoratorAuthz(t *testing.T) {
sdk.GetConfig().SetBech32PrefixForAccount("terra", "terrapub")
blocked, err := sdk.AccAddressFromBech32("terra1kvwkvurw4xexw69ef772p95jajnjjjsq6d5uca")
if err != nil {
t.Fatal(err)
}
grantee := sdk.AccAddress(make([]byte, 20))
decorator := NewBlacklistDecorator(params.MakeEncodingConfig().Marshaler)
ctx := sdk.Context{}
nextCalled := false
next := func(ctx sdk.Context, tx sdk.Tx, simulate bool) (sdk.Context, error) {
nextCalled = true
return ctx, nil
}

for _, depth := range []int{0, 1, 11} {
inner := &banktypes.MsgSend{FromAddress: blocked.String(), ToAddress: grantee.String()}
exec := authz.NewMsgExec(grantee, []sdk.Msg{inner})
for i := 0; i < depth; i++ {
innerExec := exec
exec = authz.NewMsgExec(grantee, []sdk.Msg{&innerExec})
}
nextCalled = false
_, err = decorator.AnteHandle(ctx, testSignedTx{
signers: [][]byte{grantee},
msgs: []sdk.Msg{&exec},
}, false, next)
if err == nil || !strings.Contains(err.Error(), "is blacklisted") || nextCalled {
t.Fatalf("authz bypass was not rejected (depth=%d): err=%v, next called=%t", depth, err, nextCalled)
}
}

allowed := &banktypes.MsgSend{FromAddress: grantee.String(), ToAddress: grantee.String()}
exec := authz.NewMsgExec(grantee, []sdk.Msg{allowed})
for i := 0; i < 11; i++ {
innerExec := exec
exec = authz.NewMsgExec(grantee, []sdk.Msg{&innerExec})
}
nextCalled = false
_, err = decorator.AnteHandle(ctx, testSignedTx{
signers: [][]byte{grantee},
msgs: []sdk.Msg{&exec},
}, false, next)
if err != nil || !nextCalled {
t.Fatalf("allowed deeply nested authz message was rejected: err=%v, next called=%t", err, nextCalled)
}
}

func TestBlacklistDecoratorFeeGranter(t *testing.T) {
sdk.GetConfig().SetBech32PrefixForAccount("terra", "terrapub")
blocked, err := sdk.AccAddressFromBech32("terra1kvwkvurw4xexw69ef772p95jajnjjjsq6d5uca")
if err != nil {
t.Fatal(err)
}
allowed := sdk.AccAddress(make([]byte, 20))
decorator := NewBlacklistDecorator(params.MakeEncodingConfig().Marshaler)
called := false
next := func(ctx sdk.Context, tx sdk.Tx, simulate bool) (sdk.Context, error) {
called = true
return ctx, nil
}

for _, tc := range []struct {
name string
granter []byte
blocked bool
}{
{name: "blacklisted", granter: blocked, blocked: true},
{name: "allowed", granter: allowed},
{name: "absent"},
} {
t.Run(tc.name, func(t *testing.T) {
called = false
_, err := decorator.AnteHandle(sdk.Context{}, testFeeTx{granter: tc.granter}, false, next)
if tc.blocked {
if err == nil || !strings.Contains(err.Error(), "fee granter "+blocked.String()+" is blacklisted") || called {
t.Fatalf("blacklisted fee granter was not rejected: err=%v, next called=%t", err, called)
}
} else if err != nil || !called {
t.Fatalf("allowed fee granter was rejected: err=%v, next called=%t", err, called)
}
})
}
}

func TestBlacklistDecoratorTestChainAddress(t *testing.T) {
sdk.GetConfig().SetBech32PrefixForAccount("terra", "terrapub")
address, err := sdk.AccAddressFromBech32("terra1a698u5rm2x6y50x5m3q37tnn0k6d4rjpfc8e7h")
if err != nil {
t.Fatal(err)
}
decorator := NewBlacklistDecorator(params.MakeEncodingConfig().Marshaler)

for _, tc := range []struct {
chainID string
blocked bool
}{
{chainID: "blacklist-v222-test-1", blocked: true},
{chainID: "phoenix-1", blocked: false},
} {
t.Run(tc.chainID, func(t *testing.T) {
called := false
next := func(ctx sdk.Context, tx sdk.Tx, simulate bool) (sdk.Context, error) {
called = true
return ctx, nil
}
_, err := decorator.AnteHandle(sdk.Context{}.WithChainID(tc.chainID), testSignedTx{
signers: [][]byte{address},
}, false, next)
if tc.blocked && (err == nil || !strings.Contains(err.Error(), "is blacklisted") || called) {
t.Fatalf("test address was not blocked on %s: err=%v, next called=%t", tc.chainID, err, called)
}
if !tc.blocked && (err != nil || !called) {
t.Fatalf("test address was blocked on %s: err=%v, next called=%t", tc.chainID, err, called)
}
})
}
}
1 change: 1 addition & 0 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,7 @@ func NewTerraApp(
IBCkeeper: app.Keepers.IBCKeeper,
TXCounterStoreService: txCounterStoreService,
NodeConfig: wasmConfig,
Codec: encodingConfig.Marshaler,
},
)
if err != nil {
Expand Down
1 change: 1 addition & 0 deletions app/config/const.go
Original file line number Diff line number Diff line change
Expand Up @@ -231,4 +231,5 @@ const (
Upgrade2_19 = "v2.19"
Upgrade2_20 = "v2.20"
Upgrade2_21 = "v2.21"
Upgrade2_22 = "v2.22"
)
9 changes: 9 additions & 0 deletions app/upgrade_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
v2_2_0 "github.com/terra-money/core/v2/app/upgrades/v2.2.0"
v2_20 "github.com/terra-money/core/v2/app/upgrades/v2.20"
v2_21 "github.com/terra-money/core/v2/app/upgrades/v2.21"
v2_22 "github.com/terra-money/core/v2/app/upgrades/v2.22"
v2_3_0 "github.com/terra-money/core/v2/app/upgrades/v2.3.0"
v2_4 "github.com/terra-money/core/v2/app/upgrades/v2.4"
v2_5 "github.com/terra-money/core/v2/app/upgrades/v2.5"
Expand Down Expand Up @@ -201,6 +202,14 @@ func (app *TerraApp) RegisterUpgradeHandlers() {
app.Keepers,
),
)
app.Keepers.UpgradeKeeper.SetUpgradeHandler(
terraappconfig.Upgrade2_22,
v2_22.CreateUpgradeHandler(
app.GetModuleManager(),
app.GetConfigurator(),
app.Keepers,
),
)
}

func (app *TerraApp) RegisterUpgradeStores() {
Expand Down
20 changes: 20 additions & 0 deletions app/upgrades/v2.22/upgrade.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package v2_22

import (
"context"

upgradetypes "cosmossdk.io/x/upgrade/types"
"github.com/cosmos/cosmos-sdk/types/module"

"github.com/terra-money/core/v2/app/keepers"
)

func CreateUpgradeHandler(
mm *module.Manager,
cfg module.Configurator,
k keepers.TerraAppKeepers,
) upgradetypes.UpgradeHandler {
return func(ctx context.Context, plan upgradetypes.Plan, vm module.VersionMap) (module.VersionMap, error) {
return mm.RunMigrations(ctx, cfg, vm)
}
}
18 changes: 10 additions & 8 deletions integration-tests/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions integration-tests/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"test:chain:upgrade:v19": "bash src/setup/chain-upgrade/upgrade-simulation-19.sh",
"test:chain:upgrade:v20": "bash src/setup/chain-upgrade/upgrade-simulation-20.sh",
"test:chain:upgrade:v21": "bash src/setup/chain-upgrade/upgrade-simulation-21.sh",
"test:chain:upgrade:v22": "bash src/setup/chain-upgrade/upgrade-simulation-22.sh",
"test:start": "jest --runInBand --detectOpenHandles",
"start": "npm run test:init && npm run test:relayer && npm run test:start",
"test:clean": "rm -rf src/test-data chain-upgrade-data && pkill terrad && pkill terrad && pkill relayer"
Expand Down
Loading
Loading