OSDN Git Service

add log (#373)
[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/event"
10         "github.com/vapor/protocol/bc/types"
11 )
12
13 type CoinbaseArbitrary struct {
14         Arbitrary chainjson.HexBytes `json:"arbitrary"`
15 }
16
17 func (a *API) getCoinbaseArbitrary() Response {
18         arbitrary := a.wallet.AccountMgr.GetCoinbaseArbitrary()
19         resp := &CoinbaseArbitrary{
20                 Arbitrary: arbitrary,
21         }
22         return NewSuccessResponse(resp)
23 }
24
25 // setCoinbaseArbitrary add arbitary data to the reserved coinbase data.
26 // check function createCoinbaseTx in mining/mining.go for detail.
27 // arbitraryLenLimit is 107 and can be calculated by:
28 //      maxHeight := ^uint64(0)
29 //      reserved := append([]byte{0x00}, []byte(strconv.FormatUint(maxHeight, 10))...)
30 //      arbitraryLenLimit := consensus.CoinbaseArbitrarySizeLimit - len(reserved)
31 func (a *API) setCoinbaseArbitrary(ctx context.Context, req CoinbaseArbitrary) Response {
32         arbitraryLenLimit := 107
33         if len(req.Arbitrary) > arbitraryLenLimit {
34                 err := errors.New("Arbitrary exceeds limit: " + strconv.FormatUint(uint64(arbitraryLenLimit), 10))
35                 return NewErrorResponse(err)
36         }
37         a.wallet.AccountMgr.SetCoinbaseArbitrary(req.Arbitrary)
38         return a.getCoinbaseArbitrary()
39 }
40
41 // SubmitBlockReq is req struct for submit-block API
42 type SubmitBlockReq struct {
43         Block *types.Block `json:"raw_block"`
44 }
45
46 // submitBlock trys to submit a raw block to the chain
47 func (a *API) submitBlock(ctx context.Context, req *SubmitBlockReq) Response {
48         isOrphan, err := a.chain.ProcessBlock(req.Block)
49         if err != nil {
50                 return NewErrorResponse(err)
51         }
52
53         if isOrphan {
54                 return NewErrorResponse(errors.New("block submitted is orphan"))
55         }
56
57         if err = a.eventDispatcher.Post(event.NewProposedBlockEvent{Block: *req.Block}); err != nil {
58                 return NewErrorResponse(err)
59         }
60
61         return NewSuccessResponse(true)
62 }
63
64 func (a *API) setMining(in struct {
65         IsMining bool `json:"is_mining"`
66 }) Response {
67         if in.IsMining {
68                 if _, err := a.wallet.AccountMgr.GetMiningAddress(); err != nil {
69                         return NewErrorResponse(errors.New("Mining address does not exist"))
70                 }
71                 return a.startMining()
72         }
73         return a.stopMining()
74 }
75
76 func (a *API) startMining() Response {
77         a.blockProposer.Start()
78         if !a.IsMining() {
79                 return NewErrorResponse(errors.New("Failed to start mining"))
80         }
81         return NewSuccessResponse("")
82 }
83
84 func (a *API) stopMining() Response {
85         a.blockProposer.Stop()
86         if a.IsMining() {
87                 return NewErrorResponse(errors.New("Failed to stop mining"))
88         }
89         return NewSuccessResponse("")
90 }