@@ -1167,38 +1167,147 @@ func (t TransactionLog) GetData() []byte {
11671167}
11681168
11691169func (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.
12031312func (m * Client ) WaitUntilNoPendingTxForRootKey (timeout time.Duration ) error {
12041313 return m .WaitUntilNoPendingTx (m .MustGetRootKeyAddress (), timeout )
0 commit comments