Skip to content

Commit

Permalink
set with ante
Browse files Browse the repository at this point in the history
  • Loading branch information
mmsqe committed May 2, 2024
1 parent fa6497f commit c2700f5
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 139 deletions.
93 changes: 42 additions & 51 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ import (
tmjson "github.com/cometbft/cometbft/libs/json"
"github.com/cometbft/cometbft/libs/log"
tmos "github.com/cometbft/cometbft/libs/os"
tmproto "github.com/cometbft/cometbft/proto/tendermint/types"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/codec/types"
"github.com/gorilla/mux"
Expand Down Expand Up @@ -328,6 +327,7 @@ type App struct {
interfaceRegistry types.InterfaceRegistry

invCheckPeriod uint
blockedMap map[string]struct{}

// keys to access the substores
keys map[string]*storetypes.KVStoreKey
Expand Down Expand Up @@ -385,8 +385,6 @@ type App struct {
configurator module.Configurator

qms storetypes.MultiStore

blockProposalHandler *ProposalHandler
}

// New returns a reference to an initialized chain.
Expand All @@ -396,7 +394,7 @@ func New(
homePath string, invCheckPeriod uint, encodingConfig ethermint.EncodingConfig,
// this line is used by starport scaffolding # stargate/app/newArgument
appOpts servertypes.AppOptions, baseAppOptions ...func(*baseapp.BaseApp),
) *App {
) (app *App) {
appCodec := encodingConfig.Codec
cdc := encodingConfig.Amino
interfaceRegistry := encodingConfig.InterfaceRegistry
Expand All @@ -423,34 +421,41 @@ func New(

baseAppOptions = memiavlstore.SetupMemIAVL(logger, homePath, appOpts, false, false, baseAppOptions)

blockProposalHandler := NewProposalHandler(encodingConfig.TxConfig.TxDecoder(), identity)
keys, memKeys, tkeys := StoreKeys(skipGravity)
cronosKey := keys[cronostypes.StoreKey]

txConfig := encodingConfig.TxConfig
maxTxGasWanted := cast.ToUint64(appOpts.Get(srvflags.EVMMaxTxGasWanted))
// NOTE we use custom transaction decoder that supports the sdk.Tx interface instead of sdk.StdTx
// Setup Mempool and Proposal Handlers
baseAppOptions = append(baseAppOptions, func(app *baseapp.BaseApp) {
baseAppOptions = append(baseAppOptions, func(bapp *baseapp.BaseApp) {
mempool := mempool.NoOpMempool{}
app.SetMempool(mempool)
app.SetPrepareProposal(blockProposalHandler.PrepareProposalHandler())
app.SetProcessProposal(blockProposalHandler.ProcessProposalHandler())
bapp.SetMempool(mempool)
blockProposalHandler := NewProposalHandler(
appCodec,
cronosKey,
txConfig.TxDecoder(),
identity,
func(blacklist []string) { app.setAnteHandler(txConfig, maxTxGasWanted, blacklist) },
)
bapp.SetPrepareProposal(blockProposalHandler.PrepareProposalHandler())
bapp.SetProcessProposal(blockProposalHandler.ProcessProposalHandler())
})
bApp := baseapp.NewBaseApp(Name, logger, db, encodingConfig.TxConfig.TxDecoder(), baseAppOptions...)

bApp.SetCommitMultiStoreTracer(traceStore)
bApp.SetVersion(version.Version)
bApp.SetInterfaceRegistry(interfaceRegistry)

keys, memKeys, tkeys := StoreKeys(skipGravity)

app := &App{
BaseApp: bApp,
cdc: cdc,
appCodec: appCodec,
interfaceRegistry: interfaceRegistry,
invCheckPeriod: invCheckPeriod,
keys: keys,
tkeys: tkeys,
memKeys: memKeys,
blockProposalHandler: blockProposalHandler,
app = &App{
BaseApp: bApp,
cdc: cdc,
appCodec: appCodec,
interfaceRegistry: interfaceRegistry,
invCheckPeriod: invCheckPeriod,
keys: keys,
tkeys: tkeys,
memKeys: memKeys,
}

// init params keeper and subspaces
Expand Down Expand Up @@ -606,7 +611,7 @@ func New(

app.CronosKeeper = *cronoskeeper.NewKeeper(
appCodec,
keys[cronostypes.StoreKey],
cronosKey,
keys[cronostypes.MemStoreKey],
app.BankKeeper,
app.TransferKeeper,
Expand Down Expand Up @@ -955,10 +960,6 @@ func New(
tmos.Exit(fmt.Sprintf("versiondb version %d lag behind iavl version %d", v1, v2))
}
}

if err := app.RefreshBlockList(app.NewUncachedContext(false, tmproto.Header{})); err != nil {
panic(err)
}
}

app.ScopedIBCKeeper = scopedIBCKeeper
Expand All @@ -970,8 +971,11 @@ func New(
return app
}

// use Ethermint's custom AnteHandler
func (app *App) setAnteHandler(txConfig client.TxConfig, maxGasWanted uint64, blacklist []string) error {
func (app *App) getBlockedMap() map[string]struct{} {
return app.blockedMap
}

func (app *App) setBlacklist(blacklist []string) error {
if len(blacklist) > 0 {
sort.Strings(blacklist)
// hash blacklist concatenated
Expand All @@ -991,14 +995,16 @@ func (app *App) setAnteHandler(txConfig client.TxConfig, maxGasWanted uint64, bl
}
blockedMap := make(map[string]struct{}, len(blacklist))
for _, str := range blacklist {
addr, err := sdk.AccAddressFromBech32(str)
if err != nil {
return fmt.Errorf("invalid bech32 address: %s, err: %w", str, err)
}

blockedMap[string(addr)] = struct{}{}
blockedMap[str] = struct{}{}
}
blockAddressDecorator := NewBlockAddressesDecorator(blockedMap)
app.blockedMap = blockedMap
return nil
}

// use Ethermint's custom AnteHandler
func (app *App) setAnteHandler(txConfig client.TxConfig, maxGasWanted uint64, blacklist []string) error {
app.setBlacklist(blacklist)
blockAddressDecorator := NewBlockAddressesDecorator(app.getBlockedMap)
options := evmante.HandlerOptions{
AccountKeeper: app.AccountKeeper,
BankKeeper: app.BankKeeper,
Expand Down Expand Up @@ -1053,22 +1059,7 @@ func (app *App) BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock) abci.R

// EndBlocker application updates every end block
func (app *App) EndBlocker(ctx sdk.Context, req abci.RequestEndBlock) abci.ResponseEndBlock {
rsp := app.mm.EndBlock(ctx, req)

if err := app.RefreshBlockList(ctx); err != nil {
app.Logger().Error("failed to update blocklist", "error", err)
}

return rsp
}

func (app *App) RefreshBlockList(ctx sdk.Context) error {
if app.blockProposalHandler.Identity == nil {
return nil
}

// refresh blocklist
return app.blockProposalHandler.SetBlockList(app.CronosKeeper.GetBlockList(ctx))
return app.mm.EndBlock(ctx, req)
}

// InitChainer application update at chain initialization
Expand Down
11 changes: 6 additions & 5 deletions app/block_address.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,21 @@ import (

// BlockAddressesDecorator block addresses from sending transactions
type BlockAddressesDecorator struct {
blockedMap map[string]struct{}
blockedMapGetter func() map[string]struct{}
}

func NewBlockAddressesDecorator(blacklist map[string]struct{}) BlockAddressesDecorator {
return BlockAddressesDecorator{
blockedMap: blacklist,
func NewBlockAddressesDecorator(blockedMapGetter func() map[string]struct{}) *BlockAddressesDecorator {
return &BlockAddressesDecorator{
blockedMapGetter: blockedMapGetter,
}
}

func (bad BlockAddressesDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (newCtx sdk.Context, err error) {
blockedMap := bad.blockedMapGetter()
if ctx.IsCheckTx() {
for _, msg := range tx.GetMsgs() {
for _, signer := range msg.GetSigners() {
if _, ok := bad.blockedMap[string(signer)]; ok {
if _, ok := blockedMap[signer.String()]; ok {
return ctx, fmt.Errorf("signer is blocked: %s", signer.String())
}
}
Expand Down
123 changes: 44 additions & 79 deletions app/proposal.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,111 +3,76 @@ package app
import (
"bytes"
"encoding/json"
"fmt"
"io"

"filippo.io/age"

abci "github.com/cometbft/cometbft/abci/types"
"github.com/cosmos/cosmos-sdk/codec"
storetypes "github.com/cosmos/cosmos-sdk/store/types"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/auth/signing"
cronostypes "github.com/crypto-org-chain/cronos/v2/x/cronos/types"
)

type BlockList struct {
Addresses []string `mapstructure:"addresses"`
}

type ProposalHandler struct {
TxDecoder sdk.TxDecoder
Identity age.Identity
Blocklist map[string]struct{}
LastBlockList []byte
}

func NewProposalHandler(txDecoder sdk.TxDecoder, identity age.Identity) *ProposalHandler {
return &ProposalHandler{
TxDecoder: txDecoder,
Identity: identity,
Blocklist: make(map[string]struct{}),
}
cdc codec.BinaryCodec
cronosKey *storetypes.KVStoreKey
TxDecoder sdk.TxDecoder
Identity age.Identity
LastBlockList []byte
refreshBlocklistHandler refreshBlocklistHandler
}

func (h *ProposalHandler) SetBlockList(blob []byte) error {
if h.Identity == nil {
return nil
}

if bytes.Equal(h.LastBlockList, blob) {
return nil
}
h.LastBlockList = blob

reader, err := age.Decrypt(bytes.NewBuffer(blob), h.Identity)
if err != nil {
return err
}

data, err := io.ReadAll(reader)
if err != nil {
return err
}

var blocklist BlockList
if err := json.Unmarshal(data, &blocklist); err != nil {
return err
}

// convert to map
m := make(map[string]struct{}, len(blocklist.Addresses))
for _, s := range blocklist.Addresses {
addr, err := sdk.AccAddressFromBech32(s)
if err != nil {
return fmt.Errorf("invalid bech32 address: %s, err: %w", s, err)
}
m[addr.String()] = struct{}{}
}

h.Blocklist = m
return nil
type blockList struct {
Addresses []string `mapstructure:"addresses"`
}

func (h *ProposalHandler) ValidateTransactions(txs [][]byte) error {
for _, txBz := range txs {
tx, err := h.TxDecoder(txBz)
if err != nil {
return err
}

sigTx, ok := tx.(signing.SigVerifiableTx)
if !ok {
return fmt.Errorf("tx of type %T does not implement SigVerifiableTx", tx)
}
type refreshBlocklistHandler func(blacklist []string)

for _, signer := range sigTx.GetSigners() {
if _, ok := h.Blocklist[signer.String()]; ok {
return fmt.Errorf("signer is blocked: %s", signer.String())
}
}
func NewProposalHandler(
cdc codec.BinaryCodec,
cronosKey *storetypes.KVStoreKey,
txDecoder sdk.TxDecoder,
identity age.Identity,
refreshBlocklistHandler refreshBlocklistHandler,
) *ProposalHandler {
return &ProposalHandler{
cdc: cdc,
cronosKey: cronosKey,
TxDecoder: txDecoder,
Identity: identity,
refreshBlocklistHandler: refreshBlocklistHandler,
}
return nil
}

func (h *ProposalHandler) PrepareProposalHandler() sdk.PrepareProposalHandler {
return func(ctx sdk.Context, req abci.RequestPrepareProposal) abci.ResponsePrepareProposal {
if err := h.ValidateTransactions(req.Txs); err != nil {
panic(err)
}

return abci.ResponsePrepareProposal{Txs: req.Txs}
}
}

func (h *ProposalHandler) ProcessProposalHandler() sdk.ProcessProposalHandler {
return func(ctx sdk.Context, req abci.RequestProcessProposal) abci.ResponseProcessProposal {
if err := h.ValidateTransactions(req.Txs); err != nil {
panic(err)
if h.Identity != nil {
reject := abci.ResponseProcessProposal{Status: abci.ResponseProcessProposal_REJECT}
blob := ctx.KVStore(h.cronosKey).Get(cronostypes.KeyPrefixBlockList)
if !bytes.Equal(h.LastBlockList, blob) {
reader, err := age.Decrypt(bytes.NewBuffer(blob), h.Identity)
if err != nil {
return reject
}
data, err := io.ReadAll(reader)
if err != nil {
return reject
}
var blocklist blockList
if err := json.Unmarshal(data, &blocklist); err != nil {
return reject
}
h.LastBlockList = blob
h.refreshBlocklistHandler(blocklist.Addresses)
}
}

return abci.ResponseProcessProposal{Status: abci.ResponseProcessProposal_ACCEPT}
}
}
13 changes: 9 additions & 4 deletions integration_tests/test_gov_update_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,11 +97,15 @@ def test_gov_update_params(cronos, tmp_path):

# gen two keys for two accounts
name = "e2ee-identity"
cli1 = cronos.cosmos_cli(1)
pubkey0 = cli.keygen(keyring_name=name)
pubkey1 = cli.keygen(keyring_name=name)
cli.register_e2ee_key(pubkey0, _from="validator")
cli1.register_e2ee_key(pubkey1, _from="validator")
assert cli.query_e2ee_key(cli.address("validator")) == pubkey0
cronos.supervisorctl("stop", "cronos_777-1-node0")
cronos.supervisorctl("start", "cronos_777-1-node0")
assert cli1.query_e2ee_key(cli1.address("validator")) == pubkey1
cronos.supervisorctl("stop", "all")
cronos.supervisorctl("start", "cronos_777-1-node0", "cronos_777-1-node1")
wait_for_port(ports.evmrpc_port(cronos.base_port(0)))

addr = cli.address("user")
Expand All @@ -111,11 +115,12 @@ def test_gov_update_params(cronos, tmp_path):
cli.encrypt(
plainfile,
cli.address("validator"),
cli1.address("validator"),
output=cipherfile,
)
rsp = cli.store_blocklist(cipherfile, from_="validator")
assert rsp["code"] == 0, rsp["raw_log"]
wait_for_new_blocks(cli, 4)
rsp = cli.transfer(addr, cli.address("validator"), "1basecro")
wait_for_new_blocks(cli, 2)
rsp = cli.transfer(addr, cli.address("validator"), "1basetcro")
assert rsp["code"] != 0
assert "signer is blocked" in rsp["raw_log"]

0 comments on commit c2700f5

Please sign in to comment.