diff --git a/bfa_client/src/bfa/node.go b/bfa_client/src/bfa/node.go index a63283040e465ecdbd1615c15d4230031af6a14c..40255832406490c9f33bceb94e2263b4f91f0655 100644 --- a/bfa_client/src/bfa/node.go +++ b/bfa_client/src/bfa/node.go @@ -3,7 +3,7 @@ package bfa import ( . "../clique" . "../util" - "encoding/json" + "errors" "fmt" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/consensus/clique" @@ -11,7 +11,6 @@ import ( "github.com/ethereum/go-ethereum/p2p" "github.com/ethereum/go-ethereum/rpc" "math/big" - "reflect" "sort" "strconv" ) @@ -20,28 +19,49 @@ type Node rpc.Client type BigInt big.Int -func (b BigInt) MarshalJSON() ([]byte, error) { - i := (big.Int)(b) +func (bigInt *BigInt) MarshalJSON() ([]byte, error) { + i := (*big.Int)(bigInt) return []byte(i.String()), nil } -func (b *BigInt) String() string { - return (*big.Int)(b).String() +func (bigInt *BigInt) UnmarshalJSON(b []byte) error { + if i, ok := new(big.Int).SetString(string(b[1:len(b)-1]), 0); ok { + *bigInt = BigInt(*i) + return nil + } + return errors.New("can't unmarshal BigInt") + +} + +func (bigInt *BigInt) String() string { + return (*big.Int)(bigInt).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 } // RPCTransaction represents a transaction that will serialize to the RPC representation of a transaction type RPCTransaction struct { BlockHash string `json:"blockHash"` - BlockNumber int64 `json:"blockNumber"` + BlockNumber Uint64 `json:"blockNumber"` From string `json:"from"` - Gas uint64 `json:"gas"` - GasPrice uint64 `json:"gasPrice"` + Gas Uint64 `json:"gas"` + GasPrice *BigInt `json:"gasPrice"` Hash string `json:"hash"` Input string `json:"input"` - Nonce uint64 `json:"nonce"` + Nonce Uint64 `json:"nonce"` To string `json:"to"` - TransactionIndex uint `json:"transactionIndex"` - Value string `json:"value"` + TransactionIndex Uint64 `json:"transactionIndex"` + Value *BigInt `json:"value"` V *BigInt `json:"v"` R *BigInt `json:"r"` S *BigInt `json:"s"` @@ -54,86 +74,19 @@ type Block struct { TxHash string `json:"transactionsRoot"` ReceiptHash string `json:"receiptsRoot"` Bloom string `json:"logsBloom"` - Difficulty uint64 `json:"difficulty"` - Number uint64 `json:"number"` - GasLimit uint64 `json:"gasLimit"` - GasUsed uint64 `json:"gasUsed"` - Time uint64 `json:"timestamp"` + Difficulty Uint64 `json:"difficulty"` + Number Uint64 `json:"number"` + GasLimit Uint64 `json:"gasLimit"` + GasUsed Uint64 `json:"gasUsed"` + Time Uint64 `json:"timestamp"` Extra string `json:"extraData"` MixDigest string `json:"mixHash"` - Nonce uint64 `json:"nonce"` + Nonce Uint64 `json:"nonce"` Transactions []RPCTransaction `json:"transactions"` - TotalDifficulty uint64 `json:"totalDifficulty"` + TotalDifficulty Uint64 `json:"totalDifficulty"` Signer string `json:"signer"` } -func mapToStruct(m map[string]interface{}, s interface{}) { - v := reflect.ValueOf(s).Elem() - numFields := v.NumField() - for i := 0; i < numFields; i++ { - field := v.Field(i) - jsonName := v.Type().Field(i).Tag.Get("json") - if value, ok := m[jsonName]; ok { - switch x := value.(type) { - case string: - switch field.Kind() { - case reflect.String: - field.SetString(x) - case reflect.Uint64, reflect.Uint: - if uintValue, err := strconv.ParseUint(x, 0, 64); err == nil { - field.SetUint(uintValue) - } - case reflect.Int64, reflect.Int: - if intValue, err := strconv.ParseInt(x, 0, 64); err == nil { - field.SetInt(intValue) - } - } - } - } - } -} - -func (block *Block) UnmarshalJSON(b []byte) error { - var m map[string]interface{} - if err := json.Unmarshal(b, &m); err != nil { - return err - } - mapToStruct(m, block) - //v := reflect.ValueOf(block).Elem() - //numFields := v.NumField() - //for i := 0; i < numFields; i++ { - // field := v.Field(i) - // jsonName := v.Type().Field(i).Tag.Get("json") - // if value, ok := m[jsonName]; ok { - // switch x := value.(type) { - // case string: - // switch field.Kind() { - // case reflect.String: - // field.SetString(x) - // case reflect.Uint64: - // if uintValue, err := strconv.ParseUint(x, 0, 64); err == nil { - // field.SetUint(uintValue) - // } - // } - // } - // } - //} - for _, x := range m["transactions"].([]interface{}) { - t := new(RPCTransaction) - m := x.(map[string]interface{}) - mapToStruct(m, t) - v, _ := new(big.Int).SetString(m["v"].(string), 0) - r, _ := new(big.Int).SetString(m["r"].(string), 0) - s, _ := new(big.Int).SetString(m["s"].(string), 0) - t.V = (*BigInt)(v) - t.R = (*BigInt)(r) - t.S = (*BigInt)(s) - fmt.Println(t.R, t.S, t.V) - block.Transactions = append(block.Transactions, *t) - } - return nil -} - 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 @@ -266,34 +219,10 @@ func (node *Node) BlockByNumber(blockNumber int64) (block Block) { number = fmt.Sprintf("0x%x", blockNumber) } node.Call(&block, "eth_getBlockByNumber", number, true) + block.Signer = node.BlockSigner(blockNumber) return } -//func (node *Node) BlockxByNumber(blockNumber int64) (block Block) { -// ethClient := ethclient.NewClient((*rpc.Client)(node)) -// b, err := ethClient.BlockByNumber(context.Background(), big.NewInt(blockNumber)) -// h := b.Header() -// Check(err) -// block.ParentHash = h.ParentHash -// block.Coinbase = h.Coinbase -// block.Root = h.Root -// block.TxHash = h.TxHash -// block.ReceiptHash = h.ReceiptHash -// block.Bloom = h.Bloom -// block.Difficulty = h.Difficulty -// block.Number = h.Number -// block.GasLimit = h.GasLimit -// block.GasUsed = h.GasUsed -// block.Time = h.Time -// block.Extra = h.Extra -// block.MixDigest = h.MixDigest -// block.Nonce = h.Nonce -// block.Transactions = b.Transactions() -// block.Signer, err = GetSigner(h) -// block.TotalDifficulty = b.DeprecatedTd() -// return block -//} - func (node *Node) BlockSigner(blockNumber int64) (signer string) { header := node.HeaderByNumber(blockNumber) signer, err := GetSigner(&header) diff --git a/bfa_client/src/client/bfa_client.go b/bfa_client/src/client/bfa_client.go index dcc6c4039a44c02aed5a111000a46b72571ceb13..99745668f1f809fc5f8dfc7c3b1c3b78b3745921 100644 --- a/bfa_client/src/client/bfa_client.go +++ b/bfa_client/src/client/bfa_client.go @@ -411,6 +411,20 @@ func block() { util.PrintJson(block) } +func snapshot() { + var blockNumber int64 + description = "Muestra el snapshot en un bloque" + setFlags() + flags.Int64Var(&blockNumber, "block-number", latest, "Número del bloque en el cual se quiere conocer la lista de selladores (-1 para el último)") + parseFlags() + url = updateURL(url) + node, err := bfa.Dial(url) + util.Check(err) + defer node.Close() + snapshot := node.SnapshotAtBlock(blockNumber) + util.PrintJson(snapshot) +} + func main() { var ( commands = map[string]func(){ @@ -420,6 +434,7 @@ func main() { "autovote": autovote, "status": status, "block": block, + "snapshot": snapshot, } validCommands []string )