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"
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
25 type CoinbaseArbitrary struct {
26 Arbitrary chainjson.HexBytes `json:"arbitrary"`
29 func (a *API) getCoinbaseArbitrary() Response {
30 arbitrary := a.wallet.AccountMgr.GetCoinbaseArbitrary()
31 resp := &CoinbaseArbitrary{
34 return NewSuccessResponse(resp)
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)
49 a.wallet.AccountMgr.SetCoinbaseArbitrary(req.Arbitrary)
50 return a.getCoinbaseArbitrary()
53 // getWork gets work in compressed protobuf format
54 func (a *API) getWork() Response {
55 work, err := a.GetWork()
57 return NewErrorResponse(err)
59 return NewSuccessResponse(work)
62 // getWorkJSON gets work in json format
63 func (a *API) getWorkJSON() Response {
64 work, err := a.GetWorkJSON()
66 return NewErrorResponse(err)
68 return NewSuccessResponse(work)
71 // SubmitBlockReq is req struct for submit-block API
72 type SubmitBlockReq struct {
73 Block *types.Block `json:"raw_block"`
76 // submitBlock trys to submit a raw block to the chain
77 func (a *API) submitBlock(ctx context.Context, req *SubmitBlockReq) Response {
78 isOrphan, err := a.chain.ProcessBlock(req.Block)
80 return NewErrorResponse(err)
83 return NewErrorResponse(errors.New("block submitted is orphan"))
86 blockHash := req.Block.BlockHeader.Hash()
87 a.newBlockCh <- &blockHash
88 return NewSuccessResponse(true)
91 // SubmitWorkReq is req struct for submit-work API
92 type SubmitWorkReq struct {
93 BlockHeader *types.BlockHeader `json:"block_header"`
96 // submitWork submits work in compressed protobuf format
97 func (a *API) submitWork(ctx context.Context, req *SubmitWorkReq) Response {
98 if err := a.SubmitWork(req.BlockHeader); err != nil {
99 return NewErrorResponse(err)
101 return NewSuccessResponse(true)
104 // SubmitWorkJSONReq is req struct for submit-work-json API
105 type SubmitWorkJSONReq struct {
106 BlockHeader *BlockHeaderJSON `json:"block_header"`
109 // submitWorkJSON submits work in json format
110 func (a *API) submitWorkJSON(ctx context.Context, req *SubmitWorkJSONReq) Response {
111 bh := &types.BlockHeader{
112 Version: req.BlockHeader.Version,
113 Height: req.BlockHeader.Height,
114 PreviousBlockHash: req.BlockHeader.PreviousBlockHash,
115 Timestamp: req.BlockHeader.Timestamp,
116 //Nonce: req.BlockHeader.Nonce,
117 //Bits: req.BlockHeader.Bits,
118 BlockCommitment: *req.BlockHeader.BlockCommitment,
121 if err := a.SubmitWork(bh); err != nil {
122 return NewErrorResponse(err)
124 return NewSuccessResponse(true)
127 // GetWorkResp is resp struct for get-work API
128 type GetWorkResp struct {
129 BlockHeader *types.BlockHeader `json:"block_header"`
130 Seed *bc.Hash `json:"seed"`
133 // GetWork gets work in compressed protobuf format
134 func (a *API) GetWork() (*GetWorkResp, error) {
135 bh, err := a.miningPool.GetWork()
140 seed, err := a.chain.CalcNextSeed(&bh.PreviousBlockHash)
151 // GetWorkJSONResp is resp struct for get-work-json API
152 type GetWorkJSONResp struct {
153 BlockHeader *BlockHeaderJSON `json:"block_header"`
154 Seed *bc.Hash `json:"seed"`
157 // GetWorkJSON gets work in json format
158 func (a *API) GetWorkJSON() (*GetWorkJSONResp, error) {
159 bh, err := a.miningPool.GetWork()
164 seed, err := a.chain.CalcNextSeed(&bh.PreviousBlockHash)
169 return &GetWorkJSONResp{
170 BlockHeader: &BlockHeaderJSON{
173 PreviousBlockHash: bh.PreviousBlockHash,
174 Timestamp: bh.Timestamp,
177 BlockCommitment: &bh.BlockCommitment,
183 // SubmitWork tries to submit work to the chain
184 func (a *API) SubmitWork(bh *types.BlockHeader) error {
185 return a.miningPool.SubmitWork(bh)
188 func (a *API) setMining(in struct {
189 IsMining bool `json:"is_mining"`
192 if _, err := a.wallet.AccountMgr.GetMiningAddress(); err != nil {
193 return NewErrorResponse(errors.New("Mining address does not exist"))
195 return a.startMining()
197 return a.stopMining()
200 func (a *API) startMining() Response {
204 return NewErrorResponse(errors.New("Failed to start mining"))
206 return NewSuccessResponse("")
209 func (a *API) stopMining() Response {
213 return NewErrorResponse(errors.New("Failed to stop mining"))
215 return NewSuccessResponse("")