|
7 | 7 | "math/big" |
8 | 8 | "net/http" |
9 | 9 | "path/filepath" |
| 10 | + "reflect" |
10 | 11 | "strings" |
11 | 12 | "time" |
12 | 13 |
|
@@ -1167,28 +1168,56 @@ func (t TransactionLog) GetData() []byte { |
1167 | 1168 | } |
1168 | 1169 |
|
1169 | 1170 | func (m *Client) decodeContractLogs(l zerolog.Logger, logs []types.Log, allABIs []*abi.ABI) ([]DecodedTransactionLog, error) { |
1170 | | - l.Trace().Msg("Decoding events") |
| 1171 | + l.Trace(). |
| 1172 | + Msg("Decoding events") |
1171 | 1173 | sigMap := buildEventSignatureMap(allABIs) |
1172 | 1174 |
|
1173 | 1175 | var eventsParsed []DecodedTransactionLog |
1174 | 1176 | for _, lo := range logs { |
1175 | 1177 | if len(lo.Topics) == 0 { |
1176 | | - l.Debug().Msg("Log has no topics; skipping") |
| 1178 | + l.Debug(). |
| 1179 | + Msg("Log has no topics; skipping") |
1177 | 1180 | continue |
1178 | 1181 | } |
1179 | 1182 |
|
1180 | 1183 | eventSig := lo.Topics[0].Hex() |
1181 | 1184 | possibleEvents, exists := sigMap[eventSig] |
1182 | 1185 | if !exists { |
1183 | | - l.Trace().Str("Signature", eventSig).Msg("No matching events found for signature") |
| 1186 | + l.Trace(). |
| 1187 | + Str("Event signature", eventSig). |
| 1188 | + Msg("No matching events found for signature") |
1184 | 1189 | continue |
1185 | 1190 | } |
1186 | 1191 |
|
| 1192 | + // Check if we know what contract is this log from and if we do, get its ABI to skip unnecessary iterations |
| 1193 | + var knownContractABI *abi.ABI |
| 1194 | + if contractName := m.ContractAddressToNameMap.GetContractName(lo.Address.Hex()); contractName != "" { |
| 1195 | + maybeABI, ok := m.ContractStore.GetABI(contractName) |
| 1196 | + if !ok { |
| 1197 | + l.Trace(). |
| 1198 | + Str("Event signature", eventSig). |
| 1199 | + Str("Contract name", contractName). |
| 1200 | + Str("Contract address", lo.Address.Hex()). |
| 1201 | + Msg("No ABI found for known contract; this is unexpected. Continuing with step-by-step ABI search") |
| 1202 | + } else { |
| 1203 | + knownContractABI = maybeABI |
| 1204 | + } |
| 1205 | + } |
| 1206 | + |
1187 | 1207 | // Iterate over possible events with the same signature |
1188 | 1208 | matched := false |
1189 | 1209 | for _, evWithABI := range possibleEvents { |
1190 | 1210 | evSpec := evWithABI.EventSpec |
1191 | | - eventABI := evWithABI.EventABI |
| 1211 | + contractABI := evWithABI.ContractABI |
| 1212 | + |
| 1213 | + // Check if known contract ABI matches candidate ABI and if not, skip this ABI and try the next one |
| 1214 | + if knownContractABI != nil && !reflect.DeepEqual(knownContractABI, contractABI) { |
| 1215 | + l.Trace(). |
| 1216 | + Str("Event signature", eventSig). |
| 1217 | + Str("Contract address", lo.Address.Hex()). |
| 1218 | + Msg("ABI doesn't match known ABI for this address; trying next ABI") |
| 1219 | + continue |
| 1220 | + } |
1192 | 1221 |
|
1193 | 1222 | // Validate indexed parameters count |
1194 | 1223 | // Non-indexed parameters are stored in the Data field, |
@@ -1220,7 +1249,7 @@ func (m *Client) decodeContractLogs(l zerolog.Logger, logs []types.Log, allABIs |
1220 | 1249 | Str("Signature", evSpec.Sig). |
1221 | 1250 | Msg("Unpacking event") |
1222 | 1251 |
|
1223 | | - eventsMap, topicsMap, err := decodeEventFromLog(l, *eventABI, *evSpec, d) |
| 1252 | + eventsMap, topicsMap, err := decodeEventFromLog(l, *contractABI, *evSpec, d) |
1224 | 1253 | if err != nil { |
1225 | 1254 | l.Error(). |
1226 | 1255 | Err(err). |
@@ -1256,55 +1285,23 @@ func (m *Client) decodeContractLogs(l zerolog.Logger, logs []types.Log, allABIs |
1256 | 1285 | return eventsParsed, nil |
1257 | 1286 | } |
1258 | 1287 |
|
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 |
| 1288 | +type eventWithABI struct { |
| 1289 | + ContractABI *abi.ABI |
| 1290 | + EventSpec *abi.Event |
1295 | 1291 | } |
1296 | 1292 |
|
1297 | 1293 | // 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) |
| 1294 | +func buildEventSignatureMap(allABIs []*abi.ABI) map[string][]*eventWithABI { |
| 1295 | + sigMap := make(map[string][]*eventWithABI) |
1300 | 1296 | for _, a := range allABIs { |
1301 | 1297 | for _, ev := range a.Events { |
1302 | | - sigMap[ev.ID.Hex()] = append(sigMap[ev.ID.Hex()], &EventWithABI{ |
1303 | | - EventABI: a, |
1304 | | - EventSpec: &ev, |
| 1298 | + sigMap[ev.ID.Hex()] = append(sigMap[ev.ID.Hex()], &eventWithABI{ |
| 1299 | + ContractABI: a, |
| 1300 | + EventSpec: &ev, |
1305 | 1301 | }) |
1306 | 1302 | } |
1307 | 1303 | } |
| 1304 | + |
1308 | 1305 | return sigMap |
1309 | 1306 | } |
1310 | 1307 |
|
|
0 commit comments