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
import (
"encoding/json"
"flag"
"fmt"
"io/ioutil"
"log"
"math/big"
"os"
......@@ -24,7 +26,7 @@ const (
var (
url string
json bool
jsonOutput bool
help bool
flags = flag.NewFlagSet("", flag.ExitOnError)
description string
......@@ -57,7 +59,7 @@ var (
)
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.BoolVar(&help, "h", false, "")
flags.BoolVar(&help, "help", false, "Muestra esta ayuda")
......@@ -114,7 +116,7 @@ func proposals() {
defer node.Close()
blockNumber = node.BlockNumberInRange(blockNumber)
votes := node.Votes(blockNumber)
if json {
if jsonOutput {
util.PrintJson(votes)
return
}
......@@ -169,7 +171,7 @@ func parseFormatString(s string) (format string) {
func printSealers(sealers []bfa.Address) {
bfa.SortAddresses(sealers)
if json {
if jsonOutput {
util.PrintJson(sealers)
} else {
for _, sealer := range sealers {
......@@ -236,7 +238,7 @@ func sealers() {
}
sealers := node.SealersStatus(blockNumber)
if json {
if jsonOutput {
util.PrintJson(sealers)
return
}
......@@ -359,13 +361,13 @@ func autovote() {
continue
}
node.Propose(proposal, !isSealer)
if json {
if jsonOutput {
voted[proposal.String()] = !isSealer
} else {
fmt.Printf("Voto por %v: %v\n", proposal, !isSealer)
}
}
if json {
if jsonOutput {
util.PrintJson(voted)
}
}
......@@ -401,13 +403,13 @@ func propose() {
}
}
node.Propose(address, authorize)
if json {
if jsonOutput {
voted[address.String()] = authorize
} else {
fmt.Printf("Voto por %v: %v\n", address, authorize)
}
}
if json {
if jsonOutput {
util.PrintJson(voted)
}
}
......@@ -546,7 +548,7 @@ func transfers() {
src := transaction.From
dst := transaction.To
if len(set) == 0 || set[src] || set[dst] {
if json {
if jsonOutput {
txs = append(txs, Transfer{src, dst, transaction.Value, i})
} else {
fmt.Printf("%v -> %v: %v (%v)\n", src.Hex(), dst.Hex(), transaction.Value, transaction.BlockNumber)
......@@ -566,32 +568,27 @@ func transfers() {
}
}
}
if json {
if jsonOutput {
util.PrintJson(txs)
}
}
func sealerstats() {
type Stats struct {
FirstSeen int64 `json:"first_seen,omitempty"`
LastSeen int64 `json:"last_seen,omitempty"`
FirstBlockSealed int64 `json:"first_block_sealed,omitempty"`
LastBlockSealed int64 `json:"last_block_sealed,omitempty"`
BlocksSealed int64 `json:"blocks_sealed"`
BlocksAlive int64 `json:"blocks_alive"`
Availability float64 `json:"availability"`
recent bool
}
// Stats collect statistics about a sealer
type Stats struct {
FirstSeen int64 `json:"first_seen,omitempty"`
LastSeen int64 `json:"last_seen,omitempty"`
FirstBlockSealed int64 `json:"first_block_sealed,omitempty"`
LastBlockSealed int64 `json:"last_block_sealed,omitempty"`
BlocksSealed int64 `json:"blocks_sealed"`
BlocksAlive int64 `json:"blocks_alive"`
Availability float64 `json:"availability"`
recent bool
}
func calculateSealerStats(url string, first int64, last int64, factor int64) (sealerStats map[bfa.Address]*Stats) {
var (
first, last, end, lastBlock int64
sealerStats map[bfa.Address]*Stats
lastBlock, end int64
)
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)
util.Check(err)
defer node.Close()
......@@ -618,7 +615,7 @@ func sealerstats() {
for block := first; block < end; {
snapshot := node.SnapshotAtBlock(block)
recentsLength := int64(len(snapshot.Recents))
shouldHaveSealedAfter := block - 4*recentsLength
shouldHaveSealedAfter := block - factor*int64(len(snapshot.Signers))
if shouldHaveSealedAfter < 0 {
shouldHaveSealedAfter = 0
}
......@@ -645,42 +642,44 @@ func sealerstats() {
}
}
for sealer := range snapshot.Signers {
stats := sealerStats[sealer]
stats.LastSeen = block
var firstSeen bool
if stats.FirstSeen == 0 {
// we have never seen this sealer before
fmt.Fprintf(os.Stderr, "Nuevo sellador: %v\n", sealer.Hex())
stats.FirstSeen = block
firstSeen = true
}
if !stats.recent {
// sealer is not in snapshot.Recents
if stats.FirstBlockSealed > 0 {
// Sealer has signed at least once, we never zero its BlocksAlive
if stats.LastBlockSealed > shouldHaveSealedAfter {
if stats, ok := sealerStats[sealer]; ok {
// We are only interested if the sealer is in sealersStats
stats.LastSeen = block
var firstSeen bool
if stats.FirstSeen == 0 {
// we have never seen this sealer before
fmt.Fprintf(os.Stderr, "Nuevo sellador: %v\n", sealer.Hex())
stats.FirstSeen = block
firstSeen = true
}
if !stats.recent {
// sealer is not in snapshot.Recents
if stats.FirstBlockSealed > 0 {
// 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
continue
} else {
stats.BlocksAlive = 1
}
} 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
continue
}
stats.recent = false
// sealer is in snapshot.Recents
if firstSeen {
stats.FirstSeen = stats.FirstBlockSealed
stats.BlocksAlive = block - stats.FirstSeen + 1
} 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
......@@ -703,6 +702,40 @@ func sealerstats() {
blocksSeen := stats.LastSeen - stats.FirstSeen + 1
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)
}
......
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