github.com/arieschain/arieschain@v0.0.0-20191023063405-37c074544356/consensus/bft/backend/api.go (about)

     1  package backend
     2  
     3  import (
     4  	"github.com/quickchainproject/quickchain/common"
     5  	"github.com/quickchainproject/quickchain/consensus"
     6  	"github.com/quickchainproject/quickchain/core/types"
     7  	"github.com/quickchainproject/quickchain/rpc"
     8  )
     9  
    10  // API is a user facing RPC API to dump BFT state
    11  type API struct {
    12  	chain    consensus.ChainReader
    13  	bft *backend
    14  }
    15  
    16  // GetSnapshot retrieves the state snapshot at a given block.
    17  func (api *API) GetSnapshot(number *rpc.BlockNumber) (*Snapshot, error) {
    18  	// Retrieve the requested block number (or current if none requested)
    19  	var header *types.Header
    20  	if number == nil || *number == rpc.LatestBlockNumber {
    21  		header = api.chain.CurrentHeader()
    22  	} else {
    23  		header = api.chain.GetHeaderByNumber(uint64(number.Int64()))
    24  	}
    25  	// Ensure we have an actually valid block and return its snapshot
    26  	if header == nil {
    27  		return nil, errUnknownBlock
    28  	}
    29  	return api.bft.snapshot(api.chain, header.Number.Uint64(), header.Hash(), nil)
    30  }
    31  
    32  // GetSnapshotAtHash retrieves the state snapshot at a given block.
    33  func (api *API) GetSnapshotAtHash(hash common.Hash) (*Snapshot, error) {
    34  	header := api.chain.GetHeaderByHash(hash)
    35  	if header == nil {
    36  		return nil, errUnknownBlock
    37  	}
    38  	return api.bft.snapshot(api.chain, header.Number.Uint64(), header.Hash(), nil)
    39  }
    40  
    41  // GetValidators retrieves the list of authorized validators at the specified block.
    42  func (api *API) GetValidators(number *rpc.BlockNumber) ([]common.Address, error) {
    43  	// Retrieve the requested block number (or current if none requested)
    44  	var header *types.Header
    45  	if number == nil || *number == rpc.LatestBlockNumber {
    46  		header = api.chain.CurrentHeader()
    47  	} else {
    48  		header = api.chain.GetHeaderByNumber(uint64(number.Int64()))
    49  	}
    50  	// Ensure we have an actually valid block and return the validators from its snapshot
    51  	if header == nil {
    52  		return nil, errUnknownBlock
    53  	}
    54  	snap, err := api.bft.snapshot(api.chain, header.Number.Uint64(), header.Hash(), nil)
    55  	if err != nil {
    56  		return nil, err
    57  	}
    58  	return snap.validators(), nil
    59  }
    60  
    61  // GetValidatorsAtHash retrieves the state snapshot at a given block.
    62  func (api *API) GetValidatorsAtHash(hash common.Hash) ([]common.Address, error) {
    63  	header := api.chain.GetHeaderByHash(hash)
    64  	if header == nil {
    65  		return nil, errUnknownBlock
    66  	}
    67  	snap, err := api.bft.snapshot(api.chain, header.Number.Uint64(), header.Hash(), nil)
    68  	if err != nil {
    69  		return nil, err
    70  	}
    71  	return snap.validators(), nil
    72  }
    73  
    74  // Candidates returns the current candidates the node tries to uphold and vote on.
    75  func (api *API) Candidates() map[common.Address]bool {
    76  	api.bft.candidatesLock.RLock()
    77  	defer api.bft.candidatesLock.RUnlock()
    78  
    79  	proposals := make(map[common.Address]bool)
    80  	for address, auth := range api.bft.candidates {
    81  		proposals[address] = auth
    82  	}
    83  	return proposals
    84  }
    85  
    86  // Propose injects a new authorization candidate that the validator will attempt to
    87  // push through.
    88  func (api *API) Propose(address common.Address, auth bool) {
    89  	api.bft.candidatesLock.Lock()
    90  	defer api.bft.candidatesLock.Unlock()
    91  
    92  	api.bft.candidates[address] = auth
    93  }
    94  
    95  // Discard drops a currently running candidate, stopping the validator from casting
    96  // further votes (either for or against).
    97  func (api *API) Discard(address common.Address) {
    98  	api.bft.candidatesLock.Lock()
    99  	defer api.bft.candidatesLock.Unlock()
   100  
   101  	delete(api.bft.candidates, address)
   102  }