OSDN Git Service

Merge pull request #38 from Bytom/dev_module_cliam
[bytom/vapor.git] / api / miner.go
1 package api
2
3 import (
4         "context"
5         "strconv"
6
7         chainjson "github.com/vapor/encoding/json"
8         "github.com/vapor/errors"
9         "github.com/vapor/protocol/bc"
10         "github.com/vapor/protocol/bc/types"
11 )
12
13 // BlockHeaderJSON struct provides support for get work in json format, when it also follows
14 // BlockHeader structure
15 type BlockHeaderJSON struct {
16         Version           uint64                 `json:"version"`             // The version of the block.
17         Height            uint64                 `json:"height"`              // The height of the block.
18         PreviousBlockHash bc.Hash                `json:"previous_block_hash"` // The hash of the previous block.
19         Timestamp         uint64                 `json:"timestamp"`           // The time of the block in seconds.
20         Nonce             uint64                 `json:"nonce"`               // Nonce used to generate the block.
21         Bits              uint64                 `json:"bits"`                // Difficulty target for the block.
22         BlockCommitment   *types.BlockCommitment `json:"block_commitment"`    // Block commitment
23 }
24
25 type CoinbaseArbitrary struct {
26         Arbitrary chainjson.HexBytes `json:"arbitrary"`
27 }
28
29 func (a *API) getCoinbaseArbitrary() Response {
30         arbitrary := a.wallet.AccountMgr.GetCoinbaseArbitrary()
31         resp := &CoinbaseArbitrary{
32                 Arbitrary: arbitrary,
33         }
34         return NewSuccessResponse(resp)
35 }
36
37 // setCoinbaseArbitrary add arbitary data to the reserved coinbase data.
38 // check function createCoinbaseTx in mining/mining.go for detail.
39 // arbitraryLenLimit is 107 and can be calculated by:
40 //      maxHeight := ^uint64(0)
41 //      reserved := append([]byte{0x00}, []byte(strconv.FormatUint(maxHeight, 10))...)
42 //      arbitraryLenLimit := consensus.CoinbaseArbitrarySizeLimit - len(reserved)
43 func (a *API) setCoinbaseArbitrary(ctx context.Context, req CoinbaseArbitrary) Response {
44         arbitraryLenLimit := 107
45         if len(req.Arbitrary) > arbitraryLenLimit {
46                 err := errors.New("Arbitrary exceeds limit: " + strconv.FormatUint(uint64(arbitraryLenLimit), 10))
47                 return NewErrorResponse(err)
48         }
49         a.wallet.AccountMgr.SetCoinbaseArbitrary(req.Arbitrary)
50         return a.getCoinbaseArbitrary()
51 }
52
53 // SubmitBlockReq is req struct for submit-block API
54 type SubmitBlockReq struct {
55         Block *types.Block `json:"raw_block"`
56 }
57
58 // submitBlock trys to submit a raw block to the chain
59 func (a *API) submitBlock(ctx context.Context, req *SubmitBlockReq) Response {
60         isOrphan, err := a.chain.ProcessBlock(req.Block)
61         if err != nil {
62                 return NewErrorResponse(err)
63         }
64         if isOrphan {
65                 return NewErrorResponse(errors.New("block submitted is orphan"))
66         }
67
68         blockHash := req.Block.BlockHeader.Hash()
69         a.newBlockCh <- &blockHash
70         return NewSuccessResponse(true)
71 }
72
73 // SubmitWorkReq is req struct for submit-work API
74 type SubmitWorkReq struct {
75         BlockHeader *types.BlockHeader `json:"block_header"`
76 }
77
78 // SubmitWorkJSONReq is req struct for submit-work-json API
79 type SubmitWorkJSONReq struct {
80         BlockHeader *BlockHeaderJSON `json:"block_header"`
81 }
82
83 // GetWorkResp is resp struct for get-work API
84 type GetWorkResp struct {
85         BlockHeader *types.BlockHeader `json:"block_header"`
86         Seed        *bc.Hash           `json:"seed"`
87 }
88
89 // GetWorkJSONResp is resp struct for get-work-json API
90 type GetWorkJSONResp struct {
91         BlockHeader *BlockHeaderJSON `json:"block_header"`
92         Seed        *bc.Hash         `json:"seed"`
93 }
94
95 func (a *API) setMining(in struct {
96         IsMining bool `json:"is_mining"`
97 }) Response {
98         if in.IsMining {
99                 if _, err := a.wallet.AccountMgr.GetMiningAddress(); err != nil {
100                         return NewErrorResponse(errors.New("Mining address does not exist"))
101                 }
102                 return a.startMining()
103         }
104         return a.stopMining()
105 }
106
107 func (a *API) startMining() Response {
108         //a.cpuMiner.Start()
109         a.miner.Start()
110         if !a.IsMining() {
111                 return NewErrorResponse(errors.New("Failed to start mining"))
112         }
113         return NewSuccessResponse("")
114 }
115
116 func (a *API) stopMining() Response {
117         //a.cpuMiner.Stop()
118         a.miner.Stop()
119         if a.IsMining() {
120                 return NewErrorResponse(errors.New("Failed to stop mining"))
121         }
122         return NewSuccessResponse("")
123 }