-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtransaction.go
89 lines (76 loc) · 1.97 KB
/
transaction.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
package main
import (
"context"
"fmt"
"log"
"github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/ethclient"
)
type TransactionEntry = struct {
blockHash common.Hash
txHash common.Hash
}
type TransactionJob = struct {
client *ethclient.Client
in <-chan *TransactionEntry
out chan<- string
}
func NewTransactionJob(
client *ethclient.Client,
in <-chan *TransactionEntry,
out chan<- string,
) *TransactionJob {
return &TransactionJob{client, in, out}
}
func processTransaction(job *TransactionJob) {
for entry := range job.in {
tx, err := getTransaction(entry.txHash, job.client)
if err != nil {
// RPC provider does not know the transaction
if err == ethereum.NotFound {
continue
}
log.Printf("getTransaction: hash=%s err=%s\n", entry.txHash, err)
continue
}
sender, err := getTransactionSender(tx)
if err != nil {
log.Printf("getTransactionSender: hash=%s err=%s\n", entry.txHash, err)
continue
}
// Block timestamps can be cached
block, err := getBlock(entry.blockHash, job.client)
if err != nil {
log.Printf("getBlock: block=%s tx=%s err=%s", entry.blockHash, entry.txHash, err)
continue
}
job.out <- fmt.Sprintf("%s %d", sender.Hex(), block.Time())
}
}
func getTransaction(hash common.Hash, client *ethclient.Client) (*types.Transaction, error) {
ctx := context.Background()
for {
tx, _, err := client.TransactionByHash(ctx, hash)
if err != nil {
if ok := checkErrorRetry(err); ok {
continue
}
return nil, err
}
return tx, nil
}
}
func getTransactionSender(tx *types.Transaction) (common.Address, error) {
var signer types.Signer
switch tx.Type() {
case types.AccessListTxType:
signer = types.NewEIP2930Signer(tx.ChainId())
case types.DynamicFeeTxType:
signer = types.NewLondonSigner(tx.ChainId())
default:
signer = types.NewEIP155Signer(tx.ChainId())
}
return types.Sender(signer, tx)
}