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

Cambios en el manejo del número de bloque como argumento

Cambios en la forma de encontrar el sellador de un bloque
parent 1967183f
No related branches found
No related tags found
No related merge requests found
......@@ -3,6 +3,8 @@ package bfa
import (
. "../clique"
. "../util"
"bytes"
"encoding/hex"
"errors"
"fmt"
"github.com/ethereum/go-ethereum/common"
......@@ -20,8 +22,7 @@ type Node rpc.Client
type BigInt big.Int
func (bigInt *BigInt) MarshalJSON() ([]byte, error) {
i := (*big.Int)(bigInt)
return []byte(i.String()), nil
return (*big.Int)(bigInt).MarshalJSON()
}
func (bigInt *BigInt) UnmarshalJSON(b []byte) error {
......@@ -39,16 +40,32 @@ func (bigInt *BigInt) String() string {
type Uint64 uint64
func (u *Uint64) MarshalJSON() ([]byte, error) {
return []byte(strconv.FormatUint(*(*uint64)(u), 10)), nil
}
func (u *Uint64) UnmarshalJSON(b []byte) (err error) {
i, err := strconv.ParseUint(string(b[1:len(b)-1]), 0, 64)
*u = Uint64(i)
return
}
type Bytes []byte
func (b Bytes) MarshalJSON() ([]byte, error) {
dest := make([]byte, 2+hex.EncodedLen(len(b)))
copy(dest, []byte("\"0x"))
hex.Encode(dest[2:], b)
dest[len(dest)-1] = '"'
return dest, nil
}
func (b *Bytes) UnmarshalJSON(src []byte) (err error) {
Require(len(src) >= 4 && bytes.Equal(src[1:3], []byte("0x")), "invalid json string")
dest := make([]byte, hex.DecodedLen(len(src)-4))
_, err = hex.Decode(dest, src[3:len(src)-1])
if err == nil {
*b = dest
}
return
}
// RPCTransaction represents a transaction
type RPCTransaction struct {
BlockHash common.Hash `json:"blockHash"`
......@@ -69,24 +86,49 @@ type RPCTransaction struct {
type Block struct {
ParentHash common.Hash `json:"parentHash"`
UncleHash common.Hash `json:"sha3Uncles"`
Coinbase common.Address `json:"miner"`
Root common.Hash `json:"stateRoot"`
TxHash common.Hash `json:"transactionsRoot"`
ReceiptHash common.Hash `json:"receiptsRoot"`
Bloom types.Bloom `json:"logsBloom"`
Difficulty Uint64 `json:"difficulty"`
Number Uint64 `json:"number"`
Difficulty *BigInt `json:"difficulty"`
Number *BigInt `json:"number"`
GasLimit Uint64 `json:"gasLimit"`
GasUsed Uint64 `json:"gasUsed"`
Time Uint64 `json:"timestamp"`
Extra []byte `json:"extraData"`
Time *BigInt `json:"timestamp"`
Extra Bytes `json:"extraData"`
MixDigest common.Hash `json:"mixHash"`
Nonce Uint64 `json:"nonce"`
Nonce types.BlockNonce `json:"nonce"`
Transactions []RPCTransaction `json:"transactions"`
TotalDifficulty Uint64 `json:"totalDifficulty"`
Signer common.Address `json:"signer"`
}
func (block *Block) Header() (header types.Header) {
header.ParentHash = block.ParentHash
header.UncleHash = block.UncleHash
header.Coinbase = block.Coinbase
header.Root = block.Root
header.TxHash = block.TxHash
header.ReceiptHash = block.TxHash
header.Bloom = block.Bloom
header.Difficulty = (*big.Int)(block.Difficulty)
header.Number = (*big.Int)(block.Number)
header.GasLimit = uint64(block.GasLimit)
header.GasUsed = uint64(block.GasUsed)
header.Time = (*big.Int)(block.Time)
header.Extra = block.Extra
header.MixDigest = block.MixDigest
header.Nonce = block.Nonce
return
}
func (block *Block) setSigner() {
header := block.Header()
block.Signer = GetSigner(&header)
}
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
......@@ -195,31 +237,38 @@ func (node *Node) Coinbase() (coinbase string, err error) {
return
}
func (node *Node) HeaderByNumber(blockNumber int64) types.Header {
var (
number string
resp types.Header
)
if blockNumber < 0 || blockNumber > node.BlockNumber() {
number = Latest
func hexBlockNumber(number int64) (blockNumber string) {
if number == -1 {
blockNumber = Latest
} else {
number = fmt.Sprintf("0x%x", blockNumber)
blockNumber = "0x" + strconv.FormatInt(number, 16)
}
node.Call(&resp, "eth_getBlockByNumber", number, true)
return resp
return
}
func (node *Node) BlockByNumber(blockNumber int64) (block Block) {
var (
number string
)
if blockNumber < 0 || blockNumber > node.BlockNumber() {
number = Latest
} else {
number = fmt.Sprintf("0x%x", blockNumber)
func (node *Node) BlockNumberInRange(number int64) (blockNumber int64) {
latest := node.BlockNumber()
switch {
case number == -1, number > latest:
blockNumber = latest
case number < 0:
blockNumber = Max(0, latest+1+number)
default:
blockNumber = number
}
node.Call(&block, "eth_getBlockByNumber", number, true)
block.Signer = node.BlockSigner(blockNumber)
return
}
func (node *Node) HeaderByNumber(blockNumber int64) (header types.Header) {
Require(blockNumber == -1 || blockNumber == node.BlockNumberInRange(blockNumber), "block number out of range")
node.Call(&header, "eth_getBlockByNumber", hexBlockNumber(blockNumber), true)
return
}
func (node *Node) BlockByNumber(blockNumber int64) (block Block) {
Require(blockNumber == -1 || blockNumber == node.BlockNumberInRange(blockNumber), "block number out of range")
node.Call(&block, "eth_getBlockByNumber", hexBlockNumber(blockNumber), true)
block.setSigner()
return
}
......@@ -243,10 +292,8 @@ func (node *Node) SnapshotAtHash(hash common.Hash) (snapshot Snapshot) {
}
func (node *Node) SnapshotAtBlock(blockNumber int64) (snapshot Snapshot) {
if blockNumber < 0 || blockNumber >= node.BlockNumber() {
return node.GetSnapshot()
}
node.Call(&snapshot, "clique_getSnapshot", Int64ToHex(blockNumber))
Require(blockNumber == -1 || blockNumber == node.BlockNumberInRange(blockNumber), "block number out of range")
node.Call(&snapshot, "clique_getSnapshot", hexBlockNumber(blockNumber))
return
}
......
......@@ -88,6 +88,7 @@ func proposals() {
node, err := bfa.Dial(url)
util.Check(err)
defer node.Close()
blockNumber = node.BlockNumberInRange(blockNumber)
votes := node.Votes(blockNumber)
if json {
util.PrintJson(votes)
......@@ -163,12 +164,13 @@ func sealers() {
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.")
parseFlags(false)
if blockNumber == 0 {
panic("El bloque génesis no tiene firmantes")
util.Error("El bloque génesis no tiene firmantes")
}
url = updateURL(url)
node, err := bfa.Dial(url)
util.Check(err)
defer node.Close()
blockNumber = node.BlockNumberInRange(blockNumber)
extended := lastBlock || timestamp || difficulty || balance
if extended {
sealers := node.SealersStatus(blockNumber)
......@@ -268,12 +270,12 @@ func autovote() {
flags.IntVar(&threshold, "threshold", voteThreshold, "Cantidad mínima de votos en una propuesta para habilitar el voto automático.")
setFlags()
parseFlags(false)
util.DieIf(threshold < voteThreshold, "No se puede especificar una cantidad de votos inferior a %v.", voteThreshold)
util.Ensure(threshold >= voteThreshold, "No se puede especificar una cantidad de votos inferior a %v.", voteThreshold)
url = updateURL(url)
node, err := bfa.Dial(url)
util.Check(err)
defer node.Close()
util.DieIf(!node.IsSealer(bfa.Self), "Solo los selladores pueden votar")
util.Ensure(node.IsSealer(bfa.Self), "Solo los selladores pueden votar")
votes := node.Votes(latest)
genesisSigners := node.SealersAtBlock(0)
self, err := node.Coinbase()
......@@ -283,7 +285,7 @@ func autovote() {
removedSealers += 1
}
}
util.DieIf(len(votes.Signers)-removedSealers < minSigners, "No se puede emitir un voto automático que reduzca la cantidad de selladores por debajo de %v.", minSigners)
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)
switch {
......@@ -326,25 +328,21 @@ func propose() {
node, err := bfa.Dial(url)
util.Check(err)
defer node.Close()
util.DieIf(!node.IsSealer(bfa.Self), "Solo los selladores pueden votar")
util.Ensure(node.IsSealer(bfa.Self), "Solo los selladores pueden votar")
votes := node.Votes(latest)
if flags.NArg() == 0 {
panic("No se especificaron candidatos por los cuales votar")
}
util.Ensure(flags.NArg() > 0, "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))
}
util.Ensure(util.IsAddress(address), "'%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
}
isSealer := util.Contains(votes.Signers, address)
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))
util.Error("'%v' ya es un sellador", address)
case !isSealer && !authorize:
panic(fmt.Sprintf("'%v' no es un sellador", address))
util.Error("'%v' no es un sellador", address)
}
node.Propose(address, authorize)
if json {
......@@ -411,6 +409,7 @@ func block() {
node, err := bfa.Dial(url)
util.Check(err)
defer node.Close()
blockNumber = node.BlockNumberInRange(blockNumber)
block := node.BlockByNumber(blockNumber)
util.PrintJson(block)
}
......@@ -425,6 +424,7 @@ func snapshot() {
node, err := bfa.Dial(url)
util.Check(err)
defer node.Close()
blockNumber = node.BlockNumberInRange(blockNumber)
snapshot := node.SnapshotAtBlock(blockNumber)
util.PrintJson(snapshot)
}
......
......@@ -10,8 +10,7 @@ import (
func sigHash(header *types.Header) (hash common.Hash) {
hasher := sha3.NewKeccak256()
rlp.Encode(hasher, []interface{}{
_ = rlp.Encode(hasher, []interface{}{
header.ParentHash,
header.UncleHash,
header.Coinbase,
......
......@@ -80,7 +80,3 @@ func IsAddress(address string) bool {
bytes, err := hex.DecodeString(address[2:])
return err == nil && len(bytes) == common.AddressLength
}
func DieIf(cond bool, format string, args ...interface{}) {
Ensure(!cond, 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