Skip to content
This repository has been archived by the owner on Jan 31, 2025. It is now read-only.

feat: Lane's with custom tx adapters #239

Merged
merged 23 commits into from
Nov 28, 2023
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
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
Loading