-
Notifications
You must be signed in to change notification settings - Fork 32
/
hmy.go
105 lines (94 loc) · 2.92 KB
/
hmy.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
package client
import (
"context"
"fmt"
"github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/core/types"
"github.com/synapsecns/sanguine/core/metrics"
"math/big"
)
// HarmonyVM is a strict superset of evm w/ custom harmony methods.
type HarmonyVM interface {
EVM
// FilterHarmonyLogs returns the logs that satisfy the supplied filter query.
FilterHarmonyLogs(ctx context.Context, query ethereum.FilterQuery) (logs []types.Log, err error)
// HarmonyTransactionReceipt returns the receipt of a transaction by transaction hash.
HarmonyTransactionReceipt(ctx context.Context, txHash common.Hash) (receipt *types.Receipt, err error)
}
type harmonyClient struct {
*clientImpl
}
// DialHarmonyBackend dials a harmony backend.
func DialHarmonyBackend(ctx context.Context, url string, handler metrics.Handler, ops ...Options) (HarmonyVM, error) {
evm, err := DialBackend(ctx, url, handler, ops...)
if err != nil {
return nil, fmt.Errorf("could not dial backend: %w", err)
}
client, ok := evm.(*clientImpl)
if !ok {
return nil, fmt.Errorf("could not cast to clientImpl")
}
return &harmonyClient{client}, nil
}
func (h *harmonyClient) FilterHarmonyLogs(ctx context.Context, query ethereum.FilterQuery) (logs []types.Log, err error) {
requestCtx, span := h.clientImpl.startSpan(ctx, HarmonyGetLogsMethod)
defer func() {
metrics.EndSpanWithErr(span, err)
}()
var result []types.Log
arg, err := toFilterArg(query)
if err != nil {
return nil, err
}
err = h.clientImpl.CallContext(requestCtx, &result, HarmonyGetLogsMethod.String(), arg)
return result, err
}
// HarmonyTransactionReceipt calls TransactionReceipt on the underlying client
//
//nolint:wrapcheck
func (h *harmonyClient) HarmonyTransactionReceipt(ctx context.Context, txHash common.Hash) (receipt *types.Receipt, err error) {
requestCtx, span := h.clientImpl.startSpan(ctx, HarmonyGetReceiptMethod)
defer func() {
metrics.EndSpanWithErr(span, err)
}()
var r *types.Receipt
err = h.clientImpl.CallContext(requestCtx, &r, HarmonyGetReceiptMethod.String(), txHash)
if err == nil {
if r == nil {
return nil, ethereum.NotFound
}
}
return r, err
}
func toFilterArg(q ethereum.FilterQuery) (interface{}, error) {
arg := map[string]interface{}{
"address": q.Addresses,
"topics": q.Topics,
}
if q.BlockHash != nil {
arg["blockHash"] = *q.BlockHash
if q.FromBlock != nil || q.ToBlock != nil {
return nil, fmt.Errorf("cannot specify both BlockHash and FromBlock/ToBlock")
}
} else {
if q.FromBlock == nil {
arg["fromBlock"] = "0x0"
} else {
arg["fromBlock"] = toBlockNumArg(q.FromBlock)
}
arg["toBlock"] = toBlockNumArg(q.ToBlock)
}
return arg, nil
}
func toBlockNumArg(number *big.Int) string {
if number == nil {
return "latest"
}
pending := big.NewInt(-1)
if number.Cmp(pending) == 0 {
return "pending"
}
return hexutil.EncodeBig(number)
}