lntemp+itest: refactor testSignPsbt
This commit is contained in:
5 files changed
+187
-240
No files matched your search
@@ -198,7 +198,7 @@ func (h *HarnessRPC) ImportAccount(
|
|||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
resp, err := h.WalletKit.ImportAccount(ctxt, req)
|
resp, err := h.WalletKit.ImportAccount(ctxt, req)
|
||||||
require.NoErrorf(h, err, "failed to import account")
|
h.NoError(err, "ImportAccount")
|
||||||
|
|
||||||
return resp
|
return resp
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -287,6 +287,10 @@ var allTestCasesTemp = []*lntemp.TestCase{
|
|||||||
Name: "psbt channel funding single step",
|
Name: "psbt channel funding single step",
|
||||||
TestFunc: testPsbtChanFundingSingleStep,
|
TestFunc: testPsbtChanFundingSingleStep,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Name: "sign psbt",
|
||||||
|
TestFunc: testSignPsbt,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
Name: "resolution handoff",
|
Name: "resolution handoff",
|
||||||
TestFunc: testResHandoff,
|
TestFunc: testResHandoff,
|
||||||
|
|||||||
+178
-231
@@ -576,49 +576,38 @@ func testPsbtChanFundingSingleStep(ht *lntemp.HarnessTest) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// testSignPsbt tests that the SignPsbt RPC works correctly.
|
// testSignPsbt tests that the SignPsbt RPC works correctly.
|
||||||
func testSignPsbt(net *lntest.NetworkHarness, t *harnessTest) {
|
func testSignPsbt(ht *lntemp.HarnessTest) {
|
||||||
runSignPsbtSegWitV0P2WKH(t, net, net.Alice)
|
runSignPsbtSegWitV0P2WKH(ht, ht.Alice)
|
||||||
runSignPsbtSegWitV0NP2WKH(t, net, net.Alice)
|
runSignPsbtSegWitV0NP2WKH(ht, ht.Alice)
|
||||||
runSignPsbtSegWitV1KeySpendBip86(t, net, net.Alice)
|
runSignPsbtSegWitV1KeySpendBip86(ht, ht.Alice)
|
||||||
runSignPsbtSegWitV1KeySpendRootHash(t, net, net.Alice)
|
runSignPsbtSegWitV1KeySpendRootHash(ht, ht.Alice)
|
||||||
runSignPsbtSegWitV1ScriptSpend(t, net, net.Alice)
|
runSignPsbtSegWitV1ScriptSpend(ht, ht.Alice)
|
||||||
|
|
||||||
// The above tests all make sure we can sign for keys that aren't in the
|
// The above tests all make sure we can sign for keys that aren't in
|
||||||
// wallet. But we also want to make sure we can fund and then sign PSBTs
|
// the wallet. But we also want to make sure we can fund and then sign
|
||||||
// from our wallet.
|
// PSBTs from our wallet.
|
||||||
runFundAndSignPsbt(t, net, net.Alice)
|
runFundAndSignPsbt(ht, ht.Alice)
|
||||||
}
|
}
|
||||||
|
|
||||||
// runSignPsbtSegWitV0P2WKH tests that the SignPsbt RPC works correctly for a
|
// runSignPsbtSegWitV0P2WKH tests that the SignPsbt RPC works correctly for a
|
||||||
// SegWit v0 p2wkh input.
|
// SegWit v0 p2wkh input.
|
||||||
func runSignPsbtSegWitV0P2WKH(t *harnessTest, net *lntest.NetworkHarness,
|
func runSignPsbtSegWitV0P2WKH(ht *lntemp.HarnessTest, alice *node.HarnessNode) {
|
||||||
alice *lntest.HarnessNode) {
|
|
||||||
|
|
||||||
// Everything we do here should be done within a second or two, so we
|
|
||||||
// can just keep a single timeout context around for all calls.
|
|
||||||
ctxb := context.Background()
|
|
||||||
ctxt, cancel := context.WithTimeout(ctxb, defaultTimeout)
|
|
||||||
defer cancel()
|
|
||||||
|
|
||||||
// We test that we can sign a PSBT that spends funds from an input that
|
// We test that we can sign a PSBT that spends funds from an input that
|
||||||
// the wallet doesn't know about. To set up that test case, we first
|
// the wallet doesn't know about. To set up that test case, we first
|
||||||
// derive an address manually that the wallet won't be watching on
|
// derive an address manually that the wallet won't be watching on
|
||||||
// chain. We can do that by exporting the account xpub of lnd's main
|
// chain. We can do that by exporting the account xpub of lnd's main
|
||||||
// account.
|
// account.
|
||||||
accounts, err := alice.WalletKitClient.ListAccounts(
|
accounts := alice.RPC.ListAccounts(&walletrpc.ListAccountsRequest{})
|
||||||
ctxt, &walletrpc.ListAccountsRequest{},
|
require.NotEmpty(ht, accounts.Accounts)
|
||||||
)
|
|
||||||
require.NoError(t.t, err)
|
|
||||||
require.NotEmpty(t.t, accounts.Accounts)
|
|
||||||
|
|
||||||
// We also need to parse the accounts, so we have easy access to the
|
// We also need to parse the accounts, so we have easy access to the
|
||||||
// parsed derivation paths.
|
// parsed derivation paths.
|
||||||
parsedAccounts, err := walletrpc.AccountsToWatchOnly(accounts.Accounts)
|
parsedAccounts, err := walletrpc.AccountsToWatchOnly(accounts.Accounts)
|
||||||
require.NoError(t.t, err)
|
require.NoError(ht, err)
|
||||||
|
|
||||||
account := parsedAccounts[0]
|
account := parsedAccounts[0]
|
||||||
xpub, err := hdkeychain.NewKeyFromString(account.Xpub)
|
xpub, err := hdkeychain.NewKeyFromString(account.Xpub)
|
||||||
require.NoError(t.t, err)
|
require.NoError(ht, err)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
changeIndex = 1
|
changeIndex = 1
|
||||||
@@ -634,27 +623,27 @@ func runSignPsbtSegWitV0P2WKH(t *harnessTest, net *lntest.NetworkHarness,
|
|||||||
|
|
||||||
// Let's simulate a change address.
|
// Let's simulate a change address.
|
||||||
change, err := xpub.DeriveNonStandard(changeIndex) // nolint:staticcheck
|
change, err := xpub.DeriveNonStandard(changeIndex) // nolint:staticcheck
|
||||||
require.NoError(t.t, err)
|
require.NoError(ht, err)
|
||||||
|
|
||||||
// At an index that we are certainly not watching in the wallet.
|
// At an index that we are certainly not watching in the wallet.
|
||||||
addrKey, err := change.DeriveNonStandard(addrIndex) // nolint:staticcheck
|
addrKey, err := change.DeriveNonStandard(addrIndex) // nolint:staticcheck
|
||||||
require.NoError(t.t, err)
|
require.NoError(ht, err)
|
||||||
|
|
||||||
addrPubKey, err := addrKey.ECPubKey()
|
addrPubKey, err := addrKey.ECPubKey()
|
||||||
require.NoError(t.t, err)
|
require.NoError(ht, err)
|
||||||
pubKeyHash := btcutil.Hash160(addrPubKey.SerializeCompressed())
|
pubKeyHash := btcutil.Hash160(addrPubKey.SerializeCompressed())
|
||||||
witnessAddr, err := btcutil.NewAddressWitnessPubKeyHash(
|
witnessAddr, err := btcutil.NewAddressWitnessPubKeyHash(
|
||||||
pubKeyHash, harnessNetParams,
|
pubKeyHash, harnessNetParams,
|
||||||
)
|
)
|
||||||
require.NoError(t.t, err)
|
require.NoError(ht, err)
|
||||||
|
|
||||||
pkScript, err := txscript.PayToAddrScript(witnessAddr)
|
pkScript, err := txscript.PayToAddrScript(witnessAddr)
|
||||||
require.NoError(t.t, err)
|
require.NoError(ht, err)
|
||||||
|
|
||||||
// Send some funds to the output and then try to get a signature through
|
// Send some funds to the output and then try to get a signature through
|
||||||
// the SignPsbt RPC to spend that output again.
|
// the SignPsbt RPC to spend that output again.
|
||||||
assertPsbtSpend(
|
assertPsbtSpend(
|
||||||
ctxt, t, net, alice, pkScript,
|
ht, alice, pkScript,
|
||||||
func(packet *psbt.Packet) {
|
func(packet *psbt.Packet) {
|
||||||
in := &packet.Inputs[0]
|
in := &packet.Inputs[0]
|
||||||
in.Bip32Derivation = []*psbt.Bip32Derivation{{
|
in.Bip32Derivation = []*psbt.Bip32Derivation{{
|
||||||
@@ -664,16 +653,16 @@ func runSignPsbtSegWitV0P2WKH(t *harnessTest, net *lntest.NetworkHarness,
|
|||||||
in.SighashType = txscript.SigHashAll
|
in.SighashType = txscript.SigHashAll
|
||||||
},
|
},
|
||||||
func(packet *psbt.Packet) {
|
func(packet *psbt.Packet) {
|
||||||
require.Len(t.t, packet.Inputs, 1)
|
require.Len(ht, packet.Inputs, 1)
|
||||||
require.Len(t.t, packet.Inputs[0].PartialSigs, 1)
|
require.Len(ht, packet.Inputs[0].PartialSigs, 1)
|
||||||
|
|
||||||
partialSig := packet.Inputs[0].PartialSigs[0]
|
partialSig := packet.Inputs[0].PartialSigs[0]
|
||||||
require.Equal(
|
require.Equal(
|
||||||
t.t, partialSig.PubKey,
|
ht, partialSig.PubKey,
|
||||||
addrPubKey.SerializeCompressed(),
|
addrPubKey.SerializeCompressed(),
|
||||||
)
|
)
|
||||||
require.Greater(
|
require.Greater(
|
||||||
t.t, len(partialSig.Signature), ecdsa.MinSigLen,
|
ht, len(partialSig.Signature), ecdsa.MinSigLen,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@@ -681,34 +670,23 @@ func runSignPsbtSegWitV0P2WKH(t *harnessTest, net *lntest.NetworkHarness,
|
|||||||
|
|
||||||
// runSignPsbtSegWitV0NP2WKH tests that the SignPsbt RPC works correctly for a
|
// runSignPsbtSegWitV0NP2WKH tests that the SignPsbt RPC works correctly for a
|
||||||
// SegWit v0 np2wkh input.
|
// SegWit v0 np2wkh input.
|
||||||
func runSignPsbtSegWitV0NP2WKH(t *harnessTest, net *lntest.NetworkHarness,
|
func runSignPsbtSegWitV0NP2WKH(ht *lntemp.HarnessTest, alice *node.HarnessNode) {
|
||||||
alice *lntest.HarnessNode) {
|
|
||||||
|
|
||||||
// Everything we do here should be done within a second or two, so we
|
|
||||||
// can just keep a single timeout context around for all calls.
|
|
||||||
ctxb := context.Background()
|
|
||||||
ctxt, cancel := context.WithTimeout(ctxb, defaultTimeout)
|
|
||||||
defer cancel()
|
|
||||||
|
|
||||||
// We test that we can sign a PSBT that spends funds from an input that
|
// We test that we can sign a PSBT that spends funds from an input that
|
||||||
// the wallet doesn't know about. To set up that test case, we first
|
// the wallet doesn't know about. To set up that test case, we first
|
||||||
// derive an address manually that the wallet won't be watching on
|
// derive an address manually that the wallet won't be watching on
|
||||||
// chain. We can do that by exporting the account xpub of lnd's main
|
// chain. We can do that by exporting the account xpub of lnd's main
|
||||||
// account.
|
// account.
|
||||||
accounts, err := alice.WalletKitClient.ListAccounts(
|
accounts := alice.RPC.ListAccounts(&walletrpc.ListAccountsRequest{})
|
||||||
ctxt, &walletrpc.ListAccountsRequest{},
|
require.NotEmpty(ht, accounts.Accounts)
|
||||||
)
|
|
||||||
require.NoError(t.t, err)
|
|
||||||
require.NotEmpty(t.t, accounts.Accounts)
|
|
||||||
|
|
||||||
// We also need to parse the accounts, so we have easy access to the
|
// We also need to parse the accounts, so we have easy access to the
|
||||||
// parsed derivation paths.
|
// parsed derivation paths.
|
||||||
parsedAccounts, err := walletrpc.AccountsToWatchOnly(accounts.Accounts)
|
parsedAccounts, err := walletrpc.AccountsToWatchOnly(accounts.Accounts)
|
||||||
require.NoError(t.t, err)
|
require.NoError(ht, err)
|
||||||
|
|
||||||
account := parsedAccounts[0]
|
account := parsedAccounts[0]
|
||||||
xpub, err := hdkeychain.NewKeyFromString(account.Xpub)
|
xpub, err := hdkeychain.NewKeyFromString(account.Xpub)
|
||||||
require.NoError(t.t, err)
|
require.NoError(ht, err)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
changeIndex = 1
|
changeIndex = 1
|
||||||
@@ -724,34 +702,34 @@ func runSignPsbtSegWitV0NP2WKH(t *harnessTest, net *lntest.NetworkHarness,
|
|||||||
|
|
||||||
// Let's simulate a change address.
|
// Let's simulate a change address.
|
||||||
change, err := xpub.DeriveNonStandard(changeIndex) // nolint:staticcheck
|
change, err := xpub.DeriveNonStandard(changeIndex) // nolint:staticcheck
|
||||||
require.NoError(t.t, err)
|
require.NoError(ht, err)
|
||||||
|
|
||||||
// At an index that we are certainly not watching in the wallet.
|
// At an index that we are certainly not watching in the wallet.
|
||||||
addrKey, err := change.DeriveNonStandard(addrIndex) // nolint:staticcheck
|
addrKey, err := change.DeriveNonStandard(addrIndex) // nolint:staticcheck
|
||||||
require.NoError(t.t, err)
|
require.NoError(ht, err)
|
||||||
|
|
||||||
addrPubKey, err := addrKey.ECPubKey()
|
addrPubKey, err := addrKey.ECPubKey()
|
||||||
require.NoError(t.t, err)
|
require.NoError(ht, err)
|
||||||
pubKeyHash := btcutil.Hash160(addrPubKey.SerializeCompressed())
|
pubKeyHash := btcutil.Hash160(addrPubKey.SerializeCompressed())
|
||||||
witnessAddr, err := btcutil.NewAddressWitnessPubKeyHash(
|
witnessAddr, err := btcutil.NewAddressWitnessPubKeyHash(
|
||||||
pubKeyHash, harnessNetParams,
|
pubKeyHash, harnessNetParams,
|
||||||
)
|
)
|
||||||
require.NoError(t.t, err)
|
require.NoError(ht, err)
|
||||||
|
|
||||||
witnessProgram, err := txscript.PayToAddrScript(witnessAddr)
|
witnessProgram, err := txscript.PayToAddrScript(witnessAddr)
|
||||||
require.NoError(t.t, err)
|
require.NoError(ht, err)
|
||||||
np2wkhAddr, err := btcutil.NewAddressScriptHash(
|
np2wkhAddr, err := btcutil.NewAddressScriptHash(
|
||||||
witnessProgram, harnessNetParams,
|
witnessProgram, harnessNetParams,
|
||||||
)
|
)
|
||||||
require.NoError(t.t, err)
|
require.NoError(ht, err)
|
||||||
|
|
||||||
pkScript, err := txscript.PayToAddrScript(np2wkhAddr)
|
pkScript, err := txscript.PayToAddrScript(np2wkhAddr)
|
||||||
require.NoError(t.t, err)
|
require.NoError(ht, err)
|
||||||
|
|
||||||
// Send some funds to the output and then try to get a signature through
|
// Send some funds to the output and then try to get a signature through
|
||||||
// the SignPsbt RPC to spend that output again.
|
// the SignPsbt RPC to spend that output again.
|
||||||
assertPsbtSpend(
|
assertPsbtSpend(
|
||||||
ctxt, t, net, alice, pkScript,
|
ht, alice, pkScript,
|
||||||
func(packet *psbt.Packet) {
|
func(packet *psbt.Packet) {
|
||||||
in := &packet.Inputs[0]
|
in := &packet.Inputs[0]
|
||||||
in.RedeemScript = witnessProgram
|
in.RedeemScript = witnessProgram
|
||||||
@@ -762,16 +740,16 @@ func runSignPsbtSegWitV0NP2WKH(t *harnessTest, net *lntest.NetworkHarness,
|
|||||||
in.SighashType = txscript.SigHashAll
|
in.SighashType = txscript.SigHashAll
|
||||||
},
|
},
|
||||||
func(packet *psbt.Packet) {
|
func(packet *psbt.Packet) {
|
||||||
require.Len(t.t, packet.Inputs, 1)
|
require.Len(ht, packet.Inputs, 1)
|
||||||
require.Len(t.t, packet.Inputs[0].PartialSigs, 1)
|
require.Len(ht, packet.Inputs[0].PartialSigs, 1)
|
||||||
|
|
||||||
partialSig := packet.Inputs[0].PartialSigs[0]
|
partialSig := packet.Inputs[0].PartialSigs[0]
|
||||||
require.Equal(
|
require.Equal(
|
||||||
t.t, partialSig.PubKey,
|
ht, partialSig.PubKey,
|
||||||
addrPubKey.SerializeCompressed(),
|
addrPubKey.SerializeCompressed(),
|
||||||
)
|
)
|
||||||
require.Greater(
|
require.Greater(
|
||||||
t.t, len(partialSig.Signature), ecdsa.MinSigLen,
|
ht, len(partialSig.Signature), ecdsa.MinSigLen,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@@ -779,19 +757,11 @@ func runSignPsbtSegWitV0NP2WKH(t *harnessTest, net *lntest.NetworkHarness,
|
|||||||
|
|
||||||
// runSignPsbtSegWitV1KeySpendBip86 tests that the SignPsbt RPC works correctly
|
// runSignPsbtSegWitV1KeySpendBip86 tests that the SignPsbt RPC works correctly
|
||||||
// for a SegWit v1 p2tr key spend BIP-0086 input.
|
// for a SegWit v1 p2tr key spend BIP-0086 input.
|
||||||
func runSignPsbtSegWitV1KeySpendBip86(t *harnessTest, net *lntest.NetworkHarness,
|
func runSignPsbtSegWitV1KeySpendBip86(ht *lntemp.HarnessTest,
|
||||||
alice *lntest.HarnessNode) {
|
alice *node.HarnessNode) {
|
||||||
|
|
||||||
// Everything we do here should be done within a second or two, so we
|
|
||||||
// can just keep a single timeout context around for all calls.
|
|
||||||
ctxb := context.Background()
|
|
||||||
ctxt, cancel := context.WithTimeout(ctxb, defaultTimeout)
|
|
||||||
defer cancel()
|
|
||||||
|
|
||||||
// Derive a key we can use for signing.
|
// Derive a key we can use for signing.
|
||||||
keyDesc, internalKey, fullDerivationPath := deriveInternalKey(
|
keyDesc, internalKey, fullDerivationPath := deriveInternalKey(ht, alice)
|
||||||
ctxt, t, alice,
|
|
||||||
)
|
|
||||||
|
|
||||||
// Our taproot key is a BIP0086 key spend only construction that just
|
// Our taproot key is a BIP0086 key spend only construction that just
|
||||||
// commits to the internal key and no root hash.
|
// commits to the internal key and no root hash.
|
||||||
@@ -799,14 +769,14 @@ func runSignPsbtSegWitV1KeySpendBip86(t *harnessTest, net *lntest.NetworkHarness
|
|||||||
tapScriptAddr, err := btcutil.NewAddressTaproot(
|
tapScriptAddr, err := btcutil.NewAddressTaproot(
|
||||||
schnorr.SerializePubKey(taprootKey), harnessNetParams,
|
schnorr.SerializePubKey(taprootKey), harnessNetParams,
|
||||||
)
|
)
|
||||||
require.NoError(t.t, err)
|
require.NoError(ht, err)
|
||||||
p2trPkScript, err := txscript.PayToAddrScript(tapScriptAddr)
|
p2trPkScript, err := txscript.PayToAddrScript(tapScriptAddr)
|
||||||
require.NoError(t.t, err)
|
require.NoError(ht, err)
|
||||||
|
|
||||||
// Send some funds to the output and then try to get a signature through
|
// Send some funds to the output and then try to get a signature through
|
||||||
// the SignPsbt RPC to spend that output again.
|
// the SignPsbt RPC to spend that output again.
|
||||||
assertPsbtSpend(
|
assertPsbtSpend(
|
||||||
ctxt, t, net, alice, p2trPkScript,
|
ht, alice, p2trPkScript,
|
||||||
func(packet *psbt.Packet) {
|
func(packet *psbt.Packet) {
|
||||||
in := &packet.Inputs[0]
|
in := &packet.Inputs[0]
|
||||||
in.Bip32Derivation = []*psbt.Bip32Derivation{{
|
in.Bip32Derivation = []*psbt.Bip32Derivation{{
|
||||||
@@ -820,9 +790,9 @@ func runSignPsbtSegWitV1KeySpendBip86(t *harnessTest, net *lntest.NetworkHarness
|
|||||||
in.SighashType = txscript.SigHashDefault
|
in.SighashType = txscript.SigHashDefault
|
||||||
},
|
},
|
||||||
func(packet *psbt.Packet) {
|
func(packet *psbt.Packet) {
|
||||||
require.Len(t.t, packet.Inputs, 1)
|
require.Len(ht, packet.Inputs, 1)
|
||||||
require.Len(
|
require.Len(
|
||||||
t.t, packet.Inputs[0].TaprootKeySpendSig, 64,
|
ht, packet.Inputs[0].TaprootKeySpendSig, 64,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@@ -831,37 +801,29 @@ func runSignPsbtSegWitV1KeySpendBip86(t *harnessTest, net *lntest.NetworkHarness
|
|||||||
// runSignPsbtSegWitV1KeySpendRootHash tests that the SignPsbt RPC works
|
// runSignPsbtSegWitV1KeySpendRootHash tests that the SignPsbt RPC works
|
||||||
// correctly for a SegWit v1 p2tr key spend that also commits to a script tree
|
// correctly for a SegWit v1 p2tr key spend that also commits to a script tree
|
||||||
// root hash.
|
// root hash.
|
||||||
func runSignPsbtSegWitV1KeySpendRootHash(t *harnessTest,
|
func runSignPsbtSegWitV1KeySpendRootHash(ht *lntemp.HarnessTest,
|
||||||
net *lntest.NetworkHarness, alice *lntest.HarnessNode) {
|
alice *node.HarnessNode) {
|
||||||
|
|
||||||
// Everything we do here should be done within a second or two, so we
|
|
||||||
// can just keep a single timeout context around for all calls.
|
|
||||||
ctxb := context.Background()
|
|
||||||
ctxt, cancel := context.WithTimeout(ctxb, defaultTimeout)
|
|
||||||
defer cancel()
|
|
||||||
|
|
||||||
// Derive a key we can use for signing.
|
// Derive a key we can use for signing.
|
||||||
keyDesc, internalKey, fullDerivationPath := deriveInternalKey(
|
keyDesc, internalKey, fullDerivationPath := deriveInternalKey(ht, alice)
|
||||||
ctxt, t, alice,
|
|
||||||
)
|
|
||||||
|
|
||||||
// Let's create a taproot script output now. This is a hash lock with a
|
// Let's create a taproot script output now. This is a hash lock with a
|
||||||
// simple preimage of "foobar".
|
// simple preimage of "foobar".
|
||||||
leaf1 := testScriptHashLock(t.t, []byte("foobar"))
|
leaf1 := testScriptHashLock(ht.T, []byte("foobar"))
|
||||||
|
|
||||||
rootHash := leaf1.TapHash()
|
rootHash := leaf1.TapHash()
|
||||||
taprootKey := txscript.ComputeTaprootOutputKey(internalKey, rootHash[:])
|
taprootKey := txscript.ComputeTaprootOutputKey(internalKey, rootHash[:])
|
||||||
tapScriptAddr, err := btcutil.NewAddressTaproot(
|
tapScriptAddr, err := btcutil.NewAddressTaproot(
|
||||||
schnorr.SerializePubKey(taprootKey), harnessNetParams,
|
schnorr.SerializePubKey(taprootKey), harnessNetParams,
|
||||||
)
|
)
|
||||||
require.NoError(t.t, err)
|
require.NoError(ht, err)
|
||||||
p2trPkScript, err := txscript.PayToAddrScript(tapScriptAddr)
|
p2trPkScript, err := txscript.PayToAddrScript(tapScriptAddr)
|
||||||
require.NoError(t.t, err)
|
require.NoError(ht, err)
|
||||||
|
|
||||||
// Send some funds to the output and then try to get a signature through
|
// Send some funds to the output and then try to get a signature through
|
||||||
// the SignPsbt RPC to spend that output again.
|
// the SignPsbt RPC to spend that output again.
|
||||||
assertPsbtSpend(
|
assertPsbtSpend(
|
||||||
ctxt, t, net, alice, p2trPkScript,
|
ht, alice, p2trPkScript,
|
||||||
func(packet *psbt.Packet) {
|
func(packet *psbt.Packet) {
|
||||||
in := &packet.Inputs[0]
|
in := &packet.Inputs[0]
|
||||||
in.Bip32Derivation = []*psbt.Bip32Derivation{{
|
in.Bip32Derivation = []*psbt.Bip32Derivation{{
|
||||||
@@ -876,9 +838,9 @@ func runSignPsbtSegWitV1KeySpendRootHash(t *harnessTest,
|
|||||||
in.SighashType = txscript.SigHashDefault
|
in.SighashType = txscript.SigHashDefault
|
||||||
},
|
},
|
||||||
func(packet *psbt.Packet) {
|
func(packet *psbt.Packet) {
|
||||||
require.Len(t.t, packet.Inputs, 1)
|
require.Len(ht, packet.Inputs, 1)
|
||||||
require.Len(
|
require.Len(
|
||||||
t.t, packet.Inputs[0].TaprootKeySpendSig, 64,
|
ht, packet.Inputs[0].TaprootKeySpendSig, 64,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@@ -886,43 +848,35 @@ func runSignPsbtSegWitV1KeySpendRootHash(t *harnessTest,
|
|||||||
|
|
||||||
// runSignPsbtSegWitV1ScriptSpend tests that the SignPsbt RPC works correctly
|
// runSignPsbtSegWitV1ScriptSpend tests that the SignPsbt RPC works correctly
|
||||||
// for a SegWit v1 p2tr script spend.
|
// for a SegWit v1 p2tr script spend.
|
||||||
func runSignPsbtSegWitV1ScriptSpend(t *harnessTest,
|
func runSignPsbtSegWitV1ScriptSpend(ht *lntemp.HarnessTest,
|
||||||
net *lntest.NetworkHarness, alice *lntest.HarnessNode) {
|
alice *node.HarnessNode) {
|
||||||
|
|
||||||
// Everything we do here should be done within a second or two, so we
|
|
||||||
// can just keep a single timeout context around for all calls.
|
|
||||||
ctxb := context.Background()
|
|
||||||
ctxt, cancel := context.WithTimeout(ctxb, defaultTimeout)
|
|
||||||
defer cancel()
|
|
||||||
|
|
||||||
// Derive a key we can use for signing.
|
// Derive a key we can use for signing.
|
||||||
keyDesc, internalKey, fullDerivationPath := deriveInternalKey(
|
keyDesc, internalKey, fullDerivationPath := deriveInternalKey(ht, alice)
|
||||||
ctxt, t, alice,
|
|
||||||
)
|
|
||||||
|
|
||||||
// Let's create a taproot script output now. This is a hash lock with a
|
// Let's create a taproot script output now. This is a hash lock with a
|
||||||
// simple preimage of "foobar".
|
// simple preimage of "foobar".
|
||||||
leaf1 := testScriptSchnorrSig(t.t, internalKey)
|
leaf1 := testScriptSchnorrSig(ht.T, internalKey)
|
||||||
|
|
||||||
rootHash := leaf1.TapHash()
|
rootHash := leaf1.TapHash()
|
||||||
taprootKey := txscript.ComputeTaprootOutputKey(internalKey, rootHash[:])
|
taprootKey := txscript.ComputeTaprootOutputKey(internalKey, rootHash[:])
|
||||||
tapScriptAddr, err := btcutil.NewAddressTaproot(
|
tapScriptAddr, err := btcutil.NewAddressTaproot(
|
||||||
schnorr.SerializePubKey(taprootKey), harnessNetParams,
|
schnorr.SerializePubKey(taprootKey), harnessNetParams,
|
||||||
)
|
)
|
||||||
require.NoError(t.t, err)
|
require.NoError(ht, err)
|
||||||
p2trPkScript, err := txscript.PayToAddrScript(tapScriptAddr)
|
p2trPkScript, err := txscript.PayToAddrScript(tapScriptAddr)
|
||||||
require.NoError(t.t, err)
|
require.NoError(ht, err)
|
||||||
|
|
||||||
// We need to assemble the control block to be able to spend through the
|
// We need to assemble the control block to be able to spend through the
|
||||||
// script path.
|
// script path.
|
||||||
tapscript := input.TapscriptPartialReveal(internalKey, leaf1, nil)
|
tapscript := input.TapscriptPartialReveal(internalKey, leaf1, nil)
|
||||||
controlBlockBytes, err := tapscript.ControlBlock.ToBytes()
|
controlBlockBytes, err := tapscript.ControlBlock.ToBytes()
|
||||||
require.NoError(t.t, err)
|
require.NoError(ht, err)
|
||||||
|
|
||||||
// Send some funds to the output and then try to get a signature through
|
// Send some funds to the output and then try to get a signature through
|
||||||
// the SignPsbt RPC to spend that output again.
|
// the SignPsbt RPC to spend that output again.
|
||||||
assertPsbtSpend(
|
assertPsbtSpend(
|
||||||
ctxt, t, net, alice, p2trPkScript,
|
ht, alice, p2trPkScript,
|
||||||
func(packet *psbt.Packet) {
|
func(packet *psbt.Packet) {
|
||||||
in := &packet.Inputs[0]
|
in := &packet.Inputs[0]
|
||||||
in.Bip32Derivation = []*psbt.Bip32Derivation{{
|
in.Bip32Derivation = []*psbt.Bip32Derivation{{
|
||||||
@@ -942,32 +896,27 @@ func runSignPsbtSegWitV1ScriptSpend(t *harnessTest,
|
|||||||
}}
|
}}
|
||||||
},
|
},
|
||||||
func(packet *psbt.Packet) {
|
func(packet *psbt.Packet) {
|
||||||
require.Len(t.t, packet.Inputs, 1)
|
require.Len(ht, packet.Inputs, 1)
|
||||||
require.Len(
|
require.Len(
|
||||||
t.t, packet.Inputs[0].TaprootScriptSpendSig, 1,
|
ht, packet.Inputs[0].TaprootScriptSpendSig, 1,
|
||||||
)
|
)
|
||||||
|
|
||||||
scriptSpendSig := packet.Inputs[0].TaprootScriptSpendSig[0]
|
scriptSpendSig := packet.Inputs[0].TaprootScriptSpendSig[0]
|
||||||
require.Len(t.t, scriptSpendSig.Signature, 64)
|
require.Len(ht, scriptSpendSig.Signature, 64)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// runFundAndSignPsbt makes sure we can sign PSBTs that were funded by our
|
// runFundAndSignPsbt makes sure we can sign PSBTs that were funded by our
|
||||||
// internal wallet.
|
// internal wallet.
|
||||||
func runFundAndSignPsbt(t *harnessTest, net *lntest.NetworkHarness,
|
func runFundAndSignPsbt(ht *lntemp.HarnessTest, alice *node.HarnessNode) {
|
||||||
alice *lntest.HarnessNode) {
|
alice.AddToLogf("================ runFundAndSignPsbt ===============")
|
||||||
|
|
||||||
ctxb := context.Background()
|
|
||||||
ctxt, cancel := context.WithTimeout(ctxb, defaultTimeout)
|
|
||||||
defer cancel()
|
|
||||||
|
|
||||||
// We'll be using a "main" address where we send the funds to and from
|
// We'll be using a "main" address where we send the funds to and from
|
||||||
// several times.
|
// several times.
|
||||||
mainAddrResp, err := alice.NewAddress(ctxt, &lnrpc.NewAddressRequest{
|
mainAddrResp := alice.RPC.NewAddress(&lnrpc.NewAddressRequest{
|
||||||
Type: lnrpc.AddressType_WITNESS_PUBKEY_HASH,
|
Type: lnrpc.AddressType_WITNESS_PUBKEY_HASH,
|
||||||
})
|
})
|
||||||
require.NoError(t.t, err)
|
|
||||||
|
|
||||||
fundOutputs := map[string]uint64{
|
fundOutputs := map[string]uint64{
|
||||||
mainAddrResp.Address: 999000,
|
mainAddrResp.Address: 999000,
|
||||||
@@ -979,56 +928,53 @@ func runFundAndSignPsbt(t *harnessTest, net *lntest.NetworkHarness,
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, addrType := range spendAddrTypes {
|
for _, addrType := range spendAddrTypes {
|
||||||
ctxt, cancel := context.WithTimeout(ctxb, defaultTimeout)
|
ht.Logf("testing with address type %s", addrType)
|
||||||
|
|
||||||
// First, spend all the coins in the wallet to an address of the
|
// First, spend all the coins in the wallet to an address of
|
||||||
// given type so that UTXO will be picked when funding a PSBT.
|
// the given type so that UTXO will be picked when funding a
|
||||||
sendAllCoinsToAddrType(ctxt, t, net, alice, addrType)
|
// PSBT.
|
||||||
|
sendAllCoinsToAddrType(ht, alice, addrType)
|
||||||
|
|
||||||
// Let's fund a PSBT now where we want to send a few sats to our
|
// Let's fund a PSBT now where we want to send a few sats to
|
||||||
// main address.
|
// our main address.
|
||||||
assertPsbtFundSignSpend(ctxt, t, net, alice, fundOutputs, false)
|
assertPsbtFundSignSpend(ht, alice, fundOutputs, false)
|
||||||
|
|
||||||
// Send all coins back to a single address once again.
|
// Send all coins back to a single address once again.
|
||||||
sendAllCoinsToAddrType(ctxt, t, net, alice, addrType)
|
sendAllCoinsToAddrType(ht, alice, addrType)
|
||||||
|
|
||||||
// And now make sure the alternate way of signing a PSBT, which
|
// And now make sure the alternate way of signing a PSBT, which
|
||||||
// is calling FinalizePsbt directly, also works for this address
|
// is calling FinalizePsbt directly, also works for this
|
||||||
// type.
|
// address type.
|
||||||
assertPsbtFundSignSpend(ctxt, t, net, alice, fundOutputs, true)
|
assertPsbtFundSignSpend(ht, alice, fundOutputs, true)
|
||||||
|
|
||||||
cancel()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// assertPsbtSpend creates an output with the given pkScript on chain and then
|
// assertPsbtSpend creates an output with the given pkScript on chain and then
|
||||||
// attempts to create a sweep transaction that is signed using the SignPsbt RPC
|
// attempts to create a sweep transaction that is signed using the SignPsbt RPC
|
||||||
// that spends that output again.
|
// that spends that output again.
|
||||||
func assertPsbtSpend(ctx context.Context, t *harnessTest,
|
func assertPsbtSpend(ht *lntemp.HarnessTest, alice *node.HarnessNode,
|
||||||
net *lntest.NetworkHarness, alice *lntest.HarnessNode, pkScript []byte,
|
pkScript []byte, decorateUnsigned func(*psbt.Packet),
|
||||||
decorateUnsigned func(*psbt.Packet), verifySigned func(*psbt.Packet)) {
|
verifySigned func(*psbt.Packet)) {
|
||||||
|
|
||||||
// Let's send some coins to that address now.
|
// Let's send some coins to that address now.
|
||||||
utxo := &wire.TxOut{
|
utxo := &wire.TxOut{
|
||||||
Value: 600_000,
|
Value: 600_000,
|
||||||
PkScript: pkScript,
|
PkScript: pkScript,
|
||||||
}
|
}
|
||||||
resp, err := alice.WalletKitClient.SendOutputs(
|
req := &walletrpc.SendOutputsRequest{
|
||||||
ctx, &walletrpc.SendOutputsRequest{
|
Outputs: []*signrpc.TxOut{{
|
||||||
Outputs: []*signrpc.TxOut{{
|
Value: utxo.Value,
|
||||||
Value: utxo.Value,
|
PkScript: utxo.PkScript,
|
||||||
PkScript: utxo.PkScript,
|
}},
|
||||||
}},
|
MinConfs: 0,
|
||||||
MinConfs: 0,
|
SpendUnconfirmed: true,
|
||||||
SpendUnconfirmed: true,
|
SatPerKw: 2500,
|
||||||
SatPerKw: 2500,
|
}
|
||||||
},
|
resp := alice.RPC.SendOutputs(req)
|
||||||
)
|
|
||||||
require.NoError(t.t, err)
|
|
||||||
|
|
||||||
prevTx := wire.NewMsgTx(2)
|
prevTx := wire.NewMsgTx(2)
|
||||||
err = prevTx.Deserialize(bytes.NewReader(resp.RawTx))
|
err := prevTx.Deserialize(bytes.NewReader(resp.RawTx))
|
||||||
require.NoError(t.t, err)
|
require.NoError(ht, err)
|
||||||
|
|
||||||
prevOut := -1
|
prevOut := -1
|
||||||
for idx, txOut := range prevTx.TxOut {
|
for idx, txOut := range prevTx.TxOut {
|
||||||
@@ -1036,7 +982,7 @@ func assertPsbtSpend(ctx context.Context, t *harnessTest,
|
|||||||
prevOut = idx
|
prevOut = idx
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
require.Greater(t.t, prevOut, -1)
|
require.Greater(ht, prevOut, -1)
|
||||||
|
|
||||||
// Okay, we have everything we need to create a PSBT now.
|
// Okay, we have everything we need to create a PSBT now.
|
||||||
pendingTx := &wire.MsgTx{
|
pendingTx := &wire.MsgTx{
|
||||||
@@ -1054,7 +1000,7 @@ func assertPsbtSpend(ctx context.Context, t *harnessTest,
|
|||||||
}},
|
}},
|
||||||
}
|
}
|
||||||
packet, err := psbt.NewFromUnsignedTx(pendingTx)
|
packet, err := psbt.NewFromUnsignedTx(pendingTx)
|
||||||
require.NoError(t.t, err)
|
require.NoError(ht, err)
|
||||||
|
|
||||||
// Now let's add the meta information that we need for signing.
|
// Now let's add the meta information that we need for signing.
|
||||||
packet.Inputs[0].WitnessUtxo = utxo
|
packet.Inputs[0].WitnessUtxo = utxo
|
||||||
@@ -1064,20 +1010,16 @@ func assertPsbtSpend(ctx context.Context, t *harnessTest,
|
|||||||
// That's it, we should be able to sign the PSBT now.
|
// That's it, we should be able to sign the PSBT now.
|
||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
err = packet.Serialize(&buf)
|
err = packet.Serialize(&buf)
|
||||||
require.NoError(t.t, err)
|
require.NoError(ht, err)
|
||||||
|
|
||||||
signResp, err := alice.WalletKitClient.SignPsbt(
|
signReq := &walletrpc.SignPsbtRequest{FundedPsbt: buf.Bytes()}
|
||||||
ctx, &walletrpc.SignPsbtRequest{
|
signResp := alice.RPC.SignPsbt(signReq)
|
||||||
FundedPsbt: buf.Bytes(),
|
|
||||||
},
|
|
||||||
)
|
|
||||||
require.NoError(t.t, err)
|
|
||||||
|
|
||||||
// Let's make sure we have a partial signature.
|
// Let's make sure we have a partial signature.
|
||||||
signedPacket, err := psbt.NewFromRawBytes(
|
signedPacket, err := psbt.NewFromRawBytes(
|
||||||
bytes.NewReader(signResp.SignedPsbt), false,
|
bytes.NewReader(signResp.SignedPsbt), false,
|
||||||
)
|
)
|
||||||
require.NoError(t.t, err)
|
require.NoError(ht, err)
|
||||||
|
|
||||||
// Allow the caller to also verify (and potentially move) some of the
|
// Allow the caller to also verify (and potentially move) some of the
|
||||||
// returned fields.
|
// returned fields.
|
||||||
@@ -1085,87 +1027,72 @@ func assertPsbtSpend(ctx context.Context, t *harnessTest,
|
|||||||
|
|
||||||
// We should be able to finalize the PSBT and extract the final TX now.
|
// We should be able to finalize the PSBT and extract the final TX now.
|
||||||
err = psbt.MaybeFinalizeAll(signedPacket)
|
err = psbt.MaybeFinalizeAll(signedPacket)
|
||||||
require.NoError(t.t, err)
|
require.NoError(ht, err)
|
||||||
|
|
||||||
finalTx, err := psbt.Extract(signedPacket)
|
finalTx, err := psbt.Extract(signedPacket)
|
||||||
require.NoError(t.t, err)
|
require.NoError(ht, err)
|
||||||
|
|
||||||
// Make sure we can also sign a second time. This makes sure any key
|
// Make sure we can also sign a second time. This makes sure any key
|
||||||
// tweaking that happened for the signing didn't affect any keys in the
|
// tweaking that happened for the signing didn't affect any keys in the
|
||||||
// cache.
|
// cache.
|
||||||
signResp2, err := alice.WalletKitClient.SignPsbt(
|
r := &walletrpc.SignPsbtRequest{FundedPsbt: buf.Bytes()}
|
||||||
ctx, &walletrpc.SignPsbtRequest{
|
signResp2 := alice.RPC.SignPsbt(r)
|
||||||
FundedPsbt: buf.Bytes(),
|
|
||||||
},
|
|
||||||
)
|
|
||||||
require.NoError(t.t, err)
|
|
||||||
signedPacket2, err := psbt.NewFromRawBytes(
|
signedPacket2, err := psbt.NewFromRawBytes(
|
||||||
bytes.NewReader(signResp2.SignedPsbt), false,
|
bytes.NewReader(signResp2.SignedPsbt), false,
|
||||||
)
|
)
|
||||||
require.NoError(t.t, err)
|
require.NoError(ht, err)
|
||||||
verifySigned(signedPacket2)
|
verifySigned(signedPacket2)
|
||||||
|
|
||||||
buf.Reset()
|
buf.Reset()
|
||||||
err = finalTx.Serialize(&buf)
|
err = finalTx.Serialize(&buf)
|
||||||
require.NoError(t.t, err)
|
require.NoError(ht, err)
|
||||||
|
|
||||||
// Publish the second transaction and then mine both of them.
|
// Publish the second transaction and then mine both of them.
|
||||||
_, err = alice.WalletKitClient.PublishTransaction(
|
txReq := &walletrpc.Transaction{TxHex: buf.Bytes()}
|
||||||
ctx, &walletrpc.Transaction{
|
alice.RPC.PublishTransaction(txReq)
|
||||||
TxHex: buf.Bytes(),
|
|
||||||
},
|
|
||||||
)
|
|
||||||
require.NoError(t.t, err)
|
|
||||||
|
|
||||||
// Mine one block which should contain two transactions.
|
// Mine one block which should contain two transactions.
|
||||||
block := mineBlocks(t, net, 1, 2)[0]
|
block := ht.MineBlocksAndAssertNumTxes(1, 2)[0]
|
||||||
firstTxHash := prevTx.TxHash()
|
firstTxHash := prevTx.TxHash()
|
||||||
secondTxHash := finalTx.TxHash()
|
secondTxHash := finalTx.TxHash()
|
||||||
assertTxInBlock(t, block, &firstTxHash)
|
ht.Miner.AssertTxInBlock(block, &firstTxHash)
|
||||||
assertTxInBlock(t, block, &secondTxHash)
|
ht.Miner.AssertTxInBlock(block, &secondTxHash)
|
||||||
}
|
}
|
||||||
|
|
||||||
// assertPsbtFundSignSpend funds a PSBT from the internal wallet and then
|
// assertPsbtFundSignSpend funds a PSBT from the internal wallet and then
|
||||||
// attempts to sign it by using the SignPsbt or FinalizePsbt method.
|
// attempts to sign it by using the SignPsbt or FinalizePsbt method.
|
||||||
func assertPsbtFundSignSpend(ctx context.Context, t *harnessTest,
|
func assertPsbtFundSignSpend(ht *lntemp.HarnessTest, alice *node.HarnessNode,
|
||||||
net *lntest.NetworkHarness, alice *lntest.HarnessNode,
|
|
||||||
fundOutputs map[string]uint64, useFinalize bool) {
|
fundOutputs map[string]uint64, useFinalize bool) {
|
||||||
|
|
||||||
fundResp, err := alice.WalletKitClient.FundPsbt(
|
fundResp := alice.RPC.FundPsbt(&walletrpc.FundPsbtRequest{
|
||||||
ctx, &walletrpc.FundPsbtRequest{
|
Template: &walletrpc.FundPsbtRequest_Raw{
|
||||||
Template: &walletrpc.FundPsbtRequest_Raw{
|
Raw: &walletrpc.TxTemplate{
|
||||||
Raw: &walletrpc.TxTemplate{
|
Outputs: fundOutputs,
|
||||||
Outputs: fundOutputs,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
Fees: &walletrpc.FundPsbtRequest_SatPerVbyte{
|
|
||||||
SatPerVbyte: 2,
|
|
||||||
},
|
|
||||||
MinConfs: 1,
|
|
||||||
},
|
},
|
||||||
|
Fees: &walletrpc.FundPsbtRequest_SatPerVbyte{
|
||||||
|
SatPerVbyte: 2,
|
||||||
|
},
|
||||||
|
MinConfs: 1,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
require.NoError(t.t, err)
|
require.GreaterOrEqual(ht, fundResp.ChangeOutputIndex, int32(-1))
|
||||||
require.GreaterOrEqual(
|
|
||||||
t.t, fundResp.ChangeOutputIndex, int32(-1),
|
|
||||||
)
|
|
||||||
|
|
||||||
var signedPsbt []byte
|
var signedPsbt []byte
|
||||||
if useFinalize {
|
if useFinalize {
|
||||||
finalizeResp, err := alice.WalletKitClient.FinalizePsbt(
|
finalizeResp := alice.RPC.FinalizePsbt(
|
||||||
ctx, &walletrpc.FinalizePsbtRequest{
|
&walletrpc.FinalizePsbtRequest{
|
||||||
FundedPsbt: fundResp.FundedPsbt,
|
FundedPsbt: fundResp.FundedPsbt,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
require.NoError(t.t, err)
|
|
||||||
|
|
||||||
signedPsbt = finalizeResp.SignedPsbt
|
signedPsbt = finalizeResp.SignedPsbt
|
||||||
} else {
|
} else {
|
||||||
signResp, err := alice.WalletKitClient.SignPsbt(
|
signResp := alice.RPC.SignPsbt(
|
||||||
ctx, &walletrpc.SignPsbtRequest{
|
&walletrpc.SignPsbtRequest{
|
||||||
FundedPsbt: fundResp.FundedPsbt,
|
FundedPsbt: fundResp.FundedPsbt,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
require.NoError(t.t, err)
|
|
||||||
|
|
||||||
signedPsbt = signResp.SignedPsbt
|
signedPsbt = signResp.SignedPsbt
|
||||||
}
|
}
|
||||||
@@ -1174,37 +1101,34 @@ func assertPsbtFundSignSpend(ctx context.Context, t *harnessTest,
|
|||||||
signedPacket, err := psbt.NewFromRawBytes(
|
signedPacket, err := psbt.NewFromRawBytes(
|
||||||
bytes.NewReader(signedPsbt), false,
|
bytes.NewReader(signedPsbt), false,
|
||||||
)
|
)
|
||||||
require.NoError(t.t, err)
|
require.NoError(ht, err)
|
||||||
|
|
||||||
// We should be able to finalize the PSBT and extract the final
|
// We should be able to finalize the PSBT and extract the final
|
||||||
// TX now.
|
// TX now.
|
||||||
err = psbt.MaybeFinalizeAll(signedPacket)
|
err = psbt.MaybeFinalizeAll(signedPacket)
|
||||||
require.NoError(t.t, err)
|
require.NoError(ht, err)
|
||||||
|
|
||||||
finalTx, err := psbt.Extract(signedPacket)
|
finalTx, err := psbt.Extract(signedPacket)
|
||||||
require.NoError(t.t, err)
|
require.NoError(ht, err)
|
||||||
|
|
||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
err = finalTx.Serialize(&buf)
|
err = finalTx.Serialize(&buf)
|
||||||
require.NoError(t.t, err)
|
require.NoError(ht, err)
|
||||||
|
|
||||||
// Publish the second transaction and then mine both of them.
|
// Publish the second transaction and then mine both of them.
|
||||||
_, err = alice.WalletKitClient.PublishTransaction(
|
alice.RPC.PublishTransaction(&walletrpc.Transaction{
|
||||||
ctx, &walletrpc.Transaction{
|
TxHex: buf.Bytes(),
|
||||||
TxHex: buf.Bytes(),
|
})
|
||||||
},
|
|
||||||
)
|
|
||||||
require.NoError(t.t, err)
|
|
||||||
|
|
||||||
// Mine one block which should contain two transactions.
|
// Mine one block which should contain one transaction.
|
||||||
block := mineBlocks(t, net, 1, 1)[0]
|
block := ht.MineBlocksAndAssertNumTxes(1, 1)[0]
|
||||||
finalTxHash := finalTx.TxHash()
|
finalTxHash := finalTx.TxHash()
|
||||||
assertTxInBlock(t, block, &finalTxHash)
|
ht.Miner.AssertTxInBlock(block, &finalTxHash)
|
||||||
}
|
}
|
||||||
|
|
||||||
// deriveInternalKey derives a signing key and returns its descriptor, full
|
// deriveInternalKey derives a signing key and returns its descriptor, full
|
||||||
// derivation path and parsed public key.
|
// derivation path and parsed public key.
|
||||||
func deriveInternalKey(ctx context.Context, t *harnessTest,
|
func deriveInternalKeyOld(ctx context.Context, t *harnessTest,
|
||||||
alice *lntest.HarnessNode) (*signrpc.KeyDescriptor, *btcec.PublicKey,
|
alice *lntest.HarnessNode) (*signrpc.KeyDescriptor, *btcec.PublicKey,
|
||||||
[]uint32) {
|
[]uint32) {
|
||||||
|
|
||||||
@@ -1230,6 +1154,32 @@ func deriveInternalKey(ctx context.Context, t *harnessTest,
|
|||||||
return keyDesc, parsedPubKey, fullDerivationPath
|
return keyDesc, parsedPubKey, fullDerivationPath
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// deriveInternalKey derives a signing key and returns its descriptor, full
|
||||||
|
// derivation path and parsed public key.
|
||||||
|
func deriveInternalKey(ht *lntemp.HarnessTest,
|
||||||
|
alice *node.HarnessNode) (*signrpc.KeyDescriptor, *btcec.PublicKey,
|
||||||
|
[]uint32) {
|
||||||
|
|
||||||
|
// For the next step, we need a public key. Let's use a special family
|
||||||
|
// for this.
|
||||||
|
req := &walletrpc.KeyReq{KeyFamily: testTaprootKeyFamily}
|
||||||
|
keyDesc := alice.RPC.DeriveNextKey(req)
|
||||||
|
|
||||||
|
// The DeriveNextKey returns a key from the internal 1017 scope.
|
||||||
|
fullDerivationPath := []uint32{
|
||||||
|
hdkeychain.HardenedKeyStart + keychain.BIP0043Purpose,
|
||||||
|
hdkeychain.HardenedKeyStart + harnessNetParams.HDCoinType,
|
||||||
|
hdkeychain.HardenedKeyStart + uint32(keyDesc.KeyLoc.KeyFamily),
|
||||||
|
0,
|
||||||
|
uint32(keyDesc.KeyLoc.KeyIndex),
|
||||||
|
}
|
||||||
|
|
||||||
|
parsedPubKey, err := btcec.ParsePubKey(keyDesc.RawKeyBytes)
|
||||||
|
require.NoError(ht, err)
|
||||||
|
|
||||||
|
return keyDesc, parsedPubKey, fullDerivationPath
|
||||||
|
}
|
||||||
|
|
||||||
// openChannelPsbt attempts to open a channel between srcNode and destNode with
|
// openChannelPsbt attempts to open a channel between srcNode and destNode with
|
||||||
// the passed channel funding parameters. If the passed context has a timeout,
|
// the passed channel funding parameters. If the passed context has a timeout,
|
||||||
// then if the timeout is reached before the channel pending notification is
|
// then if the timeout is reached before the channel pending notification is
|
||||||
@@ -1319,22 +1269,19 @@ func receiveChanUpdate(ctx context.Context,
|
|||||||
|
|
||||||
// sendAllCoinsToAddrType sweeps all coins from the wallet and sends them to a
|
// sendAllCoinsToAddrType sweeps all coins from the wallet and sends them to a
|
||||||
// new address of the given type.
|
// new address of the given type.
|
||||||
func sendAllCoinsToAddrType(ctx context.Context, t *harnessTest,
|
func sendAllCoinsToAddrType(ht *lntemp.HarnessTest,
|
||||||
net *lntest.NetworkHarness, node *lntest.HarnessNode,
|
hn *node.HarnessNode, addrType lnrpc.AddressType) {
|
||||||
addrType lnrpc.AddressType) {
|
|
||||||
|
|
||||||
resp, err := node.NewAddress(ctx, &lnrpc.NewAddressRequest{
|
resp := hn.RPC.NewAddress(&lnrpc.NewAddressRequest{
|
||||||
Type: addrType,
|
Type: addrType,
|
||||||
})
|
})
|
||||||
require.NoError(t.t, err)
|
|
||||||
|
|
||||||
_, err = node.SendCoins(ctx, &lnrpc.SendCoinsRequest{
|
hn.RPC.SendCoins(&lnrpc.SendCoinsRequest{
|
||||||
Addr: resp.Address,
|
Addr: resp.Address,
|
||||||
SendAll: true,
|
SendAll: true,
|
||||||
|
SpendUnconfirmed: true,
|
||||||
})
|
})
|
||||||
require.NoError(t.t, err)
|
|
||||||
|
|
||||||
_ = mineBlocks(t, net, 1, 1)[0]
|
ht.MineBlocksAndAssertNumTxes(1, 1)
|
||||||
err = node.WaitForBlockchainSync()
|
ht.WaitForBlockchainSync(hn)
|
||||||
require.NoError(t.t, err)
|
|
||||||
}
|
}
|
||||||
@@ -1136,7 +1136,7 @@ func testTaprootImportTapscriptFullTree(ctxt context.Context, t *harnessTest,
|
|||||||
|
|
||||||
// For the next step, we need a public key. Let's use a special family
|
// For the next step, we need a public key. Let's use a special family
|
||||||
// for this.
|
// for this.
|
||||||
_, internalKey, derivationPath := deriveInternalKey(ctxt, t, alice)
|
_, internalKey, derivationPath := deriveInternalKeyOld(ctxt, t, alice)
|
||||||
|
|
||||||
// Let's create a taproot script output now. This is a hash lock with a
|
// Let's create a taproot script output now. This is a hash lock with a
|
||||||
// simple preimage of "foobar".
|
// simple preimage of "foobar".
|
||||||
@@ -1213,7 +1213,7 @@ func testTaprootImportTapscriptPartialReveal(ctxt context.Context,
|
|||||||
|
|
||||||
// For the next step, we need a public key. Let's use a special family
|
// For the next step, we need a public key. Let's use a special family
|
||||||
// for this.
|
// for this.
|
||||||
_, internalKey, derivationPath := deriveInternalKey(ctxt, t, alice)
|
_, internalKey, derivationPath := deriveInternalKeyOld(ctxt, t, alice)
|
||||||
|
|
||||||
// Let's create a taproot script output now. This is a hash lock with a
|
// Let's create a taproot script output now. This is a hash lock with a
|
||||||
// simple preimage of "foobar".
|
// simple preimage of "foobar".
|
||||||
@@ -1286,7 +1286,7 @@ func testTaprootImportTapscriptRootHashOnly(ctxt context.Context,
|
|||||||
|
|
||||||
// For the next step, we need a public key. Let's use a special family
|
// For the next step, we need a public key. Let's use a special family
|
||||||
// for this.
|
// for this.
|
||||||
_, internalKey, derivationPath := deriveInternalKey(ctxt, t, alice)
|
_, internalKey, derivationPath := deriveInternalKeyOld(ctxt, t, alice)
|
||||||
|
|
||||||
// Let's create a taproot script output now. This is a hash lock with a
|
// Let's create a taproot script output now. This is a hash lock with a
|
||||||
// simple preimage of "foobar".
|
// simple preimage of "foobar".
|
||||||
@@ -1347,7 +1347,7 @@ func testTaprootImportTapscriptFullKey(ctxt context.Context, t *harnessTest,
|
|||||||
|
|
||||||
// For the next step, we need a public key. Let's use a special family
|
// For the next step, we need a public key. Let's use a special family
|
||||||
// for this.
|
// for this.
|
||||||
_, internalKey, derivationPath := deriveInternalKey(ctxt, t, alice)
|
_, internalKey, derivationPath := deriveInternalKeyOld(ctxt, t, alice)
|
||||||
|
|
||||||
// Let's create a taproot script output now. This is a hash lock with a
|
// Let's create a taproot script output now. This is a hash lock with a
|
||||||
// simple preimage of "foobar".
|
// simple preimage of "foobar".
|
||||||
|
|||||||
@@ -12,10 +12,6 @@ var allTestCases = []*testCase{
|
|||||||
name: "async bidirectional payments",
|
name: "async bidirectional payments",
|
||||||
test: testBidirectionalAsyncPayments,
|
test: testBidirectionalAsyncPayments,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: "sign psbt",
|
|
||||||
test: testSignPsbt,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: "wallet import account",
|
name: "wallet import account",
|
||||||
test: testWalletImportAccount,
|
test: testWalletImportAccount,
|
||||||
|
|||||||
Reference in new issue
Block a user