• R/O
  • HTTP
  • SSH
  • HTTPS

vapor: Commit

Golang implemented sidechain for Bytom


Commit MetaInfo

Revision3aec4988213a49fba026a673801659094b7c1280 (tree)
Time2019-07-23 12:25:46
Authormars <mars@byto...>
Commitermars

Log Message

fix review

Change Summary

Incremental Difference

--- /dev/null
+++ b/toolbar/api_node/block.go
@@ -0,0 +1,33 @@
1+package apinode
2+
3+import (
4+ "encoding/json"
5+
6+ "github.com/vapor/api"
7+ "github.com/vapor/errors"
8+ "github.com/vapor/protocol/bc/types"
9+)
10+
11+func (n *Node) GetBlockByHash(hash string) (*types.Block, error) {
12+ return n.getRawBlock(&getRawBlockReq{BlockHash: hash})
13+}
14+
15+func (n *Node) GetBlockByHeight(height uint64) (*types.Block, error) {
16+ return n.getRawBlock(&getRawBlockReq{BlockHeight: height})
17+}
18+
19+type getRawBlockReq struct {
20+ BlockHeight uint64 `json:"block_height"`
21+ BlockHash string `json:"block_hash"`
22+}
23+
24+func (n *Node) getRawBlock(req *getRawBlockReq) (*types.Block, error) {
25+ url := "/get-raw-block"
26+ payload, err := json.Marshal(req)
27+ if err != nil {
28+ return nil, errors.Wrap(err, "json marshal")
29+ }
30+
31+ resp := &api.GetRawBlockResp{}
32+ return resp.RawBlock, n.request(url, payload, resp)
33+}
--- /dev/null
+++ b/toolbar/api_node/node.go
@@ -0,0 +1,37 @@
1+package apinode
2+
3+import (
4+ "encoding/json"
5+
6+ "github.com/vapor/errors"
7+ "github.com/vapor/toolbar/common"
8+)
9+
10+// Node can invoke the api which provide by the full node server
11+type Node struct {
12+ hostPort string
13+}
14+
15+// NewNode create a api client with target server
16+func NewNode(hostPort string) *Node {
17+ return &Node{hostPort: hostPort}
18+}
19+
20+type response struct {
21+ Status string `json:"status"`
22+ Data json.RawMessage `json:"data"`
23+ ErrDetail string `json:"error_detail"`
24+}
25+
26+func (n *Node) request(path string, payload []byte, respData interface{}) error {
27+ resp := &response{}
28+ if err := common.Post(n.hostPort+path, payload, resp); err != nil {
29+ return err
30+ }
31+
32+ if resp.Status != "success" {
33+ return errors.New(resp.ErrDetail)
34+ }
35+
36+ return json.Unmarshal(resp.Data, respData)
37+}
--- /dev/null
+++ b/toolbar/api_node/node_test.go
@@ -0,0 +1,70 @@
1+package apinode
2+
3+import (
4+ "encoding/json"
5+ "testing"
6+
7+ "github.com/vapor/consensus"
8+ "github.com/vapor/errors"
9+ "github.com/vapor/protocol/bc"
10+)
11+
12+func buildTxRequest(accountID string, outputs map[string]uint64) ([]byte, error) {
13+ totalBTM := uint64(10000000)
14+ actions := []interface{}{}
15+ for address, amount := range outputs {
16+ actions = append(actions, &ControlAddressAction{
17+ Address: address,
18+ AssetAmount: &bc.AssetAmount{AssetId: consensus.BTMAssetID, Amount: amount},
19+ })
20+ totalBTM += amount
21+ }
22+
23+ actions = append(actions, &SpendAccountAction{
24+ AccountID: accountID,
25+ AssetAmount: &bc.AssetAmount{AssetId: consensus.BTMAssetID, Amount: totalBTM},
26+ })
27+ payload, err := json.Marshal(&buildTxReq{Actions: actions})
28+ if err != nil {
29+ return nil, errors.Wrap(err, "Marshal spend request")
30+ }
31+
32+ return payload, nil
33+}
34+
35+type args struct {
36+ accountID string
37+ outputs map[string]uint64
38+}
39+
40+func TestBuildTxRequest(t *testing.T) {
41+ cases := []struct {
42+ args args
43+ want string
44+ }{
45+ {
46+ args: args{
47+ accountID: "9bb77612-350e-4d53-81e2-525b28247ba5",
48+ outputs: map[string]uint64{"sp1qlryy65a5apylphqp6axvhx7nd6y2zlexuvn7gf": 100},
49+ },
50+ want: `{"actions":[{"type":"control_address","address":"sp1qlryy65a5apylphqp6axvhx7nd6y2zlexuvn7gf","asset_id":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","amount":100},{"type":"spend_account","account_id":"9bb77612-350e-4d53-81e2-525b28247ba5","asset_id":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","amount":10000100}]}`,
51+ },
52+ {
53+ args: args{
54+ accountID: "9bb77612-350e-4d53-81e2-525b28247ba5",
55+ outputs: map[string]uint64{"sp1qlryy65a5apylphqp6axvhx7nd6y2zlexuvn7gf": 100, "sp1qcgtxkhfzytul4lfttwex3skfqhm0tg6ms9da28": 200},
56+ },
57+ want: `{"actions":[{"type":"control_address","address":"sp1qlryy65a5apylphqp6axvhx7nd6y2zlexuvn7gf","asset_id":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","amount":100},{"type":"control_address","address":"sp1qcgtxkhfzytul4lfttwex3skfqhm0tg6ms9da28","asset_id":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","amount":200},{"type":"spend_account","account_id":"9bb77612-350e-4d53-81e2-525b28247ba5","asset_id":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","amount":10000300}]}`,
58+ },
59+ }
60+
61+ for i, c := range cases {
62+ tx, err := buildTxRequest(c.args.accountID, c.args.outputs)
63+ if err != nil {
64+ t.Fatal(err)
65+ }
66+ if string(tx) != string(c.want) {
67+ t.Fatal(i, string(tx))
68+ }
69+ }
70+}
--- /dev/null
+++ b/toolbar/api_node/transaction.go
@@ -0,0 +1,138 @@
1+package apinode
2+
3+import (
4+ "encoding/json"
5+
6+ "github.com/vapor/blockchain/txbuilder"
7+ "github.com/vapor/consensus"
8+ "github.com/vapor/errors"
9+ "github.com/vapor/protocol/bc"
10+ "github.com/vapor/protocol/bc/types"
11+)
12+
13+type SpendAccountAction struct {
14+ AccountID string `json:"account_id"`
15+ *bc.AssetAmount
16+}
17+
18+func (s *SpendAccountAction) MarshalJSON() ([]byte, error) {
19+ return json.Marshal(&struct {
20+ Type string `json:"type"`
21+ AccountID string `json:"account_id"`
22+ *bc.AssetAmount
23+ }{
24+ Type: "spend_account",
25+ AccountID: s.AccountID,
26+ AssetAmount: s.AssetAmount,
27+ })
28+}
29+
30+type ControlAddressAction struct {
31+ Address string `json:"address"`
32+ *bc.AssetAmount
33+}
34+
35+func (c *ControlAddressAction) MarshalJSON() ([]byte, error) {
36+ return json.Marshal(&struct {
37+ Type string `json:"type"`
38+ Address string `json:"address"`
39+ *bc.AssetAmount
40+ }{
41+ Type: "control_address",
42+ Address: c.Address,
43+ AssetAmount: c.AssetAmount,
44+ })
45+}
46+
47+func (n *Node) BatchSendBTM(accountID, password string, outputs map[string]uint64) error {
48+ totalBTM := uint64(10000000)
49+ actions := []interface{}{}
50+ for address, amount := range outputs {
51+ actions = append(actions, &ControlAddressAction{
52+ Address: address,
53+ AssetAmount: &bc.AssetAmount{AssetId: consensus.BTMAssetID, Amount: amount},
54+ })
55+ totalBTM += amount
56+ }
57+
58+ actions = append(actions, &SpendAccountAction{
59+ AccountID: accountID,
60+ AssetAmount: &bc.AssetAmount{AssetId: consensus.BTMAssetID, Amount: totalBTM},
61+ })
62+
63+ tpl, err := n.buildTx(actions)
64+ if err != nil {
65+ return err
66+ }
67+
68+ tpl, err = n.signTx(tpl, password)
69+ if err != nil {
70+ return err
71+ }
72+
73+ _, err = n.SubmitTx(tpl.Transaction)
74+ return err
75+}
76+
77+type buildTxReq struct {
78+ Actions []interface{} `json:"actions"`
79+}
80+
81+func (n *Node) buildTx(actions []interface{}) (*txbuilder.Template, error) {
82+ url := "/build-transaction"
83+ payload, err := json.Marshal(&buildTxReq{Actions: actions})
84+ if err != nil {
85+ return nil, errors.Wrap(err, "Marshal spend request")
86+ }
87+
88+ result := &txbuilder.Template{}
89+ return result, n.request(url, payload, result)
90+}
91+
92+type signTxReq struct {
93+ Tx *txbuilder.Template `json:"transaction"`
94+ Password string `json:"password"`
95+}
96+
97+type signTxResp struct {
98+ Tx *txbuilder.Template `json:"transaction"`
99+ SignComplete bool `json:"sign_complete"`
100+}
101+
102+func (n *Node) signTx(tpl *txbuilder.Template, password string) (*txbuilder.Template, error) {
103+ url := "/sign-transaction"
104+ payload, err := json.Marshal(&signTxReq{Tx: tpl, Password: password})
105+ if err != nil {
106+ return nil, errors.Wrap(err, "json marshal")
107+ }
108+
109+ resp := &signTxResp{}
110+ if err := n.request(url, payload, resp); err != nil {
111+ return nil, err
112+ }
113+
114+ if !resp.SignComplete {
115+ return nil, errors.New("sign fail")
116+ }
117+
118+ return resp.Tx, nil
119+}
120+
121+type submitTxReq struct {
122+ Tx *types.Tx `json:"raw_transaction"`
123+}
124+
125+type submitTxResp struct {
126+ TxID string `json:"tx_id"`
127+}
128+
129+func (n *Node) SubmitTx(tx *types.Tx) (string, error) {
130+ url := "/submit-transaction"
131+ payload, err := json.Marshal(submitTxReq{Tx: tx})
132+ if err != nil {
133+ return "", errors.Wrap(err, "json marshal")
134+ }
135+
136+ res := &submitTxResp{}
137+ return res.TxID, n.request(url, payload, res)
138+}
--- a/toolbar/vote_reward/synchron/block_keeper.go
+++ b/toolbar/vote_reward/synchron/block_keeper.go
@@ -8,7 +8,7 @@ import (
88
99 "github.com/vapor/errors"
1010 "github.com/vapor/protocol/bc/types"
11- "github.com/vapor/toolbar/apinode"
11+ apinode "github.com/vapor/toolbar/api_node"
1212 "github.com/vapor/toolbar/common"
1313 "github.com/vapor/toolbar/vote_reward/config"
1414 "github.com/vapor/toolbar/vote_reward/database/orm"
Show on old repository browser