chore(wallet): reorganize multitx processing code

This commit is contained in:
Dario Gabriel Lipicar 2023-06-13 11:06:36 -03:00 committed by dlipicar
parent bc92df79d5
commit fb6e2a41f7
1 changed files with 60 additions and 58 deletions

View File

@ -63,6 +63,8 @@ type ethHistoricalCommand struct {
threadLimit uint32 threadLimit uint32
} }
type Transaction []*Transfer
func (c *ethHistoricalCommand) Command() async.Command { func (c *ethHistoricalCommand) Command() async.Command {
return async.FiniteCommand{ return async.FiniteCommand{
Interval: 5 * time.Second, Interval: 5 * time.Second,
@ -393,6 +395,7 @@ func (c *transfersCommand) Run(ctx context.Context) (err error) {
err = c.processMultiTransactions(ctx, allTransfers) err = c.processMultiTransactions(ctx, allTransfers)
if err != nil { if err != nil {
log.Error("processMultiTransactions error", "error", err)
return err return err
} }
@ -435,78 +438,77 @@ func (c *transfersCommand) Run(ctx context.Context) (err error) {
return nil return nil
} }
func (c *transfersCommand) checkAndProcessPendingMultiTx(subTx *Transfer) (MultiTransactionIDType, error) { // Mark all subTxs of a given Tx with the same multiTxID
func setMultiTxID(tx Transaction, multiTxID MultiTransactionIDType) {
for _, subTx := range tx {
subTx.MultiTransactionID = multiTxID
}
}
func (c *transfersCommand) propagatePendingMultiTx(tx Transaction) error {
multiTxID := NoMultiTransactionID
// If any subTx matches a pending entry, mark all of them with the corresponding multiTxID
for _, subTx := range tx {
// Update MultiTransactionID from pending entry // Update MultiTransactionID from pending entry
entry, err := c.transactionManager.GetPendingEntry(c.chainClient.ChainID, subTx.ID) entry, err := c.transactionManager.GetPendingEntry(c.chainClient.ChainID, subTx.ID)
if err == nil { if err == nil {
// Propagate the MultiTransactionID, in case the pending entry was a multi-transaction // Propagate the MultiTransactionID, in case the pending entry was a multi-transaction
return entry.MultiTransactionID, nil multiTxID = entry.MultiTransactionID
break
} else if err != sql.ErrNoRows { } else if err != sql.ErrNoRows {
log.Error("GetPendingEntry error", "error", err) log.Error("GetPendingEntry error", "error", err)
return NoMultiTransactionID, err return err
}
} }
return NoMultiTransactionID, nil if multiTxID != NoMultiTransactionID {
setMultiTxID(tx, multiTxID)
}
return nil
} }
func (c *transfersCommand) checkAndProcessSwapMultiTx(ctx context.Context, subTx *Transfer) (MultiTransactionIDType, error) { func (c *transfersCommand) checkAndProcessSwapMultiTx(ctx context.Context, tx Transaction) (bool, error) {
for _, subTx := range tx {
switch subTx.Type { switch subTx.Type {
// If the Tx contains any uniswapV2Swap/uniswapV3Swap subTx, generate a Swap multiTx // If the Tx contains any uniswapV2Swap/uniswapV3Swap subTx, generate a Swap multiTx
case w_common.UniswapV2Swap, w_common.UniswapV3Swap: case w_common.UniswapV2Swap, w_common.UniswapV3Swap:
multiTransaction, err := buildUniswapSwapMultitransaction(ctx, c.chainClient, c.tokenManager, subTx) multiTransaction, err := buildUniswapSwapMultitransaction(ctx, c.chainClient, c.tokenManager, subTx)
if err != nil { if err != nil {
return NoMultiTransactionID, err return false, err
} }
if multiTransaction != nil { if multiTransaction != nil {
id, err := c.transactionManager.InsertMultiTransaction(multiTransaction) id, err := c.transactionManager.InsertMultiTransaction(multiTransaction)
if err != nil { if err != nil {
return NoMultiTransactionID, err return false, err
}
setMultiTxID(tx, id)
return true, nil
} }
return id, nil
} }
} }
return NoMultiTransactionID, nil return false, nil
} }
func (c *transfersCommand) processMultiTransactions(ctx context.Context, allTransfers []Transfer) error { func (c *transfersCommand) processMultiTransactions(ctx context.Context, allTransfers []Transfer) error {
subTxsByTxHash := subTransactionsByTxHash(allTransfers) txByTxHash := subTransactionListToTransactionsByTxHash(allTransfers)
// Detect / Generate multitransactions // Detect / Generate multitransactions
// Iterate over all detected transactions // Iterate over all detected transactions
for _, subTxs := range subTxsByTxHash { for _, tx := range txByTxHash {
multiTxID := NoMultiTransactionID
var err error var err error
// Iterate over transaction's subtransactions // First check for pre-existing pending transaction
for _, subTx := range subTxs { err = c.propagatePendingMultiTx(tx)
if subTx.MultiTransactionID == NoMultiTransactionID {
// First check every subTX for pending transaction
multiTxID, err = c.checkAndProcessPendingMultiTx(subTx)
if err != nil { if err != nil {
return err return err
} }
if multiTxID != NoMultiTransactionID {
break
}
// Then check for a Swap transaction // Then check for a Swap transaction
multiTxID, err = c.checkAndProcessSwapMultiTx(ctx, subTx) _, err = c.checkAndProcessSwapMultiTx(ctx, tx)
if err != nil { if err != nil {
return err return err
} }
if multiTxID != NoMultiTransactionID {
break
}
}
}
// Mark all subTxs of a given Tx with the same multiTxID
if multiTxID != NoMultiTransactionID {
for _, subTx := range subTxs {
subTx.MultiTransactionID = multiTxID
}
}
} }
return nil return nil
@ -879,8 +881,8 @@ func uniquePreloadedTransactionPerTxHash(allTransactions []*PreloadedTransaction
} }
// Organize subTransactions by Transaction Hash // Organize subTransactions by Transaction Hash
func subTransactionsByTxHash(subTransactions []Transfer) map[common.Hash][]*Transfer { func subTransactionListToTransactionsByTxHash(subTransactions []Transfer) map[common.Hash]Transaction {
rst := map[common.Hash][]*Transfer{} rst := map[common.Hash]Transaction{}
for index := range subTransactions { for index := range subTransactions {
subTx := &subTransactions[index] subTx := &subTransactions[index]