package api
import (
- log "github.com/sirupsen/logrus"
+ "math/big"
"github.com/bytom/blockchain/query"
"github.com/bytom/consensus/difficulty"
return NewSuccessResponse(blockHash)
}
-// return block header by hash
-func (a *API) getBlockHeaderByHash(strHash string) Response {
- hash := bc.Hash{}
- if err := hash.UnmarshalText([]byte(strHash)); err != nil {
- log.WithField("error", err).Error("Error occurs when transforming string hash to hash struct")
- return NewErrorResponse(err)
- }
- block, err := a.chain.GetBlockByHash(&hash)
- if err != nil {
- log.WithField("error", err).Error("Fail to get block by hash")
- return NewErrorResponse(err)
- }
-
- bcBlock := types.MapBlock(block)
- return NewSuccessResponse(bcBlock.BlockHeader)
+// return current block count
+func (a *API) getBlockCount() Response {
+ blockHeight := map[string]uint64{"block_count": a.chain.BestBlockHeight()}
+ return NewSuccessResponse(blockHeight)
}
// BlockTx is the tx struct for getBlock func
StatusFail bool `json:"status_fail"`
}
-// 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"`
}
}
// 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 {
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{},
return NewSuccessResponse(resp)
}
-// return block transactions count by hash
-func (a *API) getBlockTransactionsCountByHash(strHash string) Response {
- hash := bc.Hash{}
- if err := hash.UnmarshalText([]byte(strHash)); err != nil {
- log.WithField("error", err).Error("Error occurs when transforming string hash to hash struct")
+// GetBlockHeaderResp is resp struct for getBlockHeader API
+type GetBlockHeaderResp struct {
+ BlockHeader *types.BlockHeader `json:"block_header"`
+ Reward uint64 `json:"reward"`
+}
+
+func (a *API) getBlockHeader(ins BlockReq) Response {
+ var err error
+ block := &types.Block{}
+ if len(ins.BlockHash) == 32 {
+ b32 := [32]byte{}
+ copy(b32[:], ins.BlockHash)
+ hash := bc.NewHash(b32)
+ block, err = a.chain.GetBlockByHash(&hash)
+ } else {
+ block, err = a.chain.GetBlockByHeight(ins.BlockHeight)
+ }
+ if err != nil {
return NewErrorResponse(err)
}
- legacyBlock, err := a.chain.GetBlockByHash(&hash)
+ resp := &GetBlockHeaderResp{
+ BlockHeader: &block.BlockHeader,
+ Reward: block.Transactions[0].Outputs[0].Amount,
+ }
+ 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 {
- log.WithField("error", err).Error("Fail to get block by hash")
return NewErrorResponse(err)
}
- count := map[string]int{"count": len(legacyBlock.Transactions)}
- return NewSuccessResponse(count)
+ blockHash := block.Hash()
+ resp := &GetDifficultyResp{
+ BlockHash: &blockHash,
+ BlockHeight: block.Height,
+ Bits: block.Bits,
+ Difficulty: difficulty.CalcWork(block.Bits).String(),
+ }
+ return NewSuccessResponse(resp)
}
-// return block transactions count by height
-func (a *API) getBlockTransactionsCountByHeight(height uint64) Response {
- legacyBlock, err := a.chain.GetBlockByHeight(height)
+// 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 {
- log.WithField("error", err).Error("Fail to get block by hash")
return NewErrorResponse(err)
}
- count := map[string]int{"count": len(legacyBlock.Transactions)}
- return NewSuccessResponse(count)
-}
+ preBlock, err := a.chain.GetBlockByHash(&block.PreviousBlockHash)
+ if err != nil {
+ return NewErrorResponse(err)
+ }
-// return current block count
-func (a *API) getBlockCount() Response {
- blockHeight := map[string]uint64{"block_count": a.chain.BestBlockHeight()}
- return NewSuccessResponse(blockHeight)
+ 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)
}