lnrpc: add ability to provide chan point shims for funding, new funding modifiers

In this commit, we start to expose some of the new external funding
functionality over the RPC interface.

First, we add a new `funding_shim` field to the regular `OpenChannel`
method. This can be used by a caller to express that certain parameters
of the funding flow have already been negotiated outside the protocol,
and should be used instead. For example, a shim can be provided to use a
particular key for the commitment key (ideally cold) rather than use one
this is generated by the wallet as normal, or signal that signing will
be carried out in an interactive manner (PSBT based).

Next, we add a brand new method: `FundingStateStep`. FundingStateStep is
an advanced funding related call that allows the caller to either
execute some preparatory steps for a funding workflow, or manually
progress a funding workflow. The primary way a funding flow is
identified is via its pending channel ID. As an example, this method can
be used to specify that we're expecting a funding flow for a particular
pending channel ID, for which we need to use specific parameters.
Alternatively, this can be used to interactively drive PSBT signing for
funding for partially complete funding transactions.

The new transition methods (funding state machine modifiers) in this
commit allow a party to register a funding intent that should be used
for a specified incoming pending channel ID. The "responder" to the
external channel flow should use this to prep lnd to be able to handle
the channel flow properly.
This commit is contained in:
Olaoluwa Osuntokun 2019-11-13 20:54:34 -08:00
parent 72a49d486a
commit 3eed38d602
No known key found for this signature in database
GPG Key ID: BC13F65E2DC84465
4 changed files with 1410 additions and 692 deletions

File diff suppressed because it is too large Load Diff

View File

