-
Notifications
You must be signed in to change notification settings - Fork 107
/
query.go
124 lines (104 loc) · 3.8 KB
/
query.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
package registry
import (
"context"
"fmt"
"github.com/oasisprotocol/oasis-core/go/common"
"github.com/oasisprotocol/oasis-core/go/common/crypto/signature"
"github.com/oasisprotocol/oasis-core/go/common/entity"
"github.com/oasisprotocol/oasis-core/go/common/node"
abciAPI "github.com/oasisprotocol/oasis-core/go/consensus/tendermint/api"
registryState "github.com/oasisprotocol/oasis-core/go/consensus/tendermint/apps/registry/state"
registry "github.com/oasisprotocol/oasis-core/go/registry/api"
)
// Query is the registry query interface.
type Query interface {
Entity(context.Context, signature.PublicKey) (*entity.Entity, error)
Entities(context.Context) ([]*entity.Entity, error)
Node(context.Context, signature.PublicKey) (*node.Node, error)
NodeByConsensusAddress(context.Context, []byte) (*node.Node, error)
NodeStatus(context.Context, signature.PublicKey) (*registry.NodeStatus, error)
Nodes(context.Context) ([]*node.Node, error)
Runtime(context.Context, common.Namespace) (*registry.Runtime, error)
Runtimes(ctx context.Context, includeSuspended bool) ([]*registry.Runtime, error)
Genesis(context.Context) (*registry.Genesis, error)
}
// QueryFactory is the registry query factory.
type QueryFactory struct {
state abciAPI.ApplicationQueryState
}
// QueryAt returns the registry query interface for a specific height.
func (sf *QueryFactory) QueryAt(ctx context.Context, height int64) (Query, error) {
state, err := registryState.NewImmutableState(ctx, sf.state, height)
if err != nil {
return nil, err
}
return ®istryQuerier{sf.state, state, height}, nil
}
type registryQuerier struct {
queryState abciAPI.ApplicationQueryState
state *registryState.ImmutableState
height int64
}
func (rq *registryQuerier) Entity(ctx context.Context, id signature.PublicKey) (*entity.Entity, error) {
return rq.state.Entity(ctx, id)
}
func (rq *registryQuerier) Entities(ctx context.Context) ([]*entity.Entity, error) {
return rq.state.Entities(ctx)
}
func (rq *registryQuerier) Node(ctx context.Context, id signature.PublicKey) (*node.Node, error) {
epoch, err := rq.queryState.GetEpoch(ctx, rq.height)
if err != nil {
return nil, fmt.Errorf("failed to get epoch: %w", err)
}
node, err := rq.state.Node(ctx, id)
if err != nil {
return nil, err
}
// Do not return expired nodes.
if node.IsExpired(uint64(epoch)) {
return nil, registry.ErrNoSuchNode
}
return node, nil
}
func (rq *registryQuerier) NodeByConsensusAddress(ctx context.Context, address []byte) (*node.Node, error) {
return rq.state.NodeByConsensusAddress(ctx, address)
}
func (rq *registryQuerier) NodeStatus(ctx context.Context, id signature.PublicKey) (*registry.NodeStatus, error) {
return rq.state.NodeStatus(ctx, id)
}
func (rq *registryQuerier) Nodes(ctx context.Context) ([]*node.Node, error) {
epoch, err := rq.queryState.GetEpoch(ctx, rq.height)
if err != nil {
return nil, fmt.Errorf("failed to get epoch: %w", err)
}
nodes, err := rq.state.Nodes(ctx)
if err != nil {
return nil, err
}
// Filter out expired nodes.
var filteredNodes []*node.Node
for _, n := range nodes {
if n.IsExpired(uint64(epoch)) {
continue
}
filteredNodes = append(filteredNodes, n)
}
return filteredNodes, nil
}
func (rq *registryQuerier) Runtime(ctx context.Context, id common.Namespace) (*registry.Runtime, error) {
return rq.state.Runtime(ctx, id)
}
func (rq *registryQuerier) Runtimes(ctx context.Context, includeSuspended bool) ([]*registry.Runtime, error) {
if includeSuspended {
return rq.state.AllRuntimes(ctx)
}
return rq.state.Runtimes(ctx)
}
func (app *registryApplication) QueryFactory() interface{} {
return &QueryFactory{app.state}
}
// NewQueryFactory returns a new QueryFactory backed by the given state
// instance.
func NewQueryFactory(state abciAPI.ApplicationQueryState) *QueryFactory {
return &QueryFactory{state}
}