OSDN Git Service

add get-blocker api
authorshenao78 <shenao.78@163.com>
Thu, 13 Jun 2019 05:54:24 +0000 (13:54 +0800)
committershenao78 <shenao.78@163.com>
Thu, 13 Jun 2019 05:54:24 +0000 (13:54 +0800)
api/api.go
api/bbft.go
protocol/bbft.go
protocol/consensus_node_manager.go

index 88f43e5..9a6f641 100644 (file)
@@ -302,6 +302,7 @@ func (a *API) buildHandler() {
        m.Handle("/get-merkle-proof", jsonHandler(a.getMerkleProof))
 
        m.Handle("/get-vote-result", jsonHandler(a.getVoteResult))
+       m.Handle("/get-blocker", jsonHandler(a.getBlocker))
 
        m.HandleFunc("/websocket-subscribe", a.websocketHandler)
 
index 83cad1e..30b4197 100644 (file)
@@ -4,6 +4,7 @@ import (
        "sort"
 
        chainjson "github.com/vapor/encoding/json"
+       "github.com/vapor/protocol/bc/types"
 )
 
 type voteInfo struct {
@@ -12,9 +13,10 @@ type voteInfo struct {
 }
 
 type voteInfoSlice []*voteInfo
-func (v voteInfoSlice) Len() int { return len(v) }
+
+func (v voteInfoSlice) Len() int           { return len(v) }
 func (v voteInfoSlice) Less(i, j int) bool { return v[i].VoteNum > v[j].VoteNum }
-func (v voteInfoSlice) Swap(i, j int) { v[i], v[j] = v[j], v[i] }
+func (v voteInfoSlice) Swap(i, j int)      { v[i], v[j] = v[j], v[i] }
 
 func (a *API) getVoteResult(req struct {
        BlockHash   chainjson.HexBytes `json:"block_hash"`
@@ -45,3 +47,31 @@ func (a *API) getVoteResult(req struct {
        sort.Sort(voteInfoSlice(voteInfos))
        return NewSuccessResponse(voteInfos)
 }
+
+type getBlockerResp struct {
+       PubKey string `json:"pub_key"`
+}
+
+func (a *API) getBlocker(req struct {
+       BlockHash   chainjson.HexBytes `json:"block_hash"`
+       BlockHeight uint64             `json:"block_height"`
+}) Response {
+       var blockHeader *types.BlockHeader
+       var err error
+       if len(req.BlockHash) == 32 {
+               blockHash := hexBytesToHash(req.BlockHash)
+               blockHeader, err = a.chain.GetHeaderByHash(&blockHash)
+       } else {
+               blockHeader, err = a.chain.GetHeaderByHeight(req.BlockHeight)
+       }
+
+       if err != nil {
+               return NewErrorResponse(err)
+       }
+
+       pubKey, err := a.chain.GetBlocker(&blockHeader.PreviousBlockHash, blockHeader.Timestamp)
+       if err != nil {
+               return NewErrorResponse(err)
+       }
+       return NewSuccessResponse(&getBlockerResp{PubKey: pubKey})
+}
index 798f62d..f42e5f1 100644 (file)
@@ -52,8 +52,17 @@ func (c *Chain) GetVoteResultByHash(blockHash *bc.Hash) (*state.VoteResult, erro
 }
 
 // IsBlocker returns whether the consensus node is a blocker at the specified time
-func (c *Chain) IsBlocker(prevBlockHash *bc.Hash, pubkey string, timeStamp uint64) (bool, error) {
-       return c.consensusNodeManager.isBlocker(prevBlockHash, pubkey, timeStamp)
+func (c *Chain) IsBlocker(prevBlockHash *bc.Hash, pubKey string, timeStamp uint64) (bool, error) {
+       xPub, err := c.consensusNodeManager.getBlocker(prevBlockHash, timeStamp)
+       if err != nil {
+               return false, err
+       }
+       return xPub == pubKey, nil
+}
+
+// GetBlock return blocker by specified timestamp
+func (c *Chain) GetBlocker(prevBlockHash *bc.Hash, timestamp uint64) (string, error) {
+       return c.consensusNodeManager.getBlocker(prevBlockHash, timestamp)
 }
 
 // ProcessBlockSignature process the received block signature messages
@@ -122,7 +131,7 @@ func (c *Chain) validateSign(block *types.Block) error {
                        return err
                }
 
-               isBlocker, err := c.consensusNodeManager.isBlocker(&block.PreviousBlockHash, pubKey, block.Timestamp)
+               isBlocker, err := c.IsBlocker(&block.PreviousBlockHash, pubKey, block.Timestamp)
                if err != nil {
                        return err
                }
index 3b5f9ed..a4b59e6 100644 (file)
@@ -37,26 +37,28 @@ func (c *consensusNodeManager) getConsensusNode(prevBlockHash *bc.Hash, pubkey s
        return node, nil
 }
 
-func (c *consensusNodeManager) isBlocker(prevBlockHash *bc.Hash, pubKey string, timeStamp uint64) (bool, error) {
+func (c *consensusNodeManager) getBlocker(prevBlockHash *bc.Hash, timeStamp uint64) (string, error) {
        consensusNodeMap, err := c.getConsensusNodes(prevBlockHash)
        if err != nil {
-               return false, err
-       }
-
-       consensusNode := consensusNodeMap[pubKey]
-       if consensusNode == nil {
-               return false, nil
+               return "", err
        }
 
        prevVoteRoundLastBlock, err := c.getPrevRoundLastBlock(prevBlockHash)
        if err != nil {
-               return false, err
+               return "", err
        }
 
        startTimestamp := prevVoteRoundLastBlock.Timestamp + consensus.BlockTimeInterval
-       begin := getLastBlockTimeInTimeRange(startTimestamp, timeStamp, consensusNode.Order, uint64(len(consensusNodeMap)))
-       end := begin + consensus.BlockNumEachNode*consensus.BlockTimeInterval
-       return timeStamp >= begin && timeStamp < end, nil
+
+       for xPub, consensusNode := range consensusNodeMap {
+               begin := getLastBlockTimeInTimeRange(startTimestamp, timeStamp, consensusNode.Order, uint64(len(consensusNodeMap)))
+               end := begin + consensus.BlockNumEachNode*consensus.BlockTimeInterval
+               if timeStamp >= begin && timeStamp < end {
+                       return xPub, nil
+               }
+       }
+       // impossible occur
+       return "", errors.New("can not find blocker by given timestamp")
 }
 
 func getLastBlockTimeInTimeRange(startTimestamp, endTimestamp, order, numOfConsensusNode uint64) uint64 {