diff --git a/lntemp/rpc/wallet_kit.go b/lntemp/rpc/wallet_kit.go index 5afca17b4..4f88a046b 100644 --- a/lntemp/rpc/wallet_kit.go +++ b/lntemp/rpc/wallet_kit.go @@ -198,7 +198,7 @@ func (h *HarnessRPC) ImportAccount( defer cancel() resp, err := h.WalletKit.ImportAccount(ctxt, req) - require.NoErrorf(h, err, "failed to import account") + h.NoError(err, "ImportAccount") return resp } diff --git a/lntest/itest/list_on_test.go b/lntest/itest/list_on_test.go index e21fa8e53..6576d42d4 100644 --- a/lntest/itest/list_on_test.go +++ b/lntest/itest/list_on_test.go @@ -287,6 +287,10 @@ var allTestCasesTemp = []*lntemp.TestCase{ Name: "psbt channel funding single step", TestFunc: testPsbtChanFundingSingleStep, }, + { + Name: "sign psbt", + TestFunc: testSignPsbt, + }, { Name: "resolution handoff", TestFunc: testResHandoff, diff --git a/lntest/itest/lnd_psbt_test.go b/lntest/itest/lnd_psbt_test.go index d01597b1f..4eb614bdf 100644 --- a/lntest/itest/lnd_psbt_test.go +++ b/lntest/itest/lnd_psbt_test.go @@ -576,49 +576,38 @@ func testPsbtChanFundingSingleStep(ht *lntemp.HarnessTest) { } // testSignPsbt tests that the SignPsbt RPC works correctly. -func testSignPsbt(net *lntest.NetworkHarness, t *harnessTest) { - runSignPsbtSegWitV0P2WKH(t, net, net.Alice) - runSignPsbtSegWitV0NP2WKH(t, net, net.Alice) - runSignPsbtSegWitV1KeySpendBip86(t, net, net.Alice) - runSignPsbtSegWitV1KeySpendRootHash(t, net, net.Alice) - runSignPsbtSegWitV1ScriptSpend(t, net, net.Alice) +func testSignPsbt(ht *lntemp.HarnessTest) { + runSignPsbtSegWitV0P2WKH(ht, ht.Alice) + runSignPsbtSegWitV0NP2WKH(ht, ht.Alice) + runSignPsbtSegWitV1KeySpendBip86(ht, ht.Alice) + runSignPsbtSegWitV1KeySpendRootHash(ht, ht.Alice) + runSignPsbtSegWitV1ScriptSpend(ht, ht.Alice) - // The above tests all make sure we can sign for keys that aren't in the - // wallet. But we also want to make sure we can fund and then sign PSBTs - // from our wallet. - runFundAndSignPsbt(t, net, net.Alice) + // The above tests all make sure we can sign for keys that aren't in + // the wallet. But we also want to make sure we can fund and then sign + // PSBTs from our wallet. + runFundAndSignPsbt(ht, ht.Alice) } // runSignPsbtSegWitV0P2WKH tests that the SignPsbt RPC works correctly for a // SegWit v0 p2wkh input. -func runSignPsbtSegWitV0P2WKH(t *harnessTest, net *lntest.NetworkHarness, - 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() - +func runSignPsbtSegWitV0P2WKH(ht *lntemp.HarnessTest, alice *node.HarnessNode) { // 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 // 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 // account. - accounts, err := alice.WalletKitClient.ListAccounts( - ctxt, &walletrpc.ListAccountsRequest{}, - ) - require.NoError(t.t, err) - require.NotEmpty(t.t, accounts.Accounts) + accounts := alice.RPC.ListAccounts(&walletrpc.ListAccountsRequest{}) + require.NotEmpty(ht, accounts.Accounts) // We also need to parse the accounts, so we have easy access to the // parsed derivation paths. parsedAccounts, err := walletrpc.AccountsToWatchOnly(accounts.Accounts) - require.NoError(t.t, err) + require.NoError(ht, err) account := parsedAccounts[0] xpub, err := hdkeychain.NewKeyFromString(account.Xpub) - require.NoError(t.t, err) + require.NoError(ht, err) const ( changeIndex = 1 @@ -634,27 +623,27 @@ func runSignPsbtSegWitV0P2WKH(t *harnessTest, net *lntest.NetworkHarness, // Let's simulate a change address. 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. addrKey, err := change.DeriveNonStandard(addrIndex) // nolint:staticcheck - require.NoError(t.t, err) + require.NoError(ht, err) addrPubKey, err := addrKey.ECPubKey() - require.NoError(t.t, err) + require.NoError(ht, err) pubKeyHash := btcutil.Hash160(addrPubKey.SerializeCompressed()) witnessAddr, err := btcutil.NewAddressWitnessPubKeyHash( pubKeyHash, harnessNetParams, ) - require.NoError(t.t, err) + require.NoError(ht, err) 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 // the SignPsbt RPC to spend that output again. assertPsbtSpend( - ctxt, t, net, alice, pkScript, + ht, alice, pkScript, func(packet *psbt.Packet) { in := &packet.Inputs[0] in.Bip32Derivation = []*psbt.Bip32Derivation{{ @@ -664,16 +653,16 @@ func runSignPsbtSegWitV0P2WKH(t *harnessTest, net *lntest.NetworkHarness, in.SighashType = txscript.SigHashAll }, func(packet *psbt.Packet) { - require.Len(t.t, packet.Inputs, 1) - require.Len(t.t, packet.Inputs[0].PartialSigs, 1) + require.Len(ht, packet.Inputs, 1) + require.Len(ht, packet.Inputs[0].PartialSigs, 1) partialSig := packet.Inputs[0].PartialSigs[0] require.Equal( - t.t, partialSig.PubKey, + ht, partialSig.PubKey, addrPubKey.SerializeCompressed(), ) 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 // SegWit v0 np2wkh input. -func runSignPsbtSegWitV0NP2WKH(t *harnessTest, net *lntest.NetworkHarness, - 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() - +func runSignPsbtSegWitV0NP2WKH(ht *lntemp.HarnessTest, alice *node.HarnessNode) { // 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 // 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 // account. - accounts, err := alice.WalletKitClient.ListAccounts( - ctxt, &walletrpc.ListAccountsRequest{}, - ) - require.NoError(t.t, err) - require.NotEmpty(t.t, accounts.Accounts) + accounts := alice.RPC.ListAccounts(&walletrpc.ListAccountsRequest{}) + require.NotEmpty(ht, accounts.Accounts) // We also need to parse the accounts, so we have easy access to the // parsed derivation paths. parsedAccounts, err := walletrpc.AccountsToWatchOnly(accounts.Accounts) - require.NoError(t.t, err) + require.NoError(ht, err) account := parsedAccounts[0] xpub, err := hdkeychain.NewKeyFromString(account.Xpub) - require.NoError(t.t, err) + require.NoError(ht, err) const ( changeIndex = 1 @@ -724,34 +702,34 @@ func runSignPsbtSegWitV0NP2WKH(t *harnessTest, net *lntest.NetworkHarness, // Let's simulate a change address. 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. addrKey, err := change.DeriveNonStandard(addrIndex) // nolint:staticcheck - require.NoError(t.t, err) + require.NoError(ht, err) addrPubKey, err := addrKey.ECPubKey() - require.NoError(t.t, err) + require.NoError(ht, err) pubKeyHash := btcutil.Hash160(addrPubKey.SerializeCompressed()) witnessAddr, err := btcutil.NewAddressWitnessPubKeyHash( pubKeyHash, harnessNetParams, ) - require.NoError(t.t, err) + require.NoError(ht, err) witnessProgram, err := txscript.PayToAddrScript(witnessAddr) - require.NoError(t.t, err) + require.NoError(ht, err) np2wkhAddr, err := btcutil.NewAddressScriptHash( witnessProgram, harnessNetParams, ) - require.NoError(t.t, err) + require.NoError(ht, err) 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 // the SignPsbt RPC to spend that output again. assertPsbtSpend( - ctxt, t, net, alice, pkScript, + ht, alice, pkScript, func(packet *psbt.Packet) { in := &packet.Inputs[0] in.RedeemScript = witnessProgram @@ -762,16 +740,16 @@ func runSignPsbtSegWitV0NP2WKH(t *harnessTest, net *lntest.NetworkHarness, in.SighashType = txscript.SigHashAll }, func(packet *psbt.Packet) { - require.Len(t.t, packet.Inputs, 1) - require.Len(t.t, packet.Inputs[0].PartialSigs, 1) + require.Len(ht, packet.Inputs, 1) + require.Len(ht, packet.Inputs[0].PartialSigs, 1) partialSig := packet.Inputs[0].PartialSigs[0] require.Equal( - t.t, partialSig.PubKey, + ht, partialSig.PubKey, addrPubKey.SerializeCompressed(), ) 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 // for a SegWit v1 p2tr key spend BIP-0086 input. -func runSignPsbtSegWitV1KeySpendBip86(t *harnessTest, net *lntest.NetworkHarness, - 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() +func runSignPsbtSegWitV1KeySpendBip86(ht *lntemp.HarnessTest, + alice *node.HarnessNode) { // Derive a key we can use for signing. - keyDesc, internalKey, fullDerivationPath := deriveInternalKey( - ctxt, t, alice, - ) + keyDesc, internalKey, fullDerivationPath := deriveInternalKey(ht, alice) // Our taproot key is a BIP0086 key spend only construction that just // commits to the internal key and no root hash. @@ -799,14 +769,14 @@ func runSignPsbtSegWitV1KeySpendBip86(t *harnessTest, net *lntest.NetworkHarness tapScriptAddr, err := btcutil.NewAddressTaproot( schnorr.SerializePubKey(taprootKey), harnessNetParams, ) - require.NoError(t.t, err) + require.NoError(ht, err) 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 // the SignPsbt RPC to spend that output again. assertPsbtSpend( - ctxt, t, net, alice, p2trPkScript, + ht, alice, p2trPkScript, func(packet *psbt.Packet) { in := &packet.Inputs[0] in.Bip32Derivation = []*psbt.Bip32Derivation{{ @@ -820,9 +790,9 @@ func runSignPsbtSegWitV1KeySpendBip86(t *harnessTest, net *lntest.NetworkHarness in.SighashType = txscript.SigHashDefault }, func(packet *psbt.Packet) { - require.Len(t.t, packet.Inputs, 1) + require.Len(ht, packet.Inputs, 1) 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 // correctly for a SegWit v1 p2tr key spend that also commits to a script tree // root hash. -func runSignPsbtSegWitV1KeySpendRootHash(t *harnessTest, - net *lntest.NetworkHarness, 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() +func runSignPsbtSegWitV1KeySpendRootHash(ht *lntemp.HarnessTest, + alice *node.HarnessNode) { // Derive a key we can use for signing. - keyDesc, internalKey, fullDerivationPath := deriveInternalKey( - ctxt, t, alice, - ) + keyDesc, internalKey, fullDerivationPath := deriveInternalKey(ht, alice) // Let's create a taproot script output now. This is a hash lock with a // simple preimage of "foobar". - leaf1 := testScriptHashLock(t.t, []byte("foobar")) + leaf1 := testScriptHashLock(ht.T, []byte("foobar")) rootHash := leaf1.TapHash() taprootKey := txscript.ComputeTaprootOutputKey(internalKey, rootHash[:]) tapScriptAddr, err := btcutil.NewAddressTaproot( schnorr.SerializePubKey(taprootKey), harnessNetParams, ) - require.NoError(t.t, err) + require.NoError(ht, err) 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 // the SignPsbt RPC to spend that output again. assertPsbtSpend( - ctxt, t, net, alice, p2trPkScript, + ht, alice, p2trPkScript, func(packet *psbt.Packet) { in := &packet.Inputs[0] in.Bip32Derivation = []*psbt.Bip32Derivation{{ @@ -876,9 +838,9 @@ func runSignPsbtSegWitV1KeySpendRootHash(t *harnessTest, in.SighashType = txscript.SigHashDefault }, func(packet *psbt.Packet) { - require.Len(t.t, packet.Inputs, 1) + require.Len(ht, packet.Inputs, 1) 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 // for a SegWit v1 p2tr script spend. -func runSignPsbtSegWitV1ScriptSpend(t *harnessTest, - net *lntest.NetworkHarness, 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() +func runSignPsbtSegWitV1ScriptSpend(ht *lntemp.HarnessTest, + alice *node.HarnessNode) { // Derive a key we can use for signing. - keyDesc, internalKey, fullDerivationPath := deriveInternalKey( - ctxt, t, alice, - ) + keyDesc, internalKey, fullDerivationPath := deriveInternalKey(ht, alice) // Let's create a taproot script output now. This is a hash lock with a // simple preimage of "foobar". - leaf1 := testScriptSchnorrSig(t.t, internalKey) + leaf1 := testScriptSchnorrSig(ht.T, internalKey) rootHash := leaf1.TapHash() taprootKey := txscript.ComputeTaprootOutputKey(internalKey, rootHash[:]) tapScriptAddr, err := btcutil.NewAddressTaproot( schnorr.SerializePubKey(taprootKey), harnessNetParams, ) - require.NoError(t.t, err) + require.NoError(ht, err) 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 // script path. tapscript := input.TapscriptPartialReveal(internalKey, leaf1, nil) 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 // the SignPsbt RPC to spend that output again. assertPsbtSpend( - ctxt, t, net, alice, p2trPkScript, + ht, alice, p2trPkScript, func(packet *psbt.Packet) { in := &packet.Inputs[0] in.Bip32Derivation = []*psbt.Bip32Derivation{{ @@ -942,32 +896,27 @@ func runSignPsbtSegWitV1ScriptSpend(t *harnessTest, }} }, func(packet *psbt.Packet) { - require.Len(t.t, packet.Inputs, 1) + require.Len(ht, packet.Inputs, 1) require.Len( - t.t, packet.Inputs[0].TaprootScriptSpendSig, 1, + ht, packet.Inputs[0].TaprootScriptSpendSig, 1, ) 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 // internal wallet. -func runFundAndSignPsbt(t *harnessTest, net *lntest.NetworkHarness, - alice *lntest.HarnessNode) { - - ctxb := context.Background() - ctxt, cancel := context.WithTimeout(ctxb, defaultTimeout) - defer cancel() +func runFundAndSignPsbt(ht *lntemp.HarnessTest, alice *node.HarnessNode) { + alice.AddToLogf("================ runFundAndSignPsbt ===============") // We'll be using a "main" address where we send the funds to and from // several times. - mainAddrResp, err := alice.NewAddress(ctxt, &lnrpc.NewAddressRequest{ + mainAddrResp := alice.RPC.NewAddress(&lnrpc.NewAddressRequest{ Type: lnrpc.AddressType_WITNESS_PUBKEY_HASH, }) - require.NoError(t.t, err) fundOutputs := map[string]uint64{ mainAddrResp.Address: 999000, @@ -979,56 +928,53 @@ func runFundAndSignPsbt(t *harnessTest, net *lntest.NetworkHarness, } 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 - // given type so that UTXO will be picked when funding a PSBT. - sendAllCoinsToAddrType(ctxt, t, net, alice, addrType) + // First, spend all the coins in the wallet to an address of + // the given type so that UTXO will be picked when funding a + // PSBT. + sendAllCoinsToAddrType(ht, alice, addrType) - // Let's fund a PSBT now where we want to send a few sats to our - // main address. - assertPsbtFundSignSpend(ctxt, t, net, alice, fundOutputs, false) + // Let's fund a PSBT now where we want to send a few sats to + // our main address. + assertPsbtFundSignSpend(ht, alice, fundOutputs, false) // 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 - // is calling FinalizePsbt directly, also works for this address - // type. - assertPsbtFundSignSpend(ctxt, t, net, alice, fundOutputs, true) - - cancel() + // is calling FinalizePsbt directly, also works for this + // address type. + assertPsbtFundSignSpend(ht, alice, fundOutputs, true) } } // 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 // that spends that output again. -func assertPsbtSpend(ctx context.Context, t *harnessTest, - net *lntest.NetworkHarness, alice *lntest.HarnessNode, pkScript []byte, - decorateUnsigned func(*psbt.Packet), verifySigned func(*psbt.Packet)) { +func assertPsbtSpend(ht *lntemp.HarnessTest, alice *node.HarnessNode, + pkScript []byte, decorateUnsigned func(*psbt.Packet), + verifySigned func(*psbt.Packet)) { // Let's send some coins to that address now. utxo := &wire.TxOut{ Value: 600_000, PkScript: pkScript, } - resp, err := alice.WalletKitClient.SendOutputs( - ctx, &walletrpc.SendOutputsRequest{ - Outputs: []*signrpc.TxOut{{ - Value: utxo.Value, - PkScript: utxo.PkScript, - }}, - MinConfs: 0, - SpendUnconfirmed: true, - SatPerKw: 2500, - }, - ) - require.NoError(t.t, err) + req := &walletrpc.SendOutputsRequest{ + Outputs: []*signrpc.TxOut{{ + Value: utxo.Value, + PkScript: utxo.PkScript, + }}, + MinConfs: 0, + SpendUnconfirmed: true, + SatPerKw: 2500, + } + resp := alice.RPC.SendOutputs(req) prevTx := wire.NewMsgTx(2) - err = prevTx.Deserialize(bytes.NewReader(resp.RawTx)) - require.NoError(t.t, err) + err := prevTx.Deserialize(bytes.NewReader(resp.RawTx)) + require.NoError(ht, err) prevOut := -1 for idx, txOut := range prevTx.TxOut { @@ -1036,7 +982,7 @@ func assertPsbtSpend(ctx context.Context, t *harnessTest, prevOut = idx } } - require.Greater(t.t, prevOut, -1) + require.Greater(ht, prevOut, -1) // Okay, we have everything we need to create a PSBT now. pendingTx := &wire.MsgTx{ @@ -1054,7 +1000,7 @@ func assertPsbtSpend(ctx context.Context, t *harnessTest, }}, } 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. 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. var buf bytes.Buffer err = packet.Serialize(&buf) - require.NoError(t.t, err) + require.NoError(ht, err) - signResp, err := alice.WalletKitClient.SignPsbt( - ctx, &walletrpc.SignPsbtRequest{ - FundedPsbt: buf.Bytes(), - }, - ) - require.NoError(t.t, err) + signReq := &walletrpc.SignPsbtRequest{FundedPsbt: buf.Bytes()} + signResp := alice.RPC.SignPsbt(signReq) // Let's make sure we have a partial signature. signedPacket, err := psbt.NewFromRawBytes( 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 // 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. err = psbt.MaybeFinalizeAll(signedPacket) - require.NoError(t.t, err) + require.NoError(ht, err) 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 // tweaking that happened for the signing didn't affect any keys in the // cache. - signResp2, err := alice.WalletKitClient.SignPsbt( - ctx, &walletrpc.SignPsbtRequest{ - FundedPsbt: buf.Bytes(), - }, - ) - require.NoError(t.t, err) + r := &walletrpc.SignPsbtRequest{FundedPsbt: buf.Bytes()} + signResp2 := alice.RPC.SignPsbt(r) signedPacket2, err := psbt.NewFromRawBytes( bytes.NewReader(signResp2.SignedPsbt), false, ) - require.NoError(t.t, err) + require.NoError(ht, err) verifySigned(signedPacket2) buf.Reset() err = finalTx.Serialize(&buf) - require.NoError(t.t, err) + require.NoError(ht, err) // Publish the second transaction and then mine both of them. - _, err = alice.WalletKitClient.PublishTransaction( - ctx, &walletrpc.Transaction{ - TxHex: buf.Bytes(), - }, - ) - require.NoError(t.t, err) + txReq := &walletrpc.Transaction{TxHex: buf.Bytes()} + alice.RPC.PublishTransaction(txReq) // Mine one block which should contain two transactions. - block := mineBlocks(t, net, 1, 2)[0] + block := ht.MineBlocksAndAssertNumTxes(1, 2)[0] firstTxHash := prevTx.TxHash() secondTxHash := finalTx.TxHash() - assertTxInBlock(t, block, &firstTxHash) - assertTxInBlock(t, block, &secondTxHash) + ht.Miner.AssertTxInBlock(block, &firstTxHash) + ht.Miner.AssertTxInBlock(block, &secondTxHash) } // assertPsbtFundSignSpend funds a PSBT from the internal wallet and then // attempts to sign it by using the SignPsbt or FinalizePsbt method. -func assertPsbtFundSignSpend(ctx context.Context, t *harnessTest, - net *lntest.NetworkHarness, alice *lntest.HarnessNode, +func assertPsbtFundSignSpend(ht *lntemp.HarnessTest, alice *node.HarnessNode, fundOutputs map[string]uint64, useFinalize bool) { - fundResp, err := alice.WalletKitClient.FundPsbt( - ctx, &walletrpc.FundPsbtRequest{ - Template: &walletrpc.FundPsbtRequest_Raw{ - Raw: &walletrpc.TxTemplate{ - Outputs: fundOutputs, - }, + fundResp := alice.RPC.FundPsbt(&walletrpc.FundPsbtRequest{ + Template: &walletrpc.FundPsbtRequest_Raw{ + Raw: &walletrpc.TxTemplate{ + 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( - t.t, fundResp.ChangeOutputIndex, int32(-1), - ) + require.GreaterOrEqual(ht, fundResp.ChangeOutputIndex, int32(-1)) var signedPsbt []byte if useFinalize { - finalizeResp, err := alice.WalletKitClient.FinalizePsbt( - ctx, &walletrpc.FinalizePsbtRequest{ + finalizeResp := alice.RPC.FinalizePsbt( + &walletrpc.FinalizePsbtRequest{ FundedPsbt: fundResp.FundedPsbt, }, ) - require.NoError(t.t, err) signedPsbt = finalizeResp.SignedPsbt } else { - signResp, err := alice.WalletKitClient.SignPsbt( - ctx, &walletrpc.SignPsbtRequest{ + signResp := alice.RPC.SignPsbt( + &walletrpc.SignPsbtRequest{ FundedPsbt: fundResp.FundedPsbt, }, ) - require.NoError(t.t, err) signedPsbt = signResp.SignedPsbt } @@ -1174,37 +1101,34 @@ func assertPsbtFundSignSpend(ctx context.Context, t *harnessTest, signedPacket, err := psbt.NewFromRawBytes( 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 // TX now. err = psbt.MaybeFinalizeAll(signedPacket) - require.NoError(t.t, err) + require.NoError(ht, err) finalTx, err := psbt.Extract(signedPacket) - require.NoError(t.t, err) + require.NoError(ht, err) var buf bytes.Buffer err = finalTx.Serialize(&buf) - require.NoError(t.t, err) + require.NoError(ht, err) // Publish the second transaction and then mine both of them. - _, err = alice.WalletKitClient.PublishTransaction( - ctx, &walletrpc.Transaction{ - TxHex: buf.Bytes(), - }, - ) - require.NoError(t.t, err) + alice.RPC.PublishTransaction(&walletrpc.Transaction{ + TxHex: buf.Bytes(), + }) - // Mine one block which should contain two transactions. - block := mineBlocks(t, net, 1, 1)[0] + // Mine one block which should contain one transaction. + block := ht.MineBlocksAndAssertNumTxes(1, 1)[0] finalTxHash := finalTx.TxHash() - assertTxInBlock(t, block, &finalTxHash) + ht.Miner.AssertTxInBlock(block, &finalTxHash) } // deriveInternalKey derives a signing key and returns its descriptor, full // 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, []uint32) { @@ -1230,6 +1154,32 @@ func deriveInternalKey(ctx context.Context, t *harnessTest, 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 // the passed channel funding parameters. If the passed context has a timeout, // 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 // new address of the given type. -func sendAllCoinsToAddrType(ctx context.Context, t *harnessTest, - net *lntest.NetworkHarness, node *lntest.HarnessNode, - addrType lnrpc.AddressType) { +func sendAllCoinsToAddrType(ht *lntemp.HarnessTest, + hn *node.HarnessNode, addrType lnrpc.AddressType) { - resp, err := node.NewAddress(ctx, &lnrpc.NewAddressRequest{ + resp := hn.RPC.NewAddress(&lnrpc.NewAddressRequest{ Type: addrType, }) - require.NoError(t.t, err) - _, err = node.SendCoins(ctx, &lnrpc.SendCoinsRequest{ - Addr: resp.Address, - SendAll: true, + hn.RPC.SendCoins(&lnrpc.SendCoinsRequest{ + Addr: resp.Address, + SendAll: true, + SpendUnconfirmed: true, }) - require.NoError(t.t, err) - _ = mineBlocks(t, net, 1, 1)[0] - err = node.WaitForBlockchainSync() - require.NoError(t.t, err) + ht.MineBlocksAndAssertNumTxes(1, 1) + ht.WaitForBlockchainSync(hn) } diff --git a/lntest/itest/lnd_taproot_test.go b/lntest/itest/lnd_taproot_test.go index ad16cce7c..c7af79bd7 100644 --- a/lntest/itest/lnd_taproot_test.go +++ b/lntest/itest/lnd_taproot_test.go @@ -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 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 // 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 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 // 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 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 // 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 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 // simple preimage of "foobar". diff --git a/lntest/itest/lnd_test_list_on_test.go b/lntest/itest/lnd_test_list_on_test.go index bb9a72ecc..7afb99089 100644 --- a/lntest/itest/lnd_test_list_on_test.go +++ b/lntest/itest/lnd_test_list_on_test.go @@ -12,10 +12,6 @@ var allTestCases = []*testCase{ name: "async bidirectional payments", test: testBidirectionalAsyncPayments, }, - { - name: "sign psbt", - test: testSignPsbt, - }, { name: "wallet import account", test: testWalletImportAccount,