Skip to content

Commit

Permalink
temp
Browse files Browse the repository at this point in the history
  • Loading branch information
yihuang committed Sep 26, 2024
1 parent 1bdcd03 commit 5331cb0
Show file tree
Hide file tree
Showing 2 changed files with 212 additions and 4 deletions.
45 changes: 41 additions & 4 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import (
stdruntime "runtime"
"sort"

"filippo.io/age"

abci "github.com/cometbft/cometbft/abci/types"
tmos "github.com/cometbft/cometbft/libs/os"
dbm "github.com/cosmos/cosmos-db"
Expand Down Expand Up @@ -159,6 +161,7 @@ import (
cronosprecompiles "github.com/crypto-org-chain/cronos/v2/x/cronos/keeper/precompiles"
"github.com/crypto-org-chain/cronos/v2/x/cronos/middleware"
cronostypes "github.com/crypto-org-chain/cronos/v2/x/cronos/types"
e2eekeyring "github.com/crypto-org-chain/cronos/v2/x/e2ee/keyring"

e2ee "github.com/crypto-org-chain/cronos/v2/x/e2ee"
e2eekeeper "github.com/crypto-org-chain/cronos/v2/x/e2ee/keeper"
Expand Down Expand Up @@ -360,23 +363,57 @@ func New(
cdc := encodingConfig.Amino
txConfig := encodingConfig.TxConfig
interfaceRegistry := encodingConfig.InterfaceRegistry

txDecoder := txConfig.TxDecoder()
eip712.SetEncodingConfig(encodingConfig)

homePath := cast.ToString(appOpts.Get(flags.FlagHome))
var identity age.Identity
{
if cast.ToString(appOpts.Get("mode")) == "validator" {
krBackend := cast.ToString(appOpts.Get(flags.FlagKeyringBackend))
kr, err := e2eekeyring.New("cronosd", krBackend, homePath, os.Stdin)
if err != nil {
panic(err)
}
bz, err := kr.Get(e2eetypes.DefaultKeyringName)
if err != nil {
logger.Error("e2ee identity for validator not found", "error", err)
} else {
identity, err = age.ParseX25519Identity(string(bz))
if err != nil {
panic(err)
}
}
}
}

var mpool mempool.Mempool
if maxTxs := cast.ToInt(appOpts.Get(server.FlagMempoolMaxTxs)); maxTxs >= 0 {
// NOTE we use custom transaction decoder that supports the sdk.Tx interface instead of sdk.StdTx
// Setup Mempool and Proposal Handlers
mempool := mempool.NewPriorityMempool(mempool.PriorityNonceMempoolConfig[int64]{
mpool = mempool.NewPriorityMempool(mempool.PriorityNonceMempoolConfig[int64]{
TxPriority: mempool.NewDefaultTxPriority(),
SignerExtractor: evmapp.NewEthSignerExtractionAdapter(mempool.NewDefaultSignerExtractionAdapter()),
MaxTx: maxTxs,
})
baseAppOptions = append(baseAppOptions, baseapp.SetMempool(mempool))
} else {
mpool = mempool.NoOpMempool{}
}
blockProposalHandler := NewProposalHandler(txDecoder, identity)
baseAppOptions = append(baseAppOptions, func(app *baseapp.BaseApp) {
app.SetMempool(mpool)

// Re-use the default prepare proposal handler, extend the transaction validation logic
defaultProposalHandler := baseapp.NewDefaultProposalHandler(mpool, app)
defaultProposalHandler.SetTxSelector(NewExtTxSelector(
baseapp.NewDefaultTxSelector(),
txDecoder,
blockProposalHandler.ValidateTransaction,
))
})

blockSTMEnabled := cast.ToString(appOpts.Get(srvflags.EVMBlockExecutor)) == "block-stm"

homePath := cast.ToString(appOpts.Get(flags.FlagHome))
var cacheSize int
if !blockSTMEnabled {
// only enable memiavl cache if block-stm is not enabled, because it's not concurrency-safe.
Expand Down
171 changes: 171 additions & 0 deletions app/proposal.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
package app

import (
"bytes"
"context"
"encoding/json"
"fmt"
"io"

"filippo.io/age"

"cosmossdk.io/core/address"
abci "github.com/cometbft/cometbft/abci/types"
"github.com/cosmos/cosmos-sdk/baseapp"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/auth/signing"
)

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

var _ baseapp.TxSelector = &ExtTxSelector{}

// ExtTxSelector extends a baseapp.TxSelector with extra tx validation method
type ExtTxSelector struct {
baseapp.TxSelector
TxDecoder sdk.TxDecoder
ValidateTx func(sdk.Tx) error
}

func NewExtTxSelector(parent baseapp.TxSelector, txDecoder sdk.TxDecoder, validateTx func(sdk.Tx) error) *ExtTxSelector {
return &ExtTxSelector{
TxSelector: parent,
TxDecoder: txDecoder,
ValidateTx: validateTx,
}
}

func (ts *ExtTxSelector) SelectTxForProposal(ctx context.Context, maxTxBytes, maxBlockGas uint64, memTx sdk.Tx, txBz []byte, gasWanted uint64) bool {
var err error
if memTx == nil {
memTx, err = ts.TxDecoder(txBz)
if err != nil {
return false

Check warning on line 45 in app/proposal.go

View check run for this annotation

Codecov / codecov/patch

app/proposal.go#L40-L45

Added lines #L40 - L45 were not covered by tests
}
}

if err := ts.ValidateTx(memTx); err != nil {
return false

Check warning on line 50 in app/proposal.go

View check run for this annotation

Codecov / codecov/patch

app/proposal.go#L49-L50

Added lines #L49 - L50 were not covered by tests
}

// don't pass `memTx` to parent selector so it don't check tx gas wanted against block gas limit,
// it conflicts with the max-tx-gas-wanted logic.
return ts.TxSelector.SelectTxForProposal(ctx, maxTxBytes, maxBlockGas, nil, txBz, gasWanted)

Check warning on line 55 in app/proposal.go

View check run for this annotation

Codecov / codecov/patch

app/proposal.go#L55

Added line #L55 was not covered by tests
}

type ProposalHandler struct {
TxDecoder sdk.TxDecoder
// Identity is nil if it's not a validator node
Identity age.Identity
blocklist map[string]struct{}
lastBlockList []byte
addressCodec address.Codec
}

func NewProposalHandler(txDecoder sdk.TxDecoder, identity age.Identity) *ProposalHandler {
return &ProposalHandler{
TxDecoder: txDecoder,
Identity: identity,
blocklist: make(map[string]struct{}),
}
}

// SetBlockList don't fail if the identity is not set or the block list is empty.
func (h *ProposalHandler) SetBlockList(blob []byte) error {
if h.Identity == nil {
return nil

Check warning on line 78 in app/proposal.go

View check run for this annotation

Codecov / codecov/patch

app/proposal.go#L76-L78

Added lines #L76 - L78 were not covered by tests
}

if bytes.Equal(h.lastBlockList, blob) {
return nil

Check warning on line 82 in app/proposal.go

View check run for this annotation

Codecov / codecov/patch

app/proposal.go#L81-L82

Added lines #L81 - L82 were not covered by tests
}
h.lastBlockList = make([]byte, len(blob))
copy(h.lastBlockList, blob)

Check warning on line 85 in app/proposal.go

View check run for this annotation

Codecov / codecov/patch

app/proposal.go#L84-L85

Added lines #L84 - L85 were not covered by tests

if len(blob) == 0 {
h.blocklist = make(map[string]struct{})
return nil

Check warning on line 89 in app/proposal.go

View check run for this annotation

Codecov / codecov/patch

app/proposal.go#L87-L89

Added lines #L87 - L89 were not covered by tests
}

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

Check warning on line 94 in app/proposal.go

View check run for this annotation

Codecov / codecov/patch

app/proposal.go#L92-L94

Added lines #L92 - L94 were not covered by tests
}

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

Check warning on line 99 in app/proposal.go

View check run for this annotation

Codecov / codecov/patch

app/proposal.go#L97-L99

Added lines #L97 - L99 were not covered by tests
}

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

Check warning on line 104 in app/proposal.go

View check run for this annotation

Codecov / codecov/patch

app/proposal.go#L102-L104

Added lines #L102 - L104 were not covered by tests
}

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

Check warning on line 112 in app/proposal.go

View check run for this annotation

Codecov / codecov/patch

app/proposal.go#L108-L112

Added lines #L108 - L112 were not covered by tests
}
encoded, err := h.addressCodec.BytesToString(addr)
if err != nil {
return fmt.Errorf("invalid bech32 address: %s, err: %w", s, err)

Check warning on line 116 in app/proposal.go

View check run for this annotation

Codecov / codecov/patch

app/proposal.go#L114-L116

Added lines #L114 - L116 were not covered by tests
}
m[encoded] = struct{}{}

Check warning on line 118 in app/proposal.go

View check run for this annotation

Codecov / codecov/patch

app/proposal.go#L118

Added line #L118 was not covered by tests
}

h.blocklist = m
return nil

Check warning on line 122 in app/proposal.go

View check run for this annotation

Codecov / codecov/patch

app/proposal.go#L121-L122

Added lines #L121 - L122 were not covered by tests
}

func (h *ProposalHandler) ValidateTransaction(tx sdk.Tx) error {
sigTx, ok := tx.(signing.SigVerifiableTx)
if !ok {
return fmt.Errorf("tx of type %T does not implement SigVerifiableTx", tx)

Check warning on line 128 in app/proposal.go

View check run for this annotation

Codecov / codecov/patch

app/proposal.go#L125-L128

Added lines #L125 - L128 were not covered by tests
}

signers, err := sigTx.GetSigners()
if err != nil {
return err

Check warning on line 133 in app/proposal.go

View check run for this annotation

Codecov / codecov/patch

app/proposal.go#L131-L133

Added lines #L131 - L133 were not covered by tests
}
for _, signer := range signers {
encoded, err := h.addressCodec.BytesToString(signer)
if err != nil {
return fmt.Errorf("invalid bech32 address: %s, err: %w", signer, err)

Check warning on line 138 in app/proposal.go

View check run for this annotation

Codecov / codecov/patch

app/proposal.go#L135-L138

Added lines #L135 - L138 were not covered by tests
}
if _, ok := h.blocklist[encoded]; ok {
return fmt.Errorf("signer is blocked: %s", encoded)

Check warning on line 141 in app/proposal.go

View check run for this annotation

Codecov / codecov/patch

app/proposal.go#L140-L141

Added lines #L140 - L141 were not covered by tests
}
}
return nil

Check warning on line 144 in app/proposal.go

View check run for this annotation

Codecov / codecov/patch

app/proposal.go#L144

Added line #L144 was not covered by tests
}

func (h *ProposalHandler) ProcessProposalHandler() sdk.ProcessProposalHandler {
return func(ctx sdk.Context, req *abci.RequestProcessProposal) (*abci.ResponseProcessProposal, error) {
for _, txBz := range req.Txs {
memTx, err := h.TxDecoder(txBz)
if err != nil {
return &abci.ResponseProcessProposal{Status: abci.ResponseProcessProposal_REJECT}, nil

Check warning on line 152 in app/proposal.go

View check run for this annotation

Codecov / codecov/patch

app/proposal.go#L147-L152

Added lines #L147 - L152 were not covered by tests
}

if err := h.ValidateTransaction(memTx); err != nil {
return &abci.ResponseProcessProposal{Status: abci.ResponseProcessProposal_REJECT}, nil

Check warning on line 156 in app/proposal.go

View check run for this annotation

Codecov / codecov/patch

app/proposal.go#L155-L156

Added lines #L155 - L156 were not covered by tests
}
}

return &abci.ResponseProcessProposal{Status: abci.ResponseProcessProposal_ACCEPT}, nil

Check warning on line 160 in app/proposal.go

View check run for this annotation

Codecov / codecov/patch

app/proposal.go#L160

Added line #L160 was not covered by tests
}
}

// noneIdentity is a dummy identity which postpone the failure to the decryption time
type noneIdentity struct{}

var _ age.Identity = noneIdentity{}

func (noneIdentity) Unwrap([]*age.Stanza) ([]byte, error) {
return nil, age.ErrIncorrectIdentity

Check warning on line 170 in app/proposal.go

View check run for this annotation

Codecov / codecov/patch

app/proposal.go#L169-L170

Added lines #L169 - L170 were not covered by tests
}

0 comments on commit 5331cb0

Please sign in to comment.