multi: add co-op close custom data to close update

With this commit we populate additional information about the close
outputs (including potential custom channel data) in the close update
RPC message.
This will allow custom channels to find out how the additional close
outputs look like on chain and what data they might commit to.

We also hook up the aux custom data formatter, so it can format the
custom channel data to JSON.
This commit is contained in:
Oliver Gugger committed 2024-09-19 10:18:41 +02:00
1 parent 8dee76a1b8
commit e0b4601fb9
5 files changed
+3624 -3308

No files matched your search

+90 -9
View File
@@ -2685,7 +2685,6 @@ func (r *rpcServer) CloseChannel(in *lnrpc.CloseChannelRequest,
// transaction here rather than going to the switch as we don't require
// interaction from the peer.
if force {
// As we're force closing this channel, as a precaution, we'll
// ensure that the switch doesn't continue to see this channel
// as eligible for forwarding HTLC's. If the peer is online,
@@ -2725,15 +2724,19 @@ func (r *rpcServer) CloseChannel(in *lnrpc.CloseChannelRequest,
errChan = make(chan error, 1)
notifier := r.server.cc.ChainNotifier
go peer.WaitForChanToClose(uint32(bestHeight), notifier, errChan, chanPoint,
go peer.WaitForChanToClose(
uint32(bestHeight), notifier, errChan, chanPoint,
&closingTxid, closingTx.TxOut[0].PkScript, func() {
// Respond to the local subsystem which
// requested the channel closure.
updateChan <- &peer.ChannelCloseUpdate{
ClosingTxid: closingTxid[:],
Success: true,
// Force closure transactions don't have
// additional local/remote outputs.
}
})
},
)
} else {
// If this is a frozen channel, then we only allow the co-op
// close to proceed if we were the responder to this channel if
@@ -2857,6 +2860,19 @@ out:
return err
}
err = fn.MapOptionZ(
r.server.implCfg.AuxDataParser,
func(parser AuxDataParser) error {
return parser.InlineParseCustomData(
rpcClosingUpdate,
)
},
)
if err != nil {
return fmt.Errorf("error parsing custom data: "+
"%w", err)
}
rpcsLog.Tracef("[closechannel] sending update: %v",
rpcClosingUpdate)
@@ -2882,19 +2898,84 @@ out:
return nil
}
func createRPCCloseUpdate(update interface{}) (
*lnrpc.CloseStatusUpdate, error) {
func createRPCCloseUpdate(
update interface{}) (*lnrpc.CloseStatusUpdate, error) {
switch u := update.(type) {
case *peer.ChannelCloseUpdate:
ccu := &lnrpc.ChannelCloseUpdate{
ClosingTxid: u.ClosingTxid,
Success: u.Success,
}
err := fn.MapOptionZ(
u.LocalCloseOutput,
func(closeOut chancloser.CloseOutput) error {
cr, err := closeOut.ShutdownRecords.Serialize()
if err != nil {
return fmt.Errorf("error serializing "+
"local close out custom "+
"records: %w", err)
}
rpcCloseOut := &lnrpc.CloseOutput{
AmountSat: int64(closeOut.Amt),
PkScript: closeOut.PkScript,
IsLocal: true,
CustomChannelData: cr,
}
ccu.LocalCloseOutput = rpcCloseOut
return nil
},
)
if err != nil {
return nil, err
}
err = fn.MapOptionZ(
u.RemoteCloseOutput,
func(closeOut chancloser.CloseOutput) error {
cr, err := closeOut.ShutdownRecords.Serialize()
if err != nil {
return fmt.Errorf("error serializing "+
"remote close out custom "+
"records: %w", err)
}
rpcCloseOut := &lnrpc.CloseOutput{
AmountSat: int64(closeOut.Amt),
PkScript: closeOut.PkScript,
CustomChannelData: cr,
}
ccu.RemoteCloseOutput = rpcCloseOut
return nil
},
)
if err != nil {
return nil, err
}
u.AuxOutputs.WhenSome(func(outs chancloser.AuxCloseOutputs) {
for _, out := range outs.ExtraCloseOutputs {
ccu.AdditionalOutputs = append(
ccu.AdditionalOutputs,
&lnrpc.CloseOutput{
AmountSat: out.Value,
PkScript: out.PkScript,
IsLocal: out.IsLocal,
},
)
}
})
return &lnrpc.CloseStatusUpdate{
Update: &lnrpc.CloseStatusUpdate_ChanClose{
ChanClose: &lnrpc.ChannelCloseUpdate{
ClosingTxid: u.ClosingTxid,
Success: u.Success,
},
ChanClose: ccu,
},
}, nil
case *peer.PendingUpdate:
return &lnrpc.CloseStatusUpdate{
Update: &lnrpc.CloseStatusUpdate_ClosePending{