mirror of
https://github.com/grassrootseconomics/eth-tracker.git
synced 2025-05-09 15:51:02 +02:00
feat: add event structure, fix overflow issues
This commit is contained in:
parent
ec5dfc784a
commit
6bdea033a6
@ -16,6 +16,7 @@ import (
|
||||
"github.com/grassrootseconomics/celo-tracker/internal/cache"
|
||||
"github.com/grassrootseconomics/celo-tracker/internal/chain"
|
||||
"github.com/grassrootseconomics/celo-tracker/internal/db"
|
||||
"github.com/grassrootseconomics/celo-tracker/internal/emitter"
|
||||
"github.com/grassrootseconomics/celo-tracker/internal/processor"
|
||||
"github.com/grassrootseconomics/celo-tracker/internal/stats"
|
||||
"github.com/grassrootseconomics/celo-tracker/internal/syncer"
|
||||
@ -120,6 +121,10 @@ func main() {
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
defaultEmitter := emitter.New(emitter.EmitterOpts{
|
||||
Logg: lo,
|
||||
})
|
||||
|
||||
blockProcessor := processor.NewProcessor(processor.ProcessorOpts{
|
||||
Chain: chain,
|
||||
BlocksQueue: &blocksQueue,
|
||||
@ -127,6 +132,7 @@ func main() {
|
||||
Stats: stats,
|
||||
DB: db,
|
||||
Cache: cache,
|
||||
Emitter: defaultEmitter,
|
||||
})
|
||||
|
||||
// wg.Add(1)
|
||||
|
@ -18,13 +18,12 @@ func NewConsoleEmitter(logg *slog.Logger) *ConsoleEmitter {
|
||||
}
|
||||
}
|
||||
|
||||
func (l *ConsoleEmitter) Emit(_ context.Context, payload []byte) error {
|
||||
var event map[string]interface{}
|
||||
|
||||
if err := json.Unmarshal(payload, &event); err != nil {
|
||||
func (l *ConsoleEmitter) Emit(_ context.Context, payload interface{}) error {
|
||||
jsonData, err := json.Marshal(payload)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
l.logg.Info("emitted event", "json_payload", event)
|
||||
l.logg.Info("emitted event", "json_payload", string(jsonData))
|
||||
return nil
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ import (
|
||||
|
||||
type (
|
||||
Emitter interface {
|
||||
Emit(context.Context, []byte) error
|
||||
Emit(context.Context, interface{}) error
|
||||
}
|
||||
|
||||
EmitterOpts struct {
|
||||
|
@ -5,22 +5,42 @@ import (
|
||||
|
||||
"github.com/celo-org/celo-blockchain/core/types"
|
||||
"github.com/grassrootseconomics/celo-tracker/internal/emitter"
|
||||
"github.com/grassrootseconomics/w3-celo"
|
||||
)
|
||||
|
||||
type (
|
||||
Handler interface {
|
||||
Handle(context.Context, *types.Log, emitter.Emitter) error
|
||||
HandleLog(context.Context, LogMessage, emitter.Emitter) error
|
||||
HandleRevert(context.Context, RevertMessage, emitter.Emitter) error
|
||||
}
|
||||
|
||||
LogMessage struct {
|
||||
Log *types.Log
|
||||
BlockTime uint64
|
||||
}
|
||||
|
||||
RevertMessage struct {
|
||||
From string
|
||||
RevertReason string
|
||||
InputData string
|
||||
Block uint64
|
||||
ContractAddress string
|
||||
Timestamp uint64
|
||||
TxHash string
|
||||
}
|
||||
|
||||
Event struct {
|
||||
Block uint64 `json:"block"`
|
||||
ContractAddress string `json:"contractAddress"`
|
||||
Success bool `json:"success"`
|
||||
Timestamp uint64 `json:"timestamp"`
|
||||
TxHash string `json:"transactionHash"`
|
||||
TxType string `json:"transactionType"`
|
||||
Payload map[string]any `json:"payload"`
|
||||
}
|
||||
)
|
||||
|
||||
func New() []Handler {
|
||||
transferHandler := &TransferHandler{
|
||||
topicHash: w3.H("0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"),
|
||||
event: w3.MustNewEvent("Transfer(address indexed _from, address indexed _to, uint256 _value)"),
|
||||
}
|
||||
|
||||
return []Handler{
|
||||
transferHandler,
|
||||
&TransferHandler{},
|
||||
}
|
||||
}
|
||||
|
1
internal/handler/mint.go
Normal file
1
internal/handler/mint.go
Normal file
@ -0,0 +1 @@
|
||||
package handler
|
@ -2,11 +2,9 @@ package handler
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"math/big"
|
||||
|
||||
"github.com/celo-org/celo-blockchain/common"
|
||||
"github.com/celo-org/celo-blockchain/core/types"
|
||||
"github.com/grassrootseconomics/celo-tracker/internal/emitter"
|
||||
"github.com/grassrootseconomics/w3-celo"
|
||||
)
|
||||
@ -16,40 +14,106 @@ type (
|
||||
topicHash common.Hash
|
||||
event *w3.Event
|
||||
}
|
||||
|
||||
TransferEvent struct {
|
||||
Contract string
|
||||
From string
|
||||
To string
|
||||
Value uint64
|
||||
}
|
||||
)
|
||||
|
||||
func (h *TransferHandler) Handle(ctx context.Context, log *types.Log, emitter emitter.Emitter) error {
|
||||
if log.Topics[0] == h.topicHash {
|
||||
var (
|
||||
transferTopicHash = w3.H("0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef")
|
||||
transferEvent = w3.MustNewEvent("Transfer(address indexed _from, address indexed _to, uint256 _value)")
|
||||
transferSig = w3.MustNewFunc("transfer(address, uint256)", "bool")
|
||||
transferFromSig = w3.MustNewFunc("transferFrom(address, address, uint256)", "bool")
|
||||
)
|
||||
|
||||
func (h *TransferHandler) HandleLog(ctx context.Context, msg LogMessage, emitter emitter.Emitter) error {
|
||||
if msg.Log.Topics[0] == transferTopicHash {
|
||||
var (
|
||||
from common.Address
|
||||
to common.Address
|
||||
value big.Int
|
||||
)
|
||||
|
||||
if err := h.event.DecodeArgs(log, &from, &to, &value); err != nil {
|
||||
if err := transferEvent.DecodeArgs(msg.Log, &from, &to, &value); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
transferEvent := &TransferEvent{
|
||||
Contract: log.Address.Hex(),
|
||||
From: from.Hex(),
|
||||
To: to.Hex(),
|
||||
Value: value.Uint64(),
|
||||
transferEvent := Event{
|
||||
Block: msg.Log.BlockNumber,
|
||||
ContractAddress: msg.Log.Address.Hex(),
|
||||
Success: true,
|
||||
Timestamp: msg.BlockTime,
|
||||
TxHash: msg.Log.TxHash.Hex(),
|
||||
TxType: "TRANSFER",
|
||||
Payload: map[string]any{
|
||||
"from": from.Hex(),
|
||||
"to": to.Hex(),
|
||||
"value": value.String(),
|
||||
},
|
||||
}
|
||||
|
||||
jsonData, err := json.Marshal(transferEvent)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return emitter.Emit(ctx, jsonData)
|
||||
return emitter.Emit(ctx, transferEvent)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h *TransferHandler) HandleRevert(ctx context.Context, msg RevertMessage, emitter emitter.Emitter) error {
|
||||
if len(msg.InputData) < 8 {
|
||||
return nil
|
||||
}
|
||||
|
||||
switch msg.InputData[:8] {
|
||||
case "a9059cbb":
|
||||
var (
|
||||
to common.Address
|
||||
value big.Int
|
||||
)
|
||||
|
||||
if err := transferSig.DecodeArgs(w3.B(msg.InputData), &to, &value); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
transferEvent := Event{
|
||||
Block: msg.Block,
|
||||
ContractAddress: msg.ContractAddress,
|
||||
Success: false,
|
||||
Timestamp: msg.Timestamp,
|
||||
TxHash: msg.TxHash,
|
||||
TxType: "TRANSFER",
|
||||
Payload: map[string]any{
|
||||
"revertReason": msg.RevertReason,
|
||||
"from": msg.From,
|
||||
"to": to.Hex(),
|
||||
"value": value.String(),
|
||||
},
|
||||
}
|
||||
|
||||
return emitter.Emit(ctx, transferEvent)
|
||||
case "23b872dd":
|
||||
var (
|
||||
from common.Address
|
||||
to common.Address
|
||||
value big.Int
|
||||
)
|
||||
|
||||
if err := transferFromSig.DecodeArgs(w3.B(msg.InputData), &from, &to, &value); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
transferEvent := Event{
|
||||
Block: msg.Block,
|
||||
ContractAddress: msg.ContractAddress,
|
||||
Success: false,
|
||||
Timestamp: msg.Timestamp,
|
||||
TxHash: msg.TxHash,
|
||||
TxType: "TRANSFER",
|
||||
Payload: map[string]any{
|
||||
"revertReason": msg.RevertReason,
|
||||
"from": from.Hex(),
|
||||
"to": to.Hex(),
|
||||
"value": value.String(),
|
||||
},
|
||||
}
|
||||
|
||||
return emitter.Emit(ctx, transferEvent)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -5,7 +5,7 @@ import (
|
||||
|
||||
"github.com/celo-org/celo-blockchain/common"
|
||||
"github.com/celo-org/celo-blockchain/core/types"
|
||||
"github.com/grassrootseconomics/celo-tracker/internal/emitter"
|
||||
"github.com/grassrootseconomics/celo-tracker/internal/handler"
|
||||
)
|
||||
|
||||
func (p *Processor) processBlock(ctx context.Context, block types.Block) error {
|
||||
@ -27,15 +27,41 @@ func (p *Processor) processBlock(ctx context.Context, block types.Block) error {
|
||||
if receipt.Status > 0 {
|
||||
for _, log := range receipt.Logs {
|
||||
if p.cache.Exists(log.Address.Hex()) {
|
||||
if err := p.handleLogs(ctx, log); err != nil {
|
||||
p.logg.Error("hanlder error", "error", err)
|
||||
msg := handler.LogMessage{
|
||||
Log: log,
|
||||
BlockTime: block.Time(),
|
||||
}
|
||||
|
||||
if err := p.handleLogs(ctx, msg); err != nil {
|
||||
p.logg.Error("handler error", "handler_type", "log", "error", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if p.cache.Exists(txs[i].To().Hex()) {
|
||||
revertReason, _ := p.chain.GetRevertReason(ctx, receipt.TxHash, receipt.BlockNumber)
|
||||
p.logg.Debug("tx reverted", "hash", receipt.TxHash, "revert_reason", revertReason, "input_data", common.Bytes2Hex(txs[i].Data()))
|
||||
from, err := types.Sender(types.LatestSignerForChainID(txs[i].ChainId()), &txs[i])
|
||||
if err != nil {
|
||||
p.logg.Error("hanlder error", "handler_type", "revert", "error", err)
|
||||
}
|
||||
|
||||
revertReason, err := p.chain.GetRevertReason(ctx, receipt.TxHash, receipt.BlockNumber)
|
||||
if err != nil {
|
||||
p.logg.Error("handler error", "handler_type", "revert", "error", err)
|
||||
}
|
||||
|
||||
msg := handler.RevertMessage{
|
||||
From: from.Hex(),
|
||||
RevertReason: revertReason,
|
||||
InputData: common.Bytes2Hex(txs[i].Data()),
|
||||
Block: blockNumber,
|
||||
ContractAddress: txs[i].To().Hex(),
|
||||
Timestamp: block.Time(),
|
||||
TxHash: receipt.TxHash.Hex(),
|
||||
}
|
||||
|
||||
if err := p.handleRevert(ctx, msg); err != nil {
|
||||
p.logg.Error("handler error", "handler_type", "revert", "error", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -48,15 +74,22 @@ func (p *Processor) processBlock(ctx context.Context, block types.Block) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *Processor) handleLogs(ctx context.Context, log *types.Log) error {
|
||||
defaultEmitter := emitter.New(emitter.EmitterOpts{
|
||||
Logg: p.logg,
|
||||
})
|
||||
|
||||
func (p *Processor) handleLogs(ctx context.Context, msg handler.LogMessage) error {
|
||||
for _, handler := range p.handlers {
|
||||
if err := handler.Handle(ctx, log, defaultEmitter); err != nil {
|
||||
if err := handler.HandleLog(ctx, msg, p.emitter); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *Processor) handleRevert(ctx context.Context, msg handler.RevertMessage) error {
|
||||
for _, handler := range p.handlers {
|
||||
if err := handler.HandleRevert(ctx, msg, p.emitter); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ import (
|
||||
"github.com/grassrootseconomics/celo-tracker/internal/cache"
|
||||
"github.com/grassrootseconomics/celo-tracker/internal/chain"
|
||||
"github.com/grassrootseconomics/celo-tracker/internal/db"
|
||||
"github.com/grassrootseconomics/celo-tracker/internal/emitter"
|
||||
"github.com/grassrootseconomics/celo-tracker/internal/handler"
|
||||
"github.com/grassrootseconomics/celo-tracker/internal/pool"
|
||||
"github.com/grassrootseconomics/celo-tracker/internal/stats"
|
||||
@ -24,6 +25,7 @@ type (
|
||||
Stats *stats.Stats
|
||||
DB *db.DB
|
||||
Cache cache.Cache
|
||||
Emitter emitter.Emitter
|
||||
}
|
||||
|
||||
Processor struct {
|
||||
@ -36,6 +38,7 @@ type (
|
||||
quit chan struct{}
|
||||
handlers []handler.Handler
|
||||
cache cache.Cache
|
||||
emitter emitter.Emitter
|
||||
}
|
||||
)
|
||||
|
||||
@ -54,6 +57,7 @@ func NewProcessor(o ProcessorOpts) *Processor {
|
||||
quit: make(chan struct{}),
|
||||
handlers: handler.New(),
|
||||
cache: o.Cache,
|
||||
emitter: o.Emitter,
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user