OSDN Git Service

submit-work-json works
[bytom/bytom.git] / api / miner.go
1 package api
2
3 import (
4         "context"
5
6         "github.com/bytom/errors"
7         "github.com/bytom/protocol/bc"
8         "github.com/bytom/protocol/bc/types"
9 )
10
11 type BlockHeaderJSON struct {
12         Version           uint64                                        `json:"version"`  // The version of the block.
13         Height            uint64                                        `json:"height"`  // The height of the block.
14         PreviousBlockHash bc.Hash                                       `json:"previous_block_hash"` // The hash of the previous block.
15         Timestamp         uint64                                        `json:"timestamp"` // The time of the block in seconds.
16         Nonce             uint64                                        `json:"nonce"` // Nonce used to generate the block.
17         Bits              uint64                                        `json:"bits"` // Difficulty target for the block.
18         BlockCommitment   *types.BlockCommitment        `json:"block_commitment"` //Block commitment
19 }
20
21 func (a *API) getWork() Response {
22         work, err := a.GetWork()
23         if err != nil {
24                 return NewErrorResponse(err)
25         }
26         return NewSuccessResponse(work)
27 }
28
29 func (a *API) getWorkJSON() Response {
30         work, err := a.GetWorkJSON()
31         if err != nil {
32                 return NewErrorResponse(err)
33         }
34         return NewSuccessResponse(work)
35 }
36
37 // SubmitWorkReq used to submitWork req
38 type SubmitWorkReq struct {
39         BlockHeader *types.BlockHeader `json:"block_header"`
40 }
41
42 func (a *API) submitWork(ctx context.Context, req *SubmitWorkReq) Response {
43         if err := a.SubmitWork(req.BlockHeader); err != nil {
44                 return NewErrorResponse(err)
45         }
46         return NewSuccessResponse(true)
47 }
48
49 // SubmitWorkJSONReq used to submitWork req
50 type SubmitWorkJSONReq struct {
51         BlockHeader *BlockHeaderJSON    `json:"block_header"`
52 }
53
54 func (a *API) submitWorkJSON(ctx context.Context, req *SubmitWorkJSONReq) Response {
55         blockCommitment := types.BlockCommitment{
56                                                         TransactionsMerkleRoot: req.BlockHeader.BlockCommitment.TransactionsMerkleRoot,
57                                                         TransactionStatusHash:  req.BlockHeader.BlockCommitment.TransactionStatusHash,
58                                                 }
59
60         bh := &types.BlockHeader{
61                         Version:                        req.BlockHeader.Version,
62                         Height:                         req.BlockHeader.Height,
63                         PreviousBlockHash:      req.BlockHeader.PreviousBlockHash,
64                         Timestamp:              req.BlockHeader.Timestamp,
65                         Nonce:                  req.BlockHeader.Nonce,
66                         Bits:                   req.BlockHeader.Bits,
67                         BlockCommitment:        blockCommitment,
68                 }
69
70         if err := a.SubmitWork(bh); err != nil {
71                 return NewErrorResponse(err)
72         }
73         return NewSuccessResponse(true)
74 }
75
76 // GetWorkResp is resp struct for API
77 type GetWorkResp struct {
78         BlockHeader *types.BlockHeader `json:"block_header"`
79         Seed        *bc.Hash           `json:"seed"`
80 }
81
82 // GetWork get work
83 func (a *API) GetWork() (*GetWorkResp, error) {
84         bh, err := a.miningPool.GetWork()
85         if err != nil {
86                 return nil, err
87         }
88
89         seed, err := a.chain.CalcNextSeed(&bh.PreviousBlockHash)
90         if err != nil {
91                 return nil, err
92         }
93
94         return &GetWorkResp{
95                 BlockHeader: bh,
96                 Seed:        seed,
97         }, nil
98 }
99
100 // GetWorkJSONResp is resp struct for API get-work-json
101 type GetWorkJSONResp struct {
102         BlockHeader *BlockHeaderJSON    `json:"block_header"`
103         Seed        *bc.Hash            `json:"seed"`
104 }
105
106 // GetWorkJSON get work in json
107 func (a *API) GetWorkJSON() (*GetWorkJSONResp, error) {
108         bh, err := a.miningPool.GetWork()
109         if err != nil {
110                 return nil, err
111         }
112
113         seed, err := a.chain.CalcNextSeed(&bh.PreviousBlockHash)
114         if err != nil {
115                 return nil, err
116         }
117
118         blockCommitment := &types.BlockCommitment{
119                                                         TransactionsMerkleRoot: bh.BlockCommitment.TransactionsMerkleRoot,
120                                                         TransactionStatusHash:  bh.BlockCommitment.TransactionStatusHash,
121                                                 }
122
123         return &GetWorkJSONResp{
124                 BlockHeader: &BlockHeaderJSON{
125                         Version:                        bh.Version,
126                         Height:                         bh.Height,
127                         PreviousBlockHash:      bh.PreviousBlockHash,
128                         Timestamp:              bh.Timestamp,
129                         Nonce:                  bh.Nonce,
130                         Bits:                   bh.Bits,
131                         BlockCommitment:        blockCommitment,
132                 },
133                 Seed:        seed,
134         }, nil
135 }
136
137 // SubmitWork submit work to the miningpool
138 func (a *API) SubmitWork(bh *types.BlockHeader) error {
139         return a.miningPool.SubmitWork(bh)
140 }
141
142 func (a *API) setMining(in struct {
143         IsMining bool `json:"is_mining"`
144 }) Response {
145         if in.IsMining {
146                 return a.startMining()
147         }
148         return a.stopMining()
149 }
150
151 func (a *API) startMining() Response {
152         a.cpuMiner.Start()
153         if !a.IsMining() {
154                 return NewErrorResponse(errors.New("Failed to start mining"))
155         }
156         return NewSuccessResponse("")
157 }
158
159 func (a *API) stopMining() Response {
160         a.cpuMiner.Stop()
161         if a.IsMining() {
162                 return NewErrorResponse(errors.New("Failed to stop mining"))
163         }
164         return NewSuccessResponse("")
165 }