From 84f37d3915cfd254eb27bd25feff535e53a2fc1e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 12 Mar 2026 16:24:50 +0000 Subject: [PATCH] cmd/pushtx: add tx cost display to catch insufficient funds before broadcast Co-authored-by: drQedwards <213266729+drQedwards@users.noreply.github.com> --- cmd/pushtx/main.go | 8 ++++++++ cmd/pushtx/main_test.go | 14 ++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/cmd/pushtx/main.go b/cmd/pushtx/main.go index e4a8ff226a..bc0953c615 100644 --- a/cmd/pushtx/main.go +++ b/cmd/pushtx/main.go @@ -156,9 +156,17 @@ func printTxSummary(tx *types.Transaction) { fmt.Println(" Value: ", formatWei(tx.Value())) fmt.Println(" Gas limit:", tx.Gas()) fmt.Println(" Gas price:", formatGwei(tx.GasPrice())) + fmt.Println(" Tx cost: ", formatWei(txCost(tx))) fmt.Println(" Chain ID: ", tx.ChainId()) } +// txCost returns value + gas * gasPrice, i.e. the total ETH the sender +// must hold for the transaction to be accepted by the network. +func txCost(tx *types.Transaction) *big.Int { + gasCost := new(big.Int).Mul(new(big.Int).SetUint64(tx.Gas()), tx.GasPrice()) + return new(big.Int).Add(tx.Value(), gasCost) +} + // formatWei converts a wei amount to a human-readable string showing // both the wei value and the ETH equivalent. func formatWei(wei *big.Int) string { diff --git a/cmd/pushtx/main_test.go b/cmd/pushtx/main_test.go index 0459602928..f5b6c0eb78 100644 --- a/cmd/pushtx/main_test.go +++ b/cmd/pushtx/main_test.go @@ -272,6 +272,20 @@ func TestFormatGwei(t *testing.T) { } } +func TestTxCost(t *testing.T) { + tx := types.NewTx(&types.LegacyTx{ + GasPrice: big.NewInt(1_000_000_000), // 1 Gwei + Gas: 21055, + Value: new(big.Int).Mul(big.NewInt(10), big.NewInt(1e18)), // 10 ETH + }) + got := txCost(tx) + // Expected: 10 ETH + 21055 * 1 Gwei = 10000000000000000000 + 21055000000000 = 10000021055000000000 + want, _ := new(big.Int).SetString("10000021055000000000", 10) + if got.Cmp(want) != 0 { + t.Errorf("txCost = %s, want %s", got, want) + } +} + func TestRunEqualsSyntax(t *testing.T) { srv := fakeRPC(t, false) defer srv.Close()