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:
5 files changed
+3624
-3308
No files matched your search
+90
-9
@@ -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{
|
||||
|
||||
Reference in new issue
Block a user