From 6a83a911453cd2f3d7fbe6dfec10f15ae398c24b Mon Sep 17 00:00:00 2001 From: lupin012 <58134934+lupin012@users.noreply.github.com> Date: Sat, 23 Dec 2023 15:38:47 +0100 Subject: [PATCH] Add create access list test (#9062) --- cmd/rpctest/main.go | 14 +++ .../rpctest/bench_ethcreateaccesslist.go | 113 ++++++++++++++++++ cmd/rpctest/rpctest/request_generator.go | 22 ++++ 3 files changed, 149 insertions(+) create mode 100644 cmd/rpctest/rpctest/bench_ethcreateaccesslist.go diff --git a/cmd/rpctest/main.go b/cmd/rpctest/main.go index 7f5c8a884..44b53f85d 100644 --- a/cmd/rpctest/main.go +++ b/cmd/rpctest/main.go @@ -73,6 +73,19 @@ func main() { } with(benchEthCallCmd, withErigonUrl, withGethUrl, withNeedCompare, withBlockNum, withRecord, withErrorFile, withLatest) + var benchEthCreateAccessListCmd = &cobra.Command{ + Use: "benchEthCreateAccessList", + Short: "", + Long: ``, + Run: func(cmd *cobra.Command, args []string) { + err := rpctest.BenchEthCreateAccessList(erigonURL, gethURL, needCompare, latest, blockFrom, blockTo, recordFile, errorFile) + if err != nil { + logger.Error(err.Error()) + } + }, + } + with(benchEthCreateAccessListCmd, withErigonUrl, withGethUrl, withNeedCompare, withBlockNum, withRecord, withErrorFile, withLatest) + var benchEthGetBlockByHash = &cobra.Command{ Use: "benchEthGetBlockByHash", Short: "", @@ -434,6 +447,7 @@ func main() { benchEthGetBlockByNumber2Cmd, benchEthGetBlockByHash, benchEthCallCmd, + benchEthCreateAccessListCmd, benchEthGetTransactionByHashCmd, bench1Cmd, bench2Cmd, diff --git a/cmd/rpctest/rpctest/bench_ethcreateaccesslist.go b/cmd/rpctest/rpctest/bench_ethcreateaccesslist.go new file mode 100644 index 000000000..af9f1e59a --- /dev/null +++ b/cmd/rpctest/rpctest/bench_ethcreateaccesslist.go @@ -0,0 +1,113 @@ +package rpctest + +import ( + "bufio" + "fmt" + "net/http" + "os" + "time" +) + +// BenchEthCreateAccessList compares response of Erigon with Geth +// but also can be used for comparing RPCDaemon with Geth or infura +// parameters: +// needCompare - if false - doesn't call Erigon and doesn't compare responses +// +// false value - to generate vegeta files, it's faster but we can generate vegeta files for Geth and Erigon +// recordFile stores all eth_call returned with success +// errorFile stores information when erigon and geth doesn't return same data +func BenchEthCreateAccessList(erigonURL, gethURL string, needCompare, latest bool, blockFrom, blockTo uint64, recordFileName string, errorFileName string) error { + setRoutes(erigonURL, gethURL) + var client = &http.Client{ + Timeout: time.Second * 600, + } + + var rec *bufio.Writer + var errs *bufio.Writer + var resultsCh chan CallResult = nil + var nTransactions = 0 + + if errorFileName != "" { + f, err := os.Create(errorFileName) + if err != nil { + return fmt.Errorf("Cannot create file %s for errorFile: %v\n", errorFileName, err) + } + defer f.Close() + errs = bufio.NewWriter(f) + defer errs.Flush() + } + + if recordFileName != "" { + frec, errRec := os.Create(recordFileName) + if errRec != nil { + return fmt.Errorf("Cannot create file %s for errorFile: %v\n", recordFileName, errRec) + } + defer frec.Close() + rec = bufio.NewWriter(frec) + defer rec.Flush() + } + + if !needCompare { + resultsCh = make(chan CallResult, 1000) + defer close(resultsCh) + go vegetaWrite(true, []string{"eth_createAccessList"}, resultsCh) + } + var res CallResult + + reqGen := &RequestGenerator{ + client: client, + } + + reqGen.reqID++ + + for bn := blockFrom; bn <= blockTo; bn++ { + reqGen.reqID++ + var b EthBlockByNumber + res = reqGen.Erigon("eth_getBlockByNumber", reqGen.getBlockByNumber(bn, true /* withTxs */), &b) + if res.Err != nil { + return fmt.Errorf("Could not retrieve block (Erigon) %d: %v\n", bn, res.Err) + } + + if b.Error != nil { + return fmt.Errorf("Error retrieving block (Erigon): %d %s\n", b.Error.Code, b.Error.Message) + } + + if needCompare { + var bg EthBlockByNumber + res = reqGen.Geth("eth_getBlockByNumber", reqGen.getBlockByNumber(bn, true /* withTxs */), &bg) + if res.Err != nil { + return fmt.Errorf("Could not retrieve block (geth) %d: %v\n", bn, res.Err) + } + if bg.Error != nil { + return fmt.Errorf("Error retrieving block (geth): %d %s\n", bg.Error.Code, bg.Error.Message) + } + if !compareBlocks(&b, &bg) { + if rec != nil { + fmt.Fprintf(rec, "Block difference for block=%d\n", bn) + rec.Flush() + continue + } else { + return fmt.Errorf("Block one or more fields areis different for block %d\n", bn) + } + } + } + + for _, tx := range b.Result.Transactions { + + reqGen.reqID++ + nTransactions = nTransactions + 1 + + var request string + request = reqGen.ethCreateAccessList(tx.From, tx.To, &tx.Gas, &tx.GasPrice, &tx.Value, tx.Input, bn-1) + errCtx := fmt.Sprintf(" bn=%d hash=%s", bn, tx.Hash) + + if err := requestAndCompare(request, "eth_createAccessList", errCtx, reqGen, needCompare, rec, errs, resultsCh, + false); err != nil { + return err + } + } + + fmt.Println("\nProcessed Transactions: ", nTransactions) + } + return nil +} diff --git a/cmd/rpctest/rpctest/request_generator.go b/cmd/rpctest/rpctest/request_generator.go index dfb757630..a38ea1ef3 100644 --- a/cmd/rpctest/rpctest/request_generator.go +++ b/cmd/rpctest/rpctest/request_generator.go @@ -236,6 +236,28 @@ func (g *RequestGenerator) ethCall(from libcommon.Address, to *libcommon.Address return sb.String() } +func (g *RequestGenerator) ethCreateAccessList(from libcommon.Address, to *libcommon.Address, gas *hexutil.Big, gasPrice *hexutil.Big, value *hexutil.Big, data hexutility.Bytes, bn uint64) string { + var sb strings.Builder + fmt.Fprintf(&sb, `{ "jsonrpc": "2.0", "method": "eth_createAccessList", "params": [{"from":"0x%x"`, from) + if to != nil { + fmt.Fprintf(&sb, `,"to":"0x%x"`, *to) + } + if gas != nil { + fmt.Fprintf(&sb, `,"gas":"%s"`, gas) + } + if gasPrice != nil { + fmt.Fprintf(&sb, `,"gasPrice":"%s"`, gasPrice) + } + if len(data) > 0 { + fmt.Fprintf(&sb, `,"data":"%s"`, data) + } + if value != nil { + fmt.Fprintf(&sb, `,"value":"%s"`, value) + } + fmt.Fprintf(&sb, `},"0x%x"], "id":%d}`, bn, g.reqID) + return sb.String() +} + func (g *RequestGenerator) ethCallLatest(from libcommon.Address, to *libcommon.Address, gas *hexutil.Big, gasPrice *hexutil.Big, value *hexutil.Big, data hexutility.Bytes) string { var sb strings.Builder fmt.Fprintf(&sb, `{ "jsonrpc": "2.0", "method": "eth_call", "params": [{"from":"0x%x"`, from)