Merge pull request #9677 from NishantBansal2003/conf-count
Expose confirmation count for pending 'channel open' transactions
This commit is contained in:
14 files changed
+2928
-2151
No files matched your search
@@ -261,6 +261,10 @@ type openChannelTlvData struct {
|
||||
// customBlob is an optional TLV encoded blob of data representing
|
||||
// custom channel funding information.
|
||||
customBlob tlv.OptionalRecordT[tlv.TlvType7, tlv.Blob]
|
||||
|
||||
// confirmationHeight records the block height at which the funding
|
||||
// transaction was first confirmed.
|
||||
confirmationHeight tlv.RecordT[tlv.TlvType8, uint32]
|
||||
}
|
||||
|
||||
// encode serializes the openChannelTlvData to the given io.Writer.
|
||||
@@ -270,6 +274,7 @@ func (c *openChannelTlvData) encode(w io.Writer) error {
|
||||
c.initialLocalBalance.Record(),
|
||||
c.initialRemoteBalance.Record(),
|
||||
c.realScid.Record(),
|
||||
c.confirmationHeight.Record(),
|
||||
}
|
||||
c.memo.WhenSome(func(memo tlv.RecordT[tlv.TlvType5, []byte]) {
|
||||
tlvRecords = append(tlvRecords, memo.Record())
|
||||
@@ -283,6 +288,8 @@ func (c *openChannelTlvData) encode(w io.Writer) error {
|
||||
tlvRecords = append(tlvRecords, blob.Record())
|
||||
})
|
||||
|
||||
tlv.SortRecords(tlvRecords)
|
||||
|
||||
// Create the tlv stream.
|
||||
tlvStream, err := tlv.NewStream(tlvRecords...)
|
||||
if err != nil {
|
||||
@@ -307,6 +314,7 @@ func (c *openChannelTlvData) decode(r io.Reader) error {
|
||||
memo.Record(),
|
||||
tapscriptRoot.Record(),
|
||||
blob.Record(),
|
||||
c.confirmationHeight.Record(),
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -906,6 +914,10 @@ type OpenChannel struct {
|
||||
// been confirmed before a certain height.
|
||||
FundingBroadcastHeight uint32
|
||||
|
||||
// ConfirmationHeight records the block height at which the funding
|
||||
// transaction was first confirmed.
|
||||
ConfirmationHeight uint32
|
||||
|
||||
// NumConfsRequired is the number of confirmations a channel's funding
|
||||
// transaction must have received in order to be considered available
|
||||
// for normal transactional use.
|
||||
@@ -1207,6 +1219,7 @@ func (c *OpenChannel) amendTlvData(auxData openChannelTlvData) {
|
||||
auxData.initialRemoteBalance.Val,
|
||||
)
|
||||
c.confirmedScid = auxData.realScid.Val
|
||||
c.ConfirmationHeight = auxData.confirmationHeight.Val
|
||||
|
||||
auxData.memo.WhenSomeV(func(memo []byte) {
|
||||
c.Memo = memo
|
||||
@@ -1234,6 +1247,9 @@ func (c *OpenChannel) extractTlvData() openChannelTlvData {
|
||||
realScid: tlv.NewRecordT[tlv.TlvType4](
|
||||
c.confirmedScid,
|
||||
),
|
||||
confirmationHeight: tlv.NewPrimitiveRecord[tlv.TlvType8](
|
||||
c.ConfirmationHeight,
|
||||
),
|
||||
}
|
||||
|
||||
if len(c.Memo) != 0 {
|
||||
@@ -1501,6 +1517,37 @@ func (c *OpenChannel) fullSync(tx kvdb.RwTx) error {
|
||||
return putOpenChannel(chanBucket, c)
|
||||
}
|
||||
|
||||
// MarkConfirmationHeight updates the channel's confirmation height once the
|
||||
// channel opening transaction receives one confirmation.
|
||||
func (c *OpenChannel) MarkConfirmationHeight(height uint32) error {
|
||||
c.Lock()
|
||||
defer c.Unlock()
|
||||
|
||||
if err := kvdb.Update(c.Db.backend, func(tx kvdb.RwTx) error {
|
||||
chanBucket, err := fetchChanBucketRw(
|
||||
tx, c.IdentityPub, &c.FundingOutpoint, c.ChainHash,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
channel, err := fetchOpenChannel(chanBucket, &c.FundingOutpoint)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
channel.ConfirmationHeight = height
|
||||
|
||||
return putOpenChannel(chanBucket, channel)
|
||||
}, func() {}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
c.ConfirmationHeight = height
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarkAsOpen marks a channel as fully open given a locator that uniquely
|
||||
// describes its location within the chain.
|
||||
func (c *OpenChannel) MarkAsOpen(openLoc lnwire.ShortChannelID) error {
|
||||
|
||||
@@ -978,6 +978,73 @@ func TestChannelStateTransition(t *testing.T) {
|
||||
require.Empty(t, fwdPkgs, "no forwarding packages should exist")
|
||||
}
|
||||
|
||||
// TestOpeningChannelTxConfirmation verifies that calling MarkConfirmationHeight
|
||||
// correctly updates the confirmed state. It also ensures that calling Refresh
|
||||
// on a different OpenChannel updates its in-memory state to reflect the prior
|
||||
// MarkConfirmationHeight call.
|
||||
func TestOpeningChannelTxConfirmation(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
fullDB, err := MakeTestDB(t)
|
||||
require.NoError(t, err)
|
||||
|
||||
cdb := fullDB.ChannelStateDB()
|
||||
|
||||
// Create a pending channel that was broadcast at height 99.
|
||||
const broadcastHeight = uint32(99)
|
||||
channelState := createTestChannel(
|
||||
t, cdb, pendingHeightOption(broadcastHeight),
|
||||
)
|
||||
|
||||
// Fetch pending channels from the database.
|
||||
pendingChannels, err := cdb.FetchPendingChannels()
|
||||
require.NoError(t, err)
|
||||
require.Len(t, pendingChannels, 1)
|
||||
|
||||
// Verify the broadcast height of the pending channel.
|
||||
require.Equal(
|
||||
t, broadcastHeight, pendingChannels[0].FundingBroadcastHeight,
|
||||
)
|
||||
|
||||
confirmationHeight := broadcastHeight + 1
|
||||
|
||||
// Mark the channel's confirmation height.
|
||||
err = pendingChannels[0].MarkConfirmationHeight(confirmationHeight)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Verify the ConfirmationHeight is updated correctly.
|
||||
require.Equal(
|
||||
t, confirmationHeight, pendingChannels[0].ConfirmationHeight,
|
||||
)
|
||||
|
||||
// Re-fetch the pending channels to confirm persistence.
|
||||
pendingChannels, err = cdb.FetchPendingChannels()
|
||||
require.NoError(t, err)
|
||||
require.Len(t, pendingChannels, 1)
|
||||
|
||||
// Validate the confirmation and broadcast height.
|
||||
require.Equal(
|
||||
t, confirmationHeight, pendingChannels[0].ConfirmationHeight,
|
||||
)
|
||||
require.Equal(
|
||||
t, broadcastHeight, pendingChannels[0].FundingBroadcastHeight,
|
||||
)
|
||||
|
||||
// Ensure the original channel state's confirmation height is not
|
||||
// updated before refresh.
|
||||
require.EqualValues(t, channelState.ConfirmationHeight, 0)
|
||||
|
||||
// Refresh the original channel state.
|
||||
err = channelState.Refresh()
|
||||
require.NoError(t, err)
|
||||
|
||||
// Verify that both channel states now have the same ConfirmationHeight.
|
||||
require.Equal(
|
||||
t, channelState.ConfirmationHeight,
|
||||
pendingChannels[0].ConfirmationHeight,
|
||||
)
|
||||
}
|
||||
|
||||
func TestFetchPendingChannels(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
@@ -1007,7 +1074,7 @@ func TestFetchPendingChannels(t *testing.T) {
|
||||
}
|
||||
|
||||
chanOpenLoc := lnwire.ShortChannelID{
|
||||
BlockHeight: 5,
|
||||
BlockHeight: broadcastHeight + 1,
|
||||
TxIndex: 10,
|
||||
TxPosition: 15,
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user