github.com/MetalBlockchain/metalgo@v1.11.9/vms/example/xsvm/api/server.go (about) 1 // Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. 2 // See the file LICENSE for licensing terms. 3 4 package api 5 6 import ( 7 "net/http" 8 9 "github.com/MetalBlockchain/metalgo/database" 10 "github.com/MetalBlockchain/metalgo/ids" 11 "github.com/MetalBlockchain/metalgo/snow" 12 "github.com/MetalBlockchain/metalgo/vms/example/xsvm/block" 13 "github.com/MetalBlockchain/metalgo/vms/example/xsvm/builder" 14 "github.com/MetalBlockchain/metalgo/vms/example/xsvm/chain" 15 "github.com/MetalBlockchain/metalgo/vms/example/xsvm/genesis" 16 "github.com/MetalBlockchain/metalgo/vms/example/xsvm/state" 17 "github.com/MetalBlockchain/metalgo/vms/example/xsvm/tx" 18 "github.com/MetalBlockchain/metalgo/vms/platformvm/warp" 19 ) 20 21 // Server defines the xsvm API server. 22 type Server interface { 23 Network(r *http.Request, args *struct{}, reply *NetworkReply) error 24 Genesis(r *http.Request, args *struct{}, reply *GenesisReply) error 25 Nonce(r *http.Request, args *NonceArgs, reply *NonceReply) error 26 Balance(r *http.Request, args *BalanceArgs, reply *BalanceReply) error 27 Loan(r *http.Request, args *LoanArgs, reply *LoanReply) error 28 IssueTx(r *http.Request, args *IssueTxArgs, reply *IssueTxReply) error 29 LastAccepted(r *http.Request, args *struct{}, reply *LastAcceptedReply) error 30 Block(r *http.Request, args *BlockArgs, reply *BlockReply) error 31 Message(r *http.Request, args *MessageArgs, reply *MessageReply) error 32 } 33 34 func NewServer( 35 ctx *snow.Context, 36 genesis *genesis.Genesis, 37 state database.KeyValueReader, 38 chain chain.Chain, 39 builder builder.Builder, 40 ) Server { 41 return &server{ 42 ctx: ctx, 43 genesis: genesis, 44 state: state, 45 chain: chain, 46 builder: builder, 47 } 48 } 49 50 type server struct { 51 ctx *snow.Context 52 genesis *genesis.Genesis 53 state database.KeyValueReader 54 chain chain.Chain 55 builder builder.Builder 56 } 57 58 type NetworkReply struct { 59 NetworkID uint32 `json:"networkID"` 60 SubnetID ids.ID `json:"subnetID"` 61 ChainID ids.ID `json:"chainID"` 62 } 63 64 func (s *server) Network(_ *http.Request, _ *struct{}, reply *NetworkReply) error { 65 reply.NetworkID = s.ctx.NetworkID 66 reply.SubnetID = s.ctx.SubnetID 67 reply.ChainID = s.ctx.ChainID 68 return nil 69 } 70 71 type GenesisReply struct { 72 Genesis *genesis.Genesis `json:"genesis"` 73 } 74 75 func (s *server) Genesis(_ *http.Request, _ *struct{}, reply *GenesisReply) error { 76 reply.Genesis = s.genesis 77 return nil 78 } 79 80 type NonceArgs struct { 81 Address ids.ShortID `json:"address"` 82 } 83 84 type NonceReply struct { 85 Nonce uint64 `json:"nonce"` 86 } 87 88 func (s *server) Nonce(_ *http.Request, args *NonceArgs, reply *NonceReply) error { 89 nonce, err := state.GetNonce(s.state, args.Address) 90 reply.Nonce = nonce 91 return err 92 } 93 94 type BalanceArgs struct { 95 Address ids.ShortID `json:"address"` 96 AssetID ids.ID `json:"assetID"` 97 } 98 99 type BalanceReply struct { 100 Balance uint64 `json:"balance"` 101 } 102 103 func (s *server) Balance(_ *http.Request, args *BalanceArgs, reply *BalanceReply) error { 104 balance, err := state.GetBalance(s.state, args.Address, args.AssetID) 105 reply.Balance = balance 106 return err 107 } 108 109 type LoanArgs struct { 110 ChainID ids.ID `json:"chainID"` 111 } 112 113 type LoanReply struct { 114 Amount uint64 `json:"amount"` 115 } 116 117 func (s *server) Loan(_ *http.Request, args *LoanArgs, reply *LoanReply) error { 118 amount, err := state.GetLoan(s.state, args.ChainID) 119 reply.Amount = amount 120 return err 121 } 122 123 type IssueTxArgs struct { 124 Tx []byte `json:"tx"` 125 } 126 127 type IssueTxReply struct { 128 TxID ids.ID `json:"txID"` 129 } 130 131 func (s *server) IssueTx(r *http.Request, args *IssueTxArgs, reply *IssueTxReply) error { 132 newTx, err := tx.Parse(args.Tx) 133 if err != nil { 134 return err 135 } 136 137 ctx := r.Context() 138 s.ctx.Lock.Lock() 139 err = s.builder.AddTx(ctx, newTx) 140 s.ctx.Lock.Unlock() 141 if err != nil { 142 return err 143 } 144 145 txID, err := newTx.ID() 146 reply.TxID = txID 147 return err 148 } 149 150 type LastAcceptedReply struct { 151 BlockID ids.ID `json:"blockID"` 152 Block *block.Stateless `json:"block"` 153 } 154 155 func (s *server) LastAccepted(_ *http.Request, _ *struct{}, reply *LastAcceptedReply) error { 156 s.ctx.Lock.RLock() 157 reply.BlockID = s.chain.LastAccepted() 158 s.ctx.Lock.RUnlock() 159 blkBytes, err := state.GetBlock(s.state, reply.BlockID) 160 if err != nil { 161 return err 162 } 163 164 reply.Block, err = block.Parse(blkBytes) 165 return err 166 } 167 168 type BlockArgs struct { 169 BlockID ids.ID `json:"blockID"` 170 } 171 172 type BlockReply struct { 173 Block *block.Stateless `json:"block"` 174 } 175 176 func (s *server) Block(_ *http.Request, args *BlockArgs, reply *BlockReply) error { 177 blkBytes, err := state.GetBlock(s.state, args.BlockID) 178 if err != nil { 179 return err 180 } 181 182 reply.Block, err = block.Parse(blkBytes) 183 return err 184 } 185 186 type MessageArgs struct { 187 TxID ids.ID `json:"txID"` 188 } 189 190 type MessageReply struct { 191 Message *warp.UnsignedMessage `json:"message"` 192 Signature []byte `json:"signature"` 193 } 194 195 func (s *server) Message(_ *http.Request, args *MessageArgs, reply *MessageReply) error { 196 message, err := state.GetMessage(s.state, args.TxID) 197 if err != nil { 198 return err 199 } 200 201 reply.Message = message 202 reply.Signature, err = s.ctx.WarpSigner.Sign(message) 203 return err 204 }