From 69671cf6c689a7de09b71914d4c1445fe4569a57 Mon Sep 17 00:00:00 2001 From: primal_concrete_sledge Date: Fri, 14 Jan 2022 16:08:41 +0300 Subject: [PATCH] WIP:feature/rewrite-devnettest-to-cobra (#3227) * WIP:feature/rewrite-devnettest-to-cobra * Add parity commands * Update dev chain md --- DEV_CHAIN.md | 6 +- cmd/devnettest/commands/account.go | 46 ++++++++++++ cmd/devnettest/commands/block.go | 55 ++++++++++++++ cmd/devnettest/commands/parity.go | 36 +++++++++ cmd/devnettest/commands/root.go | 36 +++++++++ cmd/devnettest/commands/tx.go | 21 ++++++ cmd/devnettest/main.go | 28 +------ cmd/devnettest/requests/request_generator.go | 23 +++++- cmd/devnettest/requests/requests.go | 27 +++++-- cmd/devnettest/services/utility.go | 79 -------------------- cmd/rpctest/rpctest/type.go | 5 ++ 11 files changed, 244 insertions(+), 118 deletions(-) create mode 100644 cmd/devnettest/commands/account.go create mode 100644 cmd/devnettest/commands/block.go create mode 100644 cmd/devnettest/commands/parity.go create mode 100644 cmd/devnettest/commands/root.go create mode 100644 cmd/devnettest/commands/tx.go delete mode 100644 cmd/devnettest/services/utility.go diff --git a/DEV_CHAIN.md b/DEV_CHAIN.md index 1eab01467..2fdd797a9 100644 --- a/DEV_CHAIN.md +++ b/DEV_CHAIN.md @@ -28,7 +28,7 @@ On the terminal you can type the following command to start node1. Argument notes: * datadir : Tells where the data is stored, default level is dev folder. - * datadir : Tells that we want to run Erigon in the dev chain. + * chain : Tells that we want to run Erigon in the dev chain. * private.api.addr=localhost:9090 : Tells where Eigon is going to listen for connections. * mine : Add this if you want the node to mine. * dev.period : Add this to specify the timing interval amongst blocks. Number of seconds MUST be > 0 (if you want empty blocks) otherwise the default value 0 does not allow mining of empty blocks. @@ -65,12 +65,12 @@ Open terminal 3 and navigate to erigon/build/bin folder. Paste in the following ```bash ./erigon --datadir=dev2 --chain dev --private.api.addr=localhost:9091 \ --staticpeers "enode://d30d079163d7b69fcb261c0538c0c3faba4fb4429652970e60fa25deb02a789b4811e98b468726ba0be63b9dc925a019f433177eb6b45c23bb78892f786d8f7a@127.0.0.1:53171" \ - --port 30305 --p2p.eth65.port 30306 --nodiscover + --nodiscover ``` To check if the nodes are connected, you can go to the log of both the nodes and look for the line - ``` [p2p] GoodPeers eth66=0 eth65=1 ``` + ``` [p2p] GoodPeers eth66=1 ``` Note: this might take a while it is not istantaneus, also if you see a 1 on either one of the two the node is fine. diff --git a/cmd/devnettest/commands/account.go b/cmd/devnettest/commands/account.go new file mode 100644 index 000000000..932bc7b9a --- /dev/null +++ b/cmd/devnettest/commands/account.go @@ -0,0 +1,46 @@ +package commands + +import ( + "fmt" + + "github.com/ledgerwatch/erigon/cmd/devnettest/requests" + "github.com/ledgerwatch/erigon/common" + "github.com/spf13/cobra" +) + +var ( + addr string + blockNum string +) + +func init() { + getBalanceCmd.Flags().StringVar(&addr, "addr", "", "String address to check") + getBalanceCmd.MarkFlagRequired("addr") + getBalanceCmd.Flags().StringVar(&blockNum, "block-num", "latest", "String denoting block number") + + rootCmd.AddCommand(getBalanceCmd) +} + +var getBalanceCmd = &cobra.Command{ + Use: "get-balance", + Short: "Checks balance by address", + Args: func(cmd *cobra.Command, args []string) error { + var err error + switch blockNum { + case "pending", "latest", "earliest": + default: + err = fmt.Errorf("block number must be 'pending', 'latest' or 'earliest'") + } + if err != nil { + return err + } + return nil + }, + Run: func(cmd *cobra.Command, args []string) { + if clearDev { + defer clearDevDB() + } + toAddress := common.HexToAddress(addr) + requests.GetBalance(reqId, toAddress, blockNum) + }, +} diff --git a/cmd/devnettest/commands/block.go b/cmd/devnettest/commands/block.go new file mode 100644 index 000000000..31382ecf8 --- /dev/null +++ b/cmd/devnettest/commands/block.go @@ -0,0 +1,55 @@ +package commands + +import ( + "fmt" + + "github.com/holiman/uint256" + "github.com/ledgerwatch/erigon/cmd/devnettest/requests" + "github.com/ledgerwatch/erigon/common" + "github.com/ledgerwatch/erigon/core/types" + "github.com/ledgerwatch/erigon/crypto" + "github.com/ledgerwatch/erigon/params" + "github.com/spf13/cobra" +) + +var devnetSignPrivateKey, _ = crypto.HexToECDSA("26e86e45f6fc45ec6e2ecd128cec80fa1d1505e5507dcd2ae58c3130a7a97b48") + +var ( + sendAddr string + sendValue uint64 + nonce uint64 +) + +const ( + gasPrice = 50000 +) + +func init() { + sendTxCmd.Flags().StringVar(&sendAddr, "addr", "", "String address to send to") + sendTxCmd.MarkFlagRequired("addr") + sendTxCmd.Flags().Uint64Var(&sendValue, "value", 0, "Uint64 Value to send") + sendTxCmd.Flags().Uint64Var(&nonce, "nonce", 0, "Uint64 nonce") + + rootCmd.AddCommand(sendTxCmd) +} + +var sendTxCmd = &cobra.Command{ + Use: "send-tx", + Short: "Sends a transaction", + Args: func(cmd *cobra.Command, args []string) error { + if sendValue == 0 { + return fmt.Errorf("value must be > 0") + } + return nil + }, + Run: func(cmd *cobra.Command, args []string) { + if clearDev { + defer clearDevDB() + } + toAddress := common.HexToAddress(sendAddr) + signer := types.LatestSigner(params.AllCliqueProtocolChanges) + signedTx, _ := types.SignTx(types.NewTransaction(nonce, toAddress, uint256.NewInt(sendValue), + params.TxGas, uint256.NewInt(gasPrice), nil), *signer, devnetSignPrivateKey) + requests.SendTx(reqId, &signedTx) + }, +} diff --git a/cmd/devnettest/commands/parity.go b/cmd/devnettest/commands/parity.go new file mode 100644 index 000000000..c27f105cf --- /dev/null +++ b/cmd/devnettest/commands/parity.go @@ -0,0 +1,36 @@ +package commands + +import ( + "strings" + + "github.com/ledgerwatch/erigon/cmd/devnettest/requests" + "github.com/ledgerwatch/erigon/common" + "github.com/spf13/cobra" +) + +var ( + offsetAddr string + quantity int +) + +func init() { + listStorageKeysCmd.Flags().StringVar(&addr, "addr", "", "String address to list keys") + listStorageKeysCmd.MarkFlagRequired("addr") + listStorageKeysCmd.Flags().StringVar(&offsetAddr, "offset", "", "Offset storage key from which the batch should start") + listStorageKeysCmd.Flags().IntVar(&quantity, "quantity", 10, "Integer number of addresses to display in a batch") + + rootCmd.AddCommand(listStorageKeysCmd) +} + +var listStorageKeysCmd = &cobra.Command{ + Use: "parity-list", + Short: "Returns all storage keys of the given address", + Run: func(cmd *cobra.Command, args []string) { + if clearDev { + defer clearDevDB() + } + toAddress := common.HexToAddress(addr) + offset := common.Hex2Bytes(strings.TrimSuffix(offsetAddr, "0x")) + requests.ParityList(reqId, toAddress, quantity, offset) + }, +} diff --git a/cmd/devnettest/commands/root.go b/cmd/devnettest/commands/root.go new file mode 100644 index 000000000..d0113d906 --- /dev/null +++ b/cmd/devnettest/commands/root.go @@ -0,0 +1,36 @@ +package commands + +import ( + "fmt" + + "github.com/spf13/cobra" +) + +var ( + clearDev bool + reqId int +) + +func init() { + rootCmd.PersistentFlags().BoolVar(&clearDev, "clear-dev", false, "Determines if service should clear /dev after this call") + rootCmd.PersistentFlags().IntVar(&reqId, "req-id", 0, "Defines number of request id") +} + +var rootCmd = &cobra.Command{ + Use: "devnettest", + Short: "Devnettest root command", +} + +// Execute executes the root command. +func Execute() error { + return rootCmd.Execute() +} + +func clearDevDB() { + fmt.Printf("Clearing ~/dev\n") + // + //_, err := exec.Command("rm", "-rf", "~/dev", "~/dev2").Output() + //if err != nil { + // fmt.Println(err) + //} +} diff --git a/cmd/devnettest/commands/tx.go b/cmd/devnettest/commands/tx.go new file mode 100644 index 000000000..bd27b6dfe --- /dev/null +++ b/cmd/devnettest/commands/tx.go @@ -0,0 +1,21 @@ +package commands + +import ( + "github.com/ledgerwatch/erigon/cmd/devnettest/requests" + "github.com/spf13/cobra" +) + +func init() { + rootCmd.AddCommand(txPoolCmd) +} + +var txPoolCmd = &cobra.Command{ + Use: "txpool-content", + Short: "Gets content of txpool", + Run: func(cmd *cobra.Command, args []string) { + if clearDev { + defer clearDevDB() + } + requests.TxpoolContent(reqId) + }, +} diff --git a/cmd/devnettest/main.go b/cmd/devnettest/main.go index 73ff98d65..04ad70556 100644 --- a/cmd/devnettest/main.go +++ b/cmd/devnettest/main.go @@ -1,31 +1,7 @@ package main -import ( - "flag" - "github.com/ledgerwatch/erigon/cmd/devnettest/services" -) +import "github.com/ledgerwatch/erigon/cmd/devnettest/commands" func main() { - var ( - to string - value uint64 - blockNum string - getBalance bool - sendTx bool - txPoolContent bool - clearDev bool - ) - - flag.StringVar(&to, "to", "", "String Address to send to") - flag.Uint64Var(&value, "value", uint64(0), "Uint64 Value to send") - flag.StringVar(&blockNum, "block-num", "latest", "String denoting block number") - flag.BoolVar(&getBalance, "get-balance", false, "Boolean Flag to determine if API should get balance") - flag.BoolVar(&sendTx, "send-tx", false, "Boolean Flag to determine if API should send transaction") - flag.BoolVar(&txPoolContent, "txpool-content", false, "Boolean Flag to determine if API should get content of txpool") - flag.BoolVar(&clearDev, "clear-dev", false, "Boolean Flag to determine if service should clear /dev after this call") - flag.Parse() - - services.ValidateInputs(getBalance, sendTx, txPoolContent, blockNum, value, to) - - services.ParseRequests(getBalance, sendTx, txPoolContent, clearDev, blockNum, value, to) + commands.Execute() } diff --git a/cmd/devnettest/requests/request_generator.go b/cmd/devnettest/requests/request_generator.go index 09c8190e0..8a8acdc5d 100644 --- a/cmd/devnettest/requests/request_generator.go +++ b/cmd/devnettest/requests/request_generator.go @@ -2,10 +2,11 @@ package requests import ( "fmt" - "github.com/ledgerwatch/erigon/cmd/rpctest/rpctest" - "github.com/ledgerwatch/erigon/common" "net/http" "time" + + "github.com/ledgerwatch/erigon/cmd/rpctest/rpctest" + "github.com/ledgerwatch/erigon/common" ) var ( @@ -17,15 +18,18 @@ type RequestGenerator struct { client *http.Client } -func initialiseRequestGenerator() *RequestGenerator { +func initialiseRequestGenerator(reqId int) *RequestGenerator { var client = &http.Client{ Timeout: time.Second * 600, } reqGen := RequestGenerator{ client: client, + reqID: reqId, + } + if reqGen.reqID == 0 { + reqGen.reqID++ } - reqGen.reqID++ return &reqGen } @@ -61,3 +65,14 @@ func (req *RequestGenerator) txpoolContent() string { const template = `{"jsonrpc":"2.0","method":"txpool_content","params":[],"id":%d}` return fmt.Sprintf(template, req.reqID) } + +func (req *RequestGenerator) parityStorageKeyListContent(address common.Address, quantity int, offset []byte) string { + const template = `{"jsonrpc":"2.0","method":"parity_listStorageKeys","params":["0x%x", %d, %v],"id":%d}` + var offsetString string + if len(offset) != 0 { + offsetString = fmt.Sprintf(`"0x%x"`, offset) + } else { + offsetString = "null" + } + return fmt.Sprintf(template, address, quantity, offsetString, req.reqID) +} diff --git a/cmd/devnettest/requests/requests.go b/cmd/devnettest/requests/requests.go index 9874419b8..27d4f3589 100644 --- a/cmd/devnettest/requests/requests.go +++ b/cmd/devnettest/requests/requests.go @@ -4,6 +4,7 @@ import ( "bytes" "encoding/json" "fmt" + "github.com/ledgerwatch/erigon/cmd/rpctest/rpctest" "github.com/ledgerwatch/erigon/common" "github.com/ledgerwatch/erigon/core/types" @@ -18,8 +19,8 @@ func parseResponse(resp interface{}) string { return string(result) } -func GetBalance(address common.Address, blockNum string) { - reqGen := initialiseRequestGenerator() +func GetBalance(reqId int, address common.Address, blockNum string) { + reqGen := initialiseRequestGenerator(reqId) var b rpctest.EthBalance res := reqGen.Erigon("eth_getBalance", reqGen.getBalance(address, blockNum), &b) @@ -31,8 +32,8 @@ func GetBalance(address common.Address, blockNum string) { fmt.Printf("Balance retrieved: %v\n", parseResponse(b)) } -func SendTx(signedTx *types.Transaction) { - reqGen := initialiseRequestGenerator() +func SendTx(reqId int, signedTx *types.Transaction) { + reqGen := initialiseRequestGenerator(reqId) var b rpctest.EthSendRawTransaction var buf bytes.Buffer @@ -51,8 +52,8 @@ func SendTx(signedTx *types.Transaction) { fmt.Printf("Submitted transaction successfully: %v\n", parseResponse(b)) } -func TxpoolContent() { - reqGen := initialiseRequestGenerator() +func TxpoolContent(reqId int) { + reqGen := initialiseRequestGenerator(reqId) var b rpctest.EthTxPool res := reqGen.Erigon("txpool_content", reqGen.txpoolContent(), &b) @@ -63,3 +64,17 @@ func TxpoolContent() { fmt.Printf("Txpool content: %v\n", parseResponse(b)) } + +func ParityList(reqId int, account common.Address, quantity int, offset []byte) { + reqGen := initialiseRequestGenerator(reqId) + var b rpctest.ParityListStorageKeysResult + + res := reqGen.Erigon("parity_listStorageKeys", reqGen.parityStorageKeyListContent(account, quantity, offset), &b) + if res.Err != nil { + fmt.Printf("Error fetching storage keys: %v\n", res.Err) + return + } + + fmt.Printf("Storage keys: %v\n", parseResponse(b)) + +} diff --git a/cmd/devnettest/services/utility.go b/cmd/devnettest/services/utility.go deleted file mode 100644 index bce6bc38a..000000000 --- a/cmd/devnettest/services/utility.go +++ /dev/null @@ -1,79 +0,0 @@ -package services - -import ( - "fmt" - "github.com/holiman/uint256" - "github.com/ledgerwatch/erigon/cmd/devnettest/requests" - "github.com/ledgerwatch/erigon/common" - "github.com/ledgerwatch/erigon/core/types" - "github.com/ledgerwatch/erigon/crypto" - "github.com/ledgerwatch/erigon/params" -) - -var devnetSignPrivateKey, _ = crypto.HexToECDSA("26e86e45f6fc45ec6e2ecd128cec80fa1d1505e5507dcd2ae58c3130a7a97b48") - -func ValidateInputs(getBalance bool, sendTx bool, txpoolContent bool, blockNum string, value uint64, to string) { - if !(getBalance) && !(sendTx) && !(txpoolContent) { - panic("At least one function flag (get-balance, send-tx, txpool-content) should be true") - } - - seen := false - for _, val := range []bool{getBalance, sendTx, txpoolContent} { - if val { - if seen { - panic("Only function flag (get-balance, send-tx, txpool-content) can be true at a time") - } - seen = true - } - } - - if value <= 0 { - panic("Value must be greater than zero") - } - - if getBalance { - if to == "" { - panic("Cannot check balance of empty address") - } - if blockNum != "pending" && blockNum != "latest" && blockNum != "earliest" { - panic("Block number must be 'pending', 'latest' or 'earliest'") - } - } - - if sendTx && to == "" { - panic("Cannot send to empty address") - } - -} - -func ParseRequests(getBalance bool, sendTx bool, txpoolContent bool, clearDev bool, blockNum string, value uint64, to string) { - if getBalance { - toAddress := common.HexToAddress(to) - requests.GetBalance(toAddress, blockNum) - } - - if sendTx { - toAddress := common.HexToAddress(to) - signer := types.LatestSigner(params.AllCliqueProtocolChanges) - signedTx, _ := types.SignTx(types.NewTransaction(0, toAddress, uint256.NewInt(value), - params.TxGas, uint256.NewInt(50000), nil), *signer, devnetSignPrivateKey) - requests.SendTx(&signedTx) - } - - if txpoolContent { - requests.TxpoolContent() - } - - if clearDev { - clearDevDB() - } -} - -func clearDevDB() { - fmt.Printf("Clearing ~/dev\n") - // - //_, err := exec.Command("rm", "-rf", "~/dev", "~/dev2").Output() - //if err != nil { - // fmt.Println(err) - //} -} diff --git a/cmd/rpctest/rpctest/type.go b/cmd/rpctest/rpctest/type.go index df13476d7..e5c94e78d 100644 --- a/cmd/rpctest/rpctest/type.go +++ b/cmd/rpctest/rpctest/type.go @@ -254,3 +254,8 @@ type StorageResult struct { Value *hexutil.Big `json:"value"` Proof []string `json:"proof"` } + +type ParityListStorageKeysResult struct { + Result []hexutil.Bytes `json:"result"` + Error string `json:"error"` +}