Skip to content

Commit

Permalink
feat: Lane's with custom tx adapters (#239)
Browse files Browse the repository at this point in the history
* greedy approach to lane verification

* docs

* base lane testing

* mev lane testing nits

* abci top level testing done

* network spamming in E2E

* string rep of escrow address

* nit

* nit

* nit v1.0.1

* removing logs from testing

* query test

* logging with tx info

* nits

* nit

* nit

* testing nit

---------

Co-authored-by: Alex Johnson <[email protected]>
  • Loading branch information
davidterpay and Alex Johnson authored Nov 28, 2023
1 parent 01a84b1 commit be4465a
Show file tree
Hide file tree
Showing 19 changed files with 444 additions and 98 deletions.
13 changes: 13 additions & 0 deletions adapters/signer_extraction_adapter/signer_extraction_adapter.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,19 @@ type SignerData struct {
Sequence uint64
}

// NewSignerData returns a new SignerData instance.
func NewSignerData(signer sdk.AccAddress, sequence uint64) SignerData {
return SignerData{
Signer: signer,
Sequence: sequence,
}
}

// String implements the fmt.Stringer interface.
func (s SignerData) String() string {
return fmt.Sprintf("SignerData{Signer: %s, Sequence: %d}", s.Signer, s.Sequence)
}

// SignerExtractionAdapter is an interface used to determine how the signers of a transaction should be extracted
// from the transaction.
type Adapter interface {
Expand Down
38 changes: 36 additions & 2 deletions block/base/abci.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,26 @@ func (l *BaseLane) PrepareLane(
)
}

// Get the transaction info for each transaction that was selected.
txsWithInfo := make([]utils.TxWithInfo, len(txsToInclude))
for i, tx := range txsToInclude {
txInfo, err := l.GetTxInfo(ctx, tx)
if err != nil {
l.Logger().Error(
"failed to get tx info",
"lane", l.Name(),
"err", err,
)

return proposal, err
}

txsWithInfo[i] = txInfo
}

