OSDN Git Service

:white_check_mark: Check arbitrary len limit (#1283)
[bytom/bytom.git] / api / miner.go
index 5613bcf..8607371 100644 (file)
@@ -2,12 +2,54 @@ package api
 
 import (
        "context"
+       "strconv"
 
+       chainjson "github.com/bytom/encoding/json"
        "github.com/bytom/errors"
        "github.com/bytom/protocol/bc"
        "github.com/bytom/protocol/bc/types"
 )
 
+// BlockHeaderJSON struct provides support for get work in json format, when it also follows
+// BlockHeader structure
+type BlockHeaderJSON struct {
+       Version           uint64                 `json:"version"`             // The version of the block.
+       Height            uint64                 `json:"height"`              // The height of the block.
+       PreviousBlockHash bc.Hash                `json:"previous_block_hash"` // The hash of the previous block.
+       Timestamp         uint64                 `json:"timestamp"`           // The time of the block in seconds.
+       Nonce             uint64                 `json:"nonce"`               // Nonce used to generate the block.
+       Bits              uint64                 `json:"bits"`                // Difficulty target for the block.
+       BlockCommitment   *types.BlockCommitment `json:"block_commitment"`    // Block commitment
+}
+
+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()
+}
+
 // getWork gets work in compressed protobuf format
 func (a *API) getWork() Response {
        work, err := a.GetWork()
@@ -41,7 +83,7 @@ func (a *API) submitWork(ctx context.Context, req *SubmitWorkReq) Response {
 
 // SubmitWorkJSONReq is req struct for submit-work-json API
 type SubmitWorkJSONReq struct {
-       BlockHeader *types.BlockHeaderJSON `json:"block_header"`
+       BlockHeader *BlockHeaderJSON `json:"block_header"`
 }
 
 // submitWorkJSON submits work in json format
@@ -53,7 +95,7 @@ func (a *API) submitWorkJSON(ctx context.Context, req *SubmitWorkJSONReq) Respon
                Timestamp:         req.BlockHeader.Timestamp,
                Nonce:             req.BlockHeader.Nonce,
                Bits:              req.BlockHeader.Bits,
-               BlockCommitment:   req.BlockHeader.BlockCommitment,
+               BlockCommitment:   *req.BlockHeader.BlockCommitment,
        }
 
        if err := a.SubmitWork(bh); err != nil {
@@ -88,8 +130,8 @@ func (a *API) GetWork() (*GetWorkResp, error) {
 
 // GetWorkJSONResp is resp struct for get-work-json API
 type GetWorkJSONResp struct {
-       BlockHeader *types.BlockHeaderJSON `json:"block_header"`
-       Seed        *bc.Hash               `json:"seed"`
+       BlockHeader *BlockHeaderJSON `json:"block_header"`
+       Seed        *bc.Hash         `json:"seed"`
 }
 
 // GetWorkJSON gets work in json format
@@ -105,14 +147,14 @@ func (a *API) GetWorkJSON() (*GetWorkJSONResp, error) {
        }
 
        return &GetWorkJSONResp{
-               BlockHeader: &types.BlockHeaderJSON{
+               BlockHeader: &BlockHeaderJSON{
                        Version:           bh.Version,
                        Height:            bh.Height,
                        PreviousBlockHash: bh.PreviousBlockHash,
                        Timestamp:         bh.Timestamp,
                        Nonce:             bh.Nonce,
                        Bits:              bh.Bits,
-                       BlockCommitment:   bh.BlockCommitment,
+                       BlockCommitment:   &bh.BlockCommitment,
                },
                Seed: seed,
        }, nil
@@ -127,6 +169,9 @@ 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()