/
processor.go
117 lines (106 loc) · 3.06 KB
/
processor.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
package conn
import (
"context"
ingest "github.com/IRT-SystemX/eth-poller/ingest"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/ethclient"
"log"
"math"
"math/big"
)
type BlockCacheEvent struct {
number *big.Int
parentHash string
hash string
Fork bool
Size float64 `json:"block_size"`
Gas float64 `json:"block_gas"`
GasLimit float64 `json:"block_gas_limit"`
Usage float64 `json:"block_usage"`
Interval uint64
Timestamp uint64
Miner string
Transactions []*TxEvent
}
func (blockEvent *BlockCacheEvent) Number() *big.Int {
return blockEvent.number
}
func (blockEvent *BlockCacheEvent) ParentHash() string {
return blockEvent.parentHash
}
func (blockEvent *BlockCacheEvent) Hash() string {
return blockEvent.hash
}
func (blockEvent *BlockCacheEvent) SetFork(fork bool) {
blockEvent.Fork = fork
}
type TxEvent struct {
Sender string
Receiver string
Value *big.Int
FunctionId string
Events []string
Deploy string
}
type Processor struct {
client *ethclient.Client
signer types.EIP155Signer
}
func NewProcessor(client *ethclient.Client) *Processor {
processor := &Processor{client: client}
chainID, err := processor.client.NetworkID(context.Background())
if err != nil {
log.Fatal(err)
}
processor.signer = types.NewEIP155Signer(chainID)
return processor
}
func (processor *Processor) NewBlockEvent(number *big.Int, parentHash string, hash string) ingest.BlockEvent {
blockEvent := &BlockCacheEvent{
number: number,
parentHash: parentHash,
hash: hash,
}
return interface{}(blockEvent).(ingest.BlockEvent)
}
func (processor *Processor) Process(block *types.Block, event ingest.BlockEvent) {
blockEvent := interface{}(event).(*BlockCacheEvent)
blockEvent.Size = float64(block.Size())
blockEvent.Gas = float64(block.GasUsed())
blockEvent.GasLimit = float64(block.GasLimit())
blockEvent.Usage = math.Abs(float64(block.GasUsed()) * 100 / float64(block.GasLimit()))
blockEvent.Timestamp = block.Time()
blockEvent.Miner = block.Coinbase().Hex()
blockEvent.Transactions = make([]*TxEvent, len(block.Transactions()))
for i, tx := range block.Transactions() {
//log.Printf("Process tx %s", tx.Hash().Hex())
txEvent := &TxEvent{Events: make([]string, 0)}
blockEvent.Transactions[i] = txEvent
txEvent.Value = tx.Value()
if tx.To() != nil {
txEvent.Receiver = tx.To().Hex()
}
msg, err := tx.AsMessage(processor.signer)
if err != nil {
log.Println("Error msg: ", err)
} else {
txEvent.Sender = msg.From().Hex()
data := msg.Data()
if len(data) > 4 {
txEvent.FunctionId = string(hexutil.Encode(data[:4]))
}
}
receipt, err := processor.client.TransactionReceipt(context.Background(), tx.Hash())
if err != nil {
log.Println("Error receipt: ", err)
} else {
txEvent.Deploy = receipt.ContractAddress.Hex()
for _, vLog := range receipt.Logs {
for i := range vLog.Topics {
txEvent.Events = append(txEvent.Events, vLog.Topics[i].Hex())
}
}
}
}
}