github.com/klaytn/klaytn@v1.12.1/consensus/clique/api.go (about) 1 // Modifications Copyright 2019 The klaytn Authors 2 // Copyright 2017 The go-ethereum Authors 3 // This file is part of the go-ethereum library. 4 // 5 // The go-ethereum library is free software: you can redistribute it and/or modify 6 // it under the terms of the GNU Lesser General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 9 // 10 // The go-ethereum library is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU Lesser General Public License for more details. 14 // 15 // You should have received a copy of the GNU Lesser General Public License 16 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 17 // 18 // This file is derived from go-ethereum/consensus/clique/api.go (2018/06/04). 19 // Modified and improved for the klaytn development. 20 21 package clique 22 23 import ( 24 "github.com/klaytn/klaytn/blockchain/types" 25 "github.com/klaytn/klaytn/common" 26 "github.com/klaytn/klaytn/consensus" 27 "github.com/klaytn/klaytn/networks/rpc" 28 ) 29 30 // API is a user facing RPC API to allow controlling the signer and voting 31 // mechanisms of the proof-of-authority scheme. 32 type API struct { 33 chain consensus.ChainReader 34 clique *Clique 35 } 36 37 // GetSnapshot retrieves the state snapshot at a given block. 38 func (api *API) GetSnapshot(number *rpc.BlockNumber) (*Snapshot, error) { 39 // Retrieve the requested block number (or current if none requested) 40 var header *types.Header 41 if number == nil || *number == rpc.LatestBlockNumber { 42 header = api.chain.CurrentHeader() 43 } else { 44 header = api.chain.GetHeaderByNumber(uint64(number.Int64())) 45 } 46 // Ensure we have an actually valid block and return its snapshot 47 if header == nil { 48 return nil, errUnknownBlock 49 } 50 return api.clique.snapshot(api.chain, header.Number.Uint64(), header.Hash(), nil) 51 } 52 53 // GetSnapshotAtHash retrieves the state snapshot at a given block. 54 func (api *API) GetSnapshotAtHash(hash common.Hash) (*Snapshot, error) { 55 header := api.chain.GetHeaderByHash(hash) 56 if header == nil { 57 return nil, errUnknownBlock 58 } 59 return api.clique.snapshot(api.chain, header.Number.Uint64(), header.Hash(), nil) 60 } 61 62 // GetSigners retrieves the list of authorized signers at the specified block. 63 func (api *API) GetSigners(number *rpc.BlockNumber) ([]common.Address, error) { 64 // Retrieve the requested block number (or current if none requested) 65 snap, err := api.GetSnapshot(number) 66 if err != nil { 67 return nil, err 68 } 69 return snap.signers(), nil 70 } 71 72 // GetSignersAtHash retrieves the state snapshot at a given block. 73 func (api *API) GetSignersAtHash(hash common.Hash) ([]common.Address, error) { 74 header := api.chain.GetHeaderByHash(hash) 75 if header == nil { 76 return nil, errUnknownBlock 77 } 78 snap, err := api.clique.snapshot(api.chain, header.Number.Uint64(), header.Hash(), nil) 79 if err != nil { 80 return nil, err 81 } 82 return snap.signers(), nil 83 } 84 85 // Proposals returns the current proposals the node tries to uphold and vote on. 86 func (api *API) Proposals() map[common.Address]bool { 87 api.clique.lock.RLock() 88 defer api.clique.lock.RUnlock() 89 90 proposals := make(map[common.Address]bool) 91 for address, auth := range api.clique.proposals { 92 proposals[address] = auth 93 } 94 return proposals 95 } 96 97 // Propose injects a new authorization proposal that the signer will attempt to 98 // push through. 99 func (api *API) Propose(address common.Address, auth bool) { 100 api.clique.lock.Lock() 101 defer api.clique.lock.Unlock() 102 103 api.clique.proposals[address] = auth 104 } 105 106 // Discard drops a currently running proposal, stopping the signer from casting 107 // further votes (either for or against). 108 func (api *API) Discard(address common.Address) { 109 api.clique.lock.Lock() 110 defer api.clique.lock.Unlock() 111 112 delete(api.clique.proposals, address) 113 }