-
Notifications
You must be signed in to change notification settings - Fork 671
/
client.go
137 lines (116 loc) · 4.72 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
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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.
package info
import (
"context"
"time"
"github.com/ava-labs/avalanchego/ids"
"github.com/ava-labs/avalanchego/utils/rpc"
"github.com/ava-labs/avalanchego/vms/platformvm/signer"
)
var _ Client = (*client)(nil)
// Client interface for an Info API Client.
// See also AwaitBootstrapped.
type Client interface {
GetNodeVersion(context.Context, ...rpc.Option) (*GetNodeVersionReply, error)
GetNodeID(context.Context, ...rpc.Option) (ids.NodeID, *signer.ProofOfPossession, error)
GetNodeIP(context.Context, ...rpc.Option) (string, error)
GetNetworkID(context.Context, ...rpc.Option) (uint32, error)
GetNetworkName(context.Context, ...rpc.Option) (string, error)
GetBlockchainID(context.Context, string, ...rpc.Option) (ids.ID, error)
Peers(context.Context, ...rpc.Option) ([]Peer, error)
IsBootstrapped(context.Context, string, ...rpc.Option) (bool, error)
GetTxFee(context.Context, ...rpc.Option) (*GetTxFeeResponse, error)
Uptime(context.Context, ids.ID, ...rpc.Option) (*UptimeResponse, error)
GetVMs(context.Context, ...rpc.Option) (map[ids.ID][]string, error)
}
// Client implementation for an Info API Client
type client struct {
requester rpc.EndpointRequester
}
// NewClient returns a new Info API Client
func NewClient(uri string) Client {
return &client{requester: rpc.NewEndpointRequester(
uri + "/ext/info",
)}
}
func (c *client) GetNodeVersion(ctx context.Context, options ...rpc.Option) (*GetNodeVersionReply, error) {
res := &GetNodeVersionReply{}
err := c.requester.SendRequest(ctx, "info.getNodeVersion", struct{}{}, res, options...)
return res, err
}
func (c *client) GetNodeID(ctx context.Context, options ...rpc.Option) (ids.NodeID, *signer.ProofOfPossession, error) {
res := &GetNodeIDReply{}
err := c.requester.SendRequest(ctx, "info.getNodeID", struct{}{}, res, options...)
return res.NodeID, res.NodePOP, err
}
func (c *client) GetNodeIP(ctx context.Context, options ...rpc.Option) (string, error) {
res := &GetNodeIPReply{}
err := c.requester.SendRequest(ctx, "info.getNodeIP", struct{}{}, res, options...)
return res.IP, err
}
func (c *client) GetNetworkID(ctx context.Context, options ...rpc.Option) (uint32, error) {
res := &GetNetworkIDReply{}
err := c.requester.SendRequest(ctx, "info.getNetworkID", struct{}{}, res, options...)
return uint32(res.NetworkID), err
}
func (c *client) GetNetworkName(ctx context.Context, options ...rpc.Option) (string, error) {
res := &GetNetworkNameReply{}
err := c.requester.SendRequest(ctx, "info.getNetworkName", struct{}{}, res, options...)
return res.NetworkName, err
}
func (c *client) GetBlockchainID(ctx context.Context, alias string, options ...rpc.Option) (ids.ID, error) {
res := &GetBlockchainIDReply{}
err := c.requester.SendRequest(ctx, "info.getBlockchainID", &GetBlockchainIDArgs{
Alias: alias,
}, res, options...)
return res.BlockchainID, err
}
func (c *client) Peers(ctx context.Context, options ...rpc.Option) ([]Peer, error) {
res := &PeersReply{}
err := c.requester.SendRequest(ctx, "info.peers", struct{}{}, res, options...)
return res.Peers, err
}
func (c *client) IsBootstrapped(ctx context.Context, chainID string, options ...rpc.Option) (bool, error) {
res := &IsBootstrappedResponse{}
err := c.requester.SendRequest(ctx, "info.isBootstrapped", &IsBootstrappedArgs{
Chain: chainID,
}, res, options...)
return res.IsBootstrapped, err
}
func (c *client) GetTxFee(ctx context.Context, options ...rpc.Option) (*GetTxFeeResponse, error) {
res := &GetTxFeeResponse{}
err := c.requester.SendRequest(ctx, "info.getTxFee", struct{}{}, res, options...)
return res, err
}
func (c *client) Uptime(ctx context.Context, subnetID ids.ID, options ...rpc.Option) (*UptimeResponse, error) {
res := &UptimeResponse{}
err := c.requester.SendRequest(ctx, "info.uptime", &UptimeRequest{
SubnetID: subnetID,
}, res, options...)
return res, err
}
func (c *client) GetVMs(ctx context.Context, options ...rpc.Option) (map[ids.ID][]string, error) {
res := &GetVMsReply{}
err := c.requester.SendRequest(ctx, "info.getVMs", struct{}{}, res, options...)
return res.VMs, err
}
// AwaitBootstrapped polls the node every [freq] to check if [chainID] has
// finished bootstrapping. Returns true once [chainID] reports that it has
// finished bootstrapping.
// Only returns an error if [ctx] returns an error.
func AwaitBootstrapped(ctx context.Context, c Client, chainID string, freq time.Duration, options ...rpc.Option) (bool, error) {
ticker := time.NewTicker(freq)
defer ticker.Stop()
for {
res, err := c.IsBootstrapped(ctx, chainID, options...)
if err == nil && res {
return true, nil
}
select {
case <-ticker.C:
case <-ctx.Done():
return false, ctx.Err()
}
}
}