diff --git a/bfa_client/src/bfa/node.go b/bfa_client/src/bfa/node.go index 264594fbbb990ec769b02a55f6d67e116dbb6682..b0115d866e38e145cf9d891c40da613d2b7abf80 100644 --- a/bfa_client/src/bfa/node.go +++ b/bfa_client/src/bfa/node.go @@ -152,14 +152,6 @@ type Proposals struct { Votes map[string]map[string]*bool `json:"votes"` // List of votes for each proposal } -type SealerInfo struct { - Address string - CurrentBlock int64 - Since int64 - FirstBlock int64 - LastBlock int64 -} - type SealerStatus struct { LastBlock int64 `json:"lastBlockSigned"` Time uint64 `json:"timestamp"` @@ -286,11 +278,6 @@ func (node *Node) GetSnapshot() (snapshot Snapshot) { return } -func (node *Node) SnapshotAtHash(hash common.Hash) (snapshot Snapshot) { - node.Call(&snapshot, "clique_getSnapshotAtHash", hash) - return -} - func (node *Node) SnapshotAtBlock(blockNumber int64) (snapshot Snapshot) { Require(blockNumber == -1 || blockNumber == node.BlockNumberInRange(blockNumber), "block number out of range") node.Call(&snapshot, "clique_getSnapshot", hexBlockNumber(blockNumber)) @@ -311,15 +298,6 @@ func (node *Node) NodeInfo() (nodeInfo p2p.NodeInfo) { return } -func (node *Node) SealersAtHash(hash common.Hash) (signers []string) { - var s []common.Address - node.Call(&signers, "clique_getSignersAtHash", hash) - for _, signer := range s { - signers = append(signers, BytesToHex(signer.Bytes())) - } - return -} - func (node *Node) SealersAtBlock(blockNumber int64) (signers []string) { var s []common.Address if blockNumber < 0 { @@ -418,208 +396,6 @@ func (node *Node) SealersStatus(blockNumber int64) (status map[string]*SealerSta return status } -func (node *Node) SealerInception(address string) (since int64) { - if signers := node.Sealers(); !Contains(signers, address) { - return -1 - } - - lo := int64(0) - hi := node.BlockNumber() - for lo < hi { - mid := lo + (hi-lo)/2 - signers := node.SealersAtBlock(mid) - if Contains(signers, address) { - hi = mid - } else { - lo = mid + 1 - } - } - return hi -} - -func (node *Node) signerFirstBlock(signer string, since int64, until int64) (blockNumber int64) { - if since < 0 { - return -1 - } - //snapshot := node.SnapshotAtBlock(since) - var ( - count int64 = 20 - found int64 = -1 - ) - // first, we look close to the inception - if blockNumber, _ = node.searchSnapshotForward(since, signer, count); blockNumber > 0 { - return - } - // next, we do a coarse search - since += count - for i := since + 10000; i < until && found == -1; i += 10000 { - if found, _ = node.searchSnapshotBackward(i, signer, 0); found == -1 { // still not found - since = i - } - } - if found > 0 { - until = found - } - n := Min(10, (until-since)/count+1) // number of goroutines - ch := make(chan int64) - for i := int64(0); i < n; i++ { - go func() { - for blockNumber := <-ch; blockNumber > 0; blockNumber = <-ch { - cnt := Min(count, until-blockNumber+1) - if found, _ := node.searchSnapshotForward(blockNumber, signer, cnt); found > 0 { - ch <- found - } - } - ch <- -1 - }() - } - for { - select { - case ch <- since: - switch { - case since < 0: - continue - case since+count < until: - since += count - default: - since = -1 //we have exhausted the search space - } - case found := <-ch: - switch { - case found < 0: - n-- // a goroutine has ended - if n == 0 { // all goroutines have ended - return - } - case blockNumber < 0: - blockNumber = found // first time we see this signer - since = -1 // Notify everyone - case found < blockNumber: - blockNumber = found // found an earlier block - } - } - } -} - -func (node *Node) signerLastBlock(signer string, since int64, until int64) (blockNumber int64) { - if since < 0 { - return -1 - } - var ( - count int64 = 20 - visited int64 = 0 - found int64 = -1 - ) - // first, we look close to the last block - if blockNumber, visited = node.searchSnapshotBackward(until, signer, 0); blockNumber > 0 { - return - } - // next, we do a coarse search - until -= visited - for i := until - 10000; i > since && found == -1; i -= 10000 { - if found, _ = node.searchSnapshotBackward(i, signer, 0); found == -1 { // still not found - until = i - } - } - if found > 0 { - since = found - } - n := Min(10, (until-since)/count+1) // number of goroutines - ch := make(chan int64) - for i := int64(0); i < n; i++ { - go func() { - for blockNumber := <-ch; blockNumber > 0; blockNumber = <-ch { - cnt := Min(count, blockNumber-since+1) - if found, _ := node.searchSnapshotBackward(blockNumber, signer, cnt); found > 0 { - ch <- found - } - } - ch <- -1 - }() - } - for { - select { - case ch <- until: - switch { - case until < 0: - continue - case until-count > since: - until -= count - default: - until = -1 //we have exhausted the search space - } - case found := <-ch: - switch { - case found < 0: - n-- // a goroutine has ended - if n == 0 { // all goroutines have ended - return - } - case blockNumber < 0: - blockNumber = found // first time we see this signer - until = -1 // Notify everyone - case found > blockNumber: - blockNumber = found // found a later block - } - } - } -} - -func (node *Node) searchSnapshotForward(blockNumber int64, signer string, count int64) (found int64, visited int64) { - found = -1 - if blockNumber+count < 1 { - return - } - for count > 0 { - snapshot := node.SnapshotAtBlock(blockNumber + count - 1) - recents := int64(len(snapshot.Recents)) - visited += recents - count -= recents - for b, s := range snapshot.Recents { - if BytesToHex(s[:]) == signer { - found = int64(b) - } - } - } - return -} - -func (node *Node) searchSnapshotBackward(blockNumber int64, signer string, count int64) (found int64, visited int64) { - found = -1 - if blockNumber < 1 { // Genesis block has no signers - return - } - count = Min(count, blockNumber) // Never search below block 1 - for { - snapshot := node.SnapshotAtBlock(blockNumber - visited) - visited += int64(len(snapshot.Recents)) - if count == 0 { - count = Min(blockNumber, int64(2*len(snapshot.Signers))) - } - for b, s := range snapshot.Recents { - if BytesToHex(s[:]) == signer { - found = int64(b) - return - } - } - if visited >= count { - return - } - } -} - -func (node *Node) SealerInfo(sealer string) (info SealerInfo, err error) { - info.Address = sealer - info.CurrentBlock = node.BlockNumber() - info.Since = node.SealerInception(sealer) - if info.Since == -1 { - return info, fmt.Errorf("%q is not a sealer", sealer) - } - info.FirstBlock = node.signerFirstBlock(sealer, info.Since+1, info.CurrentBlock) - info.LastBlock = node.signerLastBlock(sealer, info.FirstBlock, info.CurrentBlock) - return -} - func Dial(url string) (*Node, error) { client, err := rpc.Dial(url) return (*Node)(client), err