github.com/decred/dcrlnd@v0.7.6/lntest/itest/lnd_psbt_test.go (about) 1 package itest 2 3 import ( 4 "bytes" 5 "context" 6 "crypto/rand" 7 "fmt" 8 9 "github.com/decred/dcrd/dcrutil/v4" 10 "github.com/decred/dcrd/hdkeychain/v3" 11 jsonrpctypes "github.com/decred/dcrd/rpc/jsonrpc/types/v4" 12 "github.com/decred/dcrd/txscript/v4" 13 "github.com/decred/dcrd/txscript/v4/stdaddr" 14 "github.com/decred/dcrd/wire" 15 "github.com/decred/dcrlnd/funding" 16 "github.com/decred/dcrlnd/input" 17 "github.com/decred/dcrlnd/internal/psbt" 18 "github.com/decred/dcrlnd/lnrpc" 19 "github.com/decred/dcrlnd/lnrpc/signrpc" 20 "github.com/decred/dcrlnd/lnrpc/walletrpc" 21 "github.com/decred/dcrlnd/lntest" 22 "github.com/stretchr/testify/require" 23 "matheusd.com/testctx" 24 ) 25 26 // testPsbtChanFunding makes sure a channel can be opened between carol and dave 27 // by using a Partially Signed Bitcoin Transaction that funds the channel 28 // multisig funding output. 29 func testPsbtChanFunding(net *lntest.NetworkHarness, t *harnessTest) { 30 t.Skipf("psbt is not currently implemented in dcrlnd") 31 32 const chanSize = defaultChanAmt 33 34 // First, we'll create two new nodes that we'll use to open channels 35 // between for this test. Dave gets some coins that will be used to 36 // fund the PSBT, just to make sure that Carol has an empty wallet. 37 carol := net.NewNode(t.t, "carol", nil) 38 defer shutdownAndAssert(net, t, carol) 39 40 dave := net.NewNode(t.t, "dave", nil) 41 defer shutdownAndAssert(net, t, dave) 42 43 net.SendCoins(t.t, dcrutil.AtomsPerCoin, dave) 44 runPsbtChanFunding(net, t, carol, dave) 45 } 46 47 // runPsbtChanFunding makes sure a channel can be opened between carol and dave 48 // by using a Partially Signed Bitcoin Transaction that funds the channel 49 // multisig funding output. 50 func runPsbtChanFunding(net *lntest.NetworkHarness, t *harnessTest, carol, 51 dave *lntest.HarnessNode) { 52 53 ctxb := context.Background() 54 55 // Everything we do here should be done within a second or two, so we 56 // can just keep a single timeout context around for all calls. 57 ctxt, cancel := context.WithTimeout(ctxb, defaultTimeout) 58 defer cancel() 59 60 const chanSize = funding.MaxDecredFundingAmount 61 net.SendCoins(t.t, dcrutil.AtomsPerCoin, dave) 62 63 // Before we start the test, we'll ensure both sides are connected so 64 // the funding flow can be properly executed. 65 net.EnsureConnected(t.t, carol, dave) 66 net.EnsureConnected(t.t, carol, net.Alice) 67 68 // At this point, we can begin our PSBT channel funding workflow. We'll 69 // start by generating a pending channel ID externally that will be used 70 // to track this new funding type. 71 var pendingChanID [32]byte 72 _, err := rand.Read(pendingChanID[:]) 73 require.NoError(t.t, err) 74 75 // We'll also test batch funding of two channels so we need another ID. 76 var pendingChanID2 [32]byte 77 _, err = rand.Read(pendingChanID2[:]) 78 require.NoError(t.t, err) 79 80 // Now that we have the pending channel ID, Carol will open the channel 81 // by specifying a PSBT shim. We use the NoPublish flag here to avoid 82 // publishing the whole batch TX too early. 83 chanUpdates, tempPsbt, err := openChannelPsbt( 84 ctxt, carol, dave, lntest.OpenChannelParams{ 85 Amt: chanSize, 86 FundingShim: &lnrpc.FundingShim{ 87 Shim: &lnrpc.FundingShim_PsbtShim{ 88 PsbtShim: &lnrpc.PsbtShim{ 89 PendingChanId: pendingChanID[:], 90 NoPublish: true, 91 }, 92 }, 93 }, 94 }, 95 ) 96 require.NoError(t.t, err) 97 98 // Let's add a second channel to the batch. This time between Carol and 99 // Alice. We will publish the batch TX once this channel funding is 100 // complete. 101 chanUpdates2, psbtBytes2, err := openChannelPsbt( 102 ctxt, carol, net.Alice, lntest.OpenChannelParams{ 103 Amt: chanSize, 104 FundingShim: &lnrpc.FundingShim{ 105 Shim: &lnrpc.FundingShim_PsbtShim{ 106 PsbtShim: &lnrpc.PsbtShim{ 107 PendingChanId: pendingChanID2[:], 108 NoPublish: false, 109 BasePsbt: tempPsbt, 110 }, 111 }, 112 }, 113 }, 114 ) 115 require.NoError(t.t, err) 116 117 // We'll now ask Dave's wallet to fund the PSBT for us. This will return 118 // a packet with inputs and outputs set but without any witness data. 119 // This is exactly what we need for the next step. 120 fundReq := &walletrpc.FundPsbtRequest{ 121 Template: &walletrpc.FundPsbtRequest_Psbt{ 122 Psbt: psbtBytes2, 123 }, 124 Fees: &walletrpc.FundPsbtRequest_AtomsPerByte{ 125 AtomsPerByte: 2, 126 }, 127 } 128 fundResp, err := dave.WalletKitClient.FundPsbt(ctxt, fundReq) 129 require.NoError(t.t, err) 130 131 // We have a PSBT that has no witness data yet, which is exactly what we 132 // need for the next step: Verify the PSBT with the funding intents. 133 _, err = carol.FundingStateStep(ctxb, &lnrpc.FundingTransitionMsg{ 134 Trigger: &lnrpc.FundingTransitionMsg_PsbtVerify{ 135 PsbtVerify: &lnrpc.FundingPsbtVerify{ 136 PendingChanId: pendingChanID[:], 137 FundedPsbt: fundResp.FundedPsbt, 138 }, 139 }, 140 }) 141 require.NoError(t.t, err) 142 _, err = carol.FundingStateStep(ctxb, &lnrpc.FundingTransitionMsg{ 143 Trigger: &lnrpc.FundingTransitionMsg_PsbtVerify{ 144 PsbtVerify: &lnrpc.FundingPsbtVerify{ 145 PendingChanId: pendingChanID2[:], 146 FundedPsbt: fundResp.FundedPsbt, 147 }, 148 }, 149 }) 150 require.NoError(t.t, err) 151 152 // Now we'll ask Dave's wallet to sign the PSBT so we can finish the 153 // funding flow. 154 finalizeReq := &walletrpc.FinalizePsbtRequest{ 155 FundedPsbt: fundResp.FundedPsbt, 156 } 157 finalizeRes, err := dave.WalletKitClient.FinalizePsbt(ctxt, finalizeReq) 158 require.NoError(t.t, err) 159 160 // We've signed our PSBT now, let's pass it to the intent again. 161 _, err = carol.FundingStateStep(ctxb, &lnrpc.FundingTransitionMsg{ 162 Trigger: &lnrpc.FundingTransitionMsg_PsbtFinalize{ 163 PsbtFinalize: &lnrpc.FundingPsbtFinalize{ 164 PendingChanId: pendingChanID[:], 165 SignedPsbt: finalizeRes.SignedPsbt, 166 }, 167 }, 168 }) 169 require.NoError(t.t, err) 170 171 // Consume the "channel pending" update. This waits until the funding 172 // transaction was fully compiled. 173 updateResp, err := receiveChanUpdate(ctxt, chanUpdates) 174 require.NoError(t.t, err) 175 upd, ok := updateResp.Update.(*lnrpc.OpenStatusUpdate_ChanPending) 176 require.True(t.t, ok) 177 chanPoint := &lnrpc.ChannelPoint{ 178 FundingTxid: &lnrpc.ChannelPoint_FundingTxidBytes{ 179 FundingTxidBytes: upd.ChanPending.Txid, 180 }, 181 OutputIndex: upd.ChanPending.OutputIndex, 182 } 183 184 // No transaction should have been published yet. 185 mempool, err := net.Miner.Node.GetRawMempool(context.Background(), jsonrpctypes.GRMRegular) 186 require.NoError(t.t, err) 187 require.Equal(t.t, 0, len(mempool)) 188 189 // Let's progress the second channel now. This time we'll use the raw 190 // wire format transaction directly. 191 require.NoError(t.t, err) 192 _, err = carol.FundingStateStep(ctxb, &lnrpc.FundingTransitionMsg{ 193 Trigger: &lnrpc.FundingTransitionMsg_PsbtFinalize{ 194 PsbtFinalize: &lnrpc.FundingPsbtFinalize{ 195 PendingChanId: pendingChanID2[:], 196 FinalRawTx: finalizeRes.RawFinalTx, 197 }, 198 }, 199 }) 200 require.NoError(t.t, err) 201 202 // Consume the "channel pending" update for the second channel. This 203 // waits until the funding transaction was fully compiled and in this 204 // case published. 205 updateResp2, err := receiveChanUpdate(ctxt, chanUpdates2) 206 require.NoError(t.t, err) 207 upd2, ok := updateResp2.Update.(*lnrpc.OpenStatusUpdate_ChanPending) 208 require.True(t.t, ok) 209 chanPoint2 := &lnrpc.ChannelPoint{ 210 FundingTxid: &lnrpc.ChannelPoint_FundingTxidBytes{ 211 FundingTxidBytes: upd2.ChanPending.Txid, 212 }, 213 OutputIndex: upd2.ChanPending.OutputIndex, 214 } 215 216 // Great, now we can mine a block to get the transaction confirmed, then 217 // wait for the new channel to be propagated through the network. 218 var finalTx wire.MsgTx 219 err = finalTx.Deserialize(bytes.NewReader(finalizeRes.RawFinalTx)) 220 require.NoError(t.t, err) 221 222 txHash := finalTx.TxHash() 223 block := mineBlocks(t, net, 6, 1)[0] 224 assertTxInBlock(t, block, &txHash) 225 err = carol.WaitForNetworkChannelOpen(chanPoint) 226 require.NoError(t.t, err) 227 err = carol.WaitForNetworkChannelOpen(chanPoint2) 228 require.NoError(t.t, err) 229 230 // With the channel open, ensure that it is counted towards Carol's 231 // total channel balance. 232 balReq := &lnrpc.ChannelBalanceRequest{} 233 balRes, err := carol.ChannelBalance(ctxt, balReq) 234 require.NoError(t.t, err) 235 require.NotEqual(t.t, int64(0), balRes.LocalBalance.Atoms) 236 237 // Next, to make sure the channel functions as normal, we'll make some 238 // payments within the channel. 239 payAmt := dcrutil.Amount(100000) 240 invoice := &lnrpc.Invoice{ 241 Memo: "new chans", 242 Value: int64(payAmt), 243 } 244 resp, err := dave.AddInvoice(ctxt, invoice) 245 require.NoError(t.t, err) 246 err = completePaymentRequests( 247 carol, carol.RouterClient, []string{resp.PaymentRequest}, true, 248 ) 249 require.NoError(t.t, err) 250 251 // To conclude, we'll close the newly created channel between Carol and 252 // Dave. This function will also block until the channel is closed and 253 // will additionally assert the relevant channel closing post 254 // conditions. 255 closeChannelAndAssert(t, net, carol, chanPoint, false) 256 } 257 258 // testPsbtChanFundingExternal makes sure a channel can be opened between carol 259 // and dave by using a Partially Signed Bitcoin Transaction that funds the 260 // channel multisig funding output and is fully funded by an external third 261 // party. 262 func testPsbtChanFundingExternal(net *lntest.NetworkHarness, t *harnessTest) { 263 t.Skipf("psbt is not currently implemented in dcrlnd") 264 265 ctxb := context.Background() 266 const chanSize = funding.MaxDecredFundingAmount 267 268 // Everything we do here should be done within a second or two, so we 269 // can just keep a single timeout context around for all calls. 270 ctxt, cancel := context.WithTimeout(ctxb, defaultTimeout) 271 defer cancel() 272 273 // First, we'll create two new nodes that we'll use to open channels 274 // between for this test. Both these nodes have an empty wallet as Alice 275 // will be funding the channel. 276 carol := net.NewNode(t.t, "carol", nil) 277 defer shutdownAndAssert(net, t, carol) 278 279 dave := net.NewNode(t.t, "dave", nil) 280 defer shutdownAndAssert(net, t, dave) 281 282 // Before we start the test, we'll ensure both sides are connected so 283 // the funding flow can be properly executed. 284 net.EnsureConnected(t.t, carol, dave) 285 net.EnsureConnected(t.t, carol, net.Alice) 286 287 // At this point, we can begin our PSBT channel funding workflow. We'll 288 // start by generating a pending channel ID externally that will be used 289 // to track this new funding type. 290 var pendingChanID [32]byte 291 _, err := rand.Read(pendingChanID[:]) 292 require.NoError(t.t, err) 293 294 // We'll also test batch funding of two channels so we need another ID. 295 var pendingChanID2 [32]byte 296 _, err = rand.Read(pendingChanID2[:]) 297 require.NoError(t.t, err) 298 299 // Now that we have the pending channel ID, Carol will open the channel 300 // by specifying a PSBT shim. We use the NoPublish flag here to avoid 301 // publishing the whole batch TX too early. 302 chanUpdates, tempPsbt, err := openChannelPsbt( 303 ctxt, carol, dave, lntest.OpenChannelParams{ 304 Amt: chanSize, 305 FundingShim: &lnrpc.FundingShim{ 306 Shim: &lnrpc.FundingShim_PsbtShim{ 307 PsbtShim: &lnrpc.PsbtShim{ 308 PendingChanId: pendingChanID[:], 309 NoPublish: true, 310 }, 311 }, 312 }, 313 }, 314 ) 315 require.NoError(t.t, err) 316 317 // Let's add a second channel to the batch. This time between Carol and 318 // Alice. We will publish the batch TX once this channel funding is 319 // complete. 320 chanUpdates2, psbtBytes2, err := openChannelPsbt( 321 ctxt, carol, net.Alice, lntest.OpenChannelParams{ 322 Amt: chanSize, 323 FundingShim: &lnrpc.FundingShim{ 324 Shim: &lnrpc.FundingShim_PsbtShim{ 325 PsbtShim: &lnrpc.PsbtShim{ 326 PendingChanId: pendingChanID2[:], 327 NoPublish: true, 328 BasePsbt: tempPsbt, 329 }, 330 }, 331 }, 332 }, 333 ) 334 require.NoError(t.t, err) 335 336 // We'll now ask Alice's wallet to fund the PSBT for us. This will 337 // return a packet with inputs and outputs set but without any witness 338 // data. This is exactly what we need for the next step. 339 fundReq := &walletrpc.FundPsbtRequest{ 340 Template: &walletrpc.FundPsbtRequest_Psbt{ 341 Psbt: psbtBytes2, 342 }, 343 Fees: &walletrpc.FundPsbtRequest_AtomsPerByte{ 344 AtomsPerByte: 2, 345 }, 346 } 347 fundResp, err := net.Alice.WalletKitClient.FundPsbt(ctxt, fundReq) 348 require.NoError(t.t, err) 349 350 // We have a PSBT that has no witness data yet, which is exactly what we 351 // need for the next step: Verify the PSBT with the funding intents. 352 // We tell the PSBT intent to skip the finalize step because we know the 353 // final transaction will not be broadcast by Carol herself but by 354 // Alice. And we assume that Alice is a third party that is not in 355 // direct communication with Carol and won't send the signed TX to her 356 // before broadcasting it. So we cannot call the finalize step but 357 // instead just tell lnd to wait for a TX to be published/confirmed. 358 _, err = carol.FundingStateStep(ctxb, &lnrpc.FundingTransitionMsg{ 359 Trigger: &lnrpc.FundingTransitionMsg_PsbtVerify{ 360 PsbtVerify: &lnrpc.FundingPsbtVerify{ 361 PendingChanId: pendingChanID[:], 362 FundedPsbt: fundResp.FundedPsbt, 363 SkipFinalize: true, 364 }, 365 }, 366 }) 367 require.NoError(t.t, err) 368 _, err = carol.FundingStateStep(ctxb, &lnrpc.FundingTransitionMsg{ 369 Trigger: &lnrpc.FundingTransitionMsg_PsbtVerify{ 370 PsbtVerify: &lnrpc.FundingPsbtVerify{ 371 PendingChanId: pendingChanID2[:], 372 FundedPsbt: fundResp.FundedPsbt, 373 SkipFinalize: true, 374 }, 375 }, 376 }) 377 require.NoError(t.t, err) 378 379 // Consume the "channel pending" update. This waits until the funding 380 // transaction was fully compiled for both channels. 381 updateResp, err := receiveChanUpdate(ctxt, chanUpdates) 382 require.NoError(t.t, err) 383 upd, ok := updateResp.Update.(*lnrpc.OpenStatusUpdate_ChanPending) 384 require.True(t.t, ok) 385 chanPoint := &lnrpc.ChannelPoint{ 386 FundingTxid: &lnrpc.ChannelPoint_FundingTxidBytes{ 387 FundingTxidBytes: upd.ChanPending.Txid, 388 }, 389 OutputIndex: upd.ChanPending.OutputIndex, 390 } 391 updateResp2, err := receiveChanUpdate(ctxt, chanUpdates2) 392 require.NoError(t.t, err) 393 upd2, ok := updateResp2.Update.(*lnrpc.OpenStatusUpdate_ChanPending) 394 require.True(t.t, ok) 395 chanPoint2 := &lnrpc.ChannelPoint{ 396 FundingTxid: &lnrpc.ChannelPoint_FundingTxidBytes{ 397 FundingTxidBytes: upd2.ChanPending.Txid, 398 }, 399 OutputIndex: upd2.ChanPending.OutputIndex, 400 } 401 numPending, err := numOpenChannelsPending(ctxt, carol) 402 require.NoError(t.t, err) 403 require.Equal(t.t, 2, numPending) 404 405 // Now we'll ask Alice's wallet to sign the PSBT so we can finish the 406 // funding flow. 407 finalizeReq := &walletrpc.FinalizePsbtRequest{ 408 FundedPsbt: fundResp.FundedPsbt, 409 } 410 finalizeRes, err := net.Alice.WalletKitClient.FinalizePsbt( 411 ctxt, finalizeReq, 412 ) 413 require.NoError(t.t, err) 414 415 // No transaction should have been published yet. 416 mempool, err := net.Miner.Node.GetRawMempool(testctx.New(t.t), jsonrpctypes.GRMRegular) 417 require.NoError(t.t, err) 418 require.Equal(t.t, 0, len(mempool)) 419 420 // Great, now let's publish the final raw transaction. 421 var finalTx wire.MsgTx 422 err = finalTx.Deserialize(bytes.NewReader(finalizeRes.RawFinalTx)) 423 require.NoError(t.t, err) 424 425 txHash := finalTx.TxHash() 426 _, err = net.Miner.Node.SendRawTransaction(testctx.New(t.t), &finalTx, false) 427 require.NoError(t.t, err) 428 429 // Now we can mine a block to get the transaction confirmed, then wait 430 // for the new channel to be propagated through the network. 431 block := mineBlocks(t, net, 6, 1)[0] 432 assertTxInBlock(t, block, &txHash) 433 err = carol.WaitForNetworkChannelOpen(chanPoint) 434 require.NoError(t.t, err) 435 err = carol.WaitForNetworkChannelOpen(chanPoint2) 436 require.NoError(t.t, err) 437 438 // With the channel open, ensure that it is counted towards Carol's 439 // total channel balance. 440 balReq := &lnrpc.ChannelBalanceRequest{} 441 balRes, err := carol.ChannelBalance(ctxt, balReq) 442 require.NoError(t.t, err) 443 require.NotEqual(t.t, int64(0), balRes.LocalBalance.Atoms) 444 445 // Next, to make sure the channel functions as normal, we'll make some 446 // payments within the channel. 447 payAmt := dcrutil.Amount(100000) 448 invoice := &lnrpc.Invoice{ 449 Memo: "new chans", 450 Value: int64(payAmt), 451 } 452 resp, err := dave.AddInvoice(ctxt, invoice) 453 require.NoError(t.t, err) 454 err = completePaymentRequests( 455 carol, carol.RouterClient, []string{resp.PaymentRequest}, true, 456 ) 457 require.NoError(t.t, err) 458 459 // To conclude, we'll close the newly created channel between Carol and 460 // Dave. This function will also block until the channels are closed and 461 // will additionally assert the relevant channel closing post 462 // conditions. 463 closeChannelAndAssert(t, net, carol, chanPoint, false) 464 closeChannelAndAssert(t, net, carol, chanPoint2, false) 465 } 466 467 // testPsbtChanFundingSingleStep checks whether PSBT funding works also when the 468 // wallet of both nodes are empty and one of them uses PSBT and an external 469 // wallet to fund the channel while creating reserve output in the same 470 // transaction. 471 func testPsbtChanFundingSingleStep(net *lntest.NetworkHarness, t *harnessTest) { 472 t.Skipf("psbt is not currently implemented in dcrlnd") 473 474 ctxb := context.Background() 475 const chanSize = funding.MaxDecredFundingAmount 476 477 // Everything we do here should be done within a second or two, so we 478 // can just keep a single timeout context around for all calls. 479 ctxt, cancel := context.WithTimeout(ctxb, defaultTimeout) 480 defer cancel() 481 482 args := nodeArgsForCommitType(lnrpc.CommitmentType_ANCHORS) 483 484 // First, we'll create two new nodes that we'll use to open channels 485 // between for this test. But in this case both nodes have an empty 486 // wallet. 487 carol := net.NewNode(t.t, "carol", args) 488 defer shutdownAndAssert(net, t, carol) 489 490 dave := net.NewNode(t.t, "dave", args) 491 defer shutdownAndAssert(net, t, dave) 492 493 net.SendCoins(t.t, dcrutil.AtomsPerCoin, net.Alice) 494 495 // Get new address for anchor reserve. 496 reserveAddrReq := &lnrpc.NewAddressRequest{ 497 Type: lnrpc.AddressType_WITNESS_PUBKEY_HASH, 498 } 499 addrResp, err := carol.NewAddress(ctxb, reserveAddrReq) 500 require.NoError(t.t, err) 501 reserveAddr, err := stdaddr.DecodeAddress(addrResp.Address, harnessNetParams) 502 require.NoError(t.t, err) 503 scriptVersion, reserveAddrScript := reserveAddr.PaymentScript() 504 require.NoError(t.t, err) 505 506 // Before we start the test, we'll ensure both sides are connected so 507 // the funding flow can be properly executed. 508 net.EnsureConnected(t.t, carol, dave) 509 510 // At this point, we can begin our PSBT channel funding workflow. We'll 511 // start by generating a pending channel ID externally that will be used 512 // to track this new funding type. 513 var pendingChanID [32]byte 514 _, err = rand.Read(pendingChanID[:]) 515 require.NoError(t.t, err) 516 517 // Now that we have the pending channel ID, Carol will open the channel 518 // by specifying a PSBT shim. 519 chanUpdates, tempPsbt, err := openChannelPsbt( 520 ctxt, carol, dave, lntest.OpenChannelParams{ 521 Amt: chanSize, 522 FundingShim: &lnrpc.FundingShim{ 523 Shim: &lnrpc.FundingShim_PsbtShim{ 524 PsbtShim: &lnrpc.PsbtShim{ 525 PendingChanId: pendingChanID[:], 526 NoPublish: false, 527 }, 528 }, 529 }, 530 }, 531 ) 532 require.NoError(t.t, err) 533 534 decodedPsbt, err := psbt.NewFromRawBytes(bytes.NewReader(tempPsbt), false) 535 require.NoError(t.t, err) 536 537 reserveTxOut := wire.TxOut{ 538 Value: 10000, 539 PkScript: reserveAddrScript, 540 Version: scriptVersion, 541 } 542 543 decodedPsbt.UnsignedTx.TxOut = append( 544 decodedPsbt.UnsignedTx.TxOut, &reserveTxOut, 545 ) 546 decodedPsbt.Outputs = append(decodedPsbt.Outputs, psbt.POutput{}) 547 548 var psbtBytes bytes.Buffer 549 err = decodedPsbt.Serialize(&psbtBytes) 550 require.NoError(t.t, err) 551 552 fundReq := &walletrpc.FundPsbtRequest{ 553 Template: &walletrpc.FundPsbtRequest_Psbt{ 554 Psbt: psbtBytes.Bytes(), 555 }, 556 Fees: &walletrpc.FundPsbtRequest_AtomsPerByte{ 557 AtomsPerByte: 2, 558 }, 559 } 560 fundResp, err := net.Alice.WalletKitClient.FundPsbt(ctxt, fundReq) 561 require.NoError(t.t, err) 562 563 // Make sure the wallets are actually empty 564 unspentCarol, err := carol.ListUnspent(ctxb, &lnrpc.ListUnspentRequest{}) 565 require.NoError(t.t, err) 566 require.Len(t.t, unspentCarol.Utxos, 0) 567 568 unspentDave, err := dave.ListUnspent(ctxb, &lnrpc.ListUnspentRequest{}) 569 require.NoError(t.t, err) 570 require.Len(t.t, unspentDave.Utxos, 0) 571 572 // We have a PSBT that has no witness data yet, which is exactly what we 573 // need for the next step: Verify the PSBT with the funding intents. 574 _, err = carol.FundingStateStep(ctxb, &lnrpc.FundingTransitionMsg{ 575 Trigger: &lnrpc.FundingTransitionMsg_PsbtVerify{ 576 PsbtVerify: &lnrpc.FundingPsbtVerify{ 577 PendingChanId: pendingChanID[:], 578 FundedPsbt: fundResp.FundedPsbt, 579 }, 580 }, 581 }) 582 require.NoError(t.t, err) 583 584 // Now we'll ask Alice's wallet to sign the PSBT so we can finish the 585 // funding flow. 586 finalizeReq := &walletrpc.FinalizePsbtRequest{ 587 FundedPsbt: fundResp.FundedPsbt, 588 } 589 finalizeRes, err := net.Alice.WalletKitClient.FinalizePsbt(ctxt, finalizeReq) 590 require.NoError(t.t, err) 591 592 // We've signed our PSBT now, let's pass it to the intent again. 593 _, err = carol.FundingStateStep(ctxb, &lnrpc.FundingTransitionMsg{ 594 Trigger: &lnrpc.FundingTransitionMsg_PsbtFinalize{ 595 PsbtFinalize: &lnrpc.FundingPsbtFinalize{ 596 PendingChanId: pendingChanID[:], 597 SignedPsbt: finalizeRes.SignedPsbt, 598 }, 599 }, 600 }) 601 require.NoError(t.t, err) 602 603 // Consume the "channel pending" update. This waits until the funding 604 // transaction was fully compiled. 605 updateResp, err := receiveChanUpdate(ctxt, chanUpdates) 606 require.NoError(t.t, err) 607 upd, ok := updateResp.Update.(*lnrpc.OpenStatusUpdate_ChanPending) 608 require.True(t.t, ok) 609 chanPoint := &lnrpc.ChannelPoint{ 610 FundingTxid: &lnrpc.ChannelPoint_FundingTxidBytes{ 611 FundingTxidBytes: upd.ChanPending.Txid, 612 }, 613 OutputIndex: upd.ChanPending.OutputIndex, 614 } 615 616 var finalTx wire.MsgTx 617 err = finalTx.Deserialize(bytes.NewReader(finalizeRes.RawFinalTx)) 618 require.NoError(t.t, err) 619 620 txHash := finalTx.TxHash() 621 block := mineBlocks(t, net, 6, 1)[0] 622 assertTxInBlock(t, block, &txHash) 623 err = carol.WaitForNetworkChannelOpen(chanPoint) 624 require.NoError(t.t, err) 625 626 // Next, to make sure the channel functions as normal, we'll make some 627 // payments within the channel. 628 payAmt := dcrutil.Amount(100000) 629 invoice := &lnrpc.Invoice{ 630 Memo: "new chans", 631 Value: int64(payAmt), 632 } 633 resp, err := dave.AddInvoice(ctxt, invoice) 634 require.NoError(t.t, err) 635 err = completePaymentRequests( 636 carol, carol.RouterClient, []string{resp.PaymentRequest}, 637 true, 638 ) 639 require.NoError(t.t, err) 640 641 // To conclude, we'll close the newly created channel between Carol and 642 // Dave. This function will also block until the channel is closed and 643 // will additionally assert the relevant channel closing post 644 // conditions. 645 closeChannelAndAssert(t, net, carol, chanPoint, false) 646 } 647 648 // runSignPsbt tests that the SignPsbt RPC works correctly. 649 func testSignPsbt(net *lntest.NetworkHarness, t *harnessTest) { 650 t.Skipf("psbt is not currently implemented in dcrlnd") 651 runSignPsbt(t, net, net.Alice) 652 } 653 654 // runSignPsbt tests that the SignPsbt RPC works correctly. 655 func runSignPsbt(t *harnessTest, net *lntest.NetworkHarness, 656 alice *lntest.HarnessNode) { 657 658 ctxb := context.Background() 659 660 // Everything we do here should be done within a second or two, so we 661 // can just keep a single timeout context around for all calls. 662 ctxt, cancel := context.WithTimeout(ctxb, defaultTimeout) 663 defer cancel() 664 665 // We test that we can sign a PSBT that spends funds from an input that 666 // the wallet doesn't know about. To set up that test case, we first 667 // derive an address manually that the wallet won't be watching on 668 // chain. We can do that by exporting the account xpub of lnd's main 669 // account. 670 accounts, err := alice.WalletKitClient.ListAccounts( 671 ctxt, &walletrpc.ListAccountsRequest{}, 672 ) 673 require.NoError(t.t, err) 674 require.NotEmpty(t.t, accounts.Accounts) 675 676 // We also need to parse the accounts, so we have easy access to the 677 // parsed derivation paths. 678 parsedAccounts, err := walletrpc.AccountsToWatchOnly(accounts.Accounts) 679 require.NoError(t.t, err) 680 681 account := parsedAccounts[0] 682 xpub, err := hdkeychain.NewKeyFromString(account.Xpub, harnessNetParams) 683 require.NoError(t.t, err) 684 685 const ( 686 changeIndex = 1 687 addrIndex = 1337 688 ) 689 fullDerivationPath := []uint32{ 690 hdkeychain.HardenedKeyStart + account.Purpose, 691 hdkeychain.HardenedKeyStart + account.CoinType, 692 hdkeychain.HardenedKeyStart + account.Account, 693 changeIndex, 694 addrIndex, 695 } 696 697 // Let's simulate a change address. 698 change, err := xpub.Child(changeIndex) // nolint:staticcheck 699 require.NoError(t.t, err) 700 701 // At an index that we are certainly not watching in the wallet. 702 addrKey, err := change.Child(addrIndex) // nolint:staticcheck 703 require.NoError(t.t, err) 704 705 addrPubKey, err := stdaddr.NewAddressPubKeyEcdsaSecp256k1V0Raw(addrKey.SerializedPubKey(), harnessNetParams) 706 require.NoError(t.t, err) 707 pubKeyHashAddr := addrPubKey.AddressPubKeyHash() 708 709 version, pkScript := pubKeyHashAddr.PaymentScript() 710 711 // Let's send some coins to that address now. 712 utxo := &wire.TxOut{ 713 Version: version, 714 Value: 600_000, 715 PkScript: pkScript, 716 } 717 resp, err := alice.WalletKitClient.SendOutputs( 718 ctxt, &walletrpc.SendOutputsRequest{ 719 Outputs: []*signrpc.TxOut{{ 720 Value: utxo.Value, 721 PkScript: utxo.PkScript, 722 }}, 723 MinConfs: 0, 724 SpendUnconfirmed: true, 725 AtomsPerKb: 2500, 726 }, 727 ) 728 require.NoError(t.t, err) 729 730 prevTx := wire.NewMsgTx() 731 prevTx.Version = input.LNTxVersion 732 err = prevTx.Deserialize(bytes.NewReader(resp.RawTx)) 733 require.NoError(t.t, err) 734 735 prevOut := -1 736 for idx, txOut := range prevTx.TxOut { 737 if bytes.Equal(txOut.PkScript, pkScript) { 738 prevOut = idx 739 } 740 } 741 require.Greater(t.t, prevOut, -1) 742 743 // Okay, we have everything we need to create a PSBT now. 744 pendingTx := &wire.MsgTx{ 745 Version: 2, 746 TxIn: []*wire.TxIn{{ 747 PreviousOutPoint: wire.OutPoint{ 748 Hash: prevTx.TxHash(), 749 Index: uint32(prevOut), 750 }, 751 }}, 752 // We send to the same address again, but deduct some fees. 753 TxOut: []*wire.TxOut{{ 754 Value: utxo.Value - 600, 755 PkScript: utxo.PkScript, 756 }}, 757 } 758 packet, err := psbt.NewFromUnsignedTx(pendingTx) 759 require.NoError(t.t, err) 760 761 // Now let's add the meta information that we need for signing. 762 packet.Inputs[0].Bip32Derivation = []*psbt.Bip32Derivation{{ 763 PubKey: addrKey.SerializedPubKey(), 764 Bip32Path: fullDerivationPath, 765 }} 766 packet.Inputs[0].WitnessUtxo = utxo 767 packet.Inputs[0].NonWitnessUtxo = prevTx 768 packet.Inputs[0].SighashType = txscript.SigHashAll 769 770 // That's it, we should be able to sign the PSBT now. 771 var buf bytes.Buffer 772 err = packet.Serialize(&buf) 773 require.NoError(t.t, err) 774 775 signResp, err := alice.WalletKitClient.SignPsbt( 776 ctxt, &walletrpc.SignPsbtRequest{ 777 FundedPsbt: buf.Bytes(), 778 }, 779 ) 780 require.NoError(t.t, err) 781 782 // Let's make sure we have a partial signature. 783 signedPacket, err := psbt.NewFromRawBytes( 784 bytes.NewReader(signResp.SignedPsbt), false, 785 ) 786 require.NoError(t.t, err) 787 788 require.Len(t.t, signedPacket.Inputs, 1) 789 require.Len(t.t, signedPacket.Inputs[0].PartialSigs, 1) 790 791 partialSig := signedPacket.Inputs[0].PartialSigs[0] 792 require.Equal(t.t, partialSig.PubKey, addrKey.SerializedPubKey()) 793 require.Greater(t.t, len(partialSig.Signature), 8) 794 795 // We should be able to finalize the PSBT and extract the final TX now. 796 err = psbt.MaybeFinalizeAll(signedPacket) 797 require.NoError(t.t, err) 798 799 finalTx, err := psbt.Extract(signedPacket) 800 require.NoError(t.t, err) 801 802 buf.Reset() 803 err = finalTx.Serialize(&buf) 804 require.NoError(t.t, err) 805 806 // Publish the second transaction and then mine both of them. 807 _, err = alice.WalletKitClient.PublishTransaction( 808 ctxt, &walletrpc.Transaction{ 809 TxHex: buf.Bytes(), 810 }, 811 ) 812 require.NoError(t.t, err) 813 814 // Mine one block which should contain two transactions. 815 block := mineBlocks(t, net, 1, 2)[0] 816 firstTxHash := prevTx.TxHash() 817 secondTxHash := finalTx.TxHash() 818 assertTxInBlock(t, block, &firstTxHash) 819 assertTxInBlock(t, block, &secondTxHash) 820 } 821 822 // openChannelPsbt attempts to open a channel between srcNode and destNode with 823 // the passed channel funding parameters. If the passed context has a timeout, 824 // then if the timeout is reached before the channel pending notification is 825 // received, an error is returned. An error is returned if the expected step 826 // of funding the PSBT is not received from the source node. 827 func openChannelPsbt(ctx context.Context, srcNode, destNode *lntest.HarnessNode, 828 p lntest.OpenChannelParams) (lnrpc.Lightning_OpenChannelClient, []byte, 829 error) { 830 831 // Wait until srcNode and destNode have the latest chain synced. 832 // Otherwise, we may run into a check within the funding manager that 833 // prevents any funding workflows from being kicked off if the chain 834 // isn't yet synced. 835 if err := srcNode.WaitForBlockchainSync(); err != nil { 836 return nil, nil, fmt.Errorf("unable to sync srcNode chain: %v", 837 err) 838 } 839 if err := destNode.WaitForBlockchainSync(); err != nil { 840 return nil, nil, fmt.Errorf("unable to sync destNode chain: %v", 841 err) 842 } 843 844 // Send the request to open a channel to the source node now. This will 845 // open a long-lived stream where we'll receive status updates about the 846 // progress of the channel. 847 respStream, err := srcNode.OpenChannel(ctx, &lnrpc.OpenChannelRequest{ 848 NodePubkey: destNode.PubKey[:], 849 LocalFundingAmount: int64(p.Amt), 850 PushAtoms: int64(p.PushAmt), 851 Private: p.Private, 852 SpendUnconfirmed: p.SpendUnconfirmed, 853 MinHtlcMAtoms: int64(p.MinHtlc), 854 FundingShim: p.FundingShim, 855 }) 856 if err != nil { 857 return nil, nil, fmt.Errorf("unable to open channel between "+ 858 "source and dest: %v", err) 859 } 860 861 // Consume the "PSBT funding ready" update. This waits until the node 862 // notifies us that the PSBT can now be funded. 863 resp, err := receiveChanUpdate(ctx, respStream) 864 if err != nil { 865 return nil, nil, fmt.Errorf("unable to consume channel update "+ 866 "message: %v", err) 867 } 868 upd, ok := resp.Update.(*lnrpc.OpenStatusUpdate_PsbtFund) 869 if !ok { 870 return nil, nil, fmt.Errorf("expected PSBT funding update, "+ 871 "instead got %v", resp) 872 } 873 return respStream, upd.PsbtFund.Psbt, nil 874 } 875 876 // receiveChanUpdate waits until a message is received on the stream or the 877 // context is canceled. The context must have a timeout or must be canceled 878 // in case no message is received, otherwise this function will block forever. 879 func receiveChanUpdate(ctx context.Context, 880 stream lnrpc.Lightning_OpenChannelClient) (*lnrpc.OpenStatusUpdate, 881 error) { 882 883 chanMsg := make(chan *lnrpc.OpenStatusUpdate) 884 errChan := make(chan error) 885 go func() { 886 // Consume one message. This will block until the message is 887 // received. 888 resp, err := stream.Recv() 889 if err != nil { 890 errChan <- err 891 return 892 } 893 chanMsg <- resp 894 }() 895 896 select { 897 case <-ctx.Done(): 898 return nil, fmt.Errorf("timeout reached before chan pending " + 899 "update sent") 900 901 case err := <-errChan: 902 return nil, err 903 904 case updateMsg := <-chanMsg: 905 return updateMsg, nil 906 } 907 }