"locale/en/git@gitlab.bfa.ar:pkumagae/TsaAPI.git" did not exist on "19a86db04577d087cc4ba616233e89e8c74dddaf"
Newer
Older
"flag"
"fmt"
"log"
"os"
"path"
"sort"
"strconv"
"strings"
var (
url string
json bool
help bool
flags flag.FlagSet
command string
description string
)
func setFlags() {
flags.BoolVar(&json, "json", false, "Produce salida en formato json")
flags.StringVar(&url, "url", "", "URL para conexión con geth. Ejemplo: '/home/bfa/bfa/network/node/geth.ipc' o 'http://localhost:8545'")
flags.BoolVar(&help, "h", false, "")
flags.BoolVar(&help, "help", false, "Muestra esta ayuda")
}
func updateURL(url string) (updated string) {
const (
defaultIPC = "/home/bfa/bfa/network/node/geth.ipc"
defaultHTTP = "http://localhost:8545"
)
if url != "" { // We accept the user selected URL
}
// First, we try IPC
updated = defaultIPC
if bfaNetworkDir := os.Getenv("BFANETWORKDIR"); bfaNetworkDir != "" {
updated = bfaNetworkDir + "/node/get.ipc"
}
if fileInfo, err := os.Stat(updated); err == nil && (fileInfo.Mode()&os.ModeSocket) != 0 {
return
}
updated = defaultHTTP
return
}
func usage(errorCode int) {
fmt.Fprintf(os.Stderr, "Uso: %v %v [opciones] %v\n%v\n", os.Args[0], command, otherArgs, description)
flags.PrintDefaults()
os.Exit(errorCode)
}
func parseFlags() {
flags.Parse(os.Args[2:])
if help {
usage(0)
}
}
func proposals() {
var blockNumber int64
description = "Detalla el estado de las votaciones en curso"
setFlags()
flags.Int64Var(&blockNumber, "block-number", latest, "Número del bloque en el cual se quiere conocer el estado de la propuesta (-1 para el último)")
parseFlags()
url = updateURL(url)
node, err := bfa.Dial(url)
util.Check(err)
defer node.Close()
votes := node.GetVotes(blockNumber)
if json {
util.PrintJson(votes)
return
}
fmt.Printf("Bloque: %d\nPropuestas en curso: %d\n", votes.BlockNumber, len(votes.Proposals))
for _, proposal := range votes.Proposals {
fmt.Printf("Propuesta: %v\n", proposal)
for _, signer := range votes.Signers {
b := votes.Votes[proposal][signer]
var v string
if b == nil {
v = ""
} else {
v = strconv.FormatBool(*b)
}
fmt.Printf("\t%v: %v\n", signer, v)
}
tally := votes.Tally[proposal]
fmt.Printf("A favor: %v, en contra: %v, no votaron: %v\n", tally.True, tally.False, tally.Null)
}
}
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
func parseFormatString(s string) (format string) {
replacements := []struct {
old string
new string
}{
{"YYYY", "2006"},
{"YYY", "006"},
{"YY", "06"},
{"MM", "01"},
{"DD", "02"},
{"hh", "15"},
{"mm", "04"},
{"ss", "05"},
}
switch s {
case "long":
return "2006-01-02 15:04:05"
case "short":
return "15:04:05"
case "unix":
return time.UnixDate
case "rfc3339":
return time.RFC3339
}
format = s
for _, repl := range replacements {
format = strings.Replace(format, repl.old, repl.new, 1)
}
return
}
func sealers() {
var (
blockNumber int64
status bool
length int64 = 10 // timestamp length
)
description = "Presenta la lista de selladores. Opcionalmente indica el último bloque sellado por cada uno."
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.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(×tamp, "timestamp", false, "Muestra el timestamp del sellado en lugar del número de bloque.")
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.")
panic("El bloque génesis no tiene firmantes")
}
url = updateURL(url)
defer node.Close()
if status {
sealers := node.SealersStatus(blockNumber)
if json {
util.PrintJson(sealers)
return
}
var list []string
for sealer := range sealers {
list = append(list, sealer)
}
sort.Slice(list, func(i, j int) bool { return sealers[list[i]].LastBlock > sealers[list[j]].LastBlock })
if !timestamp {
length = util.Max(2, int64(len(strconv.FormatInt(sealers[list[0]].LastBlock, 10))))
} else {
if len(format) > 0 {
format = parseFormatString(format)
length = int64(len(format))
}
var output interface{}
if timestamp {
t := int64(sealers[sealer].Time)
if len(format) > 0 && t > 0 {
output = time.Unix(t, 0).Format(format)
} else {
output = t
}
} else {
output = sealers[sealer].LastBlock
}
fmt.Printf("%v: %*v\n", sealer, length, output)
}
} else {
sealers := node.GetSignersAtBlock(blockNumber)
sort.Slice(sealers, func(i, j int) bool { return sealers[i] < sealers[j] })
if json {
util.PrintJson(sealers)
} else {
for _, sealer := range sealers {
fmt.Println(sealer)
}
}
}
proposals []string
)
description = "Vota por una propuesta."
flags.BoolVar(&auto, "auto", false, "Vota en todas las propuestas activas, en el sentido que corresponda.")
flags.BoolVar(&authorize, "authorize", true, "Sentido del voto (true: a favor, false: en contra).")
parseFlags()
url = updateURL(url)
node, err := bfa.Dial(url)
util.Check(err)
defer node.Close()
genesisSigners := node.GetSignersAtBlock(0)
util.PanicIf(!node.IsSealer(bfa.Self), "Solo los selladores pueden votar")
votes := node.GetVotes(latest)
if auto {
util.PanicIf(util.Contains(genesisSigners, proposal) && node.IsSealer(proposal), "No se puede quitar en forma automática a un sellador del bloque génesis.")
proposals = append(proposals, proposal)
}
fmt.Fprintf(os.Stderr, "Se especificó -auto. Ignorando argumentos adicionales.")
if flags.NArg() == 0 {
panic("No se especificaron candidatos por los cuales votar")
}
panic(fmt.Sprintf("'%v' no es una dirección válida", address))
}
if _, ok := votes.Tally[address]; ok {
continue // address is in a proposal, so we allow voting either way
}
switch { // address is not in a proposal, we allow removing signers or adding non signers
case isSealer && authorize:
panic(fmt.Sprintf("'%v' ya es un sellador", address))
case !isSealer && !authorize:
panic(fmt.Sprintf("'%v' no es un sellador", address))
proposals = append(proposals, flags.Arg(i))
}
self, err := node.Coinbase()
util.Check(err)
util.PanicIf(proposal == self, "No es válido votarse a sí mismo")
authorize = !node.IsSealer(proposal)
util.PanicIf(len(node.GetSigners()) <= minSigners && !authorize, "Hay sólo %v selladores. No se permite eliminar más selladores.", minSigners)
node.Propose(proposal, authorize)
fmt.Printf("Voto por %v: %v\n", proposal, authorize)
commands = map[string]func(){
"proposals": proposals,
"sealers": sealers,
for command := range commands {
validCommands = append(validCommands, command)
}
defer func() {
if err := recover(); err != nil {
}
}()
if len(os.Args) > 1 {
command = os.Args[1]
}
if commands[command] == nil {
fmt.Fprintf(os.Stderr, "Uso: %v <%v> [opciones]\n", path.Base(os.Args[0]), strings.Join(validCommands, "|"))
fmt.Fprintf(os.Stderr, "Para ayuda: %v <command> -h\n", path.Base(os.Args[0]))