WIP:feature/rewrite-devnettest-to-cobra (#3227)

* WIP:feature/rewrite-devnettest-to-cobra

* Add parity commands

* Update dev chain md
This commit is contained in:
primal_concrete_sledge 2022-01-14 16:08:41 +03:00 committed by GitHub
parent bcc88bab15
commit 69671cf6c6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 244 additions and 118 deletions

View File

@ -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 <number-of-seconds>: 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.

View File

@ -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)
},
}

View File

@ -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)
},
}

View File

@ -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)
},
}

View File

@ -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)
//}
}

View File

@ -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)
},
}

View File

@ -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()
}

View File

@ -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)
}

View File

@ -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))
}

View File

@ -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)
//}
}

View File

@ -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"`
}