mirror of
https://gitlab.com/pulsechaincom/erigon-pulse.git
synced 2024-12-22 03:30:37 +00:00
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:
parent
bcc88bab15
commit
69671cf6c6
@ -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.
|
||||
|
||||
|
46
cmd/devnettest/commands/account.go
Normal file
46
cmd/devnettest/commands/account.go
Normal 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)
|
||||
},
|
||||
}
|
55
cmd/devnettest/commands/block.go
Normal file
55
cmd/devnettest/commands/block.go
Normal 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)
|
||||
},
|
||||
}
|
36
cmd/devnettest/commands/parity.go
Normal file
36
cmd/devnettest/commands/parity.go
Normal 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)
|
||||
},
|
||||
}
|
36
cmd/devnettest/commands/root.go
Normal file
36
cmd/devnettest/commands/root.go
Normal 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)
|
||||
//}
|
||||
}
|
21
cmd/devnettest/commands/tx.go
Normal file
21
cmd/devnettest/commands/tx.go
Normal 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)
|
||||
},
|
||||
}
|
@ -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()
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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))
|
||||
|
||||
}
|
||||
|
@ -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)
|
||||
//}
|
||||
}
|
@ -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"`
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user