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