forked from ava-labs/avalanchego
-
Notifications
You must be signed in to change notification settings - Fork 4
/
server.go
204 lines (169 loc) · 4.9 KB
/
server.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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.
package api
import (
"net/http"
"github.com/MetalBlockchain/metalgo/database"
"github.com/MetalBlockchain/metalgo/ids"
"github.com/MetalBlockchain/metalgo/snow"
"github.com/MetalBlockchain/metalgo/vms/example/xsvm/block"
"github.com/MetalBlockchain/metalgo/vms/example/xsvm/builder"
"github.com/MetalBlockchain/metalgo/vms/example/xsvm/chain"
"github.com/MetalBlockchain/metalgo/vms/example/xsvm/genesis"
"github.com/MetalBlockchain/metalgo/vms/example/xsvm/state"
"github.com/MetalBlockchain/metalgo/vms/example/xsvm/tx"
"github.com/MetalBlockchain/metalgo/vms/platformvm/warp"
)
// Server defines the xsvm API server.
type Server interface {
Network(r *http.Request, args *struct{}, reply *NetworkReply) error
Genesis(r *http.Request, args *struct{}, reply *GenesisReply) error
Nonce(r *http.Request, args *NonceArgs, reply *NonceReply) error
Balance(r *http.Request, args *BalanceArgs, reply *BalanceReply) error
Loan(r *http.Request, args *LoanArgs, reply *LoanReply) error
IssueTx(r *http.Request, args *IssueTxArgs, reply *IssueTxReply) error
LastAccepted(r *http.Request, args *struct{}, reply *LastAcceptedReply) error
Block(r *http.Request, args *BlockArgs, reply *BlockReply) error
Message(r *http.Request, args *MessageArgs, reply *MessageReply) error
}
func NewServer(
ctx *snow.Context,
genesis *genesis.Genesis,
state database.KeyValueReader,
chain chain.Chain,
builder builder.Builder,
) Server {
return &server{
ctx: ctx,
genesis: genesis,
state: state,
chain: chain,
builder: builder,
}
}
type server struct {
ctx *snow.Context
genesis *genesis.Genesis
state database.KeyValueReader
chain chain.Chain
builder builder.Builder
}
type NetworkReply struct {
NetworkID uint32 `json:"networkID"`
SubnetID ids.ID `json:"subnetID"`
ChainID ids.ID `json:"chainID"`
}
func (s *server) Network(_ *http.Request, _ *struct{}, reply *NetworkReply) error {
reply.NetworkID = s.ctx.NetworkID
reply.SubnetID = s.ctx.SubnetID
reply.ChainID = s.ctx.ChainID
return nil
}
type GenesisReply struct {
Genesis *genesis.Genesis `json:"genesis"`
}
func (s *server) Genesis(_ *http.Request, _ *struct{}, reply *GenesisReply) error {
reply.Genesis = s.genesis
return nil
}
type NonceArgs struct {
Address ids.ShortID `json:"address"`
}
type NonceReply struct {
Nonce uint64 `json:"nonce"`
}
func (s *server) Nonce(_ *http.Request, args *NonceArgs, reply *NonceReply) error {
nonce, err := state.GetNonce(s.state, args.Address)
reply.Nonce = nonce
return err
}
type BalanceArgs struct {
Address ids.ShortID `json:"address"`
AssetID ids.ID `json:"assetID"`
}
type BalanceReply struct {
Balance uint64 `json:"balance"`
}
func (s *server) Balance(_ *http.Request, args *BalanceArgs, reply *BalanceReply) error {
balance, err := state.GetBalance(s.state, args.Address, args.AssetID)
reply.Balance = balance
return err
}
type LoanArgs struct {
ChainID ids.ID `json:"chainID"`
}
type LoanReply struct {
Amount uint64 `json:"amount"`
}
func (s *server) Loan(_ *http.Request, args *LoanArgs, reply *LoanReply) error {
amount, err := state.GetLoan(s.state, args.ChainID)
reply.Amount = amount
return err
}
type IssueTxArgs struct {
Tx []byte `json:"tx"`
}
type IssueTxReply struct {
TxID ids.ID `json:"txID"`
}
func (s *server) IssueTx(r *http.Request, args *IssueTxArgs, reply *IssueTxReply) error {
newTx, err := tx.Parse(args.Tx)
if err != nil {
return err
}
ctx := r.Context()
s.ctx.Lock.Lock()
err = s.builder.AddTx(ctx, newTx)
s.ctx.Lock.Unlock()
if err != nil {
return err
}
txID, err := newTx.ID()
reply.TxID = txID
return err
}
type LastAcceptedReply struct {
BlockID ids.ID `json:"blockID"`
Block *block.Stateless `json:"block"`
}
func (s *server) LastAccepted(_ *http.Request, _ *struct{}, reply *LastAcceptedReply) error {
s.ctx.Lock.RLock()
reply.BlockID = s.chain.LastAccepted()
s.ctx.Lock.RUnlock()
blkBytes, err := state.GetBlock(s.state, reply.BlockID)
if err != nil {
return err
}
reply.Block, err = block.Parse(blkBytes)
return err
}
type BlockArgs struct {
BlockID ids.ID `json:"blockID"`
}
type BlockReply struct {
Block *block.Stateless `json:"block"`
}
func (s *server) Block(_ *http.Request, args *BlockArgs, reply *BlockReply) error {
blkBytes, err := state.GetBlock(s.state, args.BlockID)
if err != nil {
return err
}
reply.Block, err = block.Parse(blkBytes)
return err
}
type MessageArgs struct {
TxID ids.ID `json:"txID"`
}
type MessageReply struct {
Message *warp.UnsignedMessage `json:"message"`
Signature []byte `json:"signature"`
}
func (s *server) Message(_ *http.Request, args *MessageArgs, reply *MessageReply) error {
message, err := state.GetMessage(s.state, args.TxID)
if err != nil {
return err
}
reply.Message = message
reply.Signature, err = s.ctx.WarpSigner.Sign(message)
return err
}