Skip to content

Commit

Permalink
fix(wallet): only mark utxos as spent after successful broadcast (#311)
Browse files Browse the repository at this point in the history
  • Loading branch information
jackstar12 authored Oct 14, 2024
1 parent a8ae3da commit f812767
Showing 1 changed file with 24 additions and 22 deletions.
46 changes: 24 additions & 22 deletions onchain/wallet/wallet.go
Original file line number Diff line number Diff line change
Expand Up @@ -702,7 +702,7 @@ func (wallet *Wallet) getUnspentOutputs(subaccount uint64, includeUnconfirmed bo
return result, nil
}

func (wallet *Wallet) SendToAddress(address string, amount uint64, satPerVbyte float64, sendAll bool) (string, error) {
func (wallet *Wallet) SendToAddress(address string, amount uint64, satPerVbyte float64, sendAll bool) (tx string, err error) {
if wallet.Readonly {
return "", errors.New("wallet is readonly")
}
Expand All @@ -716,6 +716,9 @@ func (wallet *Wallet) SendToAddress(address string, amount uint64, satPerVbyte f
return "", err
}

wallet.spentOutputsLock.Lock()
defer wallet.spentOutputsLock.Unlock()

// Disable RBF
for asset, current := range outputs.Unspent {
if len(current) > int(config.MaxInputs) {
Expand Down Expand Up @@ -777,38 +780,37 @@ func (wallet *Wallet) SendToAddress(address string, amount uint64, satPerVbyte f
if err := mapstructure.Decode(result, &signedTx); err != nil {
return "", err
}
wallet.spentOutputsLock.Lock()
for _, input := range signedTx.TransactionInputs {
wallet.spentOutputs[input.TxId] = true
if signedTx.Error != "" {
return "", fmt.Errorf("could not sign: %s", signedTx.Error)
}
wallet.spentOutputsLock.Unlock()

if wallet.txProvider != nil {

if signedTx.Error != "" {
return "", errors.New(signedTx.Error)
tx, err = wallet.txProvider.BroadcastTransaction(signedTx.Transaction)
} else {
params, free = toJson(result)
var sendTx struct {
TxHash string `json:"txhash"`
Error string `json:"error"`
}
tx, err := wallet.txProvider.BroadcastTransaction(signedTx.Transaction)
if err != nil {
if err := withAuthHandler(C.GA_send_transaction(wallet.session, params, handler), handler, &sendTx); err != nil {
return "", err
}
return tx, nil
}
free()

params, free = toJson(result)
var sendTx struct {
TxHash string `json:"txhash"`
Error string `json:"error"`
if sendTx.Error != "" {
err = errors.New(sendTx.Error)
}
tx = sendTx.TxHash
}
if err := withAuthHandler(C.GA_send_transaction(wallet.session, params, handler), handler, &sendTx); err != nil {
return "", err
if err != nil {
return "", fmt.Errorf("failed to broadcast: %w", err)
}
free()

if sendTx.Error != "" {
return "", errors.New(sendTx.Error)
for _, input := range signedTx.TransactionInputs {
wallet.spentOutputs[input.TxId] = true
}
return sendTx.TxHash, nil

return tx, nil
}

func (wallet *Wallet) SetSpentOutputs(outputs []string) {
Expand Down

0 comments on commit f812767

Please sign in to comment.