// Update the proposal with the selected transactions. This fails if the lane attempted to add
// more transactions than the allocated max block space for the lane.
if err := proposal.UpdateProposal(l, txsToInclude); err != nil {
if err := proposal.UpdateProposal(l, txsWithInfo); err != nil {
l.Logger().Error(
"failed to update proposal",
"lane", l.Name(),
Expand Down Expand Up @@ -102,8 +119,25 @@ func (l *BaseLane) ProcessLane(
return proposal, err
}

// Retrieve the transaction info for each transaction that belongs to the lane.
txsWithInfo := make([]utils.TxWithInfo, len(txsFromLane))
for i, tx := range txsFromLane {
txInfo, err := l.GetTxInfo(ctx, tx)
if err != nil {
l.Logger().Error(
"failed to get tx info",
"lane", l.Name(),
"err", err,
)

return proposal, err
}

txsWithInfo[i] = txInfo
}

// Optimistically update the proposal with the partial proposal.
if err := proposal.UpdateProposal(l, txsFromLane); err != nil {
if err := proposal.UpdateProposal(l, txsWithInfo); err != nil {
l.Logger().Error(
"failed to update proposal",
"lane", l.Name(),
Expand Down
3 changes: 1 addition & 2 deletions block/base/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import (
sdk "github.com/cosmos/cosmos-sdk/types"

"github.com/skip-mev/block-sdk/block/proposals"
"github.com/skip-mev/block-sdk/block/utils"
)

// DefaultPrepareLaneHandler returns a default implementation of the PrepareLaneHandler. It
Expand All @@ -27,7 +26,7 @@ func (l *BaseLane) DefaultPrepareLaneHandler() PrepareLaneHandler {
for iterator := l.Select(ctx, nil); iterator != nil; iterator = iterator.Next() {
tx := iterator.Tx()

txInfo, err := utils.GetTxInfo(l.TxEncoder(), tx)
txInfo, err := l.GetTxInfo(ctx, tx)
if err != nil {
l.Logger().Info("failed to get hash of tx", "err", err)

Expand Down
17 changes: 11 additions & 6 deletions block/base/mempool.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,19 +102,24 @@ func NewMempool[C comparable](txPriority TxPriority[C], txEncoder sdk.TxEncoder,
}
}

// Priority returns the priority of the transaction.
func (cm *Mempool[C]) Priority(ctx sdk.Context, tx sdk.Tx) any {
return cm.txPriority.GetTxPriority(ctx, tx)
}

// Insert inserts a transaction into the mempool.
func (cm *Mempool[C]) Insert(ctx context.Context, tx sdk.Tx) error {
if err := cm.index.Insert(ctx, tx); err != nil {
return fmt.Errorf("failed to insert tx into auction index: %w", err)
}

txInfo, err := utils.GetTxInfo(cm.txEncoder, tx)
hash, err := utils.GetTxHash(cm.txEncoder, tx)
if err != nil {
cm.Remove(tx)
return err
}

cm.txCache[txInfo.Hash] = struct{}{}
cm.txCache[hash] = struct{}{}

return nil
}
Expand All @@ -125,12 +130,12 @@ func (cm *Mempool[C]) Remove(tx sdk.Tx) error {
return fmt.Errorf("failed to remove transaction from the mempool: %w", err)
}

txInfo, err := utils.GetTxInfo(cm.txEncoder, tx)
hash, err := utils.GetTxHash(cm.txEncoder, tx)
if err != nil {
return fmt.Errorf("failed to get tx hash string: %w", err)
}

delete(cm.txCache, txInfo.Hash)
delete(cm.txCache, hash)

return nil
}
Expand All @@ -150,12 +155,12 @@ func (cm *Mempool[C]) CountTx() int {

// Contains returns true if the transaction is contained in the mempool.
func (cm *Mempool[C]) Contains(tx sdk.Tx) bool {
txInfo, err := utils.GetTxInfo(cm.txEncoder, tx)
hash, err := utils.GetTxHash(cm.txEncoder, tx)
if err != nil {
return false
}

_, ok := cm.txCache[txInfo.Hash]
_, ok := cm.txCache[hash]
return ok
}

Expand Down
41 changes: 41 additions & 0 deletions block/base/tx_info.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package base

import (
"encoding/hex"
"fmt"
"strings"

comettypes "github.com/cometbft/cometbft/types"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/skip-mev/block-sdk/block/utils"
)

// GetTxInfo returns various information about the transaction that
// belongs to the lane including its priority, signer's, sequence number,
// size and more.
func (l *BaseLane) GetTxInfo(ctx sdk.Context, tx sdk.Tx) (utils.TxWithInfo, error) {
txBytes, err := l.cfg.TxEncoder(tx)
if err != nil {
return utils.TxWithInfo{}, fmt.Errorf("failed to encode transaction: %w", err)
}

// TODO: Add an adapter to lanes so that this can be flexible to support EVM, etc.
gasTx, ok := tx.(sdk.FeeTx)
if !ok {
return utils.TxWithInfo{}, fmt.Errorf("failed to cast transaction to gas tx")
}

signers, err := l.cfg.SignerExtractor.GetSigners(tx)
if err != nil {
return utils.TxWithInfo{}, err
}

return utils.TxWithInfo{
Hash: strings.ToUpper(hex.EncodeToString(comettypes.Tx(txBytes).Hash())),
Size: int64(len(txBytes)),
GasLimit: gasTx.GetGas(),
TxBytes: txBytes,
Priority: l.LaneMempool.Priority(ctx, tx),
Signers: signers,
}, nil
}
9 changes: 9 additions & 0 deletions block/lane.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
sdkmempool "github.com/cosmos/cosmos-sdk/types/mempool"

"github.com/skip-mev/block-sdk/block/proposals"
"github.com/skip-mev/block-sdk/block/utils"
)

// LaneMempool defines the interface a lane's mempool should implement. The basic API
Expand All @@ -23,6 +24,9 @@ type LaneMempool interface {

// Contains returns true if the transaction is contained in the mempool.
Contains(tx sdk.Tx) bool

// Priority returns the priority of a transaction that belongs to this lane.
Priority(ctx sdk.Context, tx sdk.Tx) any
}

// Lane defines an interface used for matching transactions to lanes, storing transactions,
Expand Down Expand Up @@ -74,6 +78,11 @@ type Lane interface {

// Match determines if a transaction belongs to this lane.
Match(ctx sdk.Context, tx sdk.Tx) bool

// GetTxInfo returns various information about the transaction that
// belongs to the lane including its priority, signer's, sequence number,
// size and more.
GetTxInfo(ctx sdk.Context, tx sdk.Tx) (utils.TxWithInfo, error)
}

// FindLane finds a Lanes from in an array of Lanes and returns it and its index if found.
Expand Down
42 changes: 42 additions & 0 deletions block/mocks/lane.go

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

16 changes: 16 additions & 0 deletions block/mocks/lane_mempool.go

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

Loading

0 comments on commit be4465a

Please sign in to comment.