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

Refactorización y agregado de lectura de archivo

parent b8f583d3
No related branches found
No related tags found
No related merge requests found
package main package main
import ( import (
"encoding/json"
"flag" "flag"
"fmt" "fmt"
"io/ioutil"
"log" "log"
"math/big" "math/big"
"os" "os"
...@@ -24,7 +26,7 @@ const ( ...@@ -24,7 +26,7 @@ const (
var ( var (
url string url string
json bool jsonOutput bool
help bool help bool
flags = flag.NewFlagSet("", flag.ExitOnError) flags = flag.NewFlagSet("", flag.ExitOnError)
description string description string
...@@ -57,7 +59,7 @@ var ( ...@@ -57,7 +59,7 @@ var (
) )
func setFlags() { func setFlags() {
flags.BoolVar(&json, "json", false, "Produce salida en formato json") flags.BoolVar(&jsonOutput, "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.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, "h", false, "")
flags.BoolVar(&help, "help", false, "Muestra esta ayuda") flags.BoolVar(&help, "help", false, "Muestra esta ayuda")
...@@ -114,7 +116,7 @@ func proposals() { ...@@ -114,7 +116,7 @@ func proposals() {
defer node.Close() defer node.Close()
blockNumber = node.BlockNumberInRange(blockNumber) blockNumber = node.BlockNumberInRange(blockNumber)
votes := node.Votes(blockNumber) votes := node.Votes(blockNumber)
if json { if jsonOutput {
util.PrintJson(votes) util.PrintJson(votes)
return return
} }
...@@ -169,7 +171,7 @@ func parseFormatString(s string) (format string) { ...@@ -169,7 +171,7 @@ func parseFormatString(s string) (format string) {
func printSealers(sealers []bfa.Address) { func printSealers(sealers []bfa.Address) {
bfa.SortAddresses(sealers) bfa.SortAddresses(sealers)
if json { if jsonOutput {
util.PrintJson(sealers) util.PrintJson(sealers)
} else { } else {
for _, sealer := range sealers { for _, sealer := range sealers {
...@@ -236,7 +238,7 @@ func sealers() { ...@@ -236,7 +238,7 @@ func sealers() {
} }
sealers := node.SealersStatus(blockNumber) sealers := node.SealersStatus(blockNumber)
if json { if jsonOutput {
util.PrintJson(sealers) util.PrintJson(sealers)
return return
} }
...@@ -359,13 +361,13 @@ func autovote() { ...@@ -359,13 +361,13 @@ func autovote() {
continue continue
} }
node.Propose(proposal, !isSealer) node.Propose(proposal, !isSealer)
if json { if jsonOutput {
voted[proposal.String()] = !isSealer voted[proposal.String()] = !isSealer
} else { } else {
fmt.Printf("Voto por %v: %v\n", proposal, !isSealer) fmt.Printf("Voto por %v: %v\n", proposal, !isSealer)
} }
} }
if json { if jsonOutput {
util.PrintJson(voted) util.PrintJson(voted)
} }
} }
...@@ -401,13 +403,13 @@ func propose() { ...@@ -401,13 +403,13 @@ func propose() {
} }
} }
node.Propose(address, authorize) node.Propose(address, authorize)
if json { if jsonOutput {
voted[address.String()] = authorize voted[address.String()] = authorize
} else { } else {
fmt.Printf("Voto por %v: %v\n", address, authorize) fmt.Printf("Voto por %v: %v\n", address, authorize)
} }
} }
if json { if jsonOutput {
util.PrintJson(voted) util.PrintJson(voted)
} }
} }
...@@ -546,7 +548,7 @@ func transfers() { ...@@ -546,7 +548,7 @@ func transfers() {
src := transaction.From src := transaction.From
dst := transaction.To dst := transaction.To
if len(set) == 0 || set[src] || set[dst] { if len(set) == 0 || set[src] || set[dst] {
if json { if jsonOutput {
txs = append(txs, Transfer{src, dst, transaction.Value, i}) txs = append(txs, Transfer{src, dst, transaction.Value, i})
} else { } else {
fmt.Printf("%v -> %v: %v (%v)\n", src.Hex(), dst.Hex(), transaction.Value, transaction.BlockNumber) fmt.Printf("%v -> %v: %v (%v)\n", src.Hex(), dst.Hex(), transaction.Value, transaction.BlockNumber)
...@@ -566,32 +568,27 @@ func transfers() { ...@@ -566,32 +568,27 @@ func transfers() {
} }
} }
} }
if json { if jsonOutput {
util.PrintJson(txs) util.PrintJson(txs)
} }
} }
func sealerstats() { // Stats collect statistics about a sealer
type Stats struct { type Stats struct {
FirstSeen int64 `json:"first_seen,omitempty"` FirstSeen int64 `json:"first_seen,omitempty"`
LastSeen int64 `json:"last_seen,omitempty"` LastSeen int64 `json:"last_seen,omitempty"`
FirstBlockSealed int64 `json:"first_block_sealed,omitempty"` FirstBlockSealed int64 `json:"first_block_sealed,omitempty"`
LastBlockSealed int64 `json:"last_block_sealed,omitempty"` LastBlockSealed int64 `json:"last_block_sealed,omitempty"`
BlocksSealed int64 `json:"blocks_sealed"` BlocksSealed int64 `json:"blocks_sealed"`
BlocksAlive int64 `json:"blocks_alive"` BlocksAlive int64 `json:"blocks_alive"`
Availability float64 `json:"availability"` Availability float64 `json:"availability"`
recent bool recent bool
} }
func calculateSealerStats(url string, first int64, last int64, factor int64) (sealerStats map[bfa.Address]*Stats) {
var ( var (
first, last, end, lastBlock int64 lastBlock, end int64
sealerStats map[bfa.Address]*Stats
) )
description = "Calcula estadísticas de los selladores."
setFlags()
flags.Int64Var(&first, "first-block", 1, "Primer bloque del rango (Número negativo para restar del último bloque)")
flags.Int64Var(&last, "last-block", latest, "Último bloque del rango (-1 para especificar el último bloque)")
parseFlags(true)
url = updateURL(url)
node, err := bfa.Dial(url) node, err := bfa.Dial(url)
util.Check(err) util.Check(err)
defer node.Close() defer node.Close()
...@@ -618,7 +615,7 @@ func sealerstats() { ...@@ -618,7 +615,7 @@ func sealerstats() {
for block := first; block < end; { for block := first; block < end; {
snapshot := node.SnapshotAtBlock(block) snapshot := node.SnapshotAtBlock(block)
recentsLength := int64(len(snapshot.Recents)) recentsLength := int64(len(snapshot.Recents))
shouldHaveSealedAfter := block - 4*recentsLength shouldHaveSealedAfter := block - factor*int64(len(snapshot.Signers))
if shouldHaveSealedAfter < 0 { if shouldHaveSealedAfter < 0 {
shouldHaveSealedAfter = 0 shouldHaveSealedAfter = 0
} }
...@@ -645,42 +642,44 @@ func sealerstats() { ...@@ -645,42 +642,44 @@ func sealerstats() {
} }
} }
for sealer := range snapshot.Signers { for sealer := range snapshot.Signers {
stats := sealerStats[sealer] if stats, ok := sealerStats[sealer]; ok {
stats.LastSeen = block // We are only interested if the sealer is in sealersStats
var firstSeen bool stats.LastSeen = block
if stats.FirstSeen == 0 { var firstSeen bool
// we have never seen this sealer before if stats.FirstSeen == 0 {
fmt.Fprintf(os.Stderr, "Nuevo sellador: %v\n", sealer.Hex()) // we have never seen this sealer before
stats.FirstSeen = block fmt.Fprintf(os.Stderr, "Nuevo sellador: %v\n", sealer.Hex())
firstSeen = true stats.FirstSeen = block
} firstSeen = true
if !stats.recent { }
// sealer is not in snapshot.Recents if !stats.recent {
if stats.FirstBlockSealed > 0 { // sealer is not in snapshot.Recents
// Sealer has signed at least once, we never zero its BlocksAlive if stats.FirstBlockSealed > 0 {
if stats.LastBlockSealed > shouldHaveSealedAfter { // Sealer has signed at least once, we never zero its BlocksAlive
if stats.LastBlockSealed > shouldHaveSealedAfter {
stats.BlocksAlive += blocksProcessed
continue
}
} else if stats.FirstSeen <= shouldHaveSealedAfter {
// Sealer has never signed since we've seen it for the first time
stats.BlocksAlive = 0
} else if !firstSeen {
// Sealer has never signed, but only a few blocks have passed since we've seen it for the first time
// and we've seen it more than once
stats.BlocksAlive += blocksProcessed stats.BlocksAlive += blocksProcessed
continue } else {
stats.BlocksAlive = 1
} }
} else if stats.FirstSeen <= shouldHaveSealedAfter { continue
// Sealer has never signed since we've seen it for the first time }
stats.BlocksAlive = 0 stats.recent = false
} else if !firstSeen { // sealer is in snapshot.Recents
// Sealer has never signed, but only a few blocks have passed since we've seen it for the first time if firstSeen {
// and we've seen it more than once stats.FirstSeen = stats.FirstBlockSealed
stats.BlocksAlive += blocksProcessed stats.BlocksAlive = block - stats.FirstSeen + 1
} else { } else {
stats.BlocksAlive = 1 stats.BlocksAlive += blocksProcessed
} }
continue
}
stats.recent = false
// sealer is in snapshot.Recents
if firstSeen {
stats.FirstSeen = stats.FirstBlockSealed
stats.BlocksAlive = block - stats.FirstSeen + 1
} else {
stats.BlocksAlive += blocksProcessed
} }
} }
lastBlock = block lastBlock = block
...@@ -703,6 +702,40 @@ func sealerstats() { ...@@ -703,6 +702,40 @@ func sealerstats() {
blocksSeen := stats.LastSeen - stats.FirstSeen + 1 blocksSeen := stats.LastSeen - stats.FirstSeen + 1
stats.Availability = float64(stats.BlocksAlive) / float64(blocksSeen) stats.Availability = float64(stats.BlocksAlive) / float64(blocksSeen)
} }
return
}
func readStatsFromFile(filename string) (sealerStats map[bfa.Address]*Stats) {
file, err := os.Open(filename)
util.Check(err)
defer file.Close()
byteBuffer, err := ioutil.ReadAll(file)
util.Check(err)
err = json.Unmarshal(byteBuffer, &sealerStats)
util.Check(err)
return
}
func sealerstats() {
var (
first, last, factor int64
jsonFile string
sealerStats map[bfa.Address]*Stats
)
description = "Calcula estadísticas de los selladores."
setFlags()
flags.Int64Var(&first, "first-block", 1, "Primer bloque del rango (Número negativo para restar del último bloque). Ignorado si se especificó 'json_file'")
flags.Int64Var(&last, "last-block", latest, "Último bloque del rango (-1 para especificar el último bloque). Ignorado si se especificó 'json_file'")
flags.Int64Var(&factor, "factor", 2, "Bloques necesarios para declarar un nodo como no activo, especificados como múltiplos de la cantidad de selladores")
flags.StringVar(&jsonFile, "json-file", "", "Lee los datos de un archivo en lugar de recorrer la cadena")
parseFlags(true)
url = updateURL(url)
if len(jsonFile) > 0 {
sealerStats = readStatsFromFile(jsonFile)
} else {
sealerStats = calculateSealerStats(url, first, last, factor)
}
util.PrintJson(sealerStats) util.PrintJson(sealerStats)
} }
......
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