mirror of
https://gitlab.com/pulsechaincom/erigon-pulse.git
synced 2025-01-14 06:48:20 +00:00
9dbedb2e1d
* Increased hardcoded gas price from 50000 * Added functionality to search for last propagated transaction in mined blocks after sending a transaction. * Added functionality to search for last propagated transaction in mined blocks after sending a transaction.
149 lines
3.8 KiB
Go
149 lines
3.8 KiB
Go
package commands
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"github.com/ledgerwatch/erigon/common/hexutil"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/ledgerwatch/erigon/rpc"
|
|
|
|
"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
|
|
searchBlock bool
|
|
)
|
|
|
|
const (
|
|
gasPrice = 912345678
|
|
)
|
|
|
|
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")
|
|
sendTxCmd.Flags().BoolVar(&searchBlock, "search-block", false, "Boolean look for tx in mined blocks")
|
|
|
|
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)
|
|
hash, err := requests.SendTx(reqId, &signedTx)
|
|
if err != nil {
|
|
fmt.Printf("Error trying to send transaction: %v\n", err)
|
|
}
|
|
|
|
if searchBlock {
|
|
searchBlockForTx(*hash)
|
|
}
|
|
},
|
|
}
|
|
|
|
func searchBlockForTx(txnHash common.Hash) {
|
|
url := "ws://127.0.0.1:8545"
|
|
client, clientErr := rpc.DialWebsocket(context.Background(), url, "")
|
|
if clientErr != nil {
|
|
fmt.Println("error connecting to socket", clientErr)
|
|
panic(clientErr)
|
|
}
|
|
fmt.Println("Connected to web socket successfully")
|
|
|
|
if err := subscribe(client, "eth_newHeads", txnHash); err != nil {
|
|
fmt.Println("error occurred while subscribing", err)
|
|
panic(err)
|
|
}
|
|
}
|
|
|
|
func subscribe(client *rpc.Client, method string, hash common.Hash) error {
|
|
parts := strings.SplitN(method, "_", 2)
|
|
namespace := parts[0]
|
|
method = parts[1]
|
|
ch := make(chan interface{})
|
|
sub, err := client.Subscribe(context.Background(), namespace, ch, []interface{}{method}...)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer sub.Unsubscribe()
|
|
|
|
blockCount := 0
|
|
ForLoop:
|
|
for {
|
|
select {
|
|
case v := <-ch:
|
|
blockCount++
|
|
blockNumber := v.(map[string]interface{})["number"]
|
|
fmt.Printf("Searching for the transaction in block with number: %+v\n", blockNumber)
|
|
foundTx, err := blockHasHash(client, hash, blockNumber.(string))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if foundTx || blockCount == 128 {
|
|
break ForLoop
|
|
}
|
|
case err := <-sub.Err():
|
|
return err
|
|
}
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
type Block struct {
|
|
Number *hexutil.Big
|
|
Transactions []common.Hash
|
|
}
|
|
|
|
func blockHasHash(client *rpc.Client, hash common.Hash, blockNumber string) (bool, error) {
|
|
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
|
defer cancel()
|
|
|
|
var currentBlock Block
|
|
err := client.CallContext(ctx, ¤tBlock, "eth_getBlockByNumber", blockNumber, false)
|
|
if err != nil {
|
|
fmt.Println("can't get latest block:", err)
|
|
return false, err
|
|
}
|
|
|
|
for _, txnHash := range currentBlock.Transactions {
|
|
if txnHash == hash {
|
|
fmt.Println()
|
|
fmt.Printf("Block with number: %v was mined and included transaction with hash: %v ==> %+v\n", blockNumber, hash, currentBlock)
|
|
fmt.Println()
|
|
return true, nil
|
|
}
|
|
}
|
|
|
|
return false, nil
|
|
}
|