wallet: return unsigned TX in watch-only SendOutputs

If SendOutputs is called on a watch-only wallet then a transaction is
created but without any signatures. Publishing that transaction will
always fail. But the attempt to publish will already update the internal
state of the wallet so we shouldn't try to publish this unsigned TX.
Instead we return a new error along with the unsigned transaction to
give the caller the chance to sign and publish it through other means.
This commit is contained in:
Oliver Gugger 2021-10-07 13:18:53 +02:00 committed by Roy Lee
parent 9f1eb98666
commit 45a94de617

View file

@ -72,6 +72,10 @@ var (
// to true. // to true.
ErrTxLabelExists = errors.New("transaction already labelled") ErrTxLabelExists = errors.New("transaction already labelled")
// ErrTxUnsigned is returned when a transaction is created in the
// watch-only mode where we can select coins but not sign any inputs.
ErrTxUnsigned = errors.New("watch-only wallet, transaction not signed")
// Namespace bucket keys. // Namespace bucket keys.
waddrmgrNamespaceKey = []byte("waddrmgr") waddrmgrNamespaceKey = []byte("waddrmgr")
wtxmgrNamespaceKey = []byte("wtxmgr") wtxmgrNamespaceKey = []byte("wtxmgr")
@ -3209,6 +3213,13 @@ func (w *Wallet) SendOutputs(outputs []*wire.TxOut, keyScope *waddrmgr.KeyScope,
return nil, err return nil, err
} }
// If our wallet is read-only, we'll get a transaction with coins
// selected but no witness data. In such a case we need to inform our
// caller that they'll actually need to go ahead and sign the TX.
if w.Manager.WatchOnly() {
return createdTx.Tx, ErrTxUnsigned
}
txHash, err := w.reliablyPublishTransaction(createdTx.Tx, label) txHash, err := w.reliablyPublishTransaction(createdTx.Tx, label)
if err != nil { if err != nil {
return nil, err return nil, err