mirror of
https://gitlab.com/pulsechaincom/erigon-pulse.git
synced 2025-01-08 20:11:21 +00:00
1039 lines
33 KiB
Go
1039 lines
33 KiB
Go
package main
|
|
|
|
import (
|
|
"bufio"
|
|
"bytes"
|
|
"encoding/json"
|
|
"fmt"
|
|
"io"
|
|
"net/http"
|
|
"os"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/ledgerwatch/turbo-geth/common"
|
|
"github.com/ledgerwatch/turbo-geth/common/hexutil"
|
|
"github.com/ledgerwatch/turbo-geth/crypto"
|
|
)
|
|
|
|
type EthError struct {
|
|
Code int `json:"code"`
|
|
Message string `json:"message"`
|
|
}
|
|
|
|
type CommonResponse struct {
|
|
Version string `json:"jsonrpc"`
|
|
RequestId int `json:"id"`
|
|
Error *EthError `json:"error"`
|
|
}
|
|
|
|
type EthBlockNumber struct {
|
|
CommonResponse
|
|
Number hexutil.Big `json:"result"`
|
|
}
|
|
|
|
type EthBalance struct {
|
|
CommonResponse
|
|
Balance hexutil.Big `json:"result"`
|
|
}
|
|
|
|
type EthTransaction struct {
|
|
From common.Address `json:"from"`
|
|
To *common.Address `json:"to"` // Pointer because it might be missing
|
|
Hash string `json:"hash"`
|
|
Gas hexutil.Big `json:"gas"`
|
|
}
|
|
|
|
type EthBlockByNumberResult struct {
|
|
Difficulty hexutil.Big `json:"difficulty"`
|
|
Miner common.Address `json:"miner"`
|
|
Transactions []EthTransaction `json:"transactions"`
|
|
TxRoot common.Hash `json:"transactionsRoot"`
|
|
Hash common.Hash `json:"hash"`
|
|
}
|
|
|
|
type EthBlockByNumber struct {
|
|
CommonResponse
|
|
Result EthBlockByNumberResult `json:"result"`
|
|
}
|
|
|
|
type StructLog struct {
|
|
Op string `json:"op"`
|
|
Pc uint64 `json:"pc"`
|
|
Depth uint64 `json:"depth"`
|
|
Error *EthError `json:"error"`
|
|
Gas uint64 `json:"gas"`
|
|
GasCost uint64 `json:"gasCost"`
|
|
Memory []string `json:"memory"`
|
|
Stack []string `json:"stack"`
|
|
Storage map[string]string `json:"storage"`
|
|
}
|
|
|
|
type EthTxTraceResult struct {
|
|
Gas uint64 `json:"gas"`
|
|
Failed bool `json:"failed"`
|
|
ReturnValue string `json:"returnValue"`
|
|
StructLogs []StructLog `json:"structLogs"`
|
|
}
|
|
|
|
type EthTxTrace struct {
|
|
CommonResponse
|
|
Result EthTxTraceResult `json:"result"`
|
|
}
|
|
|
|
type DebugModifiedAccounts struct {
|
|
CommonResponse
|
|
Result []common.Address `json:"result"`
|
|
}
|
|
|
|
// StorageRangeResult is the result of a debug_storageRangeAt API call.
|
|
type StorageRangeResult struct {
|
|
Storage storageMap `json:"storage"`
|
|
NextKey *common.Hash `json:"nextKey"` // nil if Storage includes the last key in the trie.
|
|
}
|
|
|
|
type storageMap map[common.Hash]storageEntry
|
|
|
|
type storageEntry struct {
|
|
Key *common.Hash `json:"key"`
|
|
Value common.Hash `json:"value"`
|
|
}
|
|
|
|
type DebugStorageRange struct {
|
|
CommonResponse
|
|
Result StorageRangeResult `json:"result"`
|
|
}
|
|
|
|
// Log represents a contract log event. These events are generated by the LOG opcode and
|
|
// stored/indexed by the node.
|
|
type Log struct {
|
|
// Consensus fields:
|
|
// address of the contract that generated the event
|
|
Address common.Address `json:"address" gencodec:"required"`
|
|
// list of topics provided by the contract.
|
|
Topics []common.Hash `json:"topics" gencodec:"required"`
|
|
// supplied by the contract, usually ABI-encoded
|
|
Data hexutil.Bytes `json:"data" gencodec:"required"`
|
|
|
|
// Derived fields. These fields are filled in by the node
|
|
// but not secured by consensus.
|
|
// block in which the transaction was included
|
|
BlockNumber hexutil.Uint64 `json:"blockNumber"`
|
|
// hash of the transaction
|
|
TxHash common.Hash `json:"transactionHash" gencodec:"required"`
|
|
// index of the transaction in the block
|
|
TxIndex hexutil.Uint `json:"transactionIndex" gencodec:"required"`
|
|
// hash of the block in which the transaction was included
|
|
BlockHash common.Hash `json:"blockHash"`
|
|
// index of the log in the receipt
|
|
Index hexutil.Uint `json:"logIndex" gencodec:"required"`
|
|
|
|
// The Removed field is true if this log was reverted due to a chain reorganisation.
|
|
// You must pay attention to this field if you receive logs through a filter query.
|
|
Removed bool `json:"removed"`
|
|
}
|
|
|
|
type Receipt struct {
|
|
// Consensus fields
|
|
PostState common.Hash `json:"root"`
|
|
Status hexutil.Uint64 `json:"status"`
|
|
CumulativeGasUsed hexutil.Uint64 `json:"cumulativeGasUsed" gencodec:"required"`
|
|
Bloom hexutil.Bytes `json:"logsBloom" gencodec:"required"`
|
|
Logs []*Log `json:"logs" gencodec:"required"`
|
|
|
|
// Implementation fields (don't reorder!)
|
|
TxHash common.Hash `json:"transactionHash" gencodec:"required"`
|
|
ContractAddress *common.Address `json:"contractAddress"`
|
|
GasUsed hexutil.Uint64 `json:"gasUsed" gencodec:"required"`
|
|
}
|
|
|
|
type EthReceipt struct {
|
|
CommonResponse
|
|
Result Receipt `json:"result"`
|
|
}
|
|
|
|
type EthLogs struct {
|
|
CommonResponse
|
|
Result []*Log `json:"result"`
|
|
}
|
|
|
|
func post(client *http.Client, url, request string, response interface{}) error {
|
|
start := time.Now()
|
|
r, err := client.Post(url, "application/json", strings.NewReader(request))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if r.StatusCode != 200 {
|
|
return fmt.Errorf("Status %s", r.Status)
|
|
}
|
|
decoder := json.NewDecoder(r.Body)
|
|
defer r.Body.Close()
|
|
err = decoder.Decode(response)
|
|
fmt.Printf("%s %s %f\n", url, request, time.Since(start).Seconds())
|
|
return err
|
|
}
|
|
|
|
func print(client *http.Client, url, request string) {
|
|
r, err := client.Post(url, "application/json", strings.NewReader(request))
|
|
if err != nil {
|
|
fmt.Printf("Could not print: %v\n", err)
|
|
return
|
|
}
|
|
if r.StatusCode != 200 {
|
|
fmt.Printf("Status %s", r.Status)
|
|
return
|
|
}
|
|
fmt.Printf("ContentLength: %d\n", r.ContentLength)
|
|
buf := make([]byte, 2000000)
|
|
l, err := r.Body.Read(buf)
|
|
if err != nil && err != io.EOF {
|
|
fmt.Printf("Could not read response: %v\n", err)
|
|
return
|
|
}
|
|
if l < len(buf) {
|
|
fmt.Printf("Could not read response: %d out of %d\n", l, len(buf))
|
|
//return
|
|
}
|
|
fmt.Printf("%s\n", buf[:l])
|
|
}
|
|
|
|
func compareBlocks(b, bg *EthBlockByNumber) bool {
|
|
r := b.Result
|
|
rg := bg.Result
|
|
if r.Difficulty.ToInt().Cmp(rg.Difficulty.ToInt()) != 0 {
|
|
fmt.Printf("Difficulty difference %d %d\n", r.Difficulty.ToInt(), rg.Difficulty.ToInt())
|
|
return false
|
|
}
|
|
if r.Miner != rg.Miner {
|
|
fmt.Printf("Miner different %x %x\n", r.Miner, rg.Miner)
|
|
return false
|
|
}
|
|
if len(r.Transactions) != len(rg.Transactions) {
|
|
fmt.Printf("Num of txs different: %d %d\n", len(r.Transactions), len(rg.Transactions))
|
|
return false
|
|
}
|
|
for i, tx := range r.Transactions {
|
|
txg := rg.Transactions[i]
|
|
if tx.From != txg.From {
|
|
fmt.Printf("Tx %d different From: %x %x\n", i, tx.From, txg.From)
|
|
return false
|
|
}
|
|
if (tx.To == nil && txg.To != nil) || (tx.To != nil && txg.To == nil) {
|
|
fmt.Printf("Tx %d different To nilness: %t %t\n", i, (tx.To == nil), (txg.To == nil))
|
|
return false
|
|
}
|
|
if tx.To != nil && txg.To != nil && *tx.To != *txg.To {
|
|
fmt.Printf("Tx %d different To: %x %x\n", i, *tx.To, *txg.To)
|
|
return false
|
|
}
|
|
if tx.Hash != txg.Hash {
|
|
fmt.Printf("Tx %x different Hash: %s %s\n", i, tx.Hash, txg.Hash)
|
|
return false
|
|
}
|
|
}
|
|
return true
|
|
}
|
|
|
|
func compareTraces(trace, traceg *EthTxTrace) bool {
|
|
r := trace.Result
|
|
rg := traceg.Result
|
|
if r.Gas != rg.Gas {
|
|
fmt.Printf("Trace different Gas: %d %d\n", r.Gas, rg.Gas)
|
|
return false
|
|
}
|
|
if r.Failed != rg.Failed {
|
|
fmt.Printf("Trace different Failed: %t %t\n", r.Failed, rg.Failed)
|
|
return false
|
|
}
|
|
if r.ReturnValue != rg.ReturnValue {
|
|
fmt.Printf("Trace different ReturnValue: %s %s\n", r.ReturnValue, rg.ReturnValue)
|
|
return false
|
|
}
|
|
if len(r.StructLogs) != len(rg.StructLogs) {
|
|
fmt.Printf("Trace different length: %d %d\n", len(r.StructLogs), len(rg.StructLogs))
|
|
return false
|
|
}
|
|
for i, l := range r.StructLogs {
|
|
lg := rg.StructLogs[i]
|
|
if l.Op != lg.Op {
|
|
fmt.Printf("Trace different Op: %d %s %s\n", i, l.Op, lg.Op)
|
|
return false
|
|
}
|
|
if l.Pc != lg.Pc {
|
|
fmt.Printf("Trace different Pc: %d %d %d\n", i, l.Pc, lg.Pc)
|
|
return false
|
|
}
|
|
}
|
|
return true
|
|
}
|
|
|
|
func compareBalances(balance, balanceg *EthBalance) bool {
|
|
if balance.Balance.ToInt().Cmp(balanceg.Balance.ToInt()) != 0 {
|
|
fmt.Printf("Different balance: %d %d\n", balance.Balance.ToInt(), balanceg.Balance.ToInt())
|
|
return false
|
|
}
|
|
return true
|
|
}
|
|
|
|
func compareModifiedAccounts(ma, mag *DebugModifiedAccounts) (bool, map[common.Address]struct{}) {
|
|
r := ma.Result
|
|
rg := mag.Result
|
|
rset := make(map[common.Address]struct{})
|
|
rsetg := make(map[common.Address]struct{})
|
|
for _, a := range r {
|
|
rset[a] = struct{}{}
|
|
}
|
|
for _, a := range rg {
|
|
rsetg[a] = struct{}{}
|
|
}
|
|
for _, a := range r {
|
|
if _, ok := rsetg[a]; !ok {
|
|
fmt.Printf("%x not present in rg\n", a)
|
|
// We tolerate that
|
|
//return false
|
|
}
|
|
}
|
|
for _, a := range rg {
|
|
if _, ok := rset[a]; !ok {
|
|
fmt.Printf("%x not present in r\n", a)
|
|
return false, nil
|
|
}
|
|
}
|
|
return true, rset
|
|
}
|
|
|
|
func compareStorageRanges(sm, smg map[common.Hash]storageEntry) bool {
|
|
for k, v := range sm {
|
|
if vg, ok := smg[k]; !ok {
|
|
fmt.Printf("%x not present in smg\n", k)
|
|
return false
|
|
} else {
|
|
if k != crypto.Keccak256Hash(v.Key[:]) {
|
|
fmt.Printf("Sec key %x does not match key %x\n", k, *v.Key)
|
|
return false
|
|
}
|
|
if v.Value != vg.Value {
|
|
fmt.Printf("Different values for %x: %x %x [%x]\n", k, v.Value, vg.Value, *v.Key)
|
|
return false
|
|
}
|
|
}
|
|
}
|
|
for k, _ := range smg {
|
|
if _, ok := sm[k]; !ok {
|
|
fmt.Printf("%x not present in sm\n", k)
|
|
return false
|
|
}
|
|
}
|
|
return true
|
|
}
|
|
|
|
/*
|
|
// Derived fields. These fields are filled in by the node
|
|
// but not secured by consensus.
|
|
// block in which the transaction was included
|
|
BlockNumber hexutil.Uint64 `json:"blockNumber"`
|
|
// hash of the transaction
|
|
TxHash common.Hash `json:"transactionHash" gencodec:"required"`
|
|
// index of the transaction in the block
|
|
TxIndex hexutil.Uint `json:"transactionIndex" gencodec:"required"`
|
|
// hash of the block in which the transaction was included
|
|
BlockHash common.Hash `json:"blockHash"`
|
|
// index of the log in the receipt
|
|
Index hexutil.Uint `json:"logIndex" gencodec:"required"`
|
|
|
|
// The Removed field is true if this log was reverted due to a chain reorganisation.
|
|
// You must pay attention to this field if you receive logs through a filter query.
|
|
Removed bool `json:"removed"`
|
|
*/
|
|
|
|
func compareReceipts(receipt, receiptg *EthReceipt) bool {
|
|
r := receipt.Result
|
|
rg := receiptg.Result
|
|
if r.TxHash != rg.TxHash {
|
|
fmt.Printf("Different tx hashes: %x %x\n", r.TxHash, rg.TxHash)
|
|
return false
|
|
}
|
|
if r.Status != rg.Status {
|
|
//fmt.Printf("Different status: %d %d\n", r.Status, rg.Status)
|
|
//return false
|
|
}
|
|
if r.CumulativeGasUsed != rg.CumulativeGasUsed {
|
|
fmt.Printf("Different cumulativeGasUsed: %d %d\n", r.CumulativeGasUsed, rg.CumulativeGasUsed)
|
|
return false
|
|
}
|
|
if !bytes.Equal(r.Bloom, rg.Bloom) {
|
|
fmt.Printf("Different blooms: %x %x\n", r.Bloom, rg.Bloom)
|
|
return false
|
|
}
|
|
if r.ContractAddress == nil && rg.ContractAddress != nil {
|
|
fmt.Printf("Different contract addresses: nil %x\n", rg.ContractAddress)
|
|
return false
|
|
}
|
|
if r.ContractAddress != nil && rg.ContractAddress == nil {
|
|
fmt.Printf("Different contract addresses: %x nil\n", r.ContractAddress)
|
|
return false
|
|
}
|
|
if r.ContractAddress != nil && rg.ContractAddress != nil && *r.ContractAddress != *rg.ContractAddress {
|
|
fmt.Printf("Different contract addresses: %x %x\n", r.ContractAddress, rg.ContractAddress)
|
|
return false
|
|
}
|
|
if r.GasUsed != rg.GasUsed {
|
|
fmt.Printf("Different gasUsed: %d %d\n", r.GasUsed, rg.GasUsed)
|
|
return false
|
|
}
|
|
if len(r.Logs) != len(rg.Logs) {
|
|
fmt.Printf("Different log lenths: %d %d\n", len(r.Logs), len(rg.Logs))
|
|
return false
|
|
}
|
|
for i, l := range r.Logs {
|
|
lg := rg.Logs[i]
|
|
if l.Address != lg.Address {
|
|
fmt.Printf("Different log %d addresses: %x %x\n", i, l.Address, lg.Address)
|
|
return false
|
|
}
|
|
if len(l.Topics) != len(lg.Topics) {
|
|
fmt.Printf("Different log %d topic lengths: %d %d\n", i, len(l.Topics), len(lg.Topics))
|
|
return false
|
|
}
|
|
for j, t := range l.Topics {
|
|
tg := lg.Topics[j]
|
|
if t != tg {
|
|
fmt.Printf("Different log %d topics %d: %x %x\n", i, j, t, tg)
|
|
return false
|
|
}
|
|
}
|
|
if !bytes.Equal(l.Data, lg.Data) {
|
|
fmt.Printf("Different log %d data: %x %x\n", i, l.Data, lg.Data)
|
|
return false
|
|
}
|
|
}
|
|
return true
|
|
}
|
|
|
|
func compareLogs(logs, logsg *EthLogs) bool {
|
|
r := logs.Result
|
|
rg := logsg.Result
|
|
if len(r) != len(rg) {
|
|
fmt.Printf("Different log lenths: %d %d\n", len(r), len(rg))
|
|
return false
|
|
}
|
|
for i, l := range r {
|
|
lg := rg[i]
|
|
if l.Address != lg.Address {
|
|
fmt.Printf("Different log %d addresses: %x %x\n", i, l.Address, lg.Address)
|
|
return false
|
|
}
|
|
if len(l.Topics) != len(lg.Topics) {
|
|
fmt.Printf("Different log %d topic lengths: %d %d\n", i, len(l.Topics), len(lg.Topics))
|
|
return false
|
|
}
|
|
for j, t := range l.Topics {
|
|
tg := lg.Topics[j]
|
|
if t != tg {
|
|
fmt.Printf("Different log %d topics %d: %x %x\n", i, j, t, tg)
|
|
return false
|
|
}
|
|
}
|
|
if !bytes.Equal(l.Data, lg.Data) {
|
|
fmt.Printf("Different log %d data: %x %x\n", i, l.Data, lg.Data)
|
|
return false
|
|
}
|
|
}
|
|
return true
|
|
}
|
|
|
|
func bench1() {
|
|
var client = &http.Client{
|
|
Timeout: time.Second * 600,
|
|
}
|
|
req_id := 0
|
|
//geth_url := "http://192.168.1.96:8545"
|
|
geth_url := "http://localhost:8545"
|
|
turbogeth_url := "http://localhost:9545"
|
|
req_id++
|
|
template := `{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":%d}`
|
|
var blockNumber EthBlockNumber
|
|
if err := post(client, turbogeth_url, fmt.Sprintf(template, req_id), &blockNumber); err != nil {
|
|
fmt.Printf("Could not get block number: %v\n", err)
|
|
return
|
|
}
|
|
if blockNumber.Error != nil {
|
|
fmt.Printf("Error getting block number: %d %s\n", blockNumber.Error.Code, blockNumber.Error.Message)
|
|
return
|
|
}
|
|
lastBlock := blockNumber.Number.ToInt().Int64()
|
|
fmt.Printf("Last block: %d\n", lastBlock)
|
|
accounts := make(map[common.Address]struct{})
|
|
firstBn := 5250001
|
|
prevBn := firstBn
|
|
storageCounter := 0
|
|
for bn := firstBn; bn <= int(lastBlock); bn++ {
|
|
req_id++
|
|
template := `{"jsonrpc":"2.0","method":"eth_getBlockByNumber","params":["0x%x",true],"id":%d}`
|
|
var b EthBlockByNumber
|
|
if err := post(client, turbogeth_url, fmt.Sprintf(template, bn, req_id), &b); err != nil {
|
|
fmt.Printf("Could not retrieve block %d: %v\n", bn, err)
|
|
return
|
|
}
|
|
if b.Error != nil {
|
|
fmt.Printf("Error retrieving block: %d %s\n", b.Error.Code, b.Error.Message)
|
|
}
|
|
var bg EthBlockByNumber
|
|
if err := post(client, geth_url, fmt.Sprintf(template, bn, req_id), &bg); err != nil {
|
|
fmt.Printf("Could not retrieve block g %d: %v\n", bn, err)
|
|
return
|
|
}
|
|
if bg.Error != nil {
|
|
fmt.Printf("Error retrieving block g: %d %s\n", bg.Error.Code, bg.Error.Message)
|
|
return
|
|
}
|
|
if !compareBlocks(&b, &bg) {
|
|
fmt.Printf("Block difference for %d\n", bn)
|
|
return
|
|
}
|
|
accounts[b.Result.Miner] = struct{}{}
|
|
for i, tx := range b.Result.Transactions {
|
|
accounts[tx.From] = struct{}{}
|
|
if tx.To != nil {
|
|
accounts[*tx.To] = struct{}{}
|
|
}
|
|
if tx.To != nil && tx.Gas.ToInt().Uint64() > 21000 {
|
|
storageCounter++
|
|
if storageCounter == 100 {
|
|
storageCounter = 0
|
|
req_id++
|
|
template = `{"jsonrpc":"2.0","method":"debug_storageRangeAt","params":["0x%x", %d,"0x%x","0x%x",%d],"id":%d}`
|
|
sm := make(map[common.Hash]storageEntry)
|
|
nextKey := &common.Hash{}
|
|
for nextKey != nil {
|
|
var sr DebugStorageRange
|
|
if err := post(client, turbogeth_url, fmt.Sprintf(template, b.Result.Hash, i, tx.To, *nextKey, 1024, req_id), &sr); err != nil {
|
|
fmt.Printf("Could not get storageRange: %s: %v\n", tx.Hash, err)
|
|
return
|
|
}
|
|
if sr.Error != nil {
|
|
fmt.Printf("Error getting storageRange: %d %s\n", sr.Error.Code, sr.Error.Message)
|
|
break
|
|
} else {
|
|
nextKey = sr.Result.NextKey
|
|
for k, v := range sr.Result.Storage {
|
|
sm[k] = v
|
|
}
|
|
}
|
|
}
|
|
fmt.Printf("storageRange: %d\n", len(sm))
|
|
smg := make(map[common.Hash]storageEntry)
|
|
nextKey = &common.Hash{}
|
|
for nextKey != nil {
|
|
var srg DebugStorageRange
|
|
if err := post(client, geth_url, fmt.Sprintf(template, b.Result.Hash, i, tx.To, *nextKey, 1024, req_id), &srg); err != nil {
|
|
fmt.Printf("Could not get storageRange g: %s: %v\n", tx.Hash, err)
|
|
return
|
|
}
|
|
if srg.Error != nil {
|
|
fmt.Printf("Error getting storageRange g: %d %s\n", srg.Error.Code, srg.Error.Message)
|
|
break
|
|
} else {
|
|
nextKey = srg.Result.NextKey
|
|
for k, v := range srg.Result.Storage {
|
|
smg[k] = v
|
|
}
|
|
}
|
|
}
|
|
fmt.Printf("storageRange g: %d\n", len(smg))
|
|
if !compareStorageRanges(sm, smg) {
|
|
fmt.Printf("Different in storage ranges tx %s\n", tx.Hash)
|
|
return
|
|
}
|
|
}
|
|
}
|
|
req_id++
|
|
template = `{"jsonrpc":"2.0","method":"debug_traceTransaction","params":["%s"],"id":%d}`
|
|
var trace EthTxTrace
|
|
if err := post(client, turbogeth_url, fmt.Sprintf(template, tx.Hash, req_id), &trace); err != nil {
|
|
fmt.Printf("Could not trace transaction %s: %v\n", tx.Hash, err)
|
|
print(client, turbogeth_url, fmt.Sprintf(template, tx.Hash, req_id))
|
|
return
|
|
}
|
|
if trace.Error != nil {
|
|
fmt.Printf("Error tracing transaction: %d %s\n", trace.Error.Code, trace.Error.Message)
|
|
}
|
|
var traceg EthTxTrace
|
|
if err := post(client, geth_url, fmt.Sprintf(template, tx.Hash, req_id), &traceg); err != nil {
|
|
fmt.Printf("Could not trace transaction g %s: %v\n", tx.Hash, err)
|
|
print(client, geth_url, fmt.Sprintf(template, tx.Hash, req_id))
|
|
return
|
|
}
|
|
if traceg.Error != nil {
|
|
fmt.Printf("Error tracing transaction g: %d %s\n", traceg.Error.Code, traceg.Error.Message)
|
|
return
|
|
}
|
|
if !compareTraces(&trace, &traceg) {
|
|
fmt.Printf("Different traces block %d, tx %s\n", bn, tx.Hash)
|
|
return
|
|
}
|
|
req_id++
|
|
template = `{"jsonrpc":"2.0","method":"eth_getTransactionReceipt","params":["%s"],"id":%d}`
|
|
var receipt EthReceipt
|
|
if err := post(client, turbogeth_url, fmt.Sprintf(template, tx.Hash, req_id), &receipt); err != nil {
|
|
fmt.Printf("Count not get receipt: %s: %v\n", tx.Hash, err)
|
|
print(client, turbogeth_url, fmt.Sprintf(template, tx.Hash, req_id))
|
|
return
|
|
}
|
|
if receipt.Error != nil {
|
|
fmt.Printf("Error getting receipt: %d %s\n", receipt.Error.Code, receipt.Error.Message)
|
|
return
|
|
}
|
|
var receiptg EthReceipt
|
|
if err := post(client, geth_url, fmt.Sprintf(template, tx.Hash, req_id), &receiptg); err != nil {
|
|
fmt.Printf("Count not get receipt g: %s: %v\n", tx.Hash, err)
|
|
print(client, geth_url, fmt.Sprintf(template, tx.Hash, req_id))
|
|
return
|
|
}
|
|
if receiptg.Error != nil {
|
|
fmt.Printf("Error getting receipt g: %d %s\n", receiptg.Error.Code, receiptg.Error.Message)
|
|
return
|
|
}
|
|
if !compareReceipts(&receipt, &receiptg) {
|
|
fmt.Printf("Different receipts block %d, tx %s\n", bn, tx.Hash)
|
|
print(client, turbogeth_url, fmt.Sprintf(template, tx.Hash, req_id))
|
|
print(client, geth_url, fmt.Sprintf(template, tx.Hash, req_id))
|
|
return
|
|
}
|
|
}
|
|
req_id++
|
|
template = `{"jsonrpc":"2.0","method":"eth_getBalance","params":["0x%x", "0x%x"],"id":%d}`
|
|
var balance EthBalance
|
|
if err := post(client, turbogeth_url, fmt.Sprintf(template, b.Result.Miner, bn, req_id), &balance); err != nil {
|
|
fmt.Printf("Could not get account balance: %v\n", err)
|
|
return
|
|
}
|
|
if balance.Error != nil {
|
|
fmt.Printf("Error getting account balance: %d %s", balance.Error.Code, balance.Error.Message)
|
|
return
|
|
}
|
|
var balanceg EthBalance
|
|
if err := post(client, geth_url, fmt.Sprintf(template, b.Result.Miner, bn, req_id), &balanceg); err != nil {
|
|
fmt.Printf("Could not get account balance g: %v\n", err)
|
|
return
|
|
}
|
|
if balanceg.Error != nil {
|
|
fmt.Printf("Error getting account balance g: %d %s\n", balanceg.Error.Code, balanceg.Error.Message)
|
|
return
|
|
}
|
|
if !compareBalances(&balance, &balanceg) {
|
|
fmt.Printf("Miner %x balance difference for block %d\n", b.Result.Miner, bn)
|
|
return
|
|
}
|
|
if prevBn < bn && bn%100 == 0 {
|
|
// Checking modified accounts
|
|
req_id++
|
|
template = `{"jsonrpc":"2.0","method":"debug_getModifiedAccountsByNumber","params":[%d, %d],"id":%d}`
|
|
var ma DebugModifiedAccounts
|
|
if err := post(client, turbogeth_url, fmt.Sprintf(template, prevBn, bn, req_id), &ma); err != nil {
|
|
fmt.Printf("Could not get modified accounts: %v\n", err)
|
|
return
|
|
}
|
|
if ma.Error != nil {
|
|
fmt.Printf("Error getting modified accounts: %d %s\n", ma.Error.Code, ma.Error.Message)
|
|
return
|
|
}
|
|
var mag DebugModifiedAccounts
|
|
if err := post(client, geth_url, fmt.Sprintf(template, prevBn, bn, req_id), &mag); err != nil {
|
|
fmt.Printf("Could not get modified accounts g: %v\n", err)
|
|
return
|
|
}
|
|
if mag.Error != nil {
|
|
fmt.Printf("Error getting modified accounts g: %d %s\n", mag.Error.Code, mag.Error.Message)
|
|
return
|
|
}
|
|
ok, accountSet := compareModifiedAccounts(&ma, &mag)
|
|
if !ok {
|
|
fmt.Printf("Modified accouts different for blocks %d-%d\n", prevBn, bn)
|
|
return
|
|
}
|
|
req_id++
|
|
template = `{"jsonrpc":"2.0","method":"eth_getLogs","params":[{"fromBlock": "0x%x", "toBlock": "0x%x", "address": "0x%x"}],"id":%d}`
|
|
for account, _ := range accountSet {
|
|
var logs EthLogs
|
|
if err := post(client, turbogeth_url, fmt.Sprintf(template, prevBn, bn, account, req_id), &logs); err != nil {
|
|
fmt.Printf("Could not get logs for account %x: %v\n", account, err)
|
|
return
|
|
}
|
|
if logs.Error != nil {
|
|
fmt.Printf("Error getting logs for account %x: %d %s\n", account, logs.Error.Code, logs.Error.Message)
|
|
return
|
|
}
|
|
var logsg EthLogs
|
|
if err := post(client, geth_url, fmt.Sprintf(template, prevBn, bn, account, req_id), &logsg); err != nil {
|
|
fmt.Printf("Could not get logs for account g %x: %v\n", account, err)
|
|
return
|
|
}
|
|
if logsg.Error != nil {
|
|
fmt.Printf("Error getting logs for account g %x: %d %s\n", account, logsg.Error.Code, logsg.Error.Message)
|
|
return
|
|
}
|
|
if !compareLogs(&logs, &logsg) {
|
|
fmt.Printf("Different logs for account %x and block %d-%d\n", account, prevBn, bn)
|
|
return
|
|
}
|
|
}
|
|
fmt.Printf("Done blocks %d-%d, modified accounts: %d (%d)\n", prevBn, bn, len(ma.Result), len(mag.Result))
|
|
prevBn = bn
|
|
}
|
|
}
|
|
}
|
|
|
|
func bench2() {
|
|
var client = &http.Client{
|
|
Timeout: time.Second * 600,
|
|
}
|
|
req_id := 0
|
|
turbogeth_url := "http://localhost:8545"
|
|
req_id++
|
|
template := `
|
|
{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":%d}
|
|
`
|
|
var blockNumber EthBlockNumber
|
|
if err := post(client, turbogeth_url, fmt.Sprintf(template, req_id), &blockNumber); err != nil {
|
|
fmt.Printf("Could not get block number: %v\n", err)
|
|
return
|
|
}
|
|
if blockNumber.Error != nil {
|
|
fmt.Printf("Error getting block number: %d %s\n", blockNumber.Error.Code, blockNumber.Error.Message)
|
|
return
|
|
}
|
|
lastBlock := blockNumber.Number.ToInt().Int64()
|
|
fmt.Printf("Last block: %d\n", lastBlock)
|
|
firstBn := 1720000 - 2
|
|
prevBn := firstBn
|
|
for bn := firstBn; bn <= int(lastBlock); bn++ {
|
|
req_id++
|
|
template := `
|
|
{"jsonrpc":"2.0","method":"eth_getBlockByNumber","params":["0x%x",true],"id":%d}
|
|
`
|
|
var b EthBlockByNumber
|
|
if err := post(client, turbogeth_url, fmt.Sprintf(template, bn, req_id), &b); err != nil {
|
|
fmt.Printf("Could not retrieve block %d: %v\n", bn, err)
|
|
return
|
|
}
|
|
if b.Error != nil {
|
|
fmt.Printf("Error retrieving block: %d %s\n", b.Error.Code, b.Error.Message)
|
|
}
|
|
for i, tx := range b.Result.Transactions {
|
|
if tx.To != nil && tx.Gas.ToInt().Uint64() > 21000 {
|
|
// Request storage range
|
|
// blockHash common.Hash, txIndex int, contractAddress common.Address, keyStart hexutil.Bytes, maxResult int
|
|
req_id++
|
|
template = `
|
|
{"jsonrpc":"2.0","method":"debug_storageRangeAt","params":["0x%x", %d,"0x%x","0x%x",%d],"id":%d}
|
|
`
|
|
sm := make(map[common.Hash]storageEntry)
|
|
nextKey := &common.Hash{}
|
|
for nextKey != nil {
|
|
var sr DebugStorageRange
|
|
if err := post(client, turbogeth_url, fmt.Sprintf(template, b.Result.Hash, i, tx.To, *nextKey, 1024, req_id), &sr); err != nil {
|
|
fmt.Printf("Could not get storageRange: %x: %v\n", tx.Hash, err)
|
|
return
|
|
}
|
|
if sr.Error != nil {
|
|
fmt.Printf("Error getting storageRange: %d %s\n", sr.Error.Code, sr.Error.Message)
|
|
break
|
|
} else {
|
|
nextKey = sr.Result.NextKey
|
|
for k, v := range sr.Result.Storage {
|
|
sm[k] = v
|
|
if v.Key == nil {
|
|
fmt.Printf("No key for sec key: %x\n", k)
|
|
} else if k != crypto.Keccak256Hash(v.Key[:]) {
|
|
fmt.Printf("Different sec key: %x %x (%x), value %x\n", k, crypto.Keccak256Hash(v.Key[:]), *(v.Key), v.Value)
|
|
} else {
|
|
fmt.Printf("Keys: %x %x, value %x\n", *(v.Key), k, v.Value)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
fmt.Printf("storageRange: %d\n", len(sm))
|
|
}
|
|
}
|
|
if prevBn < bn && bn%1000 == 0 {
|
|
// Checking modified accounts
|
|
req_id++
|
|
template = `
|
|
{"jsonrpc":"2.0","method":"debug_getModifiedAccountsByNumber","params":[%d, %d],"id":%d}
|
|
`
|
|
var ma DebugModifiedAccounts
|
|
if err := post(client, turbogeth_url, fmt.Sprintf(template, prevBn, bn, req_id), &ma); err != nil {
|
|
fmt.Printf("Could not get modified accounts: %v\n", err)
|
|
return
|
|
}
|
|
if ma.Error != nil {
|
|
fmt.Printf("Error getting modified accounts: %d %s\n", ma.Error.Code, ma.Error.Message)
|
|
return
|
|
}
|
|
fmt.Printf("Done blocks %d-%d, modified accounts: %d\n", prevBn, bn, len(ma.Result))
|
|
prevBn = bn
|
|
}
|
|
}
|
|
}
|
|
|
|
func bench3() {
|
|
var client = &http.Client{
|
|
Timeout: time.Second * 600,
|
|
}
|
|
geth_url := "http://localhost:8545"
|
|
turbogeth_url := "http://localhost:9545"
|
|
blockhash := common.HexToHash("0xdf15213766f00680c6a20ba76ba2cc9534435e19bc490039f3a7ef42095c8d13")
|
|
req_id := 1
|
|
template := `
|
|
{"jsonrpc":"2.0","method":"eth_getBlockByNumber","params":["0x%x",true],"id":%d}
|
|
`
|
|
var b EthBlockByNumber
|
|
if err := post(client, turbogeth_url, fmt.Sprintf(template, 1720000, req_id), &b); err != nil {
|
|
fmt.Printf("Could not retrieve block %d: %v\n", 1720000, err)
|
|
return
|
|
}
|
|
if b.Error != nil {
|
|
fmt.Printf("Error retrieving block: %d %s\n", b.Error.Code, b.Error.Message)
|
|
}
|
|
for txindex := 0; txindex < 18; txindex++ {
|
|
txhash := b.Result.Transactions[txindex].Hash
|
|
req_id++
|
|
template = `
|
|
{"jsonrpc":"2.0","method":"debug_traceTransaction","params":["%s"],"id":%d}
|
|
`
|
|
var trace EthTxTrace
|
|
if err := post(client, turbogeth_url, fmt.Sprintf(template, txhash, req_id), &trace); err != nil {
|
|
fmt.Printf("Could not trace transaction %s: %v\n", txhash, err)
|
|
print(client, turbogeth_url, fmt.Sprintf(template, txhash, req_id))
|
|
return
|
|
}
|
|
if trace.Error != nil {
|
|
fmt.Printf("Error tracing transaction: %d %s\n", trace.Error.Code, trace.Error.Message)
|
|
}
|
|
var traceg EthTxTrace
|
|
if err := post(client, geth_url, fmt.Sprintf(template, txhash, req_id), &traceg); err != nil {
|
|
fmt.Printf("Could not trace transaction g %s: %v\n", txhash, err)
|
|
print(client, geth_url, fmt.Sprintf(template, txhash, req_id))
|
|
return
|
|
}
|
|
if traceg.Error != nil {
|
|
fmt.Printf("Error tracing transaction g: %d %s\n", traceg.Error.Code, traceg.Error.Message)
|
|
return
|
|
}
|
|
//print(client, turbogeth_url, fmt.Sprintf(template, txhash, req_id))
|
|
if !compareTraces(&trace, &traceg) {
|
|
fmt.Printf("Different traces block %d, tx %s\n", 1720000, txhash)
|
|
return
|
|
}
|
|
}
|
|
to := common.HexToAddress("0xbb9bc244d798123fde783fcc1c72d3bb8c189413")
|
|
sm := make(map[common.Hash]storageEntry)
|
|
start := common.HexToHash("0x5aa12c260b07325d83f0c9170a2c667948d0247cad4ad999cd00148658b0552d")
|
|
|
|
req_id++
|
|
template = `
|
|
{"jsonrpc":"2.0","method":"debug_storageRangeAt","params":["0x%x", %d,"0x%x","0x%x",%d],"id":%d}
|
|
`
|
|
i := 18
|
|
nextKey := &start
|
|
for nextKey != nil {
|
|
var sr DebugStorageRange
|
|
if err := post(client, turbogeth_url, fmt.Sprintf(template, blockhash, i, to, *nextKey, 1024, req_id), &sr); err != nil {
|
|
fmt.Printf("Could not get storageRange: %v\n", err)
|
|
return
|
|
}
|
|
if sr.Error != nil {
|
|
fmt.Printf("Error getting storageRange: %d %s\n", sr.Error.Code, sr.Error.Message)
|
|
break
|
|
} else {
|
|
nextKey = sr.Result.NextKey
|
|
for k, v := range sr.Result.Storage {
|
|
sm[k] = v
|
|
}
|
|
}
|
|
}
|
|
fmt.Printf("storageRange: %d\n", len(sm))
|
|
smg := make(map[common.Hash]storageEntry)
|
|
nextKey = &start
|
|
for nextKey != nil {
|
|
var srg DebugStorageRange
|
|
if err := post(client, geth_url, fmt.Sprintf(template, blockhash, i, to, *nextKey, 1024, req_id), &srg); err != nil {
|
|
fmt.Printf("Could not get storageRange g: %v\n", err)
|
|
return
|
|
}
|
|
if srg.Error != nil {
|
|
fmt.Printf("Error getting storageRange g: %d %s\n", srg.Error.Code, srg.Error.Message)
|
|
break
|
|
} else {
|
|
nextKey = srg.Result.NextKey
|
|
for k, v := range srg.Result.Storage {
|
|
smg[k] = v
|
|
}
|
|
}
|
|
}
|
|
fmt.Printf("storageRange g: %d\n", len(smg))
|
|
if !compareStorageRanges(sm, smg) {
|
|
fmt.Printf("Different in storage ranges tx\n")
|
|
return
|
|
}
|
|
}
|
|
|
|
func bench4() {
|
|
var client = &http.Client{
|
|
Timeout: time.Second * 600,
|
|
}
|
|
turbogeth_url := "http://localhost:9545"
|
|
blockhash := common.HexToHash("0xdf15213766f00680c6a20ba76ba2cc9534435e19bc490039f3a7ef42095c8d13")
|
|
req_id := 1
|
|
template := `
|
|
{"jsonrpc":"2.0","method":"eth_getBlockByNumber","params":["0x%x",true],"id":%d}
|
|
`
|
|
var b EthBlockByNumber
|
|
if err := post(client, turbogeth_url, fmt.Sprintf(template, 1720000, req_id), &b); err != nil {
|
|
fmt.Printf("Could not retrieve block %d: %v\n", 1720000, err)
|
|
return
|
|
}
|
|
if b.Error != nil {
|
|
fmt.Printf("Error retrieving block: %d %s\n", b.Error.Code, b.Error.Message)
|
|
}
|
|
for txindex := 0; txindex < 6; txindex++ {
|
|
txhash := b.Result.Transactions[txindex].Hash
|
|
req_id++
|
|
template = `
|
|
{"jsonrpc":"2.0","method":"debug_traceTransaction","params":["%s"],"id":%d}
|
|
`
|
|
var trace EthTxTrace
|
|
if err := post(client, turbogeth_url, fmt.Sprintf(template, txhash, req_id), &trace); err != nil {
|
|
fmt.Printf("Could not trace transaction %s: %v\n", txhash, err)
|
|
print(client, turbogeth_url, fmt.Sprintf(template, txhash, req_id))
|
|
return
|
|
}
|
|
if trace.Error != nil {
|
|
fmt.Printf("Error tracing transaction: %d %s\n", trace.Error.Code, trace.Error.Message)
|
|
}
|
|
print(client, turbogeth_url, fmt.Sprintf(template, txhash, req_id))
|
|
}
|
|
to := common.HexToAddress("0x8b3b3b624c3c0397d3da8fd861512393d51dcbac")
|
|
sm := make(map[common.Hash]storageEntry)
|
|
start := common.HexToHash("0xa283ff49a55f86420a4acd5835658d8f45180db430c7b0d7ae98da5c64f620dc")
|
|
|
|
req_id++
|
|
template = `
|
|
{"jsonrpc":"2.0","method":"debug_storageRangeAt","params":["0x%x", %d,"0x%x","0x%x",%d],"id":%d}
|
|
`
|
|
i := 6
|
|
nextKey := &start
|
|
for nextKey != nil {
|
|
var sr DebugStorageRange
|
|
if err := post(client, turbogeth_url, fmt.Sprintf(template, blockhash, i, to, *nextKey, 1024, req_id), &sr); err != nil {
|
|
fmt.Printf("Could not get storageRange: %v\n", err)
|
|
return
|
|
}
|
|
if sr.Error != nil {
|
|
fmt.Printf("Error getting storageRange: %d %s\n", sr.Error.Code, sr.Error.Message)
|
|
break
|
|
} else {
|
|
nextKey = sr.Result.NextKey
|
|
for k, v := range sr.Result.Storage {
|
|
sm[k] = v
|
|
}
|
|
}
|
|
}
|
|
fmt.Printf("storageRange: %d\n", len(sm))
|
|
}
|
|
|
|
func bench5() {
|
|
var client = &http.Client{
|
|
Timeout: time.Second * 600,
|
|
}
|
|
turbogeth_url := "http://localhost:9545"
|
|
file, err := os.Open("txs.txt")
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
req_id := 0
|
|
template := `{"jsonrpc":"2.0","method":"eth_getTransactionReceipt","params":["0x%s"],"id":%d}`
|
|
var receipt EthReceipt
|
|
scanner := bufio.NewScanner(file)
|
|
for scanner.Scan() {
|
|
req_id++
|
|
if err := post(client, turbogeth_url, fmt.Sprintf(template, scanner.Text(), req_id), &receipt); err != nil {
|
|
fmt.Printf("Count not get receipt: %s: %v\n", scanner.Text(), err)
|
|
return
|
|
}
|
|
if receipt.Error != nil {
|
|
fmt.Printf("Error getting receipt: %d %s\n", receipt.Error.Code, receipt.Error.Message)
|
|
return
|
|
}
|
|
}
|
|
err = scanner.Err()
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
}
|
|
|
|
func bench6() {
|
|
var client = &http.Client{
|
|
Timeout: time.Second * 600,
|
|
}
|
|
req_id := 0
|
|
turbogeth_url := "http://localhost:8545"
|
|
req_id++
|
|
template := `
|
|
{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":%d}
|
|
`
|
|
var blockNumber EthBlockNumber
|
|
if err := post(client, turbogeth_url, fmt.Sprintf(template, req_id), &blockNumber); err != nil {
|
|
fmt.Printf("Could not get block number: %v\n", err)
|
|
return
|
|
}
|
|
if blockNumber.Error != nil {
|
|
fmt.Printf("Error getting block number: %d %s\n", blockNumber.Error.Code, blockNumber.Error.Message)
|
|
return
|
|
}
|
|
lastBlock := blockNumber.Number.ToInt().Int64()
|
|
fmt.Printf("Last block: %d\n", lastBlock)
|
|
accounts := make(map[common.Address]struct{})
|
|
firstBn := 100000
|
|
for bn := firstBn; bn <= int(lastBlock); bn++ {
|
|
req_id++
|
|
template := `
|
|
{"jsonrpc":"2.0","method":"eth_getBlockByNumber","params":["0x%x",true],"id":%d}
|
|
`
|
|
var b EthBlockByNumber
|
|
if err := post(client, turbogeth_url, fmt.Sprintf(template, bn, req_id), &b); err != nil {
|
|
fmt.Printf("Could not retrieve block %d: %v\n", bn, err)
|
|
return
|
|
}
|
|
if b.Error != nil {
|
|
fmt.Printf("Error retrieving block: %d %s\n", b.Error.Code, b.Error.Message)
|
|
}
|
|
accounts[b.Result.Miner] = struct{}{}
|
|
for _, tx := range b.Result.Transactions {
|
|
accounts[tx.From] = struct{}{}
|
|
if tx.To != nil {
|
|
accounts[*tx.To] = struct{}{}
|
|
}
|
|
req_id++
|
|
template = `
|
|
{"jsonrpc":"2.0","method":"eth_getTransactionReceipt","params":["%s"],"id":%d}
|
|
`
|
|
var receipt EthReceipt
|
|
if err := post(client, turbogeth_url, fmt.Sprintf(template, tx.Hash, req_id), &receipt); err != nil {
|
|
fmt.Printf("Count not get receipt: %s: %v\n", tx.Hash, err)
|
|
print(client, turbogeth_url, fmt.Sprintf(template, tx.Hash, req_id))
|
|
return
|
|
}
|
|
if receipt.Error != nil {
|
|
fmt.Printf("Error getting receipt: %d %s\n", receipt.Error.Code, receipt.Error.Message)
|
|
return
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func main() {
|
|
bench1()
|
|
}
|