From 7fed4244353bb9b95b6c18fb26c039d7274bd2c8 Mon Sep 17 00:00:00 2001
From: obscuren <geffobscura@gmail.com>
Date: Tue, 5 May 2015 23:09:46 +0200
Subject: cmd/geth: implemented resending transaction with different gas
 settings

---
 cmd/geth/admin.go | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 83 insertions(+)

(limited to 'cmd')

diff --git a/cmd/geth/admin.go b/cmd/geth/admin.go
index 31f8d4400..13efe5dd6 100644
--- a/cmd/geth/admin.go
+++ b/cmd/geth/admin.go
@@ -3,6 +3,7 @@ package main
 import (
 	"errors"
 	"fmt"
+	"strconv"
 	"time"
 
 	"github.com/ethereum/go-ethereum/cmd/utils"
@@ -22,6 +23,11 @@ node admin bindings
 */
 
 func (js *jsre) adminBindings() {
+	ethO, _ := js.re.Get("eth")
+	eth := ethO.Object()
+	eth.Set("transactions", js.transactions)
+	eth.Set("resend", js.resend)
+
 	js.re.Set("admin", struct{}{})
 	t, _ := js.re.Get("admin")
 	admin := t.Object()
@@ -74,6 +80,83 @@ func (js *jsre) getBlock(call otto.FunctionCall) (*types.Block, error) {
 	return nil, errors.New("requires block number or block hash as argument")
 }
 
+type tx struct {
+	tx *types.Transaction
+
+	To       string
+	From     string
+	Nonce    string
+	Value    string
+	Data     string
+	GasLimit string
+	GasPrice string
+}
+
+func newTx(t *types.Transaction) *tx {
+	from, _ := t.From()
+	var to string
+	if t := t.To(); t != nil {
+		to = t.Hex()
+	}
+
+	return &tx{
+		tx:       t,
+		To:       to,
+		From:     from.Hex(),
+		Value:    t.Amount.String(),
+		Nonce:    strconv.Itoa(int(t.Nonce())),
+		Data:     "0x" + common.Bytes2Hex(t.Data()),
+		GasLimit: t.GasLimit.String(),
+		GasPrice: t.GasPrice().String(),
+	}
+}
+
+func (js *jsre) transactions(call otto.FunctionCall) otto.Value {
+	txs := js.ethereum.TxPool().GetTransactions()
+
+	ltxs := make([]*tx, len(txs))
+	for i, tx := range txs {
+		ltxs[i] = newTx(tx)
+	}
+
+	return js.re.ToVal(ltxs)
+}
+
+func (js *jsre) resend(call otto.FunctionCall) otto.Value {
+	if len(call.ArgumentList) == 0 {
+		fmt.Println("first argument must be a transaction")
+		return otto.FalseValue()
+	}
+
+	v, err := call.Argument(0).Export()
+	if err != nil {
+		fmt.Println(err)
+		return otto.FalseValue()
+	}
+
+	if tx, ok := v.(*tx); ok {
+		gl, gp := tx.GasLimit, tx.GasPrice
+		if len(call.ArgumentList) > 1 {
+			gl = call.Argument(1).String()
+		}
+		if len(call.ArgumentList) > 2 {
+			gp = call.Argument(2).String()
+		}
+
+		ret, err := js.xeth.Transact(tx.From, tx.To, tx.Nonce, tx.Value, gl, gp, tx.Data)
+		if err != nil {
+			fmt.Println(err)
+			return otto.FalseValue()
+		}
+		js.ethereum.TxPool().RemoveTransactions(types.Transactions{tx.tx})
+
+		return js.re.ToVal(ret)
+	}
+
+	fmt.Println("first argument must be a transaction")
+	return otto.FalseValue()
+}
+
 func (js *jsre) debugBlock(call otto.FunctionCall) otto.Value {
 	block, err := js.getBlock(call)
 	if err != nil {
-- 
cgit v1.2.3