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