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

Mejoras en el código de votación

parent 9b0d2d5b
No related branches found
No related tags found
No related merge requests found
......@@ -44,6 +44,10 @@ type SealerInfo struct {
LastBlock int64
}
const (
Latest = "latest"
Self = "self"
)
func (node *Node) Call(result interface{}, method string, args ...interface{}) {
Check((*rpc.Client)(node).Call(result, method, args...))
......@@ -55,7 +59,21 @@ func (node *Node) blockNumber() int64 {
return bn.Int64()
}
func (node *Node) Coinbase() (coinbase string, err error) {
defer func(){
if e := recover(); e != nil {
switch s := e.(type){
case string: err = fmt.Errorf(s)
case error: err = s
default: err = fmt.Errorf("unknown error while getting coinbase: %v", e)
}
}
}()
var address common.Address
node.Call(&address, "eth_coinbase")
coinbase = BytesToHex(address[:])
return
}
func (node *Node) GetBlockByNumber(blockNumber int64) types.Header {
var (
......@@ -63,7 +81,7 @@ func (node *Node) GetBlockByNumber(blockNumber int64) types.Header {
resp types.Header
)
if blockNumber < 0 {
number = "latest"
number = Latest
} else {
number = fmt.Sprintf("0x%x", blockNumber)
}
......@@ -71,7 +89,6 @@ func (node *Node) GetBlockByNumber(blockNumber int64) types.Header {
return resp
}
func (node *Node) GetBlockSigner(blockNumber int64) (signer string) {
header := node.GetBlockByNumber(blockNumber)
signer, err := GetSigner(&header)
......@@ -79,8 +96,6 @@ func (node *Node) GetBlockSigner(blockNumber int64) (signer string) {
return
}
func (node *Node) GetSnapshot() (snapshot Snapshot) {
node.Call(&snapshot, "clique_getSnapshot", nil)
return
......@@ -129,7 +144,17 @@ func (node *Node) GetSignersAtBlock(blockNumber int64) (signers []string) {
return
}
func (node *Node) Propose(address string, vote bool){
func (node *Node) IsSealer(address string) bool {
if address == Self {
var err error
if address, err = node.Coinbase(); err != nil {
return false
}
}
return Contains(node.GetSigners(), address)
}
func (node *Node) Propose(address string, vote bool) {
node.Call(nil, "clique_propose", address, vote)
return
}
......@@ -185,7 +210,7 @@ func (node *Node) SealersStatus(blockNumber int64) (status map[string]int64) {
notSeen := int64(len(status))
block := node.GetBlockByNumber(blockNumber)
blockNumber = block.Number.Int64()
until := Max(1, blockNumber - 5*notSeen)
until := Max(1, blockNumber-5*notSeen)
for notSeen > 0 {
signer, _ := GetSigner(&block)
if status[signer] == -1 {
......@@ -201,7 +226,6 @@ func (node *Node) SealersStatus(blockNumber int64) (status map[string]int64) {
return status
}
func (node *Node) GetSealerInception(address string) (since int64) {
if signers := node.GetSigners(); !Contains(signers, address) {
return -1
......@@ -226,7 +250,8 @@ func (node *Node) getSignerFirstBlock(signer string, since int64, until int64) (
return -1
}
//snapshot := node.GetSnapshotAtBlock(since)
var (count int64 = 20
var (
count int64 = 20
found int64 = -1
)
// first, we look close to the inception
......@@ -348,7 +373,6 @@ func (node *Node) getSignerLastBlock(signer string, since int64, until int64) (b
}
}
func (node *Node) searchSnapshotForward(blockNumber int64, signer string, count int64) (found int64, visited int64) {
found = -1
if blockNumber+count < 1 {
......@@ -392,8 +416,6 @@ func (node *Node) searchSnapshotBackward(blockNumber int64, signer string, count
}
}
func (node *Node) SealerInfo(sealer string) (info SealerInfo, err error) {
info.Address = sealer
info.CurrentBlock = node.blockNumber()
......@@ -406,8 +428,6 @@ func (node *Node) SealerInfo(sealer string) (info SealerInfo, err error) {
return
}
func Dial(url string) (*Node, error) {
client, err := rpc.Dial(url)
return (*Node)(client), err
......@@ -416,5 +436,3 @@ func Dial(url string) (*Node, error) {
func (node *Node) Close() {
(*rpc.Client)(node).Close()
}
......@@ -28,6 +28,7 @@ var (
flags flag.FlagSet
command string
description string
otherArgs string
)
func setFlags() {
......@@ -58,7 +59,7 @@ func updateURL(url string) (updated string) {
}
func usage(errorCode int) {
fmt.Fprintf(os.Stderr, "Uso: %v %v [opciones]\n%v\n", os.Args[0], command, description)
fmt.Fprintf(os.Stderr, "Uso: %v %v [opciones] %v\n%v\n", os.Args[0], command, otherArgs, description)
flags.PrintDefaults()
os.Exit(errorCode)
}
......@@ -151,31 +152,48 @@ func sealers() {
func propose() {
var (
all bool
vote bool
authorize bool
proposals []string
)
description = "Vota por una propuesta."
otherArgs = "[propuesta...]"
setFlags()
flags.BoolVar(&all, "all", false, "Vota en todas las propuestas activas")
flags.BoolVar(&vote, "vote", true, "Sentido del voto (true: a favor, false: en contra)")
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()
util.PanicIf(!node.IsSealer(bfa.Self), "Solo los selladores pueden votar")
if all {
votes := node.GetVotes(latest)
for _, proposal := range votes.Proposals {
proposals = append(proposals, proposal)
}
if flags.NArg() != 0 {
fmt.Fprintf(os.Stderr, "Se especificó -all. Ignorando argumentos adicionales.")
}
} else {
if flags.NArg() == 0 {
panic("No se especificaron candidatos por los cuales votar")
}
for i := 0; i < flags.NArg(); i++ {
address := flags.Arg(i)
if !util.IsAddress(address){
panic(fmt.Sprintf("'%v' no es una dirección válida", address))
}
isSealer := node.IsSealer(address)
switch {
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))
}
}
for _, proposal := range proposals {
node.Propose(proposal, vote)
fmt.Printf("Voto por %v: %v\n", proposal, vote)
node.Propose(proposal, authorize)
fmt.Printf("Voto por %v: %v\n", proposal, authorize)
}
}
......
package util
import (
"encoding/hex"
"encoding/json"
"fmt"
"github.com/ethereum/go-ethereum/common"
"runtime"
"strconv"
)
......@@ -57,5 +59,16 @@ func PrintJson(s interface{}){
}
func IsAddress(address string) bool {
bytes, err := hex.DecodeString(address[2:])
return err == nil && len(bytes) == common.AddressLength
}
func PanicIf(cond bool, format string, args ...interface{}){
if cond {
panic(fmt.Sprintf(format, args...))
}
}
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