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

Cambio de presentación de la información sobre selladores

Agregada presentación de información de balance
Agregada información sobre el nodo
parent 81453a5e
No related branches found
No related tags found
No related merge requests found
...@@ -7,7 +7,9 @@ import ( ...@@ -7,7 +7,9 @@ import (
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/consensus/clique" "github.com/ethereum/go-ethereum/consensus/clique"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/p2p"
"github.com/ethereum/go-ethereum/rpc" "github.com/ethereum/go-ethereum/rpc"
"math/big"
"sort" "sort"
) )
...@@ -45,26 +47,61 @@ type SealerInfo struct { ...@@ -45,26 +47,61 @@ type SealerInfo struct {
} }
type SealerStatus struct { type SealerStatus struct {
LastBlock int64 `json:"lastBlockSigned"` LastBlock int64 `json:"lastBlockSigned"`
Time uint64 `json:"timestamp"` Time uint64 `json:"timestamp"`
Difficulty uint64 `json:"difficulty"` Difficulty uint64 `json:"difficulty"`
Balance *big.Int `json:"balance"`
} }
const ( const (
Latest = "latest" Latest = "latest"
Self = "self" Self = "self"
Network = 47525974938
Genesis = "0xe0e26f415af00fe32e1e8d94336355db43a78d9f59eb70910172b61fb670d99e"
) )
func (node *Node) Call(result interface{}, method string, args ...interface{}) { func (node *Node) Call(result interface{}, method string, args ...interface{}) {
Check((*rpc.Client)(node).Call(result, method, args...)) Check((*rpc.Client)(node).Call(result, method, args...))
} }
func (node *Node) blockNumber() int64 { func (node *Node) BlockNumber() int64 {
var bn rpc.BlockNumber var bn rpc.BlockNumber
node.Call(&bn, "eth_blockNumber") node.Call(&bn, "eth_blockNumber")
return bn.Int64() return bn.Int64()
} }
func (node *Node) Accounts() (accounts []string) {
node.Call(&accounts, "eth_accounts")
return
}
func (node *Node) IsMining() (mining bool) {
node.Call(&mining, "eth_mining")
return
}
func (node *Node) PeerCount() (peerCount int64) {
node.Call(&peerCount, "net_peerCount")
return
}
func (node *Node) BalanceAtBlock(account string, blockNumber int64) *big.Int {
var (
balance string
block = Latest
)
if blockNumber >= 0 {
block = Int64ToHex(blockNumber)
}
node.Call(&balance, "eth_getBalance", account, block)
n, _ := new(big.Int).SetString(balance, 0)
return n
}
func (node *Node) Balance(account string) *big.Int {
return node.BalanceAtBlock(account, -1)
}
func (node *Node) Coinbase() (coinbase string, err error) { func (node *Node) Coinbase() (coinbase string, err error) {
defer func() { defer func() {
if e := recover(); e != nil { if e := recover(); e != nil {
...@@ -84,7 +121,7 @@ func (node *Node) Coinbase() (coinbase string, err error) { ...@@ -84,7 +121,7 @@ func (node *Node) Coinbase() (coinbase string, err error) {
return return
} }
func (node *Node) GetBlockByNumber(blockNumber int64) types.Header { func (node *Node) BlockByNumber(blockNumber int64) types.Header {
var ( var (
number string number string
resp types.Header resp types.Header
...@@ -98,8 +135,8 @@ func (node *Node) GetBlockByNumber(blockNumber int64) types.Header { ...@@ -98,8 +135,8 @@ func (node *Node) GetBlockByNumber(blockNumber int64) types.Header {
return resp return resp
} }
func (node *Node) GetBlockSigner(blockNumber int64) (signer string) { func (node *Node) BlockSigner(blockNumber int64) (signer string) {
header := node.GetBlockByNumber(blockNumber) header := node.BlockByNumber(blockNumber)
signer, err := GetSigner(&header) signer, err := GetSigner(&header)
Check(err) Check(err)
return return
...@@ -110,12 +147,12 @@ func (node *Node) GetSnapshot() (snapshot Snapshot) { ...@@ -110,12 +147,12 @@ func (node *Node) GetSnapshot() (snapshot Snapshot) {
return return
} }
func (node *Node) GetSnapshotAtHash(hash common.Hash) (snapshot Snapshot) { func (node *Node) SnapshotAtHash(hash common.Hash) (snapshot Snapshot) {
node.Call(&snapshot, "clique_getSnapshotAtHash", hash) node.Call(&snapshot, "clique_getSnapshotAtHash", hash)
return return
} }
func (node *Node) GetSnapshotAtBlock(blockNumber int64) (snapshot Snapshot) { func (node *Node) SnapshotAtBlock(blockNumber int64) (snapshot Snapshot) {
if blockNumber < 0 { if blockNumber < 0 {
return node.GetSnapshot() return node.GetSnapshot()
} }
...@@ -123,7 +160,7 @@ func (node *Node) GetSnapshotAtBlock(blockNumber int64) (snapshot Snapshot) { ...@@ -123,7 +160,7 @@ func (node *Node) GetSnapshotAtBlock(blockNumber int64) (snapshot Snapshot) {
return return
} }
func (node *Node) GetSigners() (signers []string) { func (node *Node) Sealers() (signers []string) {
var s []common.Address var s []common.Address
node.Call(&s, "clique_getSigners", nil) node.Call(&s, "clique_getSigners", nil)
for _, signer := range s { for _, signer := range s {
...@@ -132,7 +169,12 @@ func (node *Node) GetSigners() (signers []string) { ...@@ -132,7 +169,12 @@ func (node *Node) GetSigners() (signers []string) {
return return
} }
func (node *Node) GetSignersAtHash(hash common.Hash) (signers []string) { func (node *Node) NodeInfo() (nodeInfo p2p.NodeInfo) {
node.Call(&nodeInfo, "admin_nodeInfo", nil)
return
}
func (node *Node) SealersAtHash(hash common.Hash) (signers []string) {
var s []common.Address var s []common.Address
node.Call(&signers, "clique_getSignersAtHash", hash) node.Call(&signers, "clique_getSignersAtHash", hash)
for _, signer := range s { for _, signer := range s {
...@@ -141,10 +183,10 @@ func (node *Node) GetSignersAtHash(hash common.Hash) (signers []string) { ...@@ -141,10 +183,10 @@ func (node *Node) GetSignersAtHash(hash common.Hash) (signers []string) {
return return
} }
func (node *Node) GetSignersAtBlock(blockNumber int64) (signers []string) { func (node *Node) SealersAtBlock(blockNumber int64) (signers []string) {
var s []common.Address var s []common.Address
if blockNumber < 0 { if blockNumber < 0 {
return node.GetSigners() return node.Sealers()
} }
node.Call(&s, "clique_getSigners", Int64ToHex(blockNumber)) node.Call(&s, "clique_getSigners", Int64ToHex(blockNumber))
for _, signer := range s { for _, signer := range s {
...@@ -160,7 +202,7 @@ func (node *Node) IsSealer(address string) bool { ...@@ -160,7 +202,7 @@ func (node *Node) IsSealer(address string) bool {
return false return false
} }
} }
return Contains(node.GetSigners(), address) return Contains(node.Sealers(), address)
} }
func (node *Node) Propose(address string, vote bool) { func (node *Node) Propose(address string, vote bool) {
...@@ -168,14 +210,14 @@ func (node *Node) Propose(address string, vote bool) { ...@@ -168,14 +210,14 @@ func (node *Node) Propose(address string, vote bool) {
return return
} }
func (node *Node) GetVotes(blockNumber int64) (votes Proposals) { func (node *Node) Votes(blockNumber int64) (votes Proposals) {
var ( var (
snapshot Snapshot snapshot Snapshot
) )
if blockNumber < 0 { if blockNumber < 0 {
snapshot = node.GetSnapshot() snapshot = node.GetSnapshot()
} else { } else {
snapshot = node.GetSnapshotAtBlock(blockNumber) snapshot = node.SnapshotAtBlock(blockNumber)
} }
votes.BlockNumber = int64(snapshot.Number) votes.BlockNumber = int64(snapshot.Number)
for signer := range snapshot.Signers { for signer := range snapshot.Signers {
...@@ -213,11 +255,13 @@ func (node *Node) SealersStatus(blockNumber int64) (status map[string]*SealerSta ...@@ -213,11 +255,13 @@ func (node *Node) SealersStatus(blockNumber int64) (status map[string]*SealerSta
return return
} }
status = make(map[string]*SealerStatus) status = make(map[string]*SealerStatus)
for _, address := range node.GetSignersAtBlock(blockNumber) { for _, address := range node.SealersAtBlock(blockNumber) {
status[address] = &SealerStatus{} status[address] = &SealerStatus{
Balance: node.BalanceAtBlock(address, blockNumber),
}
} }
notSeen := int64(len(status)) notSeen := int64(len(status))
block := node.GetBlockByNumber(blockNumber) block := node.BlockByNumber(blockNumber)
blockNumber = block.Number.Int64() blockNumber = block.Number.Int64()
until := Max(1, blockNumber-5*notSeen) until := Max(1, blockNumber-5*notSeen)
for notSeen > 0 { for notSeen > 0 {
...@@ -232,21 +276,21 @@ func (node *Node) SealersStatus(blockNumber int64) (status map[string]*SealerSta ...@@ -232,21 +276,21 @@ func (node *Node) SealersStatus(blockNumber int64) (status map[string]*SealerSta
break break
} }
blockNumber-- blockNumber--
block = node.GetBlockByNumber(blockNumber) block = node.BlockByNumber(blockNumber)
} }
return status return status
} }
func (node *Node) GetSealerInception(address string) (since int64) { func (node *Node) SealerInception(address string) (since int64) {
if signers := node.GetSigners(); !Contains(signers, address) { if signers := node.Sealers(); !Contains(signers, address) {
return -1 return -1
} }
lo := int64(0) lo := int64(0)
hi := node.blockNumber() hi := node.BlockNumber()
for lo < hi { for lo < hi {
mid := lo + (hi-lo)/2 mid := lo + (hi-lo)/2
signers := node.GetSignersAtBlock(mid) signers := node.SealersAtBlock(mid)
if Contains(signers, address) { if Contains(signers, address) {
hi = mid hi = mid
} else { } else {
...@@ -256,11 +300,11 @@ func (node *Node) GetSealerInception(address string) (since int64) { ...@@ -256,11 +300,11 @@ func (node *Node) GetSealerInception(address string) (since int64) {
return hi return hi
} }
func (node *Node) getSignerFirstBlock(signer string, since int64, until int64) (blockNumber int64) { func (node *Node) signerFirstBlock(signer string, since int64, until int64) (blockNumber int64) {
if since < 0 { if since < 0 {
return -1 return -1
} }
//snapshot := node.GetSnapshotAtBlock(since) //snapshot := node.SnapshotAtBlock(since)
var ( var (
count int64 = 20 count int64 = 20
found int64 = -1 found int64 = -1
...@@ -320,7 +364,7 @@ func (node *Node) getSignerFirstBlock(signer string, since int64, until int64) ( ...@@ -320,7 +364,7 @@ func (node *Node) getSignerFirstBlock(signer string, since int64, until int64) (
} }
} }
func (node *Node) getSignerLastBlock(signer string, since int64, until int64) (blockNumber int64) { func (node *Node) signerLastBlock(signer string, since int64, until int64) (blockNumber int64) {
if since < 0 { if since < 0 {
return -1 return -1
} }
...@@ -390,7 +434,7 @@ func (node *Node) searchSnapshotForward(blockNumber int64, signer string, count ...@@ -390,7 +434,7 @@ func (node *Node) searchSnapshotForward(blockNumber int64, signer string, count
return return
} }
for count > 0 { for count > 0 {
snapshot := node.GetSnapshotAtBlock(blockNumber + count - 1) snapshot := node.SnapshotAtBlock(blockNumber + count - 1)
recents := int64(len(snapshot.Recents)) recents := int64(len(snapshot.Recents))
visited += recents visited += recents
count -= recents count -= recents
...@@ -410,7 +454,7 @@ func (node *Node) searchSnapshotBackward(blockNumber int64, signer string, count ...@@ -410,7 +454,7 @@ func (node *Node) searchSnapshotBackward(blockNumber int64, signer string, count
} }
count = Min(count, blockNumber) // Never search below block 1 count = Min(count, blockNumber) // Never search below block 1
for { for {
snapshot := node.GetSnapshotAtBlock(blockNumber - visited) snapshot := node.SnapshotAtBlock(blockNumber - visited)
visited += int64(len(snapshot.Recents)) visited += int64(len(snapshot.Recents))
if count == 0 { if count == 0 {
count = Min(blockNumber, int64(2*len(snapshot.Signers))) count = Min(blockNumber, int64(2*len(snapshot.Signers)))
...@@ -429,13 +473,13 @@ func (node *Node) searchSnapshotBackward(blockNumber int64, signer string, count ...@@ -429,13 +473,13 @@ func (node *Node) searchSnapshotBackward(blockNumber int64, signer string, count
func (node *Node) SealerInfo(sealer string) (info SealerInfo, err error) { func (node *Node) SealerInfo(sealer string) (info SealerInfo, err error) {
info.Address = sealer info.Address = sealer
info.CurrentBlock = node.blockNumber() info.CurrentBlock = node.BlockNumber()
info.Since = node.GetSealerInception(sealer) info.Since = node.SealerInception(sealer)
if info.Since == -1 { if info.Since == -1 {
return info, fmt.Errorf("%q is not a sealer", sealer) return info, fmt.Errorf("%q is not a sealer", sealer)
} }
info.FirstBlock = node.getSignerFirstBlock(sealer, info.Since+1, info.CurrentBlock) info.FirstBlock = node.signerFirstBlock(sealer, info.Since+1, info.CurrentBlock)
info.LastBlock = node.getSignerLastBlock(sealer, info.FirstBlock, info.CurrentBlock) info.LastBlock = node.signerLastBlock(sealer, info.FirstBlock, info.CurrentBlock)
return return
} }
......
...@@ -6,6 +6,7 @@ import ( ...@@ -6,6 +6,7 @@ import (
"flag" "flag"
"fmt" "fmt"
"log" "log"
"math/big"
"os" "os"
"path" "path"
"sort" "sort"
...@@ -26,7 +27,7 @@ var ( ...@@ -26,7 +27,7 @@ var (
url string url string
json bool json bool
help bool help bool
flags flag.FlagSet flags = flag.NewFlagSet("", flag.ExitOnError)
command string command string
description string description string
otherArgs string otherArgs string
...@@ -83,7 +84,7 @@ func proposals() { ...@@ -83,7 +84,7 @@ func proposals() {
node, err := bfa.Dial(url) node, err := bfa.Dial(url)
util.Check(err) util.Check(err)
defer node.Close() defer node.Close()
votes := node.GetVotes(blockNumber) votes := node.Votes(blockNumber)
if json { if json {
util.PrintJson(votes) util.PrintJson(votes)
return return
...@@ -140,16 +141,21 @@ func parseFormatString(s string) (format string) { ...@@ -140,16 +141,21 @@ func parseFormatString(s string) (format string) {
func sealers() { func sealers() {
var ( var (
blockNumber int64 blockNumber int64
status bool lastBlock bool
timestamp bool timestamp bool
difficulty bool
balance bool
header bool
format string format string
length int64 = 10 // timestamp length
) )
description = "Presenta la lista de selladores. Opcionalmente indica el último bloque sellado por cada uno." description = "Presenta la lista de selladores. Opcionalmente indica el último bloque sellado por cada uno."
setFlags() setFlags()
flags.Int64Var(&blockNumber, "block-number", latest, "Número del bloque en el cual se quiere conocer la lista de selladores (-1 para el último)") flags.Int64Var(&blockNumber, "block-number", latest, "Número del bloque en el cual se quiere conocer la lista de selladores (-1 para el último)")
flags.BoolVar(&status, "status", false, "Indica el último bloque sellado por cada sellador, o 0 si un nodo no ha sellado en las últimas 5 rondas.") flags.BoolVar(&lastBlock, "last-block", false, "Muestra el último bloque sellado por cada sellador, o 0 si un nodo no ha sellado en las últimas 5 rondas.")
flags.BoolVar(&timestamp, "timestamp", false, "Muestra el timestamp del sellado en lugar del número de bloque.") flags.BoolVar(&timestamp, "timestamp", false, "Muestra el timestamp del sellado.")
flags.BoolVar(&difficulty, "difficulty", false, "Muestra la dificultad del sellado (1: fuera de turno, 2: en turno).")
flags.BoolVar(&balance, "balance", false, "Muestra el saldo del sellador (en Wei).")
flags.BoolVar(&header, "header", true, "Muestra un encabezado en cada columna.")
flags.StringVar(&format, "format", "", "Formato del timestamp. Ignorado en formato json. Opciones: 'unix', 'rfc3339', 'long' ('YYYY-MM-DD hh:mm:ss'), 'short' ('hh:mm:ss') o un formato específico. Ejemplo 'DD/MM/YY hh.mm.ss'. También se admite el formato del paquete 'time' de go.") flags.StringVar(&format, "format", "", "Formato del timestamp. Ignorado en formato json. Opciones: 'unix', 'rfc3339', 'long' ('YYYY-MM-DD hh:mm:ss'), 'short' ('hh:mm:ss') o un formato específico. Ejemplo 'DD/MM/YY hh.mm.ss'. También se admite el formato del paquete 'time' de go.")
parseFlags() parseFlags()
if blockNumber == 0 { if blockNumber == 0 {
...@@ -159,42 +165,80 @@ func sealers() { ...@@ -159,42 +165,80 @@ func sealers() {
node, err := bfa.Dial(url) node, err := bfa.Dial(url)
util.Check(err) util.Check(err)
defer node.Close() defer node.Close()
if status { extended := lastBlock || timestamp || difficulty || balance
if extended {
sealers := node.SealersStatus(blockNumber) sealers := node.SealersStatus(blockNumber)
if json { if json {
util.PrintJson(sealers) util.PrintJson(sealers)
return return
} }
var list []string var (
list []string
lastBlockLen int64
timestampLen int64
balanceLen int64
)
for sealer := range sealers { for sealer := range sealers {
list = append(list, sealer) list = append(list, sealer)
} }
sort.Slice(list, func(i, j int) bool { return sealers[list[i]].LastBlock > sealers[list[j]].LastBlock }) switch {
if !timestamp { case lastBlock:
sort.Slice(list, func(i, j int) bool { return sealers[list[i]].LastBlock > sealers[list[j]].LastBlock })
length = util.Max(2, int64(len(strconv.FormatInt(sealers[list[0]].LastBlock, 10)))) case timestamp:
} else { sort.Slice(list, func(i, j int) bool { return sealers[list[i]].Time > sealers[list[j]].Time })
case difficulty:
sort.Slice(list, func(i, j int) bool { return sealers[list[i]].Difficulty > sealers[list[j]].Difficulty })
case balance:
sort.Slice(list, func(i, j int) bool { return sealers[list[i]].Balance.Cmp(sealers[list[j]].Balance) > 0 })
}
formatStr := "%42v"
if lastBlock {
formatStr += " %[2]*[3]v"
lastBlockLen = util.Max(2, int64(len(strconv.FormatInt(sealers[list[0]].LastBlock, 10))))
}
if timestamp {
formatStr += " %[4]*[5]v"
if len(format) > 0 { if len(format) > 0 {
format = parseFormatString(format) format = parseFormatString(format)
length = int64(len(format)) timestampLen = int64(len(format))
} else {
timestampLen = 10
} }
} }
if difficulty {
formatStr += " %2[6]v"
}
if balance {
formatStr += " %[7]*[8]v"
balanceLen = 0
for _, s := range sealers {
balanceLen = util.Max(balanceLen, int64(len(s.Balance.String())))
}
}
formatStr += "\n"
if header {
fmt.Printf(formatStr,
fmt.Sprintf("%-24v", "Sealer"),
lastBlockLen, fmt.Sprintf("%*v", -lastBlockLen/2-2, "Last"),
timestampLen, fmt.Sprintf("%*v", -timestampLen/2-2, "Time"),
"Dif",
balanceLen, fmt.Sprintf("%*v", -balanceLen/2-4, "Balance"))
}
for _, sealer := range list { for _, sealer := range list {
var output interface{} var formatedTimestamp interface{}
s := sealers[sealer]
if timestamp { if timestamp {
t := int64(sealers[sealer].Time) t := int64(s.Time)
if len(format) > 0 && t > 0 { if len(format) > 0 && t > 0 {
output = time.Unix(t, 0).Format(format) formatedTimestamp = time.Unix(t, 0).Format(format)
} else { } else {
output = t formatedTimestamp = t
} }
} else {
output = sealers[sealer].LastBlock
} }
fmt.Printf("%v: %*v\n", sealer, length, output) fmt.Printf(formatStr, sealer, lastBlockLen, s.LastBlock, timestampLen, formatedTimestamp, s.Difficulty, balanceLen, s.Balance)
} }
} else { } else {
sealers := node.GetSignersAtBlock(blockNumber) sealers := node.SealersAtBlock(blockNumber)
sort.Slice(sealers, func(i, j int) bool { return sealers[i] < sealers[j] }) sort.Slice(sealers, func(i, j int) bool { return sealers[i] < sealers[j] })
if json { if json {
util.PrintJson(sealers) util.PrintJson(sealers)
...@@ -226,8 +270,8 @@ func autovote() { ...@@ -226,8 +270,8 @@ func autovote() {
util.Check(err) util.Check(err)
defer node.Close() defer node.Close()
util.PanicIf(!node.IsSealer(bfa.Self), "Solo los selladores pueden votar") util.PanicIf(!node.IsSealer(bfa.Self), "Solo los selladores pueden votar")
votes := node.GetVotes(latest) votes := node.Votes(latest)
genesisSigners := node.GetSignersAtBlock(0) genesisSigners := node.SealersAtBlock(0)
self, err := node.Coinbase() self, err := node.Coinbase()
util.Check(err) util.Check(err)
for _, tally := range votes.Tally { for _, tally := range votes.Tally {
...@@ -279,7 +323,7 @@ func propose() { ...@@ -279,7 +323,7 @@ func propose() {
util.Check(err) util.Check(err)
defer node.Close() defer node.Close()
util.PanicIf(!node.IsSealer(bfa.Self), "Solo los selladores pueden votar") util.PanicIf(!node.IsSealer(bfa.Self), "Solo los selladores pueden votar")
votes := node.GetVotes(latest) votes := node.Votes(latest)
if flags.NArg() == 0 { if flags.NArg() == 0 {
panic("No se especificaron candidatos por los cuales votar") panic("No se especificaron candidatos por los cuales votar")
} }
...@@ -310,6 +354,45 @@ func propose() { ...@@ -310,6 +354,45 @@ func propose() {
} }
} }
func status() {
nodeStatus := struct {
Enode string `json:"enode"`
Network uint64 `json:"network"`
Genesis string `json:"genesis"`
BFANetwork bool `json:"bfaNetwork"`
BFAGenesis bool `json:"bfaGenesis"`
Accounts map[string]*big.Int `json:"accounts"`
Coinbase string `json:"coinbase"`
IsSealer bool `json:"isSealer"`
IsMining bool `json:"isMining"`
BlockNumber int64 `json:"blockNumber"`
}{
Accounts: make(map[string]*big.Int),
}
description = "Muestra el estado del nodo."
setFlags()
parseFlags()
url = updateURL(url)
node, err := bfa.Dial(url)
util.Check(err)
defer node.Close()
for _, account := range node.Accounts() {
nodeStatus.Accounts[account] = node.Balance(account)
}
nodeStatus.Coinbase, _ = node.Coinbase()
nodeStatus.BlockNumber = node.BlockNumber()
nodeStatus.IsSealer = node.IsSealer(bfa.Self)
nodeStatus.IsMining = node.IsMining()
nodeInfo := node.NodeInfo()
nodeStatus.Enode = nodeInfo.Enode
ethInfo := nodeInfo.Protocols["eth"].(map[string]interface{})
nodeStatus.Genesis = ethInfo["genesis"].(string)
nodeStatus.Network = uint64(ethInfo["network"].(float64))
nodeStatus.BFAGenesis = nodeStatus.Genesis == bfa.Genesis
nodeStatus.BFANetwork = nodeStatus.Network == bfa.Network
util.PrintJson(nodeStatus)
}
func main() { func main() {
var ( var (
commands = map[string]func(){ commands = map[string]func(){
...@@ -317,6 +400,7 @@ func main() { ...@@ -317,6 +400,7 @@ func main() {
"sealers": sealers, "sealers": sealers,
"vote": propose, "vote": propose,
"autovote": autovote, "autovote": autovote,
"status": status,
} }
validCommands []string validCommands []string
) )
...@@ -326,7 +410,6 @@ func main() { ...@@ -326,7 +410,6 @@ func main() {
defer func() { defer func() {
if err := recover(); err != nil { if err := recover(); err != nil {
log.Printf("Error: %s", err) log.Printf("Error: %s", err)
usage(1)
} }
}() }()
if len(os.Args) > 1 { if len(os.Args) > 1 {
......
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