-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathclient.go
68 lines (60 loc) · 1.63 KB
/
client.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
package main
import (
"bytes"
"context"
"math/big"
"github.com/ethereum/go-ethereum/cmd/utils"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/node"
)
type Client interface {
BlockByHash(ctx context.Context, hash common.Hash) (*types.Block, error)
BlockByNumber(ctx context.Context, number *big.Int) (*types.Block, error)
Close()
}
type LocalClient struct {
n *node.Node
db ethdb.Database
}
func NewLocalClient(dataDir string) (Client, error) {
nodeCfg := node.DefaultConfig
nodeCfg.Name = "geth"
nodeCfg.DataDir = dataDir
n, err := node.New(&nodeCfg)
if err != nil {
return nil, err
}
handles := utils.MakeDatabaseHandles(0)
db, err := n.OpenDatabaseWithFreezer("chaindata", 512, handles, "", "", true)
if err != nil {
return nil, err
}
return &LocalClient{
n: n,
db: db,
}, nil
}
func (c *LocalClient) Close() {
_ = c.db.Close()
_ = c.n.Close()
}
func (c *LocalClient) BlockByHash(ctx context.Context, hash common.Hash) (*types.Block, error) {
number := rawdb.ReadHeaderNumber(c.db, hash)
if number == nil {
return nil, nil
}
return rawdb.ReadBlock(c.db, hash, *number), nil
}
func (c *LocalClient) BlockByNumber(ctx context.Context, number *big.Int) (*types.Block, error) {
if number.Int64() < 0 {
return c.BlockByHash(ctx, rawdb.ReadHeadBlockHash(c.db))
}
hash := rawdb.ReadCanonicalHash(c.db, number.Uint64())
if bytes.Equal(hash.Bytes(), common.Hash{}.Bytes()) {
return nil, nil
}
return rawdb.ReadBlock(c.db, hash, number.Uint64()), nil
}