Skip to content
Snippets Groups Projects
Commit fd6f11a0 authored by Miguel Montes's avatar Miguel Montes
Browse files

Cambio de organización del código de bfa_client

parent 37d9680f
No related branches found
No related tags found
No related merge requests found
package bfa
import (
. "../util"
"fmt"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/consensus/clique"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/crypto/sha3"
"github.com/ethereum/go-ethereum/rlp"
"github.com/ethereum/go-ethereum/rpc"
"sort"
"strconv"
)
type Node rpc.Client
type Snapshot struct {
Number uint64 `json:"number"` // Block number where the snapshot was created
Hash common.Hash `json:"hash"` // Block hash where the snapshot was created
Signers map[common.Address]struct{} `json:"signers"` // Set of authorized signers at this moment
Recents map[uint64]common.Address `json:"recents"` // Set of recent signers for spam protections
Votes []*clique.Vote `json:"votes"` // List of votes cast in chronological order
Tally map[common.Address]clique.Tally `json:"tally"` // Current vote tally to avoid recalculating
}
type Tally struct {
True int `json:"true"`
False int `json:"false"`
Null int `json:"null"`
}
type Proposals struct {
BlockNumber int64 `json:"number"` // Block number where the snapshot was created
Proposals []string `json:"proposals"` // List of proposals being voted
Signers []string `json:"signers"` // List of authorized signers at this moment
Tally map[string]*Tally `json:"tally"` // Count of positive, negative and empty votes for a proposal
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
}
func sigHash(header *types.Header) (hash common.Hash) {
hasher := sha3.NewKeccak256()
rlp.Encode(hasher, []interface{}{
header.ParentHash,
header.UncleHash,
header.Coinbase,
header.Root,
header.TxHash,
header.ReceiptHash,
header.Bloom,
header.Difficulty,
header.Number,
header.GasLimit,
header.GasUsed,
header.Time,
header.Extra[:len(header.Extra)-65], // Yes, this will panic if extra is too short
header.MixDigest,
header.Nonce,
})
hasher.Sum(hash[:0])
return hash
}
func (node *Node) Call(result interface{}, method string, args ...interface{}) {
Check((*rpc.Client)(node).Call(result, method, args...))
}
func (node *Node) blockNumber() int64 {
var bn rpc.BlockNumber
node.Call(&bn, "eth_blockNumber")
return bn.Int64()
}
func (node *Node) GetBlockByNumber(blockNumber int64) types.Header {
var (
number string
resp types.Header
)
if blockNumber < 0 {
number = "latest"
} else {
number = fmt.Sprintf("0x%x", blockNumber)
}
node.Call(&resp, "eth_getBlockByNumber", number, false)
return resp
}
func getSigner(header *types.Header) (signer string, err error) {
signature := header.Extra[len(header.Extra)-65:]
hash := sigHash(header).Bytes()
pubkey, err := crypto.Ecrecover(hash, signature)
address := make([]byte, 20)
copy(address, crypto.Keccak256(pubkey[1:])[12:])
signer = ToHex(address)
return
}
func (node *Node) GetBlockSigner(blockNumber int64) (signer string) {
header := node.GetBlockByNumber(blockNumber)
signer, err := getSigner(&header)
Check(err)
return
}
func (node *Node) GetSnapshot() (snapshot Snapshot) {
node.Call(&snapshot, "clique_getSnapshot", nil)
return
}
func (node *Node) GetSnapshotAtHash(hash common.Hash) (snapshot Snapshot) {
node.Call(&snapshot, "clique_getSnapshotAtHash", hash)
return
}
func (node *Node) GetSnapshotAtBlock(blockNumber int64) (snapshot Snapshot) {
node.Call(&snapshot, "clique_getSnapshot", fmt.Sprintf("0x%x", blockNumber))
return
}
func (node *Node) GetSigners() (signers []string) {
var s []common.Address
node.Call(&s, "clique_getSigners", nil)
for _, signer := range s {
signers = append(signers, ToHex(signer.Bytes()))
}
return
}
func (node *Node) GetSignersAtHash(hash common.Hash) (signers []string) {
var s []common.Address
node.Call(&signers, "clique_getSignersAtHash", hash)
for _, signer := range s {
signers = append(signers, ToHex(signer.Bytes()))
}
return
}
func (node *Node) GetSignersAtBlock(blockNumber int64) (signers []string) {
var s []common.Address
node.Call(&s, "clique_getSigners", "0x"+strconv.FormatInt(blockNumber, 16))
for _, signer := range s {
signers = append(signers, ToHex(signer.Bytes()))
}
return
}
func (node *Node) GetVotes(blockNumber int64) (votes Proposals) {
var (
snapshot Snapshot
)
if blockNumber < 0 {
snapshot = node.GetSnapshot()
} else {
snapshot = node.GetSnapshotAtBlock(blockNumber)
}
votes.BlockNumber = int64(snapshot.Number)
for signer := range snapshot.Signers {
votes.Signers = append(votes.Signers, ToHex(signer[:]))
sort.Strings(votes.Signers)
}
for proposal := range snapshot.Tally {
votes.Proposals = append(votes.Proposals, ToHex(proposal[:]))
}
votes.Votes = make(map[string]map[string]*bool)
votes.Tally = make(map[string]*Tally)
for _, v := range snapshot.Votes {
proposal := ToHex(v.Address[:])
signer := ToHex(v.Signer[:])
if votes.Votes[proposal] == nil {
votes.Votes[proposal] = make(map[string]*bool)
for _, signer := range votes.Signers {
votes.Votes[proposal][signer] = nil
}
votes.Tally[proposal] = &Tally{0, 0, len(votes.Signers)}
}
votes.Votes[proposal][signer] = &v.Authorize
if v.Authorize {
votes.Tally[proposal].True += 1
} else {
votes.Tally[proposal].False += 1
}
votes.Tally[proposal].Null -= 1
}
return
}
func (node *Node) SealersStatus() map[string]int64 {
status := make(map[string]int64)
for _, address := range node.GetSigners() {
status[address] = -1
}
notSeen := int64(len(status))
block := node.GetBlockByNumber(-1)
blockNumber := block.Number.Int64()
until := blockNumber - 5*notSeen
for notSeen > 0 {
signer, _ := getSigner(&block)
if status[signer] == -1 {
status[signer] = block.Number.Int64()
notSeen--
}
if blockNumber == until {
break
}
blockNumber--
block = node.GetBlockByNumber(blockNumber)
}
return status
}
func (node *Node) GetSealerInception(address string) (since int64) {
if signers := node.GetSigners(); !Contains(signers, address) {
return -1
}
lo := int64(0)
hi := node.blockNumber()
for lo < hi {
mid := lo + (hi-lo)/2
signers := node.GetSignersAtBlock(mid)
if Contains(signers, address) {
hi = mid
} else {
lo = mid + 1
}
}
return hi
}
func (node *Node) getSignerFirstBlock(signer string, since int64, until int64) (blockNumber int64) {
if since < 0 {
return -1
}
//snapshot := node.GetSnapshotAtBlock(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) getSignerLastBlock(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) {
//printDebug("In",fmt.Sprintf("(%v, %v, %v)", blockNumber, signer, count))
//defer printDebug("Out", "")
found = -1
if blockNumber+count < 1 {
return
}
for count > 0 {
snapshot := node.GetSnapshotAtBlock(blockNumber + count - 1)
recents := int64(len(snapshot.Recents))
visited += recents
count -= recents
for b, s := range snapshot.Recents {
if ToHex(s[:]) == signer {
found = int64(b)
}
}
}
return
}
func (node *Node) searchSnapshotBackward(blockNumber int64, signer string, count int64) (found int64, visited int64) {
//printDebug("In",fmt.Sprintf("(%v, %v, %v)", blockNumber, signer, count))
//defer printDebug("Out", "")
found = -1
if blockNumber < 1 { // Genesis block has no signers
return
}
count = Min(count, blockNumber) // Never search below block 1
for {
snapshot := node.GetSnapshotAtBlock(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 ToHex(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.GetSealerInception(sealer)
if info.Since == -1 {
return info, fmt.Errorf("%q is not a sealer", sealer)
}
info.FirstBlock = node.getSignerFirstBlock(sealer, info.Since+1, info.CurrentBlock)
info.LastBlock = node.getSignerLastBlock(sealer, info.FirstBlock, info.CurrentBlock)
return
}
func Dial(url string) *Node {
client, err := rpc.Dial(url)
Check(err)
return (*Node)(client)
}
func (node *Node) Close() {
(*rpc.Client)(node).Close()
}
...@@ -4,461 +4,27 @@ import ( ...@@ -4,461 +4,27 @@ import (
"encoding/json" "encoding/json"
"flag" "flag"
"fmt" "fmt"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/consensus/clique"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/crypto/sha3"
"github.com/ethereum/go-ethereum/rlp"
"github.com/ethereum/go-ethereum/rpc"
"log" "log"
"os" "os"
"path" "path"
"runtime"
"sort" "sort"
"strconv" "strconv"
"strings" "strings"
"../util"
"../bfa"
) )
const ( const (
DefaultURL = "http://localhost:8545" DefaultURL = "http://localhost:8545"
) )
type Node rpc.Client type Node = bfa.Node
func toHex(b []byte) string { func printVotes(node *bfa.Node, useJson bool) {
return fmt.Sprintf("0x%02x", b) votes := node.GetVotes(-1)
}
func (node *Node) blockNumber() int64 {
var bn rpc.BlockNumber
node.Call(&bn, "eth_blockNumber")
return bn.Int64()
}
func check(err error) {
if err != nil {
panic(err.Error())
}
}
func (node *Node) Call(result interface{}, method string, args ...interface{}) {
check((*rpc.Client)(node).Call(result, method, args...))
}
func (node *Node) getBlockByNumber(blockNumber int64) types.Header {
var (
number string
resp types.Header
)
if blockNumber < 0 {
number = "latest"
} else {
number = fmt.Sprintf("0x%x", blockNumber)
}
node.Call(&resp, "eth_getBlockByNumber", number, false)
return resp
}
func getSigner(header *types.Header) (signer string, err error) {
signature := header.Extra[len(header.Extra)-65:]
hash := sigHash(header).Bytes()
pubkey, err := crypto.Ecrecover(hash, signature)
address := make([]byte, 20)
copy(address, crypto.Keccak256(pubkey[1:])[12:])
signer = toHex(address)
return
}
func (node *Node) getBlockSigner(blockNumber int64) (signer string) {
header := node.getBlockByNumber(blockNumber)
signer, err := getSigner(&header)
check(err)
return
}
type Snapshot struct {
Number uint64 `json:"number"` // Block number where the snapshot was created
Hash common.Hash `json:"hash"` // Block hash where the snapshot was created
Signers map[common.Address]struct{} `json:"signers"` // Set of authorized signers at this moment
Recents map[uint64]common.Address `json:"recents"` // Set of recent signers for spam protections
Votes []*clique.Vote `json:"votes"` // List of votes cast in chronological order
Tally map[common.Address]clique.Tally `json:"tally"` // Current vote tally to avoid recalculating
}
type Tally struct {
True int `json:"true"`
False int `json:"false"`
Null int `json:"null"`
}
type Proposals struct {
BlockNumber int64 `json:"number"` // Block number where the snapshot was created
Proposals []string `json:"proposals"` // List of proposals being voted
Signers []string `json:"signers"` // List of authorized signers at this moment
Tally map[string]*Tally `json:"tally"` // Count of positive, negative and empty votes for a proposal
Votes map[string]map[string]*bool `json:"votes"` // List of votes for each proposal
}
func (node *Node) getSnapshot() (snapshot Snapshot) {
node.Call(&snapshot, "clique_getSnapshot", nil)
return
}
func (node *Node) getSnapshotAtHash(hash common.Hash) (snapshot Snapshot) {
node.Call(&snapshot, "clique_getSnapshotAtHash", hash)
return
}
func (node *Node) getSnapshotAtBlock(blockNumber int64) Snapshot {
block := node.getBlockByNumber(blockNumber)
return node.getSnapshotAtHash(block.Hash())
}
func (node *Node) getSigners() (signers []string) {
var s []common.Address
node.Call(&s, "clique_getSigners", nil)
for _, signer := range s {
signers = append(signers, toHex(signer.Bytes()))
}
return
}
func (node *Node) getSignersAtHash(hash common.Hash) (signers []string) {
var s []common.Address
node.Call(&signers, "clique_getSignersAtHash", hash)
for _, signer := range s {
signers = append(signers, toHex(signer.Bytes()))
}
return
}
func (node *Node) getSignersAtBlock(blockNumber int64) []string {
block := node.getBlockByNumber(blockNumber)
return node.getSignersAtHash(block.Hash())
}
func (node *Node) getVotes(blockNumber int64) (votes Proposals) {
var (
snapshot Snapshot
)
if blockNumber < 0 {
snapshot = node.getSnapshot()
} else {
snapshot = node.getSnapshotAtBlock(blockNumber)
}
votes.BlockNumber = int64(snapshot.Number)
for signer := range snapshot.Signers {
votes.Signers = append(votes.Signers, toHex(signer[:]))
sort.Strings(votes.Signers)
}
for proposal := range snapshot.Tally {
votes.Proposals = append(votes.Proposals, toHex(proposal[:]))
}
votes.Votes = make(map[string]map[string]*bool)
votes.Tally = make(map[string]*Tally)
for _, v := range snapshot.Votes {
proposal := toHex(v.Address[:])
signer := toHex(v.Signer[:])
if votes.Votes[proposal] == nil {
votes.Votes[proposal] = make(map[string]*bool)
for _, signer := range votes.Signers {
votes.Votes[proposal][signer] = nil
}
votes.Tally[proposal] = &Tally{0, 0, len(votes.Signers)}
}
votes.Votes[proposal][signer] = &v.Authorize
if v.Authorize {
votes.Tally[proposal].True += 1
} else {
votes.Tally[proposal].False += 1
}
votes.Tally[proposal].Null -= 1
}
return
}
func (node *Node) sealersStatus() map[string]int64 {
status := make(map[string]int64)
for _, address := range node.getSigners() {
status[address] = -1
}
notSeen := int64(len(status))
block := node.getBlockByNumber(-1)
blockNumber := block.Number.Int64()
until := blockNumber - 5*notSeen
for notSeen > 0 {
signer, _ := getSigner(&block)
if status[signer] == -1 {
status[signer] = block.Number.Int64()
notSeen--
}
if blockNumber == until {
break
}
blockNumber--
block = node.getBlockByNumber(blockNumber)
}
return status
}
func printDebug(msg string) {
ptr, _, _, _ := runtime.Caller(1)
fmt.Printf("%v: %v\n", msg, runtime.FuncForPC(ptr).Name())
}
func (node *Node) getSealerInception(address string) (since int64) {
if signers := node.getSigners(); !contains(signers, address) {
return -1
}
lo := int64(0)
hi := node.blockNumber()
for lo < hi {
mid := lo + (hi-lo)/2
signers := node.getSignersAtBlock(mid)
if contains(signers, address) {
hi = mid
} else {
lo = mid + 1
}
}
return hi
}
func min(a, b int64) int64 {
if a < b {
return a
}
return b
}
func (node *Node) getSignerFirstBlock(signer string, since int64, until int64) (blockNumber int64) {
if since < 0 {
return -1
}
//snapshot := node.getSnapshotAtBlock(since)
var count int64 = 20
// first, we look close to the inception
if blockNumber = node.searchSnapshotForward(since, signer, count); blockNumber > 0 {
return
}
since += count
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) getSignerFirstBlock_(signer string, since int64, until int64) (blockNumber int64) {
if since < 0 {
return -1
}
last := since
for i := since; ; {
snapshot := node.getSnapshotAtBlock(i)
n := int64(len(snapshot.Recents))
if int64(snapshot.Number)-n > last {
i--
continue
}
for b, s := range snapshot.Recents {
if toHex(s[:]) == signer {
return int64(b)
}
}
if i >= until {
return -1
}
last = i
i += n
}
}
func (node *Node) searchSnapshot(blockNumber int64, signer string, count int64, forward bool) (found int64) {
found = -1
for count > 0 {
snapshot := node.getSnapshotAtBlock(blockNumber + count - 1)
for b, s := range snapshot.Recents {
if toHex(s[:]) == signer {
found = int64(b)
if !forward {
return
}
}
}
count -= int64(len(snapshot.Recents))
}
return
}
func (node *Node) searchSnapshotForward(blockNumber int64, signer string, count int64) (found int64) {
found = -1
for count > 0 {
snapshot := node.getSnapshotAtBlock(blockNumber + count - 1)
for b, s := range snapshot.Recents {
if toHex(s[:]) == signer {
found = int64(b)
}
}
count -= int64(len(snapshot.Recents))
}
return
}
func (node *Node) searchSnapshotBackward(blockNumber int64, signer string, count int64) (found int64) {
found = -1
for i := int64(0); i < count; {
snapshot := node.getSnapshotAtBlock(blockNumber - i)
for b, s := range snapshot.Recents {
if toHex(s[:]) == signer {
return int64(b)
}
}
i += int64(len(snapshot.Recents))
}
return
}
func (node *Node) getSignerLastBlock(signer string, since int64, until int64) (blockNumber int64) {
if since < 0 {
return -1
}
var count int64 = 20
// first, we look close to the last block
if blockNumber = node.searchSnapshotBackward(until, signer, count); blockNumber > 0 {
return
}
until -= count
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 <- since:
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) getSignerLastBlock__(signer string, since int64, until int64) (blockNumber int64) {
if since < 0 {
return -1
}
for i := until; i >= since; {
snapshot := node.getSnapshotAtBlock(i)
for b, s := range snapshot.Recents {
if toHex(s[:]) == signer {
return int64(b)
}
}
i -= int64(len(snapshot.Recents))
}
return -1
}
func (node *Node) getSignerLastBlock_(signer string, since int64, until int64) (blockNumber int64) {
if since < 0 {
return -1
}
for i := until; i >= since; i-- {
if signer == node.getBlockSigner(i) {
return i
}
}
return -1
}
type SealerInfo struct {
Address string
CurrentBlock int64
Since int64
FirstBlock int64
LastBlock int64
}
func (node *Node) sealerInfo(sealer string) (info SealerInfo, err error) {
info.Address = sealer
info.CurrentBlock = node.blockNumber()
info.Since = node.getSealerInception(sealer)
if info.Since == -1 {
return info, fmt.Errorf("%q is not a sealer", sealer)
}
info.FirstBlock = node.getSignerFirstBlock(sealer, info.Since + 1, info.CurrentBlock)
info.LastBlock = node.getSignerLastBlock(sealer, info.FirstBlock, info.CurrentBlock)
return
}
func printVotes(node *Node, useJson bool) {
votes := node.getVotes(-1)
if useJson { if useJson {
v, err := json.MarshalIndent(votes, "", " ") v, err := json.MarshalIndent(votes, "", " ")
check(err) util.Check(err)
fmt.Println(string(v)) fmt.Println(string(v))
return return
} }
...@@ -481,18 +47,18 @@ func printVotes(node *Node, useJson bool) { ...@@ -481,18 +47,18 @@ func printVotes(node *Node, useJson bool) {
} }
func printSealerInfo(node *Node, sealer string) { func printSealerInfo(node *Node, sealer string) {
info, err := node.sealerInfo(sealer) info, err := node.SealerInfo(sealer)
check(err) util.Check(err)
v, err := json.MarshalIndent(info, "", " ") v, err := json.MarshalIndent(info, "", " ")
check(err) util.Check(err)
fmt.Println(string(v)) fmt.Println(string(v))
} }
func printSealers(node *Node, useJson bool) { func printSealers(node *Node, useJson bool) {
sealers := node.sealersStatus() sealers := node.SealersStatus()
if useJson { if useJson {
v, err := json.MarshalIndent(sealers, "", " ") v, err := json.MarshalIndent(sealers, "", " ")
check(err) util.Check(err)
fmt.Println(string(v)) fmt.Println(string(v))
return return
} }
...@@ -507,48 +73,6 @@ func printSealers(node *Node, useJson bool) { ...@@ -507,48 +73,6 @@ func printSealers(node *Node, useJson bool) {
} }
} }
func sigHash(header *types.Header) (hash common.Hash) {
hasher := sha3.NewKeccak256()
rlp.Encode(hasher, []interface{}{
header.ParentHash,
header.UncleHash,
header.Coinbase,
header.Root,
header.TxHash,
header.ReceiptHash,
header.Bloom,
header.Difficulty,
header.Number,
header.GasLimit,
header.GasUsed,
header.Time,
header.Extra[:len(header.Extra)-65], // Yes, this will panic if extra is too short
header.MixDigest,
header.Nonce,
})
hasher.Sum(hash[:0])
return hash
}
func Dial(url string) *Node {
client, err := rpc.Dial(url)
check(err)
return (*Node)(client)
}
func (node *Node) Close() {
(*rpc.Client)(node).Close()
}
func contains(slice []string, s string) bool {
for _, x := range slice {
if x == s {
return true
}
}
return false
}
func main() { func main() {
var ( var (
...@@ -572,7 +96,7 @@ func main() { ...@@ -572,7 +96,7 @@ func main() {
if len(os.Args) > 1 { if len(os.Args) > 1 {
command = os.Args[1] command = os.Args[1]
} }
if !contains(commands, command) { if !util.Contains(commands, command) {
fmt.Fprintf(os.Stderr, "Uso: %v <%v> [opciones]\n", path.Base(os.Args[0]), strings.Join(commands, "|")) fmt.Fprintf(os.Stderr, "Uso: %v <%v> [opciones]\n", path.Base(os.Args[0]), strings.Join(commands, "|"))
fmt.Fprintf(os.Stderr, "For help: %v <command> -h\n", path.Base(os.Args[0])) fmt.Fprintf(os.Stderr, "For help: %v <command> -h\n", path.Base(os.Args[0]))
os.Exit(1) os.Exit(1)
...@@ -587,7 +111,7 @@ func main() { ...@@ -587,7 +111,7 @@ func main() {
flags.PrintDefaults() flags.PrintDefaults()
return return
} }
node := Dial(url) node := bfa.Dial(url)
defer node.Close() defer node.Close()
switch command { switch command {
case "sealers": case "sealers":
......
package util
import (
"fmt"
"runtime"
)
func Contains(slice []string, s string) bool {
for _, x := range slice {
if x == s {
return true
}
}
return false
}
func Check(err error) {
if err != nil {
panic(err.Error())
}
}
func ToHex(b []byte) string {
return fmt.Sprintf("0x%02x", b)
}
func PrintDebug(prefix, suffix string) {
ptr, _, _, _ := runtime.Caller(1)
fmt.Printf("%v: %v%v\n", prefix, runtime.FuncForPC(ptr).Name(), suffix)
}
func Min(a, b int64) int64 {
if a < b {
return a
}
return b
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment