itest: do batch PSBT channel open

This commit is contained in:
Oliver Gugger 2020-07-08 17:13:41 -07:00 committed by Conner Fromknecht
parent 563e56987b
commit 1a57dfc24c
No known key found for this signature in database
GPG Key ID: E7D737B67FA592C7

@ -45,6 +45,10 @@ func testPsbtChanFunding(net *lntest.NetworkHarness, t *harnessTest) {
if err != nil {
t.Fatalf("unable to connect peers: %v", err)
}
err = net.EnsureConnected(ctxt, carol, net.Alice)
if err != nil {
t.Fatalf("unable to connect peers: %v", err)
}
// At this point, we can begin our PSBT channel funding workflow. We'll
// start by generating a pending channel ID externally that will be used
@ -54,8 +58,15 @@ func testPsbtChanFunding(net *lntest.NetworkHarness, t *harnessTest) {
t.Fatalf("unable to gen pending chan ID: %v", err)
}
// We'll also test batch funding of two channels so we need another ID.
var pendingChanID2 [32]byte
if _, err := rand.Read(pendingChanID2[:]); err != nil {
t.Fatalf("unable to gen pending chan ID: %v", err)
}
// Now that we have the pending channel ID, Carol will open the channel
// by specifying a PSBT shim.
// by specifying a PSBT shim. We use the NoPublish flag here to avoid
// publishing the whole batch TX too early.
ctxt, cancel = context.WithTimeout(ctxb, defaultTimeout)
defer cancel()
chanUpdates, psbtBytes, err := openChannelPsbt(
@ -65,23 +76,50 @@ func testPsbtChanFunding(net *lntest.NetworkHarness, t *harnessTest) {
Shim: &lnrpc.FundingShim_PsbtShim{
PsbtShim: &lnrpc.PsbtShim{
PendingChanId: pendingChanID[:],
NoPublish: true,
},
},
},
},
)
if err != nil {
t.Fatalf("unable to open channel: %v", err)
t.Fatalf("unable to open channel to dave: %v", err)
}
packet, err := psbt.NewFromRawBytes(bytes.NewReader(psbtBytes), false)
if err != nil {
t.Fatalf("unable to parse returned PSBT: %v", err)
}
// Let's add a second channel to the batch. This time between carol and
// alice. We will the batch TX once this channel funding is complete.
ctxt, cancel = context.WithTimeout(ctxb, defaultTimeout)
defer cancel()
chanUpdates2, psbtBytes2, err := openChannelPsbt(
ctxt, carol, net.Alice, lntest.OpenChannelParams{
Amt: chanSize,
FundingShim: &lnrpc.FundingShim{
Shim: &lnrpc.FundingShim_PsbtShim{
PsbtShim: &lnrpc.PsbtShim{
PendingChanId: pendingChanID2[:],
NoPublish: false,
},
},
},
},
)
if err != nil {
t.Fatalf("unable to open channel to alice: %v", err)
}
packet2, err := psbt.NewFromRawBytes(bytes.NewReader(psbtBytes2), false)
if err != nil {
t.Fatalf("unable to parse returned PSBT: %v", err)
}
// We'll now create a fully signed transaction that sends to the outputs
// encoded in the PSBT. We'll let the miner do it and convert the final
// TX into a PSBT, that's way easier than assembling a PSBT manually.
tx, err := net.Miner.CreateTransaction(packet.UnsignedTx.TxOut, 5, true)
allOuts := append(packet.UnsignedTx.TxOut, packet2.UnsignedTx.TxOut...)
tx, err := net.Miner.CreateTransaction(allOuts, 5, true)
if err != nil {
t.Fatalf("unable to create funding transaction: %v", err)
}
@ -119,7 +157,7 @@ func testPsbtChanFunding(net *lntest.NetworkHarness, t *harnessTest) {
}
// We have a PSBT that has no witness data yet, which is exactly what we
// need for the next step: Verify the PSBT with the funding intent.
// need for the next step: Verify the PSBT with the funding intents.
_, err = carol.FundingStateStep(ctxb, &lnrpc.FundingTransitionMsg{
Trigger: &lnrpc.FundingTransitionMsg_PsbtVerify{
PsbtVerify: &lnrpc.FundingPsbtVerify{
@ -131,6 +169,17 @@ func testPsbtChanFunding(net *lntest.NetworkHarness, t *harnessTest) {
if err != nil {
t.Fatalf("error verifying PSBT with funding intent: %v", err)
}
_, err = carol.FundingStateStep(ctxb, &lnrpc.FundingTransitionMsg{
Trigger: &lnrpc.FundingTransitionMsg_PsbtVerify{
PsbtVerify: &lnrpc.FundingPsbtVerify{
PendingChanId: pendingChanID2[:],
FundedPsbt: buf.Bytes(),
},
},
})
if err != nil {
t.Fatalf("error verifying PSBT with funding intent 2: %v", err)
}
// Now we'll add the witness data back into the PSBT to make it a
// complete and signed transaction that can be finalized. We'll trick
@ -162,7 +211,7 @@ func testPsbtChanFunding(net *lntest.NetworkHarness, t *harnessTest) {
}
// Consume the "channel pending" update. This waits until the funding
// transaction has been published.
// transaction was fully compiled.
ctxt, cancel = context.WithTimeout(ctxb, defaultTimeout)
defer cancel()
updateResp, err := receiveChanUpdate(ctxt, chanUpdates)
@ -181,6 +230,49 @@ func testPsbtChanFunding(net *lntest.NetworkHarness, t *harnessTest) {
OutputIndex: upd.ChanPending.OutputIndex,
}
// No transaction should have been published yet.
mempool, err := net.Miner.Node.GetRawMempool()
if err != nil {
t.Fatalf("error querying mempool: %v", err)
}
if len(mempool) != 0 {
t.Fatalf("unexpected txes in mempool: %v", mempool)
}
// Let's progress the second channel now.
_, err = carol.FundingStateStep(ctxb, &lnrpc.FundingTransitionMsg{
Trigger: &lnrpc.FundingTransitionMsg_PsbtFinalize{
PsbtFinalize: &lnrpc.FundingPsbtFinalize{
PendingChanId: pendingChanID2[:],
SignedPsbt: buf.Bytes(),
},
},
})
if err != nil {
t.Fatalf("error finalizing PSBT with funding intent 2: %v", err)
}
// Consume the "channel pending" update for the second channel. This
// waits until the funding transaction was fully compiled and in this
// case published.
ctxt, cancel = context.WithTimeout(ctxb, defaultTimeout)
defer cancel()
updateResp2, err := receiveChanUpdate(ctxt, chanUpdates2)
if err != nil {
t.Fatalf("unable to consume channel update message: %v", err)
}
upd2, ok := updateResp2.Update.(*lnrpc.OpenStatusUpdate_ChanPending)
if !ok {
t.Fatalf("expected PSBT funding update, instead got %v",
updateResp2)
}
chanPoint2 := &lnrpc.ChannelPoint{
FundingTxid: &lnrpc.ChannelPoint_FundingTxidBytes{
FundingTxidBytes: upd2.ChanPending.Txid,
},
OutputIndex: upd2.ChanPending.OutputIndex,
}
// Great, now we can mine a block to get the transaction confirmed, then
// wait for the new channel to be propagated through the network.
txHash := tx.TxHash()
@ -192,6 +284,10 @@ func testPsbtChanFunding(net *lntest.NetworkHarness, t *harnessTest) {
if err != nil {
t.Fatalf("carol didn't report channel: %v", err)
}
err = carol.WaitForNetworkChannelOpen(ctxt, chanPoint2)
if err != nil {
t.Fatalf("carol didn't report channel 2: %v", err)
}
// With the channel open, ensure that it is counted towards Carol's
// total channel balance.