Skip to content

multi: bump to latest lnd/tapd, assert close chan data #1017

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Apr 2, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ require (
github.com/lightninglabs/pool v0.6.5-beta.0.20250305125211-4e860ec4e77f
github.com/lightninglabs/pool/auctioneerrpc v1.1.3-0.20250305125211-4e860ec4e77f
github.com/lightninglabs/pool/poolrpc v1.0.1-0.20250305125211-4e860ec4e77f
github.com/lightninglabs/taproot-assets v0.5.2-0.20250326140136-a724d385e7ae
github.com/lightningnetwork/lnd v0.19.0-beta.rc1
github.com/lightninglabs/taproot-assets v0.5.2-0.20250401150538-a9ea76a9ed3c
github.com/lightningnetwork/lnd v0.19.0-beta.rc1.0.20250327183348-eb822a5e117f
github.com/lightningnetwork/lnd/cert v1.2.2
github.com/lightningnetwork/lnd/clock v1.1.1
github.com/lightningnetwork/lnd/fn v1.2.3
Expand Down
8 changes: 4 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -1181,12 +1181,12 @@ github.com/lightninglabs/pool/poolrpc v1.0.1-0.20250305125211-4e860ec4e77f h1:5p
github.com/lightninglabs/pool/poolrpc v1.0.1-0.20250305125211-4e860ec4e77f/go.mod h1:lGs2hSVZ+GFpdv3btaIl9icG5/gz7BBRfvmD2iqqNl0=
github.com/lightninglabs/protobuf-go-hex-display v1.34.2-hex-display h1:w7FM5LH9Z6CpKxl13mS48idsu6F+cEZf0lkyiV+Dq9g=
github.com/lightninglabs/protobuf-go-hex-display v1.34.2-hex-display/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
github.com/lightninglabs/taproot-assets v0.5.2-0.20250326140136-a724d385e7ae h1:t2GDmnV/ab+dsaTDjCDTGbCVSMCE13pxc6zu4zQFsJs=
github.com/lightninglabs/taproot-assets v0.5.2-0.20250326140136-a724d385e7ae/go.mod h1:hLK/spdccubmDZjufTqGJrj9mn0hQpOxaJBQ767Idxw=
github.com/lightninglabs/taproot-assets v0.5.2-0.20250401150538-a9ea76a9ed3c h1:Rebx5DVZx3u327vKRrueFjZNlei1RzdGzFmOZmenkiQ=
github.com/lightninglabs/taproot-assets v0.5.2-0.20250401150538-a9ea76a9ed3c/go.mod h1:e3SjXbbi4xKhOzq54c672Z/j9UTRq5DLJGx/URgVTJo=
github.com/lightningnetwork/lightning-onion v1.2.1-0.20240712235311-98bd56499dfb h1:yfM05S8DXKhuCBp5qSMZdtSwvJ+GFzl94KbXMNB1JDY=
github.com/lightningnetwork/lightning-onion v1.2.1-0.20240712235311-98bd56499dfb/go.mod h1:c0kvRShutpj3l6B9WtTsNTBUtjSmjZXbJd9ZBRQOSKI=
github.com/lightningnetwork/lnd v0.19.0-beta.rc1 h1:FJvsdw4PZ41ykrHi7vNGit9IIohE+IlKpVwL5/1+L+0=
github.com/lightningnetwork/lnd v0.19.0-beta.rc1/go.mod h1:BP+neeFpmeAA7o5hu3zp3FwOEl26idSyPV9zBOavp6E=
github.com/lightningnetwork/lnd v0.19.0-beta.rc1.0.20250327183348-eb822a5e117f h1:+Bejv2Ij/ryUjLacBd5au0acMH0AYs0lhb7ki5rx9ms=
github.com/lightningnetwork/lnd v0.19.0-beta.rc1.0.20250327183348-eb822a5e117f/go.mod h1:BP+neeFpmeAA7o5hu3zp3FwOEl26idSyPV9zBOavp6E=
github.com/lightningnetwork/lnd/cert v1.2.2 h1:71YK6hogeJtxSxw2teq3eGeuy4rHGKcFf0d0Uy4qBjI=
github.com/lightningnetwork/lnd/cert v1.2.2/go.mod h1:jQmFn/Ez4zhDgq2hnYSw8r35bqGVxViXhX6Cd7HXM6U=
github.com/lightningnetwork/lnd/clock v1.1.1 h1:OfR3/zcJd2RhH0RU+zX/77c0ZiOnIMsDIBjgjWdZgA0=
Expand Down
199 changes: 180 additions & 19 deletions itest/assets_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -473,9 +473,9 @@ func assertPendingChannels(t *testing.T, node *HarnessNode,
pendingChan.Channel.CustomChannelData, &pendingJSON,
)
require.NoError(t, err)
require.Len(t, pendingJSON.Assets, 1)
require.Len(t, pendingJSON.FundingAssets, 1)

require.NotZero(t, pendingJSON.Assets[0].Capacity)
require.NotZero(t, pendingJSON.Capacity)

// Check the decimal display of the channel funding blob. If no explicit
// value was set, we assume and expect the value of 0.
Expand All @@ -488,7 +488,7 @@ func assertPendingChannels(t *testing.T, node *HarnessNode,

require.Equal(
t, expectedDecimalDisplay,
pendingJSON.Assets[0].AssetInfo.DecimalDisplay,
pendingJSON.FundingAssets[0].DecimalDisplay,
)

// Check the balance of the pending channel.
Expand All @@ -501,21 +501,36 @@ func assertPendingChannels(t *testing.T, node *HarnessNode,
require.EqualValues(t, remoteSum, pendingRemoteBalance)
}

// haveFundingAsset returns true if the given channel has the asset with the
// given asset ID as a funding asset.
func haveFundingAsset(assetChannel *rfqmsg.JsonAssetChannel,
assetID []byte) bool {

assetIDStr := hex.EncodeToString(assetID)
for _, fundingAsset := range assetChannel.FundingAssets {
if fundingAsset.AssetGenesis.AssetID == assetIDStr {
return true
}
}

return false
}

func assertAssetChan(t *testing.T, src, dst *HarnessNode, fundingAmount uint64,
mintedAsset *taprpc.Asset) {

assetID := mintedAsset.AssetGenesis.AssetId
assetIDStr := hex.EncodeToString(assetID)
err := wait.NoError(func() error {
a, err := getChannelCustomData(src, dst)
if err != nil {
return err
}

if a.AssetInfo.AssetGenesis.AssetID != assetIDStr {
return fmt.Errorf("expected asset ID %s, got %s",
assetIDStr, a.AssetInfo.AssetGenesis.AssetID)
assetID := mintedAsset.AssetGenesis.AssetId
if !haveFundingAsset(a, assetID) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For my understanding:
In the old situation there could only be one type of AssetID as the funding asset of a custom channel. But in the new situation we can have funding assets with different AssetID's and we check if one of them is the assetID we expect.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct. This is in preparation for when we can actually have multiple assets in a channel (#987). So there is a tiny bit of overlap between this PR and #987 (if this one gets in first, the other one will be rebased accordingly).

return fmt.Errorf("expected asset ID %x, to "+
"be in channel", assetID)
}

if a.Capacity != fundingAmount {
return fmt.Errorf("expected capacity %d, got %d",
fundingAmount, a.Capacity)
Expand All @@ -530,10 +545,10 @@ func assertAssetChan(t *testing.T, src, dst *HarnessNode, fundingAmount uint64,
)
}

if a.AssetInfo.DecimalDisplay != expectedDecimalDisplay {
if a.FundingAssets[0].DecimalDisplay != expectedDecimalDisplay {
return fmt.Errorf("expected decimal display %d, got %d",
expectedDecimalDisplay,
a.AssetInfo.DecimalDisplay)
a.FundingAssets[0].DecimalDisplay)
}

return nil
Expand Down Expand Up @@ -580,7 +595,7 @@ func assertChannelKnown(t *testing.T, node *HarnessNode,
require.NoError(t, err)
}

func getChannelCustomData(src, dst *HarnessNode) (*rfqmsg.JsonAssetChanInfo,
func getChannelCustomData(src, dst *HarnessNode) (*rfqmsg.JsonAssetChannel,
error) {

ctxb := context.Background()
Expand Down Expand Up @@ -614,12 +629,12 @@ func getChannelCustomData(src, dst *HarnessNode) (*rfqmsg.JsonAssetChanInfo,
err)
}

if len(assetData.Assets) != 1 {
if len(assetData.FundingAssets) != 1 {
return nil, fmt.Errorf("expected 1 asset, got %d",
len(assetData.Assets))
len(assetData.FundingAssets))
}

return &assetData.Assets[0], nil
return &assetData, nil
}

func getAssetChannelBalance(t *testing.T, node *HarnessNode, assetID []byte,
Expand Down Expand Up @@ -706,10 +721,10 @@ func assertChannelAssetBalance(t *testing.T, node *HarnessNode,
err := json.Unmarshal(targetChan.CustomChannelData, &assetBalance)
require.NoError(t, err)

require.Len(t, assetBalance.Assets, 1)
require.Len(t, assetBalance.FundingAssets, 1)

require.InDelta(t, local, assetBalance.Assets[0].LocalBalance, 1)
require.InDelta(t, remote, assetBalance.Assets[0].RemoteBalance, 1)
require.InDelta(t, local, assetBalance.LocalBalance, 1)
require.InDelta(t, remote, assetBalance.RemoteBalance, 1)
}

// addRoutingFee adds the default routing fee (1 part per million fee rate plus
Expand Down Expand Up @@ -1385,6 +1400,9 @@ func closeAssetChannelAndAssert(t *harnessTest, net *NetworkHarness,
)
require.NoError(t.t, err)

assertWaitingCloseChannelAssetData(t.t, local, chanPoint)
assertWaitingCloseChannelAssetData(t.t, remote, chanPoint)

mineBlocks(t, net, 1, 1)

closeUpdate, err := t.lndHarness.WaitForChannelClose(closeStream)
Expand All @@ -1405,6 +1423,9 @@ func closeAssetChannelAndAssert(t *harnessTest, net *NetworkHarness,
t.t, local, remote, closeTx, closeUpdate, assetID, groupKey,
universeTap,
)

assertClosedChannelAssetData(t.t, local, chanPoint)
assertClosedChannelAssetData(t.t, remote, chanPoint)
}

// assertDefaultCoOpCloseBalance returns a default implementation of the co-op
Expand Down Expand Up @@ -2128,8 +2149,8 @@ func newCloseExpiryInfo(t *testing.T, node *HarnessNode) forceCloseExpiryInfo {
csvDelay: mainChan.CsvDelay,
currentHeight: nodeInfo.BlockHeight,
cltvDelays: cltvs,
localAssetBalance: assetData.Assets[0].LocalBalance,
remoteAssetBalance: assetData.Assets[0].RemoteBalance,
localAssetBalance: assetData.LocalBalance,
remoteAssetBalance: assetData.RemoteBalance,
t: t,
node: node,
}
Expand Down Expand Up @@ -2200,3 +2221,143 @@ func assertInvoiceState(t *testing.T, hn *HarnessNode, payAddr []byte,
}, defaultTimeout)
require.NoError(t, err, "timeout waiting for invoice settled state")
}

type pendingChan = lnrpc.PendingChannelsResponse_PendingChannel

// assertWaitingCloseChannelAssetData asserts that the waiting close channel has
// the expected asset data.
func assertPendingChannelAssetData(t *testing.T, node *HarnessNode,
chanPoint *lnrpc.ChannelPoint, find func(string,
*lnrpc.PendingChannelsResponse) (*pendingChan, error)) {

ctxb := context.Background()

err := wait.NoError(func() error {
// Make sure we can find the closed channel in the channel
// database.
pendingChannels, err := node.PendingChannels(
ctxb, &lnrpc.PendingChannelsRequest{},
)
if err != nil {
return err
}

targetChanPointStr := fmt.Sprintf("%v:%v",
chanPoint.GetFundingTxidStr(),
chanPoint.GetOutputIndex())

targetChan, err := find(targetChanPointStr, pendingChannels)
if err != nil {
return err
}

if len(targetChan.CustomChannelData) == 0 {
return fmt.Errorf("pending channel %s has no "+
"custom channel data", targetChanPointStr)
}

var closeData rfqmsg.JsonAssetChannel
err = json.Unmarshal(targetChan.CustomChannelData, &closeData)
if err != nil {
return fmt.Errorf("error unmarshalling custom channel "+
"data: %v", err)
}

if len(closeData.FundingAssets) != 1 {
return fmt.Errorf("expected 1 funding asset, got %d",
len(closeData.FundingAssets))
}

return nil
}, defaultTimeout)
require.NoError(t, err, "timeout waiting for pending channel")
}

// assertPendingForceCloseChannelAssetData asserts that the pending force close
// channel has the expected asset data.
func assertPendingForceCloseChannelAssetData(t *testing.T, node *HarnessNode,
chanPoint *lnrpc.ChannelPoint) {

assertPendingChannelAssetData(
t, node, chanPoint, func(chanPoint string,
resp *lnrpc.PendingChannelsResponse) (*pendingChan,
error) {

if len(resp.PendingForceClosingChannels) == 0 {
return nil, fmt.Errorf("no pending force close " +
"channels found")
}

for _, ch := range resp.PendingForceClosingChannels {
if ch.Channel.ChannelPoint == chanPoint {
return ch.Channel, nil
}
}

return nil, fmt.Errorf("pending channel %s not found",
chanPoint)
},
)
}

// assertWaitingCloseChannelAssetData asserts that the waiting close channel has
// the expected asset data.
func assertWaitingCloseChannelAssetData(t *testing.T, node *HarnessNode,
chanPoint *lnrpc.ChannelPoint) {

assertPendingChannelAssetData(
t, node, chanPoint, func(chanPoint string,
resp *lnrpc.PendingChannelsResponse) (*pendingChan,
error) {

if len(resp.WaitingCloseChannels) == 0 {
return nil, fmt.Errorf("no waiting close " +
"channels found")
}

for _, ch := range resp.WaitingCloseChannels {
if ch.Channel.ChannelPoint == chanPoint {
return ch.Channel, nil
}
}

return nil, fmt.Errorf("pending channel %s not found",
chanPoint)
},
)
}

// assertClosedChannelAssetData asserts that the closed channel has the expected
// asset data.
func assertClosedChannelAssetData(t *testing.T, node *HarnessNode,
chanPoint *lnrpc.ChannelPoint) {

ctxb := context.Background()

// Make sure we can find the closed channel in the channel database.
closedChannels, err := node.ClosedChannels(
ctxb, &lnrpc.ClosedChannelsRequest{},
)
require.NoError(t, err)

require.NotEmpty(t, closedChannels.Channels)

targetChanPointStr := fmt.Sprintf("%v:%v",
chanPoint.GetFundingTxidStr(), chanPoint.GetOutputIndex())

var closedChan *lnrpc.ChannelCloseSummary
for _, ch := range closedChannels.Channels {
if ch.ChannelPoint == targetChanPointStr {
closedChan = ch
break
}
}
require.NotNil(t, closedChan)
require.NotEmpty(t, closedChan.CustomChannelData)

var closeData rfqmsg.JsonAssetChannel
err = json.Unmarshal(closedChan.CustomChannelData, &closeData)
require.NoError(t, err)

require.GreaterOrEqual(t, len(closeData.FundingAssets), 1)
}
Loading
Loading