mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-06-12 09:51:36 +00:00
cmd/pushtx: fix gas price 0 rejection, show gas price in summary, print raw hex on error
Co-authored-by: drQedwards <213266729+drQedwards@users.noreply.github.com>
This commit is contained in:
parent
53ff818308
commit
cc2957508f
2 changed files with 58 additions and 6 deletions
|
|
@ -105,6 +105,9 @@ func run(args []string, stdin io.Reader) error {
|
|||
// Send to the RPC endpoint.
|
||||
hash, err := sendRawTransaction(rpcURL, rawTx)
|
||||
if err != nil {
|
||||
// Still print the raw hex so the user can submit it elsewhere
|
||||
// (e.g. etherscan.io/pushTx).
|
||||
fmt.Println("Raw tx:", txHex)
|
||||
return fmt.Errorf("sending transaction: %w", err)
|
||||
}
|
||||
fmt.Println("Transaction submitted successfully")
|
||||
|
|
@ -112,7 +115,7 @@ func run(args []string, stdin io.Reader) error {
|
|||
|
||||
// Print the raw hex transaction as the last output for easy
|
||||
// copy-paste into block explorers like etherscan.io/pushTx.
|
||||
fmt.Println("Raw tx: 0x" + hex.EncodeToString(rawTx))
|
||||
fmt.Println("Raw tx:", txHex)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
@ -152,6 +155,7 @@ func printTxSummary(tx *types.Transaction) {
|
|||
fmt.Println(" Nonce: ", tx.Nonce())
|
||||
fmt.Println(" Value: ", formatWei(tx.Value()))
|
||||
fmt.Println(" Gas limit:", tx.Gas())
|
||||
fmt.Println(" Gas price:", formatGwei(tx.GasPrice()))
|
||||
fmt.Println(" Chain ID: ", tx.ChainId())
|
||||
}
|
||||
|
||||
|
|
@ -165,6 +169,15 @@ func formatWei(wei *big.Int) string {
|
|||
return fmt.Sprintf("%s wei (%s ETH)", wei.String(), ether.Text('f', 18))
|
||||
}
|
||||
|
||||
// formatGwei converts a wei gas price to a human-readable string in Gwei.
|
||||
func formatGwei(wei *big.Int) string {
|
||||
if wei == nil || wei.Sign() == 0 {
|
||||
return "0 wei (0 Gwei)"
|
||||
}
|
||||
gwei := new(big.Float).Quo(new(big.Float).SetInt(wei), new(big.Float).SetFloat64(1e9))
|
||||
return fmt.Sprintf("%s wei (%s Gwei)", wei.String(), gwei.Text('f', 9))
|
||||
}
|
||||
|
||||
func printUsage() {
|
||||
fmt.Fprintf(os.Stderr, `Usage: pushtx [--rpc URL] <tx-hex>
|
||||
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ func signedTestTxWithKey(t *testing.T, key *ecdsa.PrivateKey) (*types.Transactio
|
|||
|
||||
tx := types.NewTx(&types.LegacyTx{
|
||||
Nonce: 6,
|
||||
GasPrice: big.NewInt(0),
|
||||
GasPrice: big.NewInt(1_000_000_000), // 1 Gwei – real networks reject gas price 0
|
||||
Gas: 21055,
|
||||
To: addrPtr(common.HexToAddress("0x78b5290269740033b05bd8d71c97331295eb5918")),
|
||||
Value: new(big.Int).Mul(big.NewInt(10), big.NewInt(1e18)), // 10 ETH
|
||||
|
|
@ -149,12 +149,33 @@ func TestRunRPCError(t *testing.T) {
|
|||
defer srv.Close()
|
||||
|
||||
_, txHex := signedTestTx(t)
|
||||
err := run([]string{"--rpc", srv.URL, txHex}, strings.NewReader(""))
|
||||
if err == nil {
|
||||
|
||||
// Capture stdout – raw hex should still be printed on RPC failure.
|
||||
oldStdout := os.Stdout
|
||||
r, w, err := os.Pipe()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
os.Stdout = w
|
||||
|
||||
runErr := run([]string{"--rpc", srv.URL, txHex}, strings.NewReader(""))
|
||||
|
||||
w.Close()
|
||||
os.Stdout = oldStdout
|
||||
|
||||
if runErr == nil {
|
||||
t.Fatal("expected error, got nil")
|
||||
}
|
||||
if !strings.Contains(err.Error(), "already known") {
|
||||
t.Fatalf("unexpected error message: %v", err)
|
||||
if !strings.Contains(runErr.Error(), "already known") {
|
||||
t.Fatalf("unexpected error message: %v", runErr)
|
||||
}
|
||||
|
||||
out, err := io.ReadAll(r)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !strings.Contains(string(out), "Raw tx: 0x") {
|
||||
t.Fatal("expected raw hex in output even on RPC error")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -233,6 +254,24 @@ func TestFormatWei(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestFormatGwei(t *testing.T) {
|
||||
tests := []struct {
|
||||
wei *big.Int
|
||||
want string
|
||||
}{
|
||||
{nil, "0 wei (0 Gwei)"},
|
||||
{big.NewInt(0), "0 wei (0 Gwei)"},
|
||||
{big.NewInt(1_000_000_000), "1000000000 wei (1.000000000 Gwei)"},
|
||||
{big.NewInt(20_000_000_000), "20000000000 wei (20.000000000 Gwei)"},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
got := formatGwei(tt.wei)
|
||||
if got != tt.want {
|
||||
t.Errorf("formatGwei(%v) = %q, want %q", tt.wei, got, tt.want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestRunEqualsSyntax(t *testing.T) {
|
||||
srv := fakeRPC(t, false)
|
||||
defer srv.Close()
|
||||
|
|
|
|||
Loading…
Reference in a new issue