OSDN Git Service

:white_check_mark: Check arbitrary len limit (#1283)
[bytom/bytom.git] / api / miner.go
index fc7fce5..8607371 100644 (file)
@@ -2,22 +2,55 @@ 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
+       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()
        if err != nil {
@@ -26,6 +59,7 @@ func (a *API) getWork() Response {
        return NewSuccessResponse(work)
 }
 
+// getWorkJSON gets work in json format
 func (a *API) getWorkJSON() Response {
        work, err := a.GetWorkJSON()
        if err != nil {
@@ -34,11 +68,12 @@ func (a *API) getWorkJSON() Response {
        return NewSuccessResponse(work)
 }
 
-// SubmitWorkReq used to submitWork req
+// SubmitWorkJSONReq is req struct for submit-work API
 type SubmitWorkReq struct {
        BlockHeader *types.BlockHeader `json:"block_header"`
 }
 
+// submitWork submits work in compressed protobuf format
 func (a *API) submitWork(ctx context.Context, req *SubmitWorkReq) Response {
        if err := a.SubmitWork(req.BlockHeader); err != nil {
                return NewErrorResponse(err)
@@ -46,26 +81,22 @@ func (a *API) submitWork(ctx context.Context, req *SubmitWorkReq) Response {
        return NewSuccessResponse(true)
 }
 
-// SubmitWorkJSONReq used to submitWork req
+// SubmitWorkJSONReq is req struct for submit-work-json API
 type SubmitWorkJSONReq struct {
-       BlockHeader *BlockHeaderJSON    `json:"block_header"`
+       BlockHeader *BlockHeaderJSON `json:"block_header"`
 }
 
+// submitWorkJSON submits work in json format
 func (a *API) submitWorkJSON(ctx context.Context, req *SubmitWorkJSONReq) Response {
-       blockCommitment := types.BlockCommitment{
-                                                       TransactionsMerkleRoot: req.BlockHeader.BlockCommitment.TransactionsMerkleRoot,
-                                                       TransactionStatusHash:  req.BlockHeader.BlockCommitment.TransactionStatusHash,
-                                               }
-
        bh := &types.BlockHeader{
-                       Version:                        req.BlockHeader.Version,
-                       Height:                         req.BlockHeader.Height,
-                       PreviousBlockHash:      req.BlockHeader.PreviousBlockHash,
-                       Timestamp:              req.BlockHeader.Timestamp,
-                       Nonce:                  req.BlockHeader.Nonce,
-                       Bits:                   req.BlockHeader.Bits,
-                       BlockCommitment:        blockCommitment,
-               }
+               Version:           req.BlockHeader.Version,
+               Height:            req.BlockHeader.Height,
+               PreviousBlockHash: req.BlockHeader.PreviousBlockHash,
+               Timestamp:         req.BlockHeader.Timestamp,
+               Nonce:             req.BlockHeader.Nonce,
+               Bits:              req.BlockHeader.Bits,
+               BlockCommitment:   *req.BlockHeader.BlockCommitment,
+       }
 
        if err := a.SubmitWork(bh); err != nil {
                return NewErrorResponse(err)
@@ -73,13 +104,13 @@ func (a *API) submitWorkJSON(ctx context.Context, req *SubmitWorkJSONReq) Respon
        return NewSuccessResponse(true)
 }
 
-// GetWorkResp is resp struct for API
+// GetWorkResp is resp struct for get-work API
 type GetWorkResp struct {
        BlockHeader *types.BlockHeader `json:"block_header"`
        Seed        *bc.Hash           `json:"seed"`
 }
 
-// GetWork get work
+// GetWork gets work in compressed protobuf format
 func (a *API) GetWork() (*GetWorkResp, error) {
        bh, err := a.miningPool.GetWork()
        if err != nil {
@@ -97,13 +128,13 @@ func (a *API) GetWork() (*GetWorkResp, error) {
        }, nil
 }
 
-// GetWorkJSONResp is resp struct for API get-work-json
+// GetWorkJSONResp is resp struct for get-work-json API
 type GetWorkJSONResp struct {
-       BlockHeader *BlockHeaderJSON    `json:"block_header"`
-       Seed        *bc.Hash            `json:"seed"`
+       BlockHeader *BlockHeaderJSON `json:"block_header"`
+       Seed        *bc.Hash         `json:"seed"`
 }
 
-// GetWorkJSON get work in json
+// GetWorkJSON gets work in json format
 func (a *API) GetWorkJSON() (*GetWorkJSONResp, error) {
        bh, err := a.miningPool.GetWork()
        if err != nil {
@@ -115,26 +146,21 @@ func (a *API) GetWorkJSON() (*GetWorkJSONResp, error) {
                return nil, err
        }
 
-       blockCommitment := &types.BlockCommitment{
-                                                       TransactionsMerkleRoot: bh.BlockCommitment.TransactionsMerkleRoot,
-                                                       TransactionStatusHash:  bh.BlockCommitment.TransactionStatusHash,
-                                               }
-
        return &GetWorkJSONResp{
                BlockHeader: &BlockHeaderJSON{
-                       Version:                        bh.Version,
-                       Height:                         bh.Height,
-                       PreviousBlockHash:      bh.PreviousBlockHash,
-                       Timestamp:              bh.Timestamp,
-                       Nonce:                  bh.Nonce,
-                       Bits:                   bh.Bits,
-                       BlockCommitment:        blockCommitment,
+                       Version:           bh.Version,
+                       Height:            bh.Height,
+                       PreviousBlockHash: bh.PreviousBlockHash,
+                       Timestamp:         bh.Timestamp,
+                       Nonce:             bh.Nonce,
+                       Bits:              bh.Bits,
+                       BlockCommitment:   &bh.BlockCommitment,
                },
-               Seed:        seed,
+               Seed: seed,
        }, nil
 }
 
-// SubmitWork submit work to the miningpool
+// SubmitWork tries to submit work to the chain
 func (a *API) SubmitWork(bh *types.BlockHeader) error {
        return a.miningPool.SubmitWork(bh)
 }
@@ -143,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()