forked from cerc-io/ipld-eth-server
fetch event logs in batches- all events for a contract address at a given block height are fetched together, different contract events still fetched separately
This commit is contained in:
@@ -34,6 +34,7 @@ import (
|
||||
|
||||
type Converter interface {
|
||||
Convert(logs []gethTypes.Log, event types.Event, headerID int64) ([]types.Log, error)
|
||||
ConvertBatch(logs []gethTypes.Log, events map[string]types.Event, headerID int64) (map[string][]types.Log, error)
|
||||
Update(info *contract.Contract)
|
||||
}
|
||||
|
||||
@@ -129,3 +130,93 @@ func (c *converter) Convert(logs []gethTypes.Log, event types.Event, headerID in
|
||||
|
||||
return returnLogs, nil
|
||||
}
|
||||
|
||||
// Convert the given watched event logs into types.Logs
|
||||
func (c *converter) ConvertBatch(logs []gethTypes.Log, events map[string]types.Event, headerID int64) (map[string][]types.Log, error) {
|
||||
contract := bind.NewBoundContract(common.HexToAddress(c.ContractInfo.Address), c.ContractInfo.ParsedAbi, nil, nil, nil)
|
||||
eventsToLogs := make(map[string][]types.Log)
|
||||
for _, event := range events {
|
||||
eventsToLogs[event.Name] = make([]types.Log, 0, len(logs))
|
||||
// Iterate through all event logs
|
||||
for _, log := range logs {
|
||||
// If the log is of this event type, process it as such
|
||||
if event.Sig() == log.Topics[0] {
|
||||
values := make(map[string]interface{})
|
||||
for _, field := range event.Fields {
|
||||
var i interface{}
|
||||
values[field.Name] = i
|
||||
}
|
||||
|
||||
err := contract.UnpackLogIntoMap(values, event.Name, log)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
strValues := make(map[string]string, len(values))
|
||||
seenAddrs := make([]interface{}, 0, len(values))
|
||||
seenHashes := make([]interface{}, 0, len(values))
|
||||
for fieldName, input := range values {
|
||||
// Postgres cannot handle custom types, resolve everything to strings
|
||||
switch input.(type) {
|
||||
case *big.Int:
|
||||
b := input.(*big.Int)
|
||||
strValues[fieldName] = b.String()
|
||||
case common.Address:
|
||||
a := input.(common.Address)
|
||||
strValues[fieldName] = a.String()
|
||||
seenAddrs = append(seenAddrs, a)
|
||||
case common.Hash:
|
||||
h := input.(common.Hash)
|
||||
strValues[fieldName] = h.String()
|
||||
seenHashes = append(seenHashes, h)
|
||||
case string:
|
||||
strValues[fieldName] = input.(string)
|
||||
case bool:
|
||||
strValues[fieldName] = strconv.FormatBool(input.(bool))
|
||||
case []byte:
|
||||
b := input.([]byte)
|
||||
strValues[fieldName] = hexutil.Encode(b)
|
||||
if len(b) == 32 {
|
||||
seenHashes = append(seenHashes, common.HexToHash(strValues[fieldName]))
|
||||
}
|
||||
case byte:
|
||||
b := input.(byte)
|
||||
strValues[fieldName] = string(b)
|
||||
default:
|
||||
return nil, errors.New(fmt.Sprintf("error: unhandled abi type %T", input))
|
||||
}
|
||||
}
|
||||
|
||||
// Only hold onto logs that pass our address filter, if any
|
||||
if c.ContractInfo.PassesEventFilter(strValues) {
|
||||
raw, err := json.Marshal(log)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
eventsToLogs[event.Name] = append(eventsToLogs[event.Name], types.Log{
|
||||
LogIndex: log.Index,
|
||||
Values: strValues,
|
||||
Raw: raw,
|
||||
TransactionIndex: log.TxIndex,
|
||||
Id: headerID,
|
||||
})
|
||||
|
||||
// Cache emitted values if their caching is turned on
|
||||
if c.ContractInfo.EmittedAddrs != nil {
|
||||
c.ContractInfo.AddEmittedAddr(seenAddrs...)
|
||||
}
|
||||
if c.ContractInfo.EmittedHashes != nil {
|
||||
c.ContractInfo.AddEmittedHash(seenHashes...)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return eventsToLogs, nil
|
||||
}
|
||||
|
||||
func (c *converter) handleDSNote() {
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user