mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-03-13 11:09:23 +01:00
Merge pull request #3796 from carlaKC/3786-setupfrontshutdown
Add Upfront Shutdown Address to OpenChannelRequest
This commit is contained in:
commit
7f3771e74f
6 changed files with 783 additions and 599 deletions
|
@ -590,6 +590,12 @@ var openChannelCommand = cli.Command{
|
|||
amount to the remote node as part of the channel opening. Once the channel is open,
|
||||
a channelPoint (txid:vout) of the funding output is returned.
|
||||
|
||||
If the remote peer supports the option upfront shutdown feature bit (query
|
||||
listpeers to see their supported feature bits), an address to enforce
|
||||
payout of funds on cooperative close can optionally be provided. Note that
|
||||
if you set this value, you will not be able to cooperatively close out to
|
||||
another address.
|
||||
|
||||
One can manually set the fee to be used for the funding transaction via either
|
||||
the --conf_target or --sat_per_byte arguments. This is optional.`,
|
||||
ArgsUsage: "node-key local-amt push-amt",
|
||||
|
@ -659,6 +665,13 @@ var openChannelCommand = cli.Command{
|
|||
"transaction must satisfy",
|
||||
Value: 1,
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "close_address",
|
||||
Usage: "(optional) an address to enforce payout of our " +
|
||||
"funds to on cooperative close. Note that if this " +
|
||||
"value is set on channel open, you will *not* be " +
|
||||
"able to cooperatively close to a different address.",
|
||||
},
|
||||
},
|
||||
Action: actionDecorator(openChannel),
|
||||
}
|
||||
|
@ -686,6 +699,7 @@ func openChannel(ctx *cli.Context) error {
|
|||
RemoteCsvDelay: uint32(ctx.Uint64("remote_csv_delay")),
|
||||
MinConfs: minConfs,
|
||||
SpendUnconfirmed: minConfs == 0,
|
||||
CloseAddress: ctx.String("close_address"),
|
||||
}
|
||||
|
||||
switch {
|
||||
|
@ -1935,22 +1949,23 @@ func getInfo(ctx *cli.Context) error {
|
|||
// We print a struct that mimics the proto definition of GetInfoResponse
|
||||
// but has a better ordering for the same list of fields.
|
||||
printJSON(struct {
|
||||
Version string `json:"version"`
|
||||
IdentityPubkey string `json:"identity_pubkey"`
|
||||
Alias string `json:"alias"`
|
||||
Color string `json:"color"`
|
||||
NumPendingChannels uint32 `json:"num_pending_channels"`
|
||||
NumActiveChannels uint32 `json:"num_active_channels"`
|
||||
NumInactiveChannels uint32 `json:"num_inactive_channels"`
|
||||
NumPeers uint32 `json:"num_peers"`
|
||||
BlockHeight uint32 `json:"block_height"`
|
||||
BlockHash string `json:"block_hash"`
|
||||
BestHeaderTimestamp int64 `json:"best_header_timestamp"`
|
||||
SyncedToChain bool `json:"synced_to_chain"`
|
||||
SyncedToGraph bool `json:"synced_to_graph"`
|
||||
Testnet bool `json:"testnet"`
|
||||
Chains []chain `json:"chains"`
|
||||
Uris []string `json:"uris"`
|
||||
Version string `json:"version"`
|
||||
IdentityPubkey string `json:"identity_pubkey"`
|
||||
Alias string `json:"alias"`
|
||||
Color string `json:"color"`
|
||||
NumPendingChannels uint32 `json:"num_pending_channels"`
|
||||
NumActiveChannels uint32 `json:"num_active_channels"`
|
||||
NumInactiveChannels uint32 `json:"num_inactive_channels"`
|
||||
NumPeers uint32 `json:"num_peers"`
|
||||
BlockHeight uint32 `json:"block_height"`
|
||||
BlockHash string `json:"block_hash"`
|
||||
BestHeaderTimestamp int64 `json:"best_header_timestamp"`
|
||||
SyncedToChain bool `json:"synced_to_chain"`
|
||||
SyncedToGraph bool `json:"synced_to_graph"`
|
||||
Testnet bool `json:"testnet"`
|
||||
Chains []chain `json:"chains"`
|
||||
Uris []string `json:"uris"`
|
||||
Features map[uint32]*lnrpc.Feature `json:"features"`
|
||||
}{
|
||||
Version: resp.Version,
|
||||
IdentityPubkey: resp.IdentityPubkey,
|
||||
|
@ -1968,6 +1983,7 @@ func getInfo(ctx *cli.Context) error {
|
|||
Testnet: resp.Testnet,
|
||||
Chains: chains,
|
||||
Uris: resp.Uris,
|
||||
Features: resp.Features,
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -108,3 +108,14 @@ func (m *Manager) Get(set Set) *lnwire.FeatureVector {
|
|||
raw := m.GetRaw(set)
|
||||
return lnwire.NewFeatureVector(raw, lnwire.Features)
|
||||
}
|
||||
|
||||
// ListSets returns a list of the feature sets that our node supports.
|
||||
func (m *Manager) ListSets() []Set {
|
||||
var sets []Set
|
||||
|
||||
for set := range m.fsets {
|
||||
sets = append(sets, set)
|
||||
}
|
||||
|
||||
return sets
|
||||
}
|
||||
|
|
1211
lnrpc/rpc.pb.go
1211
lnrpc/rpc.pb.go
File diff suppressed because it is too large
Load diff
|
@ -1344,6 +1344,15 @@ message Channel {
|
|||
by the channel scoring system over the lifetime of the channel [EXPERIMENTAL].
|
||||
*/
|
||||
int64 uptime = 24 [json_name = "uptime"];
|
||||
|
||||
/**
|
||||
Close address is the address that we will enforce payout to on cooperative
|
||||
close if the channel was opened utilizing option upfront shutdown. This
|
||||
value can be set on channel open by setting close_address in an open channel
|
||||
request. If this value is not set, you can still choose a payout address by
|
||||
cooperatively closing with the delivery_address field set.
|
||||
*/
|
||||
string close_address = 25 [json_name ="close_address"];
|
||||
}
|
||||
|
||||
|
||||
|
@ -1539,6 +1548,12 @@ message GetInfoResponse {
|
|||
|
||||
// Whether we consider ourselves synced with the public channel graph.
|
||||
bool synced_to_graph = 18 [json_name = "synced_to_graph"];
|
||||
|
||||
/*
|
||||
Features that our node has advertised in our init message, node
|
||||
announcements and invoices.
|
||||
*/
|
||||
map<uint32, Feature> features = 19 [json_name = "features"];
|
||||
}
|
||||
|
||||
message Chain {
|
||||
|
@ -1643,6 +1658,18 @@ message OpenChannelRequest {
|
|||
|
||||
/// Whether unconfirmed outputs should be used as inputs for the funding transaction.
|
||||
bool spend_unconfirmed = 12 [json_name = "spend_unconfirmed"];
|
||||
|
||||
/*
|
||||
Close address is an optional address which specifies the address to which
|
||||
funds should be paid out to upon cooperative close. This field may only be
|
||||
set if the peer supports the option upfront feature bit (call listpeers
|
||||
to check). The remote peer will only accept cooperative closes to this
|
||||
address if it is set.
|
||||
|
||||
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"];
|
||||
}
|
||||
message OpenStatusUpdate {
|
||||
oneof update {
|
||||
|
|
|
@ -1819,6 +1819,10 @@
|
|||
"type": "string",
|
||||
"format": "int64",
|
||||
"description": "*\nThe number of seconds that the remote peer has been observed as being online\nby the channel scoring system over the lifetime of the channel [EXPERIMENTAL]."
|
||||
},
|
||||
"close_address": {
|
||||
"type": "string",
|
||||
"description": "*\nClose address is the address that we will enforce payout to on cooperative\nclose if the channel was opened utilizing option upfront shutdown. This\nvalue can be set on channel open by setting close_address in an open channel\nrequest. If this value is not set, you can still choose a payout address by\ncooperatively closing with the delivery_address field set."
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -2504,6 +2508,13 @@
|
|||
"type": "boolean",
|
||||
"format": "boolean",
|
||||
"description": "Whether we consider ourselves synced with the public channel graph."
|
||||
},
|
||||
"features": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"$ref": "#/definitions/lnrpcFeature"
|
||||
},
|
||||
"description": "Features that our node has advertised in our init message, node\nannouncements and invoices."
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -3233,6 +3244,10 @@
|
|||
"type": "boolean",
|
||||
"format": "boolean",
|
||||
"description": "/ Whether unconfirmed outputs should be used as inputs for the funding transaction."
|
||||
},
|
||||
"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."
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
70
rpcserver.go
70
rpcserver.go
|
@ -1542,6 +1542,11 @@ func (r *rpcServer) OpenChannel(in *lnrpc.OpenChannelRequest,
|
|||
rpcsLog.Debugf("[openchannel]: using fee of %v sat/kw for funding tx",
|
||||
int64(feeRate))
|
||||
|
||||
script, err := parseUpfrontShutdownAddress(in.CloseAddress)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error parsing upfront shutdown: %v", err)
|
||||
}
|
||||
|
||||
// Instruct the server to trigger the necessary events to attempt to
|
||||
// open a new channel. A stream is returned in place, this stream will
|
||||
// be used to consume updates of the state of the pending channel.
|
||||
|
@ -1555,6 +1560,7 @@ func (r *rpcServer) OpenChannel(in *lnrpc.OpenChannelRequest,
|
|||
private: in.Private,
|
||||
remoteCsvDelay: remoteCsvDelay,
|
||||
minConfs: minConfs,
|
||||
shutdownScript: script,
|
||||
}
|
||||
|
||||
updateChan, errChan := r.server.OpenChannel(req)
|
||||
|
@ -1687,6 +1693,11 @@ func (r *rpcServer) OpenChannelSync(ctx context.Context,
|
|||
rpcsLog.Tracef("[openchannel] target sat/kw for funding tx: %v",
|
||||
int64(feeRate))
|
||||
|
||||
script, err := parseUpfrontShutdownAddress(in.CloseAddress)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error parsing upfront shutdown: %v", err)
|
||||
}
|
||||
|
||||
req := &openChanReq{
|
||||
targetPubkey: nodepubKey,
|
||||
chainHash: *activeNetParams.GenesisHash,
|
||||
|
@ -1697,6 +1708,7 @@ func (r *rpcServer) OpenChannelSync(ctx context.Context,
|
|||
private: in.Private,
|
||||
remoteCsvDelay: remoteCsvDelay,
|
||||
minConfs: minConfs,
|
||||
shutdownScript: script,
|
||||
}
|
||||
|
||||
updateChan, errChan := r.server.OpenChannel(req)
|
||||
|
@ -1730,6 +1742,24 @@ func (r *rpcServer) OpenChannelSync(ctx context.Context,
|
|||
}
|
||||
}
|
||||
|
||||
// parseUpfrontShutdownScript attempts to parse an upfront shutdown address.
|
||||
// If the address is empty, it returns nil. If it successfully decoded the
|
||||
// address, it returns a script that pays out to the address.
|
||||
func parseUpfrontShutdownAddress(address string) (lnwire.DeliveryAddress, error) {
|
||||
if len(address) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
addr, err := btcutil.DecodeAddress(
|
||||
address, activeNetParams.Params,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid address: %v", err)
|
||||
}
|
||||
|
||||
return txscript.PayToAddrScript(addr)
|
||||
}
|
||||
|
||||
// GetChanPointFundingTxid returns the given channel point's funding txid in
|
||||
// raw bytes.
|
||||
func GetChanPointFundingTxid(chanPoint *lnrpc.ChannelPoint) (*chainhash.Hash, error) {
|
||||
|
@ -2190,6 +2220,22 @@ func (r *rpcServer) GetInfo(ctx context.Context,
|
|||
|
||||
isGraphSynced := r.server.authGossiper.SyncManager().IsGraphSynced()
|
||||
|
||||
features := make(map[uint32]*lnrpc.Feature)
|
||||
sets := r.server.featureMgr.ListSets()
|
||||
|
||||
for _, set := range sets {
|
||||
// Get the a list of lnrpc features for each set we support.
|
||||
featureVector := r.server.featureMgr.Get(set)
|
||||
rpcFeatures := invoicesrpc.CreateRPCFeatures(featureVector)
|
||||
|
||||
// Add the features to our map of features, allowing over writing of
|
||||
// existing values because features in different sets with the same bit
|
||||
// are duplicated across sets.
|
||||
for bit, feature := range rpcFeatures {
|
||||
features[bit] = feature
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(roasbeef): add synced height n stuff
|
||||
return &lnrpc.GetInfoResponse{
|
||||
IdentityPubkey: encodedIDPub,
|
||||
|
@ -2208,6 +2254,7 @@ func (r *rpcServer) GetInfo(ctx context.Context,
|
|||
BestHeaderTimestamp: int64(bestHeaderTimestamp),
|
||||
Version: build.Version(),
|
||||
SyncedToGraph: isGraphSynced,
|
||||
Features: features,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
@ -2942,6 +2989,25 @@ func createRPCOpenChannel(r *rpcServer, graph *channeldb.ChannelGraph,
|
|||
}
|
||||
channel.Uptime = int64(uptime.Seconds())
|
||||
|
||||
if len(dbChannel.LocalShutdownScript) > 0 {
|
||||
_, addresses, _, err := txscript.ExtractPkScriptAddrs(
|
||||
dbChannel.LocalShutdownScript, activeNetParams.Params,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// We only expect one upfront shutdown address for a channel. If
|
||||
// LocalShutdownScript is non-zero, there should be one payout address
|
||||
// set.
|
||||
if len(addresses) != 1 {
|
||||
return nil, fmt.Errorf("expected one upfront shutdown address, "+
|
||||
"got: %v", len(addresses))
|
||||
}
|
||||
|
||||
channel.CloseAddress = addresses[0].String()
|
||||
}
|
||||
|
||||
return channel, nil
|
||||
}
|
||||
|
||||
|
@ -3020,6 +3086,7 @@ func (r *rpcServer) SubscribeChannelEvents(req *lnrpc.ChannelEventSubscription,
|
|||
OpenChannel: channel,
|
||||
},
|
||||
}
|
||||
|
||||
case channelnotifier.ClosedChannelEvent:
|
||||
closedChannel := createRPCClosedChannel(event.CloseSummary)
|
||||
update = &lnrpc.ChannelEventUpdate{
|
||||
|
@ -3028,6 +3095,7 @@ func (r *rpcServer) SubscribeChannelEvents(req *lnrpc.ChannelEventSubscription,
|
|||
ClosedChannel: closedChannel,
|
||||
},
|
||||
}
|
||||
|
||||
case channelnotifier.ActiveChannelEvent:
|
||||
update = &lnrpc.ChannelEventUpdate{
|
||||
Type: lnrpc.ChannelEventUpdate_ACTIVE_CHANNEL,
|
||||
|
@ -3040,6 +3108,7 @@ func (r *rpcServer) SubscribeChannelEvents(req *lnrpc.ChannelEventSubscription,
|
|||
},
|
||||
},
|
||||
}
|
||||
|
||||
case channelnotifier.InactiveChannelEvent:
|
||||
update = &lnrpc.ChannelEventUpdate{
|
||||
Type: lnrpc.ChannelEventUpdate_INACTIVE_CHANNEL,
|
||||
|
@ -3052,6 +3121,7 @@ func (r *rpcServer) SubscribeChannelEvents(req *lnrpc.ChannelEventSubscription,
|
|||
},
|
||||
},
|
||||
}
|
||||
|
||||
default:
|
||||
return fmt.Errorf("unexpected channel event update: %v", event)
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue