This repository has been archived by the owner on Mar 8, 2023. It is now read-only.
forked from ava-labs/avalanchego
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathclient.go
128 lines (115 loc) · 4.18 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
// Copyright (C) 2019-2021, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.
package indexer
import (
"fmt"
"time"
"github.com/ava-labs/avalanchego/utils/formatting"
"github.com/ava-labs/avalanchego/utils/rpc"
)
// Interface compliance
var _ Client = &client{}
// Client interface for Avalanche Indexer API Endpoint
type Client interface {
// GetContainerRange returns the transactions at index [startIndex], [startIndex+1], ... , [startIndex+n-1]
// If [n] == 0, returns an empty response (i.e. null).
// If [startIndex] > the last accepted index, returns an error (unless the above apply.)
// If we run out of transactions, returns the ones fetched before running out.
GetContainerRange(*GetContainerRangeArgs) ([]Container, error)
// Get a container by its index
GetContainerByIndex(*GetContainer) (Container, error)
// Get the most recently accepted container
GetLastAccepted(*GetLastAcceptedArgs) (Container, error)
// Returns 1 less than the number of containers accepted on this chain
GetIndex(*GetIndexArgs) (uint64, error)
// Returns true if the given container is accepted
IsAccepted(*GetIndexArgs) (bool, error)
// Get a container by its index
GetContainerByID(*GetIndexArgs) (Container, error)
}
// Client implementation for Avalanche Indexer API Endpoint
type client struct {
requester rpc.EndpointRequester
}
// NewClient creates a client that can interact with an index via HTTP API calls.
// [host] is the host to make API calls to (e.g. http://1.2.3.4:9650).
// [endpoint] is the path to the index endpoint (e.g. /ext/index/C/block or /ext/index/X/tx).
func NewClient(host, endpoint string, requestTimeout time.Duration) Client {
return &client{
requester: rpc.NewEndpointRequester(host, endpoint, "index", requestTimeout),
}
}
func (c *client) GetContainerRange(args *GetContainerRangeArgs) ([]Container, error) {
var fcs GetContainerRangeResponse
if err := c.requester.SendRequest("getContainerRange", args, &fcs); err != nil {
return nil, err
}
response := make([]Container, len(fcs.Containers))
for i, resp := range fcs.Containers {
containerBytes, err := formatting.Decode(resp.Encoding, resp.Bytes)
if err != nil {
return nil, fmt.Errorf("couldn't decode container %s: %w", resp.ID, err)
}
response[i] = Container{
ID: resp.ID,
Timestamp: resp.Timestamp.Unix(),
Bytes: containerBytes,
}
}
return response, nil
}
func (c *client) GetContainerByIndex(args *GetContainer) (Container, error) {
var fc FormattedContainer
if err := c.requester.SendRequest("getContainerByIndex", args, &fc); err != nil {
return Container{}, err
}
containerBytes, err := formatting.Decode(fc.Encoding, fc.Bytes)
if err != nil {
return Container{}, fmt.Errorf("couldn't decode container %s: %w", fc.ID, err)
}
return Container{
ID: fc.ID,
Timestamp: fc.Timestamp.Unix(),
Bytes: containerBytes,
}, nil
}
func (c *client) GetLastAccepted(args *GetLastAcceptedArgs) (Container, error) {
var fc FormattedContainer
if err := c.requester.SendRequest("getLastAccepted", args, &fc); err != nil {
return Container{}, nil
}
containerBytes, err := formatting.Decode(fc.Encoding, fc.Bytes)
if err != nil {
return Container{}, fmt.Errorf("couldn't decode container %s: %w", fc.ID, err)
}
return Container{
ID: fc.ID,
Timestamp: fc.Timestamp.Unix(),
Bytes: containerBytes,
}, nil
}
func (c *client) GetIndex(args *GetIndexArgs) (uint64, error) {
var index GetIndexResponse
err := c.requester.SendRequest("getIndex", args, &index)
return uint64(index.Index), err
}
func (c *client) IsAccepted(args *GetIndexArgs) (bool, error) {
var isAccepted bool
err := c.requester.SendRequest("isAccepted", args, &isAccepted)
return isAccepted, err
}
func (c *client) GetContainerByID(args *GetIndexArgs) (Container, error) {
var fc FormattedContainer
if err := c.requester.SendRequest("getContainerByID", args, &fc); err != nil {
return Container{}, err
}
containerBytes, err := formatting.Decode(fc.Encoding, fc.Bytes)
if err != nil {
return Container{}, fmt.Errorf("couldn't decode container %s: %w", fc.ID, err)
}
return Container{
ID: fc.ID,
Timestamp: fc.Timestamp.Unix(),
Bytes: containerBytes,
}, nil
}