lnrpc+rpcserver: enable abandonchannel for externally funded chans

To make sure we can use the abandonchannel RPC for getting rid of
externally funded channels who's funding transaction was never
published, we allow the RPC to be used on non-dev builds for externally
funded and pending channels only.
This commit is contained in:
Oliver Gugger 2020-08-21 13:08:36 +02:00
parent f2e0ed19ff
commit 3caca4fa3f
No known key found for this signature in database
GPG key ID: 8E4256593F177720
4 changed files with 790 additions and 751 deletions

File diff suppressed because it is too large Load diff

View file

@ -235,8 +235,10 @@ service Lightning {
/* lncli: `abandonchannel`
AbandonChannel removes all channel state from the database except for a
close summary. This method can be used to get rid of permanently unusable
channels due to bugs fixed in newer versions of lnd. Only available
when in debug builds of lnd.
channels due to bugs fixed in newer versions of lnd. This method can also be
used to remove externally funded channels where the funding transaction was
never broadcast. Only available for non-externally funded channels in dev
build.
*/
rpc AbandonChannel (AbandonChannelRequest) returns (AbandonChannelResponse);
@ -3058,6 +3060,8 @@ message DeleteAllPaymentsResponse {
message AbandonChannelRequest {
ChannelPoint channel_point = 1;
bool pending_funding_shim_only = 2;
}
message AbandonChannelResponse {

View file

@ -151,7 +151,7 @@
},
"/v1/channels/abandon/{channel_point.funding_txid_str}/{channel_point.output_index}": {
"delete": {
"summary": "lncli: `abandonchannel`\nAbandonChannel removes all channel state from the database except for a\nclose summary. This method can be used to get rid of permanently unusable\nchannels due to bugs fixed in newer versions of lnd. Only available\nwhen in debug builds of lnd.",
"summary": "lncli: `abandonchannel`\nAbandonChannel removes all channel state from the database except for a\nclose summary. This method can be used to get rid of permanently unusable\nchannels due to bugs fixed in newer versions of lnd. This method can also be\nused to remove externally funded channels where the funding transaction was\nnever broadcast. Only available for non-externally funded channels in dev\nbuild.",
"operationId": "AbandonChannel",
"responses": {
"200": {
@ -190,6 +190,13 @@
"required": false,
"type": "string",
"format": "byte"
},
{
"name": "pending_funding_shim_only",
"in": "query",
"required": false,
"type": "boolean",
"format": "boolean"
}
],
"tags": [

View file

@ -2358,13 +2358,14 @@ func abandonChanFromGraph(chanGraph *channeldb.ChannelGraph,
// AbandonChannel removes all channel state from the database except for a
// close summary. This method can be used to get rid of permanently unusable
// channels due to bugs fixed in newer versions of lnd.
func (r *rpcServer) AbandonChannel(ctx context.Context,
func (r *rpcServer) AbandonChannel(_ context.Context,
in *lnrpc.AbandonChannelRequest) (*lnrpc.AbandonChannelResponse, error) {
// If this isn't the dev build, then we won't allow the RPC to be
// executed, as it's an advanced feature and won't be activated in
// regular production/release builds.
if !build.IsDevBuild() {
// regular production/release builds except for the explicit case of
// externally funded channels that are still pending.
if !in.PendingFundingShimOnly && !build.IsDevBuild() {
return nil, fmt.Errorf("AbandonChannel RPC call only " +
"available in dev builds")
}
@ -2396,6 +2397,20 @@ func (r *rpcServer) AbandonChannel(ctx context.Context,
// on-disk state, we'll remove the channel from the switch and peer
// state if it's been loaded in.
case err == nil:
// If the user requested the more safe version that only allows
// the removal of externally (shim) funded channels that are
// still pending, we enforce this option now that we know the
// state of the channel.
//
// TODO(guggero): Properly store the funding type (wallet, shim,
// PSBT) on the channel so we don't need to use the thaw height.
isShimFunded := dbChan.ThawHeight > 0
isPendingShimFunded := isShimFunded && dbChan.IsPending
if in.PendingFundingShimOnly && !isPendingShimFunded {
return nil, fmt.Errorf("channel %v is not externally "+
"funded or not pending", chanPoint)
}
// We'll mark the channel as borked before we remove the state
// from the switch/peer so it won't be loaded back in if the
// peer reconnects.