Skip to content

Commit a3f07b2

Browse files
committed
check number of indexed parameters when decoding events
1 parent d9665c9 commit a3f07b2

File tree

2 files changed

+252
-143
lines changed

2 files changed

+252
-143
lines changed

seth/client.go

Lines changed: 132 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1167,38 +1167,147 @@ func (t TransactionLog) GetData() []byte {
11671167
}
11681168

11691169
func (m *Client) decodeContractLogs(l zerolog.Logger, logs []types.Log, allABIs []*abi.ABI) ([]DecodedTransactionLog, error) {
1170-
l.Trace().Msg("Decoding ALL events")
1170+
l.Trace().Msg("Decoding events")
1171+
sigMap := buildEventSignatureMap(allABIs)
1172+
11711173
var eventsParsed []DecodedTransactionLog
11721174
for _, lo := range logs {
1173-
ABI_LOOP:
1174-
for _, a := range allABIs {
1175-
for _, evSpec := range a.Events {
1176-
if evSpec.ID.Hex() == lo.Topics[0].Hex() {
1177-
d := TransactionLog{lo.Topics, lo.Data}
1178-
l.Trace().Str("Name", evSpec.RawName).Str("Signature", evSpec.Sig).Msg("Unpacking event")
1179-
eventsMap, topicsMap, err := decodeEventFromLog(l, *a, evSpec, d)
1180-
if err != nil {
1181-
return nil, errors.Wrap(err, ErrDecodeLog)
1182-
}
1183-
parsedEvent := decodedLogFromMaps(&DecodedTransactionLog{}, eventsMap, topicsMap)
1184-
decodedTransactionLog, ok := parsedEvent.(*DecodedTransactionLog)
1185-
if ok {
1186-
decodedTransactionLog.Signature = evSpec.Sig
1187-
m.mergeLogMeta(decodedTransactionLog, lo)
1188-
eventsParsed = append(eventsParsed, *decodedTransactionLog)
1189-
l.Trace().Interface("Log", parsedEvent).Msg("Transaction log")
1190-
break ABI_LOOP
1191-
}
1192-
l.Trace().
1193-
Str("Actual type", fmt.Sprintf("%T", decodedTransactionLog)).
1194-
Msg("Failed to cast decoded event to DecodedCommonLog")
1175+
if len(lo.Topics) == 0 {
1176+
l.Debug().Msg("Log has no topics; skipping")
1177+
continue
1178+
}
1179+
1180+
eventSig := lo.Topics[0].Hex()
1181+
possibleEvents, exists := sigMap[eventSig]
1182+
if !exists {
1183+
l.Trace().Str("Signature", eventSig).Msg("No matching events found for signature")
1184+
continue
1185+
}
1186+
1187+
// Iterate over possible events with the same signature
1188+
matched := false
1189+
for _, evWithABI := range possibleEvents {
1190+
evSpec := evWithABI.EventSpec
1191+
eventABI := evWithABI.EventABI
1192+
1193+
// Validate indexed parameters count
1194+
// Non-indexed parameters are stored in the Data field,
1195+
// and much harder to validate due to dynamic types,
1196+
// so we skip them for now
1197+
var indexedParams abi.Arguments
1198+
for _, input := range evSpec.Inputs {
1199+
if input.Indexed {
1200+
indexedParams = append(indexedParams, input)
11951201
}
11961202
}
1203+
1204+
expectedIndexed := len(indexedParams)
1205+
actualIndexed := len(lo.Topics) - 1 // First topic is the event signature
1206+
1207+
if expectedIndexed != actualIndexed {
1208+
l.Trace().
1209+
Str("Event", evSpec.Name).
1210+
Int("Expected indexed param count", expectedIndexed).
1211+
Int("Actual indexed param count", actualIndexed).
1212+
Msg("Mismatch in indexed parameters; skipping event")
1213+
continue
1214+
}
1215+
1216+
// Proceed to decode the event
1217+
d := TransactionLog{lo.Topics, lo.Data}
1218+
l.Trace().
1219+
Str("Name", evSpec.RawName).
1220+
Str("Signature", evSpec.Sig).
1221+
Msg("Unpacking event")
1222+
1223+
eventsMap, topicsMap, err := decodeEventFromLog(l, *eventABI, *evSpec, d)
1224+
if err != nil {
1225+
l.Error().
1226+
Err(err).
1227+
Str("Event", evSpec.Name).
1228+
Msg("Failed to decode event; skipping")
1229+
continue // Skip this event instead of returning an error
1230+
}
1231+
1232+
parsedEvent := decodedLogFromMaps(&DecodedTransactionLog{}, eventsMap, topicsMap)
1233+
decodedTransactionLog, ok := parsedEvent.(*DecodedTransactionLog)
1234+
if ok {
1235+
decodedTransactionLog.Signature = evSpec.Sig
1236+
m.mergeLogMeta(decodedTransactionLog, lo)
1237+
eventsParsed = append(eventsParsed, *decodedTransactionLog)
1238+
l.Trace().
1239+
Interface("Log", parsedEvent).
1240+
Msg("Transaction log decoded successfully")
1241+
matched = true
1242+
break // Move to the next log after successful decoding
1243+
}
1244+
1245+
l.Trace().
1246+
Str("Actual type", fmt.Sprintf("%T", decodedTransactionLog)).
1247+
Msg("Failed to cast decoded event to DecodedTransactionLog")
1248+
}
1249+
1250+
if !matched {
1251+
l.Warn().
1252+
Str("Signature", eventSig).
1253+
Msg("No matching event with valid indexed parameter count found for log")
11971254
}
11981255
}
11991256
return eventsParsed, nil
12001257
}
12011258

1259+
// func (m *Client) decodeContractLogs(l zerolog.Logger, logs []types.Log, allABIs []*abi.ABI) ([]DecodedTransactionLog, error) {
1260+
// l.Trace().Msg("Decoding events")
1261+
// var eventsParsed []DecodedTransactionLog
1262+
// for _, lo := range logs {
1263+
// ABI_LOOP:
1264+
// for _, a := range allABIs {
1265+
// for _, evSpec := range a.Events {
1266+
// if evSpec.ID.Hex() == lo.Topics[0].Hex() {
1267+
// d := TransactionLog{lo.Topics, lo.Data}
1268+
// l.Trace().Str("Name", evSpec.RawName).Str("Signature", evSpec.Sig).Msg("Unpacking event")
1269+
// eventsMap, topicsMap, err := decodeEventFromLog(l, *a, evSpec, d)
1270+
// if err != nil {
1271+
// return nil, errors.Wrap(err, ErrDecodeLog)
1272+
// }
1273+
// parsedEvent := decodedLogFromMaps(&DecodedTransactionLog{}, eventsMap, topicsMap)
1274+
// decodedTransactionLog, ok := parsedEvent.(*DecodedTransactionLog)
1275+
// if ok {
1276+
// decodedTransactionLog.Signature = evSpec.Sig
1277+
// m.mergeLogMeta(decodedTransactionLog, lo)
1278+
// eventsParsed = append(eventsParsed, *decodedTransactionLog)
1279+
// l.Trace().Interface("Log", parsedEvent).Msg("Transaction log")
1280+
// break ABI_LOOP
1281+
// }
1282+
// l.Trace().
1283+
// Str("Actual type", fmt.Sprintf("%T", decodedTransactionLog)).
1284+
// Msg("Failed to cast decoded event to DecodedCommonLog")
1285+
// }
1286+
// }
1287+
// }
1288+
// }
1289+
// return eventsParsed, nil
1290+
// }
1291+
1292+
type EventWithABI struct {
1293+
EventABI *abi.ABI
1294+
EventSpec *abi.Event
1295+
}
1296+
1297+
// buildEventSignatureMap precomputes a mapping from event signature to events with their ABIs
1298+
func buildEventSignatureMap(allABIs []*abi.ABI) map[string][]*EventWithABI {
1299+
sigMap := make(map[string][]*EventWithABI)
1300+
for _, a := range allABIs {
1301+
for _, ev := range a.Events {
1302+
sigMap[ev.ID.Hex()] = append(sigMap[ev.ID.Hex()], &EventWithABI{
1303+
EventABI: a,
1304+
EventSpec: &ev,
1305+
})
1306+
}
1307+
}
1308+
return sigMap
1309+
}
1310+
12021311
// WaitUntilNoPendingTxForRootKey waits until there's no pending transaction for root key. If after timeout there are still pending transactions, it returns error.
12031312
func (m *Client) WaitUntilNoPendingTxForRootKey(timeout time.Duration) error {
12041313
return m.WaitUntilNoPendingTx(m.MustGetRootKeyAddress(), timeout)

0 commit comments

Comments
 (0)