Skip to content

Commit

Permalink
fix: correctly return an error when unable to properly parse a transa…
Browse files Browse the repository at this point in the history
…ction and its logs
  • Loading branch information
seanmcgary committed Dec 11, 2024
1 parent f7a7893 commit 5829346
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 22 deletions.
9 changes: 6 additions & 3 deletions pkg/indexer/indexer.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"github.com/Layr-Labs/sidecar/pkg/storage"
"gorm.io/gorm"
"slices"
"strings"

"github.com/Layr-Labs/sidecar/internal/config"
"go.uber.org/zap"
Expand All @@ -37,14 +38,16 @@ const (
IndexError_FailedToCombineAbis IndexErrorType = 3
IndexError_FailedToFindContract IndexErrorType = 4
IndexError_FailedToParseAbi IndexErrorType = 5
IndexError_EmptyAbi IndexErrorType = 6
IndexError_FailedToDecodeLog IndexErrorType = 7
)

type IndexError struct {
Type IndexErrorType
Err error
BlockNumber uint64
TransactionHash string
LogIndex int
LogIndex uint64
Metadata map[string]interface{}
Message string
}
Expand All @@ -71,7 +74,7 @@ func (e *IndexError) WithTransactionHash(txHash string) *IndexError {
return e
}

func (e *IndexError) WithLogIndex(logIndex int) *IndexError {
func (e *IndexError) WithLogIndex(logIndex uint64) *IndexError {
e.LogIndex = logIndex
return e
}
Expand Down Expand Up @@ -234,7 +237,7 @@ func (idx *Indexer) IsInterestingAddress(addr string) bool {
if addr == "" {
return false
}
return slices.Contains(idx.Config.GetInterestingAddressForConfigEnv(), addr)
return slices.Contains(idx.Config.GetInterestingAddressForConfigEnv(), strings.ToLower(addr))
}

func (idx *Indexer) IsInterestingTransaction(txn *ethereum.EthereumTransaction, receipt *ethereum.EthereumTransactionReceipt) bool {
Expand Down
75 changes: 56 additions & 19 deletions pkg/indexer/transactionLogs.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,23 +77,26 @@ func (idx *Indexer) ParseTransactionLogs(
WithMetadata("contractAddress", contractAddress.Value())
}

// if the contract is interesting but not found, throw an error to stop processing
if contract == nil {
idx.Logger.Sugar().Debugw("No contract found for address", zap.String("hash", transaction.Hash.Value()))
return nil, nil
idx.Logger.Sugar().Errorw("No contract found for address", zap.String("hash", transaction.Hash.Value()))
return nil, NewIndexError(IndexError_FailedToFindContract, err).
WithMessage("No contract found for address").
WithBlockNumber(transaction.BlockNumber.Value()).
WithTransactionHash(transaction.Hash.Value()).
WithMetadata("contractAddress", contractAddress.Value())
}

contractAbi := contract.CombineAbis()
if err != nil {
idx.Logger.Sugar().Errorw("Failed to combine ABIs")
return nil, NewIndexError(IndexError_FailedToCombineAbis, err).
WithMessage("Failed to combine ABIs").
WithBlockNumber(transaction.BlockNumber.Value()).
WithTransactionHash(transaction.Hash.Value())
}

// If the ABI is empty, return an error
if contractAbi == "" {
idx.Logger.Sugar().Debugw("No ABI found for contract", zap.String("hash", transaction.Hash.Value()))
return parsedTransaction, nil
idx.Logger.Sugar().Errorw("No ABI found for contract", zap.String("hash", transaction.Hash.Value()))
return nil, NewIndexError(IndexError_EmptyAbi, err).
WithMessage("No ABI found for contract").
WithBlockNumber(transaction.BlockNumber.Value()).
WithTransactionHash(transaction.Hash.Value()).
WithMetadata("contractAddress", contractAddress.Value())
}
a, err = idx.getAbi(contractAbi)
if err != nil {
Expand All @@ -112,18 +115,33 @@ func (idx *Indexer) ParseTransactionLogs(
decodedSig, err := hex.DecodeString(txInput[2:10])
if err != nil {
idx.Logger.Sugar().Errorw("Failed to decode signature")
return nil, NewIndexError(IndexError_FailedToParseTransaction, err).
WithMessage("Failed to decode signature").
WithBlockNumber(transaction.BlockNumber.Value()).
WithTransactionHash(transaction.Hash.Value()).
WithMetadata("contractAddress", contractAddress.Value())
}

if len(decodedSig) > 0 {
method, err = a.MethodById(decodedSig)
if err != nil {
idx.Logger.Sugar().Debugw(fmt.Sprintf("Failed to find method by ID '%s'", common.BytesToHash(decodedSig).String()))
parsedTransaction.MethodName = "unknown"
msg := fmt.Sprintf("Failed to find method by ID '%s'", common.BytesToHash(decodedSig).String())
idx.Logger.Sugar().Debugw(msg)
return nil, NewIndexError(IndexError_FailedToParseTransaction, err).
WithMessage(msg).
WithBlockNumber(transaction.BlockNumber.Value()).
WithTransactionHash(transaction.Hash.Value()).
WithMetadata("contractAddress", contractAddress.Value())
} else {
parsedTransaction.MethodName = method.RawName
decodedData, err := hex.DecodeString(txInput[10:])
if err != nil {
idx.Logger.Sugar().Errorw("Failed to decode input data")
idx.Logger.Sugar().Errorw("Failed to decode transaction input data")
return nil, NewIndexError(IndexError_FailedToParseTransaction, err).
WithMessage("Failed to decode transaction input data").
WithBlockNumber(transaction.BlockNumber.Value()).
WithTransactionHash(transaction.Hash.Value()).
WithMetadata("contractAddress", contractAddress.Value())
} else {
callMap := map[string]interface{}{}
if err := method.Inputs.UnpackIntoMap(callMap, decodedData); err != nil {
Expand All @@ -132,10 +150,20 @@ func (idx *Indexer) ParseTransactionLogs(
zap.String("transactionHash", transaction.Hash.Value()),
zap.Uint64("blockNumber", transaction.BlockNumber.Value()),
)
return nil, NewIndexError(IndexError_FailedToParseTransaction, err).
WithMessage("Failed to unpack data").
WithBlockNumber(transaction.BlockNumber.Value()).
WithTransactionHash(transaction.Hash.Value()).
WithMetadata("contractAddress", contractAddress.Value())
}
callMapBytes, err := json.Marshal(callMap)
if err != nil {
idx.Logger.Sugar().Errorw("Failed to marshal callMap data", zap.String("hash", transaction.Hash.Value()))
return nil, NewIndexError(IndexError_FailedToParseTransaction, err).
WithMessage("Failed to marshal callMap data").
WithBlockNumber(transaction.BlockNumber.Value()).
WithTransactionHash(transaction.Hash.Value()).
WithMetadata("contractAddress", contractAddress.Value())
}
parsedTransaction.DecodedData = string(callMapBytes)
}
Expand All @@ -159,7 +187,14 @@ func (idx *Indexer) ParseTransactionLogs(
}
decodedLog, err := idx.DecodeLogWithAbi(a, receipt, lg)
if err != nil {
idx.Logger.Sugar().Debugw(fmt.Sprintf("Error decoding log - index: '%d' - '%s'", i, transaction.Hash.Value()), zap.Error(err))
msg := fmt.Sprintf("Error decoding log - index: '%d' - '%s'", i, transaction.Hash.Value())
idx.Logger.Sugar().Debugw(msg, zap.Error(err))
return nil, NewIndexError(IndexError_FailedToDecodeLog, err).
WithMessage(msg).
WithBlockNumber(transaction.BlockNumber.Value()).
WithTransactionHash(transaction.Hash.Value()).
WithMetadata("contractAddress", contractAddress.Value()).
WithLogIndex(lg.LogIndex.Value())
} else {
idx.Logger.Sugar().Debugw(fmt.Sprintf("Decoded log - index: '%d' - '%s'", i, transaction.Hash.Value()), zap.Any("decodedLog", decodedLog))
}
Expand Down Expand Up @@ -246,9 +281,10 @@ func (idx *Indexer) DecodeLog(a *abi.ABI, lg *ethereum.EthereumEventLog) (*parse
}

if a == nil {
idx.Logger.Sugar().Debugw(fmt.Sprintf("No ABI provided, using topic hash as event name '%s'", logAddress.String()))
decodedLog.EventName = topicHash.String()
return decodedLog, nil
idx.Logger.Sugar().Errorw("No ABI provided for decoding log",
zap.String("address", logAddress.String()),
)
return nil, errors.New("no ABI provided for decoding log")
}

event, err := a.EventByID(topicHash)
Expand Down Expand Up @@ -290,13 +326,14 @@ func (idx *Indexer) DecodeLog(a *abi.ABI, lg *ethereum.EthereumEventLog) (*parse
outputDataMap := make(map[string]interface{})
err = a.UnpackIntoMap(outputDataMap, event.Name, byteData)
if err != nil {
idx.Logger.Sugar().Errorw("Failed to unpack data: ",
idx.Logger.Sugar().Errorw("Failed to unpack data",
zap.Error(err),
zap.String("hash", lg.TransactionHash.Value()),
zap.String("address", lg.Address.Value()),
zap.String("eventName", event.Name),
zap.String("transactionHash", lg.TransactionHash.Value()),
)
return nil, errors.New("failed to unpack data")
}

decodedLog.OutputData = outputDataMap
Expand Down

0 comments on commit 5829346

Please sign in to comment.