OSDN Git Service

move BlockHeaderJSON type
[bytom/bytom.git] / api / block_retrieve.go
index c036c4c..e9daea1 100644 (file)
@@ -1,6 +1,8 @@
 package api
 
 import (
+       "math/big"
+
        "github.com/bytom/blockchain/query"
        "github.com/bytom/consensus/difficulty"
        chainjson "github.com/bytom/encoding/json"
@@ -29,10 +31,11 @@ type BlockTx struct {
        Inputs     []*query.AnnotatedInput  `json:"inputs"`
        Outputs    []*query.AnnotatedOutput `json:"outputs"`
        StatusFail bool                     `json:"status_fail"`
+       MuxID      bc.Hash                  `json:"mux_id"`
 }
 
-// GetBlockReq is used to handle getBlock req
-type GetBlockReq struct {
+// BlockReq is used to handle getBlock req
+type BlockReq struct {
        BlockHeight uint64             `json:"block_height"`
        BlockHash   chainjson.HexBytes `json:"block_hash"`
 }
@@ -54,7 +57,7 @@ type GetBlockResp struct {
 }
 
 // return block by hash
-func (a *API) getBlock(ins GetBlockReq) Response {
+func (a *API) getBlock(ins BlockReq) Response {
        var err error
        block := &types.Block{}
        if len(ins.BlockHash) == 32 {
@@ -85,7 +88,7 @@ func (a *API) getBlock(ins GetBlockReq) Response {
                Timestamp:              block.Timestamp,
                Nonce:                  block.Nonce,
                Bits:                   block.Bits,
-               Difficulty:             difficulty.CompactToBig(block.Bits).String(),
+               Difficulty:             difficulty.CalcWork(block.Bits).String(),
                TransactionsMerkleRoot: &block.TransactionsMerkleRoot,
                TransactionStatusHash:  &block.TransactionStatusHash,
                Transactions:           []*BlockTx{},
@@ -105,6 +108,15 @@ func (a *API) getBlock(ins GetBlockReq) Response {
                        NewSuccessResponse(resp)
                }
 
+               resOutID := orig.ResultIds[0]
+               resOut, ok := orig.Entries[*resOutID].(*bc.Output)
+               if ok {
+                       tx.MuxID = *resOut.Source.Ref
+               } else {
+                       resRetire, _ := orig.Entries[*resOutID].(*bc.Retirement)
+                       tx.MuxID = *resRetire.Source.Ref
+               }
+
                for i := range orig.Inputs {
                        tx.Inputs = append(tx.Inputs, a.wallet.BuildAnnotatedInput(orig, uint32(i)))
                }
@@ -122,7 +134,7 @@ type GetBlockHeaderResp struct {
        Reward      uint64             `json:"reward"`
 }
 
-func (a *API) getBlockHeader(ins GetBlockReq) Response {
+func (a *API) getBlockHeader(ins BlockReq) Response {
        var err error
        block := &types.Block{}
        if len(ins.BlockHash) == 32 {
@@ -143,3 +155,86 @@ func (a *API) getBlockHeader(ins GetBlockReq) Response {
        }
        return NewSuccessResponse(resp)
 }
+
+// GetDifficultyResp is resp struct for getDifficulty API
+type GetDifficultyResp struct {
+       BlockHash   *bc.Hash `json:"hash"`
+       BlockHeight uint64   `json:"height"`
+       Bits        uint64   `json:"bits"`
+       Difficulty  string   `json:"difficulty"`
+}
+
+func (a *API) getDifficulty(ins *BlockReq) Response {
+       var err error
+       block := &types.Block{}
+
+       if len(ins.BlockHash) == 32 && ins.BlockHash != nil {
+               b32 := [32]byte{}
+               copy(b32[:], ins.BlockHash)
+               hash := bc.NewHash(b32)
+               block, err = a.chain.GetBlockByHash(&hash)
+       } else if ins.BlockHeight > 0 {
+               block, err = a.chain.GetBlockByHeight(ins.BlockHeight)
+       } else {
+               hash := a.chain.BestBlockHash()
+               block, err = a.chain.GetBlockByHash(hash)
+       }
+
+       if err != nil {
+               return NewErrorResponse(err)
+       }
+
+       blockHash := block.Hash()
+       resp := &GetDifficultyResp{
+               BlockHash:   &blockHash,
+               BlockHeight: block.Height,
+               Bits:        block.Bits,
+               Difficulty:  difficulty.CalcWork(block.Bits).String(),
+       }
+       return NewSuccessResponse(resp)
+}
+
+// getHashRateResp is resp struct for getHashRate API
+type getHashRateResp struct {
+       BlockHash   *bc.Hash `json:"hash"`
+       BlockHeight uint64   `json:"height"`
+       HashRate    uint64   `json:"hash_rate"`
+}
+
+func (a *API) getHashRate(ins BlockReq) Response {
+       var err error
+       block := &types.Block{}
+
+       if len(ins.BlockHash) == 32 && ins.BlockHash != nil {
+               b32 := [32]byte{}
+               copy(b32[:], ins.BlockHash)
+               hash := bc.NewHash(b32)
+               block, err = a.chain.GetBlockByHash(&hash)
+       } else if ins.BlockHeight > 0 {
+               block, err = a.chain.GetBlockByHeight(ins.BlockHeight)
+       } else {
+               hash := a.chain.BestBlockHash()
+               block, err = a.chain.GetBlockByHash(hash)
+       }
+
+       if err != nil {
+               return NewErrorResponse(err)
+       }
+
+       preBlock, err := a.chain.GetBlockByHash(&block.PreviousBlockHash)
+       if err != nil {
+               return NewErrorResponse(err)
+       }
+
+       diffTime := block.Timestamp - preBlock.Timestamp
+       hashCount := difficulty.CalcWork(block.Bits)
+       hashRate := new(big.Int).Div(hashCount, big.NewInt(int64(diffTime)))
+
+       blockHash := block.Hash()
+       resp := &getHashRateResp{
+               BlockHash:   &blockHash,
+               BlockHeight: block.Height,
+               HashRate:    hashRate.Uint64(),
+       }
+       return NewSuccessResponse(resp)
+}