@@ -156,6 +156,53 @@ func createCloseAlloc(isLocal bool, outputSum uint64,
156156 }, nil
157157}
158158
159+ // signCommitVirtualPackets signs the commit virtual packets with the funding
160+ // witness, which is just the script and control block for the OP_TRUE spend.
161+ func signCommitVirtualPackets (ctx context.Context ,
162+ vPackets []* tappsbt.VPacket ) error {
163+
164+ // Now that we've added all the relevant vPackets, we'll prepare the
165+ // funding witness which includes the OP_TRUE ctrl block.
166+ fundingWitness , err := fundingSpendWitness ().Unpack ()
167+ if err != nil {
168+ return fmt .Errorf ("unable to make funding witness: %w" , err )
169+ }
170+
171+ // With all the vPackets created, we'll create output commitments from
172+ // them, as we'll need them to ship the transaction off to the porter.
173+ for idx := range vPackets {
174+ err = tapsend .PrepareOutputAssets (ctx , vPackets [idx ])
175+ if err != nil {
176+ return fmt .Errorf ("unable to prepare output " +
177+ "assets: %w" , err )
178+ }
179+
180+ // With the packets prepared, we'll swap in the correct witness
181+ // for each of them. We need to do this _after_ calling
182+ // PrepareOutputAsset, because that method will overwrite any
183+ // asset in the virtual outputs. Which means we'll also need to
184+ // set the witness on _every_ output of the packet, to make sure
185+ // each split output's root asset reference also gets the
186+ // correct witness.
187+ for outIdx := range vPackets [idx ].Outputs {
188+ outAsset := vPackets [idx ].Outputs [outIdx ].Asset
189+
190+ // There is always only a single input, as we're
191+ // spending a single funding output w/ each vPkt.
192+ const inputIndex = 0
193+ err := outAsset .UpdateTxWitness (
194+ inputIndex , fundingWitness ,
195+ )
196+ if err != nil {
197+ return fmt .Errorf ("error updating witness: %w" ,
198+ err )
199+ }
200+ }
201+ }
202+
203+ return nil
204+ }
205+
159206// fundingSpendWitness creates a complete witness to spend the OP_TRUE funding
160207// script of an asset funding output.
161208func fundingSpendWitness () lfn.Result [wire.TxWitness ] {
@@ -377,35 +424,12 @@ func (a *AuxChanCloser) AuxCloseOutputs(
377424 return none , fmt .Errorf ("unable to distribute coins: %w" , err )
378425 }
379426
380- // With the vPackets created we'll now prepare all the split
381- // information encoded in the vPackets.
382- fundingWitness , err := fundingSpendWitness ().Unpack ()
383- if err != nil {
384- return none , fmt .Errorf ("unable to make funding " +
385- "witness: %w" , err )
386- }
387- ctx := context .Background ()
388- for idx := range vPackets {
389- err := tapsend .PrepareOutputAssets (ctx , vPackets [idx ])
390- if err != nil {
391- return none , fmt .Errorf ("unable to prepare output " +
392- "assets: %w" , err )
393- }
394-
395- for outIdx := range vPackets [idx ].Outputs {
396- outAsset := vPackets [idx ].Outputs [outIdx ].Asset
397-
398- // There is always only a single input, which is the
399- // funding output.
400- const inputIndex = 0
401- err := outAsset .UpdateTxWitness (
402- inputIndex , fundingWitness ,
403- )
404- if err != nil {
405- return none , fmt .Errorf ("error updating " +
406- "witness: %w" , err )
407- }
408- }
427+ // We can now add the witness for the OP_TRUE spend of the commitment
428+ // output to the vPackets.
429+ ctxb := context .Background ()
430+ if err := signCommitVirtualPackets (ctxb , vPackets ); err != nil {
431+ return none , fmt .Errorf ("error signing commit virtual " +
432+ "packets: %w" , err )
409433 }
410434
411435 // With the outputs prepared, we can now create the set of output
0 commit comments