OSDN Git Service

Merge pull request #201 from Bytom/v0.1
[bytom/vapor.git] / federation / service / node.go
1 package service
2
3 import (
4         "encoding/json"
5
6         "github.com/vapor/errors"
7         "github.com/vapor/federation/util"
8         "github.com/vapor/protocol/bc"
9         "github.com/vapor/protocol/bc/types"
10 )
11
12 // Node can invoke the api which provide by the full node server
13 type Node struct {
14         ip string
15 }
16
17 // Node create a api client with target server
18 func NewNode(ip string) *Node {
19         return &Node{ip: ip}
20 }
21
22 func (n *Node) GetBlockByHash(hash string) (string, *bc.TransactionStatus, error) {
23         return n.getRawBlock(&getRawBlockReq{BlockHash: hash})
24 }
25
26 func (n *Node) GetBlockByHeight(height uint64) (string, *bc.TransactionStatus, error) {
27         return n.getRawBlock(&getRawBlockReq{BlockHeight: height})
28 }
29
30 type getBlockCountResp struct {
31         BlockCount uint64 `json:"block_count"`
32 }
33
34 func (n *Node) GetBlockCount() (uint64, error) {
35         url := "/get-block-count"
36         res := &getBlockCountResp{}
37         return res.BlockCount, n.request(url, nil, res)
38 }
39
40 type getRawBlockReq struct {
41         BlockHeight uint64 `json:"block_height"`
42         BlockHash   string `json:"block_hash"`
43 }
44
45 type getRawBlockResp struct {
46         RawBlock string `json:"raw_block"`
47         // TransactionStatus has same marshalling rule for both bytom and vapor
48         TransactionStatus *bc.TransactionStatus `json:"transaction_status"`
49 }
50
51 func (n *Node) getRawBlock(req *getRawBlockReq) (string, *bc.TransactionStatus, error) {
52         url := "/get-raw-block"
53         payload, err := json.Marshal(req)
54         if err != nil {
55                 return "", nil, errors.Wrap(err, "json marshal")
56         }
57
58         res := &getRawBlockResp{}
59         return res.RawBlock, res.TransactionStatus, n.request(url, payload, res)
60 }
61
62 type submitTxReq struct {
63         Tx *types.Tx `json:"raw_transaction"`
64 }
65
66 type response struct {
67         Status    string          `json:"status"`
68         Data      json.RawMessage `json:"data"`
69         ErrDetail string          `json:"error_detail"`
70 }
71
72 func (n *Node) request(url string, payload []byte, respData interface{}) error {
73         resp := &response{}
74         if err := util.Post(n.ip+url, payload, resp); err != nil {
75                 return err
76         }
77
78         if resp.Status != "success" {
79                 return errors.New(resp.ErrDetail)
80         }
81
82         return json.Unmarshal(resp.Data, respData)
83 }