@ -437,10 +437,25 @@ service Lightning {
request to a remote peer. Users are able to specify a target number of
blocks that the funding transaction should be confirmed in, or a manual fee
rate to us for the funding transaction. If neither are specified, then a
lax block confirmation target is used.
lax block confirmation target is used. Each OpenStatusUpdate will return
the pending channel ID of the in-progress channel. Depending on the
arguments specified in the OpenChannelRequest, this pending channel ID can
then be used to manually progress the channel funding flow.
*/
rpc OpenChannel (OpenChannelRequest) returns (stream OpenStatusUpdate);
/**
FundingStateStep is an advanced funding related call that allows the caller
to either execute some preparatory steps for a funding workflow, or
manually progress a funding workflow. The primary way a funding flow is
identified is via its pending channel ID. As an example, this method can be
used to specify that we're expecting a funding flow for a particular
pending channel ID, for which we need to use specific parameters.
Alternatively, this can be used to interactively drive PSBT signing for
funding for partially complete funding transactions.
*/
rpc FundingStateStep(FundingTransitionMsg) returns (FundingStateStepResp);
/**
ChannelAcceptor dispatches a bi-directional streaming RPC in which
OpenChannel requests are sent to the client and the client responds with
@ -1678,15 +1693,103 @@ message OpenChannelRequest {
Note: If this value is set on channel creation, you will *not* be able to
cooperatively close out to a different address.
*/
string close_address = 13[json_name = "close_address"];
string close_address = 13 [json_name = "close_address"];
/**
Funding shims are an optional argument that allow the caller to intercept
certain funding functionality. For example, a shim can be provided to use a
particular key for the commitment key (ideally cold) rather than use one
that is generated by the wallet as normal, or signal that signing will be
carried out in an interactive manner (PSBT based).
*/
FundingShim funding_shim = 14 [json_name = "funding_shim"];
}
message OpenStatusUpdate {
oneof update {
PendingUpdate chan_pending = 1 [json_name = "chan_pending"];
ChannelOpenUpdate chan_open = 3 [json_name = "chan_open"];
}
/**
The pending channel ID of the created channel. This value may be used to
further the funding flow manually via the FundingStateStep method.
*/
bytes pending_chan_id = 4 [json_name = "pending_chan_id"];
}
message KeyLocator {
/// The family of key being identified.
int32 key_family = 1;
/// The precise index of the key being identified.
int32 key_index = 2;
}
message KeyDescriptor {
/**
The raw bytes of the key being identified.
*/
bytes raw_key_bytes = 1;
/**
The key locator that identifies which key to use for signing.
*/
KeyLocator key_loc = 2;
}
message ChanPointShim {
/**
The size of the pre-crafted output to be used as the channel point for this
channel funding.
*/
int64 amt = 1;
/// The target channel point to refrence in created commitment transactions.
ChannelPoint chan_point = 2;
/// Our local key to use when creating the multi-sig output.
KeyDescriptor local_key = 3;
/// The key of the remote party to use when creating the multi-sig output.
bytes remote_key = 4;
/**
If non-zero, then this will be used as the pending channel ID on the wire
protocol to initate the funding request. This is an optional field, and
should only be set if the responder is already expecting a specific pending
channel ID.
*/
bytes pending_chan_id = 5;
}
message FundingShim {
oneof shim {
ChanPointShim chan_point_shim = 1;
}
}
message FundingShimCancel {
/// The pending channel ID of the channel to cancel the funding shim for.
bytes pending_chan_id = 1;
}
message FundingTransitionMsg {
oneof trigger {
/**
The funding shim to regsiter. This should be used before any
channel funding has began by the remote party, as it is intended as a
prepatory step for the full channel funding.
*/
FundingShim shim_register = 1;
/// Used to cancel an existing registered funding shim.
FundingShimCancel shim_cancel = 2;
}
}
message FundingStateStepResp {
}
message PendingHTLC {
/// The direction within the channel that the htlc was sent

View File

@ -1680,6 +1680,34 @@
}
}
},
"lnrpcChanPointShim": {
"type": "object",
"properties": {
"amt": {
"type": "string",
"format": "int64",
"description": "*\nThe size of the pre-crafted output to be used as the channel point for this\nchannel funding."
},
"chan_point": {
"$ref": "#/definitions/lnrpcChannelPoint",
"description": "/ The target channel point to refrence in created commitment transactions."
},
"local_key": {
"$ref": "#/definitions/lnrpcKeyDescriptor",
"description": "/ Our local key to use when creating the multi-sig output."
},
"remote_key": {
"type": "string",
"format": "byte",
"description": "/ The key of the remote party to use when creating the multi-sig output."
},
"pending_chan_id": {
"type": "string",
"format": "byte",
"description": "*\nIf non-zero, then this will be used as the pending channel ID on the wire\nprotocol to initate the funding request. This is an optional field, and\nshould only be set if the responder is already expecting a specific pending\nchannel ID."
}
}
},
"lnrpcChangePasswordRequest": {
"type": "object",
"properties": {
@ -2433,6 +2461,27 @@
}
}
},
"lnrpcFundingShim": {
"type": "object",
"properties": {
"chan_point_shim": {
"$ref": "#/definitions/lnrpcChanPointShim"
}
}
},
"lnrpcFundingShimCancel": {
"type": "object",
"properties": {
"pending_chan_id": {
"type": "string",
"format": "byte",
"description": "/ The pending channel ID of the channel to cancel the funding shim for."
}
}
},
"lnrpcFundingStateStepResp": {
"type": "object"
},
"lnrpcGenSeedResponse": {
"type": "object",
"properties": {
@ -2917,6 +2966,35 @@
],
"default": "ACCEPTED"
},
"lnrpcKeyDescriptor": {
"type": "object",
"properties": {
"raw_key_bytes": {
"type": "string",
"format": "byte",
"description": "*\nThe raw bytes of the key being identified."
},
"key_loc": {
"$ref": "#/definitions/lnrpcKeyLocator",
"description": "* \nThe key locator that identifies which key to use for signing."
}
}
},
"lnrpcKeyLocator": {
"type": "object",
"properties": {
"key_family": {
"type": "integer",
"format": "int32",
"description": "/ The family of key being identified."
},
"key_index": {
"type": "integer",
"format": "int32",
"description": "/ The precise index of the key being identified."
}
}
},
"lnrpcLightningAddress": {
"type": "object",
"properties": {
@ -3271,6 +3349,10 @@
"close_address": {
"type": "string",
"description": "Close address is an optional address which specifies the address to which\nfunds should be paid out to upon cooperative close. This field may only be\nset if the peer supports the option upfront feature bit (call listpeers\nto check). The remote peer will only accept cooperative closes to this\naddress if it is set.\n\nNote: If this value is set on channel creation, you will *not* be able to\ncooperatively close out to a different address."
},
"funding_shim": {
"$ref": "#/definitions/lnrpcFundingShim",
"description": "*\nFunding shims are an optional argument that allow the caller to intercept\ncertain funding functionality. For example, a shim can be provided to use a\nparticular key for the commitment key (ideally cold) rather than use one\nthat is generated by the wallet as normal, or signal that signing will be\ncarried out in an interactive manner (PSBT based)."
}
}
},
@ -3282,6 +3364,11 @@
},
"chan_open": {
"$ref": "#/definitions/lnrpcChannelOpenUpdate"
},
"pending_chan_id": {
"type": "string",
"format": "byte",
"description": "*\nThe pending channel ID of the created channel. This value may be used to\nfurther the funding flow manually via the FundingStateStep method."
}
}
},

View File

@ -440,6 +440,13 @@ func mainRPCServerPermissions() map[string][]bakery.Op {
Entity: "peers",
Action: "read",
}},
"/lnrpc.Lightning/FundingStateStep": {{
Entity: "onchain",
Action: "write",
}, {
Entity: "offchain",
Action: "write",
}},
}
}
@ -5692,3 +5699,17 @@ func (r *rpcServer) BakeMacaroon(ctx context.Context,
return resp, nil
}
// FundingStateStep is an advanced funding related call that allows the caller
// to either execute some preparatory steps for a funding workflow, or manually
// progress a funding workflow. The primary way a funding flow is identified is
// via its pending channel ID. As an example, this method can be used to
// specify that we're expecting a funding flow for a particular pending channel
// ID, for which we need to use specific parameters. Alternatively, this can
// be used to interactively drive PSBT signing for funding for partially
// complete funding transactions.
func (r *rpcServer) FundingStateStep(context.Context,
*lnrpc.FundingTransitionMsg) (*lnrpc.FundingStateStepResp, error) {
return nil, fmt.Errorf("not implemented")
}