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 }