Keep a pool of unmined transactions, and resend if unmined.

This commit is contained in:
Josh Rickmar 2013-10-23 18:23:20 -04:00
parent 32da412254
commit adf4970fa4
3 changed files with 59 additions and 0 deletions

View file

@ -574,6 +574,12 @@ func SendMany(reply chan []byte, msg *btcjson.Message) {
w.UtxoStore.Unlock()
}
// Add hex string of raw tx to sent tx pool. If future blocks
// do not contain a tx, a resend is attempted.
UnminedTxs.Lock()
UnminedTxs.m[result.(string)] = hex.EncodeToString(rawtx)
UnminedTxs.Unlock()
ReplySuccess(reply, msg.Id, result)
// TODO(jrick): If message succeeded in being sent, save the

View file

@ -44,6 +44,18 @@ var TxFee struct {
i int64
}
// UnminedTXs holds a map of transaction IDs as keys mapping to a
// hex string of a raw transaction. If sending a raw transaction
// succeeds, the tx is added to this map and checked again after each
// new block. If the new block contains a tx, it is removed from
// this map. Otherwise, btcwallet will resend the tx to btcd.
var UnminedTxs = struct {
sync.Mutex
m map[string]string
}{
m: make(map[string]string),
}
// ByAmount defines the methods needed to satisify sort.Interface to
// sort a slice of Utxos by their amount.
type ByAmount []*tx.Utxo

View file

@ -341,8 +341,23 @@ func NtfnBlockConnected(r interface{}) {
heightf, ok := result["height"].(float64)
if !ok {
log.Error("blockconnected notification: invalid height")
return
}
height := int64(heightf)
iminedTxs, ok := result["minedtxs"].([]interface{})
if !ok {
log.Error("blockconnected notification: invalid mined tx array")
return
}
minedTxs := make([]string, len(iminedTxs))
for i, iminedTx := range iminedTxs {
minedTx, ok := iminedTx.(string)
if !ok {
log.Error("blockconnected notification: mined tx is not a string")
continue
}
minedTxs[i] = minedTx
}
curHeight.Lock()
curHeight.h = height
@ -370,6 +385,32 @@ func NtfnBlockConnected(r interface{}) {
NotifyWalletBalanceUnconfirmed(frontendNotificationMaster, w.name, unconfirmed)
}
wallets.RUnlock()
// Remove all mined transactions from pool.
UnminedTxs.Lock()
for _, txid := range minedTxs {
delete(UnminedTxs.m, txid)
}
// Resend any remaining transactions still left in pool. These are
// transactions that have not yet been mined into a block.
for _, hextx := range UnminedTxs.m {
n := <-NewJSONID
var id interface{} = fmt.Sprintf("btcwallet(%v)", n)
m, err := btcjson.CreateMessageWithId("sendrawtransaction", id, hextx)
if err != nil {
log.Errorf("cannot create resend request: %v", err)
continue
}
replyHandlers.Lock()
replyHandlers.m[n] = func(result interface{}, err *btcjson.Error) bool {
// Do nothing, just remove the handler.
return true
}
replyHandlers.Unlock()
btcdMsgs <- m
}
UnminedTxs.Unlock()
}
// NtfnBlockDisconnected handles btcd notifications resulting from