104 lines
2.7 KiB
Go
104 lines
2.7 KiB
Go
|
// Copyright (c) 2020 The btcsuite developers
|
||
|
// Use of this source code is governed by an ISC
|
||
|
// license that can be found in the LICENSE file.
|
||
|
|
||
|
package wallet
|
||
|
|
||
|
import (
|
||
|
"testing"
|
||
|
|
||
|
"github.com/btcsuite/btcd/txscript"
|
||
|
"github.com/btcsuite/btcd/wire"
|
||
|
"github.com/btcsuite/btcutil"
|
||
|
"github.com/btcsuite/btcwallet/waddrmgr"
|
||
|
)
|
||
|
|
||
|
// TestComputeInputScript checks that the wallet can create the full
|
||
|
// witness script for a witness output.
|
||
|
func TestComputeInputScript(t *testing.T) {
|
||
|
testCases := []struct {
|
||
|
name string
|
||
|
scope waddrmgr.KeyScope
|
||
|
expectedScriptLen int
|
||
|
}{{
|
||
|
name: "BIP084 P2WKH",
|
||
|
scope: waddrmgr.KeyScopeBIP0084,
|
||
|
expectedScriptLen: 0,
|
||
|
}, {
|
||
|
name: "BIP049 nested P2WKH",
|
||
|
scope: waddrmgr.KeyScopeBIP0049Plus,
|
||
|
expectedScriptLen: 23,
|
||
|
}}
|
||
|
|
||
|
w, cleanup := testWallet(t)
|
||
|
defer cleanup()
|
||
|
|
||
|
for _, tc := range testCases {
|
||
|
t.Run(tc.name, func(t *testing.T) {
|
||
|
runTestCase(t, w, tc.scope, tc.expectedScriptLen)
|
||
|
})
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func runTestCase(t *testing.T, w *Wallet, scope waddrmgr.KeyScope,
|
||
|
scriptLen int) {
|
||
|
|
||
|
// Create an address we can use to send some coins to.
|
||
|
addr, err := w.CurrentAddress(0, scope)
|
||
|
if err != nil {
|
||
|
t.Fatalf("unable to get current address: %v", addr)
|
||
|
}
|
||
|
p2shAddr, err := txscript.PayToAddrScript(addr)
|
||
|
if err != nil {
|
||
|
t.Fatalf("unable to convert wallet address to p2sh: %v", err)
|
||
|
}
|
||
|
|
||
|
// Add an output paying to the wallet's address to the database.
|
||
|
utxOut := wire.NewTxOut(100000, p2shAddr)
|
||
|
incomingTx := &wire.MsgTx{
|
||
|
TxIn: []*wire.TxIn{{}},
|
||
|
TxOut: []*wire.TxOut{utxOut},
|
||
|
}
|
||
|
addUtxo(t, w, incomingTx)
|
||
|
|
||
|
// Create a transaction that spends the UTXO created above and spends to
|
||
|
// the same address again.
|
||
|
prevOut := wire.OutPoint{
|
||
|
Hash: incomingTx.TxHash(),
|
||
|
Index: 0,
|
||
|
}
|
||
|
outgoingTx := &wire.MsgTx{
|
||
|
TxIn: []*wire.TxIn{{
|
||
|
PreviousOutPoint: prevOut,
|
||
|
}},
|
||
|
TxOut: []*wire.TxOut{utxOut},
|
||
|
}
|
||
|
sigHashes := txscript.NewTxSigHashes(outgoingTx)
|
||
|
|
||
|
// Compute the input script to spend the UTXO now.
|
||
|
witness, script, err := w.ComputeInputScript(
|
||
|
outgoingTx, utxOut, 0, sigHashes, txscript.SigHashAll, nil,
|
||
|
)
|
||
|
if err != nil {
|
||
|
t.Fatalf("error computing input script: %v", err)
|
||
|
}
|
||
|
if len(script) != scriptLen {
|
||
|
t.Fatalf("unexpected script length, got %d wanted %d",
|
||
|
len(script), scriptLen)
|
||
|
}
|
||
|
if len(witness) != 2 {
|
||
|
t.Fatalf("unexpected witness stack length, got %d, wanted %d",
|
||
|
len(witness), 2)
|
||
|
}
|
||
|
|
||
|
// Finally verify that the created witness is valid.
|
||
|
outgoingTx.TxIn[0].Witness = witness
|
||
|
outgoingTx.TxIn[0].SignatureScript = script
|
||
|
err = validateMsgTx(
|
||
|
outgoingTx, [][]byte{utxOut.PkScript}, []btcutil.Amount{100000},
|
||
|
)
|
||
|
if err != nil {
|
||
|
t.Fatalf("error validating tx: %v", err)
|
||
|
}
|
||
|
}
|