lnrpc+rpcserver: add ConfirmationsUntilActive and ConfirmationHeight

Introduce ConfirmationsUntilActive and ConfirmationHeight in
PendingChannelsResponse_PendingChannel. ConfirmationsUntilActive indicates
the remaining confirmations needed for the channel to become active. If the
funding transaction is unconfirmed, ConfirmationsUntilActive defaults to the
total required confirmations (NumConfsRequired). ConfirmationHeight records
the block height at which the funding transaction was first confirmed; if
unconfirmed, it will be 0.

Signed-off-by: Nishant Bansal <nishant.bansal.282003@gmail.com>
This commit is contained in:
Nishant Bansal committed 2025-09-11 18:27:14 +05:30
1 parent ede08a8883
commit 5fd42ac61d
4 files changed
+2091 -1981

No files matched your search

+2014 -1976
View File
File diff suppressed because it is too large. Load diff
+19
View File
@@ -2848,6 +2848,25 @@ message PendingChannelsResponse {
// very likely canceled the funding and the channel will never become
// fully operational.
int32 funding_expiry_blocks = 3;
// The number of blocks remaining until the channel status changes from
// pending to active. A value of 0 indicates that the channel is now
// active.
//
// "Active" here means both channel peers have the channel marked OPEN
// and can immediately start using it. For public channels, this does
// not imply a channel_announcement has been gossiped. It only becomes
// public on the network after 6 on‐chain confirmations.
// See BOLT07 "Routing Gossip":
// https://github.com/lightning/bolts/blob/master/07-routing-gossip.md
//
// ZeroConf channels bypass the pending state entirely: they are marked
// active immediately upon creation, so they never show up as "pending".
uint32 confirmations_until_active = 7;
// The confirmation height records the block height at which the funding
// transaction was first confirmed.
uint32 confirmation_height = 8;
}
message WaitingCloseChannel {
+10
View File
@@ -3337,6 +3337,16 @@
"type": "integer",
"format": "int32",
"description": "The number of blocks until the funding transaction is considered\nexpired. If this value gets close to zero, there is a risk that the\nchannel funding will be canceled by the channel responder. The\nchannel should be fee bumped using CPFP (see walletrpc.BumpFee) to\nensure that the channel confirms in time. Otherwise a force-close\nwill be necessary if the channel confirms after the funding\ntransaction expires. A negative value means the channel responder has\nvery likely canceled the funding and the channel will never become\nfully operational."
},
"confirmations_until_active": {
"type": "integer",
"format": "int64",
"description": "The number of blocks remaining until the channel status changes from\npending to active. A value of 0 indicates that the channel is now\nactive.\n\n\"Active\" here means both channel peers have the channel marked OPEN\nand can immediately start using it. For public channels, this does\nnot imply a channel_announcement has been gossiped. It only becomes\npublic on the network after 6 on‐chain confirmations.\nSee BOLT07 \"Routing Gossip\":\nhttps://github.com/lightning/bolts/blob/master/07-routing-gossip.md\n\nZeroConf channels bypass the pending state entirely: they are marked\nactive immediately upon creation, so they never show up as \"pending\"."
},
"confirmation_height": {
"type": "integer",
"format": "int64",
"description": "The confirmation height records the block height at which the funding\ntransaction was first confirmed."
}
}
},
+48 -5
View File
@@ -3889,6 +3889,37 @@ type (
waitingCloseChannels []*lnrpc.PendingChannelsResponse_WaitingCloseChannel
)
// calcRemainingConfs calculates how many more confirmations are needed for a
// pending channel to be fully confirmed. It takes into account:
// 1. The current blockchain height
// 2. The block height at which the funding transaction was first confirmed
// 3. The total number of confirmations required for the channel.
func calcRemainingConfs(pendingChan *channeldb.OpenChannel,
currentHeight uint32) uint32 {
// If the funding transaction hasn't been confirmed yet,
// we need all the required confirmations.
if pendingChan.ConfirmationHeight == 0 {
return uint32(pendingChan.NumConfsRequired)
}
// Calculate the target height at which the channel will be fully
// confirmed. The -1 is because the confirmation height of the first
// confirmation has to be taken into account.
targetConfirmationHeight := pendingChan.ConfirmationHeight +
uint32(pendingChan.NumConfsRequired) - 1
// In case the current height is already past the target, return 0. This
// should never happen because the channel should already be moved from
// pending to open state but we handle this case in case of timing
// issues.
if currentHeight >= targetConfirmationHeight {
return 0
}
return targetConfirmationHeight - currentHeight
}
// fetchPendingOpenChannels queries the database for a list of channels that
// have pending open state. The returned result is used in the response of the
// PendingChannels RPC.
@@ -3948,6 +3979,15 @@ func (r *rpcServer) fetchPendingOpenChannels() (pendingOpenChannels, error) {
pendingChan.BroadcastHeight()
fundingExpiryBlocks := int32(maxFundingHeight) - currentHeight
// Calculate remainingConfs, the number of blocks left until the
// funding transaction reaches the required confirmation height.
//
// ZeroConf channels are marked OPEN immediately upon creation,
// so they never enter the "pending" state.
remainingConfs := calcRemainingConfs(
pendingChan, uint32(currentHeight),
)
customChanBytes, err := encodeCustomChanData(pendingChan)
if err != nil {
return nil, fmt.Errorf("unable to encode open chan "+
@@ -3969,11 +4009,14 @@ func (r *rpcServer) fetchPendingOpenChannels() (pendingOpenChannels, error) {
Memo: string(pendingChan.Memo),
CustomChannelData: customChanBytes,
},
CommitWeight: commitWeight,
CommitFee: int64(localCommitment.CommitFee),
FeePerKw: int64(localCommitment.FeePerKw),
FundingExpiryBlocks: fundingExpiryBlocks,
// TODO(roasbeef): need to track confirmation height
CommitWeight: commitWeight,
CommitFee: int64(localCommitment.CommitFee),
FeePerKw: int64(localCommitment.
FeePerKw),
FundingExpiryBlocks: fundingExpiryBlocks,
ConfirmationsUntilActive: remainingConfs,
ConfirmationHeight: pendingChan.
ConfirmationHeight,
}
}