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

Cambios de tipo de direcciones en Proposals y Snapshot

parent f17085d1
No related branches found
No related tags found
No related merge requests found
......@@ -17,12 +17,12 @@ type Node rpc.Client
type Address struct{ common.Address }
type Snapshot struct {
Number uint64 `json:"number"` // Block number where the snapshot was created
Hash common.Hash `json:"hash"` // Block hash where the snapshot was created
Signers map[common.Address]struct{} `json:"signers"` // Set of authorized signers at this moment
Recents map[uint64]common.Address `json:"recents"` // Set of recent signers for spam protections
Votes []*clique.Vote `json:"votes"` // List of votes cast in chronological order
Tally map[common.Address]clique.Tally `json:"tally"` // Current vote tally to avoid recalculating
Number uint64 `json:"number"` // Block number where the snapshot was created
Hash common.Hash `json:"hash"` // Block hash where the snapshot was created
Signers map[Address]struct{} `json:"signers"` // Set of authorized signers at this moment
Recents map[uint64]Address `json:"recents"` // Set of recent signers for spam protections
Votes []*clique.Vote `json:"votes"` // List of votes cast in chronological order
Tally map[Address]clique.Tally `json:"tally"` // Current vote tally to avoid recalculating
}
type Tally struct {
......@@ -33,10 +33,10 @@ type Tally struct {
type Proposals struct {
BlockNumber int64 `json:"number"` // Block number where the snapshot was created
Proposals []string `json:"proposals"` // List of proposals being voted
Signers []string `json:"signers"` // List of authorized signers at this moment
Tally map[string]*Tally `json:"tally"` // Count of positive, negative and empty votes for a proposal
Votes map[string]map[string]*bool `json:"votes"` // List of votes for each proposal
Proposals []Address `json:"proposals"` // List of proposals being voted
Signers []Address `json:"signers"` // List of authorized signers at this moment
Tally map[Address]*Tally `json:"tally"` // Count of positive, negative and empty votes for a proposal
Votes map[Address]map[Address]*bool `json:"votes"` // List of votes for each proposal
}
type SealerStatus struct {
......@@ -58,6 +58,26 @@ func (address Address) MarshalText() ([]byte, error) {
return []byte(address.Hex()), nil
}
func (a Address) lessThan(b Address) bool {
for i, x := range a.Address {
if x < b.Address[i] {
return true
}
}
return false
}
func ContainsAddress(slice []Address, address Address) bool {
for _, x := range slice {
if x == address {
return true
}
}
return false
}
func (node *Node) Call(result interface{}, method string, args ...interface{}) {
Check((*rpc.Client)(node).Call(result, method, args...))
}
......@@ -220,8 +240,8 @@ func (node *Node) IsSealerAtBlock(address string, blockNumber int64) bool {
return Contains(node.SealersAtBlock(blockNumber), address)
}
func (node *Node) Propose(address string, vote bool) {
node.Call(nil, "clique_propose", address, vote)
func (node *Node) Propose(address Address, vote bool) {
node.Call(nil, "clique_propose", address.String(), vote)
return
}
......@@ -236,20 +256,20 @@ func (node *Node) Votes(blockNumber int64) (votes Proposals) {
}
votes.BlockNumber = int64(snapshot.Number)
for signer := range snapshot.Signers {
votes.Signers = append(votes.Signers, BytesToHex(signer[:]))
sort.Strings(votes.Signers)
votes.Signers = append(votes.Signers, signer)
sort.Slice(votes.Signers, func(i int, j int) bool { return votes.Signers[i].lessThan(votes.Signers[j])})
}
for proposal := range snapshot.Tally {
votes.Proposals = append(votes.Proposals, BytesToHex(proposal[:]))
votes.Proposals = append(votes.Proposals, proposal)
}
sort.Strings(votes.Proposals)
votes.Votes = make(map[string]map[string]*bool)
votes.Tally = make(map[string]*Tally)
sort.Slice(votes.Proposals, func(i int, j int) bool { return votes.Proposals[i].lessThan(votes.Proposals[j])})
votes.Votes = make(map[Address]map[Address]*bool)
votes.Tally = make(map[Address]*Tally)
for _, v := range snapshot.Votes {
proposal := BytesToHex(v.Address[:])
signer := BytesToHex(v.Signer[:])
proposal := Address{v.Address}
signer := Address{v.Signer}
if votes.Votes[proposal] == nil {
votes.Votes[proposal] = make(map[string]*bool)
votes.Votes[proposal] = make(map[Address]*bool)
for _, signer := range votes.Signers {
votes.Votes[proposal][signer] = nil
}
......@@ -273,7 +293,8 @@ func (node *Node) LastBlockSignedBy(address string, upperLimit int64) (blockNumb
for i := 0; i < 5; i++ {
snapshot := node.SnapshotAtBlock(upperLimit)
for number, sealer := range snapshot.Recents {
if BytesToHex(sealer[:]) == address {
a := Address{common.HexToAddress(address)}
if sealer == a {
return int64(number)
}
}
......
......@@ -335,9 +335,10 @@ func autovote() {
defer node.Close()
util.Ensure(node.IsSealer(bfa.Self), "Solo los selladores pueden votar")
votes := node.Votes(latest)
genesisSigners := node.SealersAtBlock(0)
self, err := node.Coinbase()
// genesisSigners := node.SealersAtBlock(0)
s, err := node.Coinbase()
util.Check(err)
self := bfa.Address{common.HexToAddress(s)}
for _, tally := range votes.Tally {
if tally.False >= threshold { // We are trying to remove a sealer
removedSealers += 1
......@@ -345,7 +346,7 @@ func autovote() {
}
util.Ensure(len(votes.Signers)-removedSealers >= minSigners, "No se puede emitir un voto automático que reduzca la cantidad de selladores por debajo de %v.", minSigners)
for _, proposal := range votes.Proposals {
isSealer := util.Contains(votes.Signers, proposal)
isSealer := bfa.ContainsAddress(votes.Signers, proposal)
switch {
case votes.Votes[proposal][self] != nil:
continue // Already voted
......@@ -353,16 +354,17 @@ func autovote() {
continue // There aren't enough votes to enable autovote
case !isSealer && votes.Tally[proposal].True < threshold:
continue // There aren't enough votes to enable autovote
case util.Contains(genesisSigners, proposal) && isSealer:
log.Printf("No se puede quitar en forma automática a un sellador del bloque génesis: %v.\n", proposal)
continue
// TODO: Restaurar este caso
// case bfa.ContainsAddress(genesisSigners, proposal) && isSealer:
// log.Printf("No se puede quitar en forma automática a un sellador del bloque génesis: %v.\n", proposal)
// continue
case proposal == self:
log.Println("No se puede votar para eliminarse uno mismo de la lista de selladores.")
continue
}
node.Propose(proposal, !isSealer)
if json {
voted[proposal] = !isSealer
voted[proposal.String()] = !isSealer
} else {
fmt.Printf("Voto por %v: %v\n", proposal, !isSealer)
}
......@@ -390,10 +392,11 @@ func propose() {
votes := node.Votes(latest)
util.Ensure(flags.NArg() > 0, "No se especificaron candidatos por los cuales votar\n")
for i := 0; i < flags.NArg(); i++ {
address := flags.Arg(i)
util.Ensure(util.IsAddress(address), "'%v' no es una dirección válida", address)
addr := flags.Arg(i)
util.Ensure(util.IsAddress(addr), "'%v' no es una dirección válida", addr)
address := bfa.Address{common.HexToAddress(addr)}
if _, ok := votes.Tally[address]; !ok {
isSealer := util.Contains(votes.Signers, address)
isSealer := bfa.ContainsAddress(votes.Signers, address)
switch { // address is not in a proposal, we only allow removing signers or adding non signers
case isSealer && authorize:
util.Error("'%v' ya es un sellador\n", address)
......@@ -403,7 +406,7 @@ func propose() {
}
node.Propose(address, authorize)
if json {
voted[address] = authorize
voted[address.String()] = authorize
} else {
fmt.Printf("Voto por %v: %v\n", address, authorize)
}
......
......@@ -20,23 +20,6 @@ func Contains(slice []string, s string) bool {
return false
}
func ContainsAddress(slice []common.Address, address common.Address) bool {
for _, x := range slice {
if x == address {
return true
}
}
return false
}
func LessThanAddress(a common.Address, b common.Address) bool {
for i, x := range a {
if x < b[i] {
return true
}
}
return false
}
func Error(format string, args ...interface{}) {
_, _ = fmt.Fprintf(os.Stderr, 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