mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-06-28 17:53:30 +02:00
Merge branch '0-18-3-branch-9046' into 0-18-3-branch
This commit is contained in:
commit
ce442a5083
@ -3905,6 +3905,27 @@ func (lc *LightningChannel) SignNextCommitment() (*NewCommitState, error) {
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// resignMusigCommit is used to resign a commitment transaction for taproot
|
||||||
|
// channels when we need to retransmit a signature after a channel reestablish
|
||||||
|
// message. Taproot channels use musig2, which means we must use fresh nonces
|
||||||
|
// each time. After we receive the channel reestablish message, we learn the
|
||||||
|
// nonce we need to use for the remote party. As a result, we need to generate
|
||||||
|
// the partial signature again with the new nonce.
|
||||||
|
func (lc *LightningChannel) resignMusigCommit(commitTx *wire.MsgTx,
|
||||||
|
) (lnwire.OptPartialSigWithNonceTLV, error) {
|
||||||
|
|
||||||
|
remoteSession := lc.musigSessions.RemoteSession
|
||||||
|
musig, err := remoteSession.SignCommit(commitTx)
|
||||||
|
if err != nil {
|
||||||
|
var none lnwire.OptPartialSigWithNonceTLV
|
||||||
|
return none, err
|
||||||
|
}
|
||||||
|
|
||||||
|
partialSig := lnwire.MaybePartialSigWithNonce(musig.ToWireSig())
|
||||||
|
|
||||||
|
return partialSig, nil
|
||||||
|
}
|
||||||
|
|
||||||
// ProcessChanSyncMsg processes a ChannelReestablish message sent by the remote
|
// ProcessChanSyncMsg processes a ChannelReestablish message sent by the remote
|
||||||
// connection upon re establishment of our connection with them. This method
|
// connection upon re establishment of our connection with them. This method
|
||||||
// will return a single message if we are currently out of sync, otherwise a
|
// will return a single message if we are currently out of sync, otherwise a
|
||||||
@ -4182,12 +4203,23 @@ func (lc *LightningChannel) ProcessChanSyncMsg(
|
|||||||
commitUpdates = append(commitUpdates, logUpdate.UpdateMsg)
|
commitUpdates = append(commitUpdates, logUpdate.UpdateMsg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If this is a taproot channel, then we need to regenerate the
|
||||||
|
// musig2 signature for the remote party, using their fresh
|
||||||
|
// nonce.
|
||||||
|
if lc.channelState.ChanType.IsTaproot() {
|
||||||
|
partialSig, err := lc.resignMusigCommit(
|
||||||
|
commitDiff.Commitment.CommitTx,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
commitDiff.CommitSig.PartialSig = partialSig
|
||||||
|
}
|
||||||
|
|
||||||
// With the batch of updates accumulated, we'll now re-send the
|
// With the batch of updates accumulated, we'll now re-send the
|
||||||
// original CommitSig message required to re-sync their remote
|
// original CommitSig message required to re-sync their remote
|
||||||
// commitment chain with our local version of their chain.
|
// commitment chain with our local version of their chain.
|
||||||
//
|
|
||||||
// TODO(roasbeef): need to re-sign commitment states w/
|
|
||||||
// fresh nonce
|
|
||||||
commitUpdates = append(commitUpdates, commitDiff.CommitSig)
|
commitUpdates = append(commitUpdates, commitDiff.CommitSig)
|
||||||
|
|
||||||
// NOTE: If a revocation is not owed, then updates is empty.
|
// NOTE: If a revocation is not owed, then updates is empty.
|
||||||
|
@ -47,8 +47,8 @@ func createHTLC(id int, amount lnwire.MilliSatoshi) (*lnwire.UpdateAddHTLC, [32]
|
|||||||
}
|
}
|
||||||
|
|
||||||
func assertOutputExistsByValue(t *testing.T, commitTx *wire.MsgTx,
|
func assertOutputExistsByValue(t *testing.T, commitTx *wire.MsgTx,
|
||||||
value btcutil.Amount) {
|
value btcutil.Amount,
|
||||||
|
) {
|
||||||
for _, txOut := range commitTx.TxOut {
|
for _, txOut := range commitTx.TxOut {
|
||||||
if txOut.Value == int64(value) {
|
if txOut.Value == int64(value) {
|
||||||
return
|
return
|
||||||
@ -63,8 +63,8 @@ func assertOutputExistsByValue(t *testing.T, commitTx *wire.MsgTx,
|
|||||||
// add, the settle an HTLC between themselves.
|
// add, the settle an HTLC between themselves.
|
||||||
func testAddSettleWorkflow(t *testing.T, tweakless bool,
|
func testAddSettleWorkflow(t *testing.T, tweakless bool,
|
||||||
chanTypeModifier channeldb.ChannelType,
|
chanTypeModifier channeldb.ChannelType,
|
||||||
storeFinalHtlcResolutions bool) {
|
storeFinalHtlcResolutions bool,
|
||||||
|
) {
|
||||||
// Create a test channel which will be used for the duration of this
|
// Create a test channel which will be used for the duration of this
|
||||||
// unittest. The channel will be funded evenly with Alice having 5 BTC,
|
// unittest. The channel will be funded evenly with Alice having 5 BTC,
|
||||||
// and Bob having 5 BTC.
|
// and Bob having 5 BTC.
|
||||||
@ -514,7 +514,6 @@ func TestCheckCommitTxSize(t *testing.T) {
|
|||||||
if 0 > diff || BaseCommitmentTxSizeEstimationError < diff {
|
if 0 > diff || BaseCommitmentTxSizeEstimationError < diff {
|
||||||
t.Fatalf("estimation is wrong, diff: %v", diff)
|
t.Fatalf("estimation is wrong, diff: %v", diff)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a test channel which will be used for the duration of this
|
// Create a test channel which will be used for the duration of this
|
||||||
@ -1467,8 +1466,8 @@ func TestHTLCSigNumber(t *testing.T) {
|
|||||||
// createChanWithHTLC is a helper method that sets ut two channels, and
|
// createChanWithHTLC is a helper method that sets ut two channels, and
|
||||||
// adds HTLCs with the passed values to the channels.
|
// adds HTLCs with the passed values to the channels.
|
||||||
createChanWithHTLC := func(htlcValues ...btcutil.Amount) (
|
createChanWithHTLC := func(htlcValues ...btcutil.Amount) (
|
||||||
*LightningChannel, *LightningChannel) {
|
*LightningChannel, *LightningChannel,
|
||||||
|
) {
|
||||||
// Create a test channel funded evenly with Alice having 5 BTC,
|
// Create a test channel funded evenly with Alice having 5 BTC,
|
||||||
// and Bob having 5 BTC. Alice's dustlimit is 200 sat, while
|
// and Bob having 5 BTC. Alice's dustlimit is 200 sat, while
|
||||||
// Bob has 1300 sat.
|
// Bob has 1300 sat.
|
||||||
@ -2367,7 +2366,6 @@ func TestUpdateFeeFail(t *testing.T) {
|
|||||||
if err == nil {
|
if err == nil {
|
||||||
t.Fatalf("expected bob to fail receiving alice's signature")
|
t.Fatalf("expected bob to fail receiving alice's signature")
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestUpdateFeeConcurrentSig tests that the channel can properly handle a fee
|
// TestUpdateFeeConcurrentSig tests that the channel can properly handle a fee
|
||||||
@ -2547,7 +2545,6 @@ func TestUpdateFeeSenderCommits(t *testing.T) {
|
|||||||
// Bob receives revocation from Alice.
|
// Bob receives revocation from Alice.
|
||||||
_, _, _, _, err = bobChannel.ReceiveRevocation(aliceRevocation)
|
_, _, _, _, err = bobChannel.ReceiveRevocation(aliceRevocation)
|
||||||
require.NoError(t, err, "bob unable to process alice's revocation")
|
require.NoError(t, err, "bob unable to process alice's revocation")
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestUpdateFeeReceiverCommits tests that the state machine progresses as
|
// TestUpdateFeeReceiverCommits tests that the state machine progresses as
|
||||||
@ -2857,8 +2854,8 @@ func TestAddHTLCNegativeBalance(t *testing.T) {
|
|||||||
// two channels conclude that they're fully synchronized and don't need to
|
// two channels conclude that they're fully synchronized and don't need to
|
||||||
// retransmit any new messages.
|
// retransmit any new messages.
|
||||||
func assertNoChanSyncNeeded(t *testing.T, aliceChannel *LightningChannel,
|
func assertNoChanSyncNeeded(t *testing.T, aliceChannel *LightningChannel,
|
||||||
bobChannel *LightningChannel) {
|
bobChannel *LightningChannel,
|
||||||
|
) {
|
||||||
_, _, line, _ := runtime.Caller(1)
|
_, _, line, _ := runtime.Caller(1)
|
||||||
|
|
||||||
aliceChanSyncMsg, err := aliceChannel.channelState.ChanSyncMsg()
|
aliceChanSyncMsg, err := aliceChannel.channelState.ChanSyncMsg()
|
||||||
@ -3007,19 +3004,11 @@ func restartChannel(channelOld *LightningChannel) (*LightningChannel, error) {
|
|||||||
return channelNew, nil
|
return channelNew, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestChanSyncOweCommitment tests that if Bob restarts (and then Alice) before
|
func testChanSyncOweCommitment(t *testing.T, chanType channeldb.ChannelType) {
|
||||||
// he receives Alice's CommitSig message, then Alice concludes that she needs
|
|
||||||
// to re-send the CommitDiff. After the diff has been sent, both nodes should
|
|
||||||
// resynchronize and be able to complete the dangling commit.
|
|
||||||
func TestChanSyncOweCommitment(t *testing.T) {
|
|
||||||
t.Parallel()
|
|
||||||
|
|
||||||
// Create a test channel which will be used for the duration of this
|
// Create a test channel which will be used for the duration of this
|
||||||
// unittest. The channel will be funded evenly with Alice having 5 BTC,
|
// unittest. The channel will be funded evenly with Alice having 5 BTC,
|
||||||
// and Bob having 5 BTC.
|
// and Bob having 5 BTC.
|
||||||
aliceChannel, bobChannel, err := CreateTestChannels(
|
aliceChannel, bobChannel, err := CreateTestChannels(t, chanType)
|
||||||
t, channeldb.SingleFunderTweaklessBit,
|
|
||||||
)
|
|
||||||
require.NoError(t, err, "unable to create test channels")
|
require.NoError(t, err, "unable to create test channels")
|
||||||
|
|
||||||
var fakeOnionBlob [lnwire.OnionPacketSize]byte
|
var fakeOnionBlob [lnwire.OnionPacketSize]byte
|
||||||
@ -3094,6 +3083,15 @@ func TestChanSyncOweCommitment(t *testing.T) {
|
|||||||
aliceNewCommit, err := aliceChannel.SignNextCommitment()
|
aliceNewCommit, err := aliceChannel.SignNextCommitment()
|
||||||
require.NoError(t, err, "unable to sign commitment")
|
require.NoError(t, err, "unable to sign commitment")
|
||||||
|
|
||||||
|
// If this is a taproot channel, then we'll generate fresh verification
|
||||||
|
// nonce for both sides.
|
||||||
|
if chanType.IsTaproot() {
|
||||||
|
_, err = aliceChannel.GenMusigNonces()
|
||||||
|
require.NoError(t, err)
|
||||||
|
_, err = bobChannel.GenMusigNonces()
|
||||||
|
require.NoError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
// Bob doesn't get this message so upon reconnection, they need to
|
// Bob doesn't get this message so upon reconnection, they need to
|
||||||
// synchronize. Alice should conclude that she owes Bob a commitment,
|
// synchronize. Alice should conclude that she owes Bob a commitment,
|
||||||
// while Bob should think he's properly synchronized.
|
// while Bob should think he's properly synchronized.
|
||||||
@ -3105,7 +3103,7 @@ func TestChanSyncOweCommitment(t *testing.T) {
|
|||||||
// This is a helper function that asserts Alice concludes that she
|
// This is a helper function that asserts Alice concludes that she
|
||||||
// needs to retransmit the exact commitment that we failed to send
|
// needs to retransmit the exact commitment that we failed to send
|
||||||
// above.
|
// above.
|
||||||
assertAliceCommitRetransmit := func() {
|
assertAliceCommitRetransmit := func() *lnwire.CommitSig {
|
||||||
aliceMsgsToSend, _, _, err := aliceChannel.ProcessChanSyncMsg(
|
aliceMsgsToSend, _, _, err := aliceChannel.ProcessChanSyncMsg(
|
||||||
bobSyncMsg,
|
bobSyncMsg,
|
||||||
)
|
)
|
||||||
@ -3170,12 +3168,25 @@ func TestChanSyncOweCommitment(t *testing.T) {
|
|||||||
len(commitSigMsg.HtlcSigs))
|
len(commitSigMsg.HtlcSigs))
|
||||||
}
|
}
|
||||||
for i, htlcSig := range commitSigMsg.HtlcSigs {
|
for i, htlcSig := range commitSigMsg.HtlcSigs {
|
||||||
if htlcSig != aliceNewCommit.HtlcSigs[i] {
|
if !bytes.Equal(htlcSig.RawBytes(),
|
||||||
|
aliceNewCommit.HtlcSigs[i].RawBytes()) {
|
||||||
|
|
||||||
t.Fatalf("htlc sig msgs don't match: "+
|
t.Fatalf("htlc sig msgs don't match: "+
|
||||||
"expected %x got %x",
|
"expected %v got %v",
|
||||||
aliceNewCommit.HtlcSigs[i], htlcSig)
|
spew.Sdump(aliceNewCommit.HtlcSigs[i]),
|
||||||
|
spew.Sdump(htlcSig))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If this is a taproot channel, then partial sig information
|
||||||
|
// should be present in the commit sig sent over. This
|
||||||
|
// signature will be re-regenerated, so we can't compare it
|
||||||
|
// with the old one.
|
||||||
|
if chanType.IsTaproot() {
|
||||||
|
require.True(t, commitSigMsg.PartialSig.IsSome())
|
||||||
|
}
|
||||||
|
|
||||||
|
return commitSigMsg
|
||||||
}
|
}
|
||||||
|
|
||||||
// Alice should detect that she needs to re-send 5 messages: the 3
|
// Alice should detect that she needs to re-send 5 messages: the 3
|
||||||
@ -3196,14 +3207,19 @@ func TestChanSyncOweCommitment(t *testing.T) {
|
|||||||
// send the exact same set of messages.
|
// send the exact same set of messages.
|
||||||
aliceChannel, err = restartChannel(aliceChannel)
|
aliceChannel, err = restartChannel(aliceChannel)
|
||||||
require.NoError(t, err, "unable to restart alice")
|
require.NoError(t, err, "unable to restart alice")
|
||||||
assertAliceCommitRetransmit()
|
|
||||||
|
|
||||||
// TODO(roasbeef): restart bob as well???
|
// To properly simulate a restart, we'll use the *new* signature that
|
||||||
|
// would send in an actual p2p setting.
|
||||||
|
aliceReCommitSig := assertAliceCommitRetransmit()
|
||||||
|
|
||||||
// At this point, we should be able to resume the prior state update
|
// At this point, we should be able to resume the prior state update
|
||||||
// without any issues, resulting in Alice settling the 3 htlc's, and
|
// without any issues, resulting in Alice settling the 3 htlc's, and
|
||||||
// adding one of her own.
|
// adding one of her own.
|
||||||
err = bobChannel.ReceiveNewCommitment(aliceNewCommit.CommitSigs)
|
err = bobChannel.ReceiveNewCommitment(&CommitSigs{
|
||||||
|
CommitSig: aliceReCommitSig.CommitSig,
|
||||||
|
HtlcSigs: aliceReCommitSig.HtlcSigs,
|
||||||
|
PartialSig: aliceReCommitSig.PartialSig,
|
||||||
|
})
|
||||||
require.NoError(t, err, "bob unable to process alice's commitment")
|
require.NoError(t, err, "bob unable to process alice's commitment")
|
||||||
bobRevocation, _, _, err := bobChannel.RevokeCurrentCommitment()
|
bobRevocation, _, _, err := bobChannel.RevokeCurrentCommitment()
|
||||||
require.NoError(t, err, "unable to revoke bob commitment")
|
require.NoError(t, err, "unable to revoke bob commitment")
|
||||||
@ -3290,16 +3306,46 @@ func TestChanSyncOweCommitment(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestChanSyncOweCommitmentPendingRemote asserts that local updates are applied
|
// TestChanSyncOweCommitment tests that if Bob restarts (and then Alice) before
|
||||||
// to the remote commit across restarts.
|
// he receives Alice's CommitSig message, then Alice concludes that she needs
|
||||||
func TestChanSyncOweCommitmentPendingRemote(t *testing.T) {
|
// to re-send the CommitDiff. After the diff has been sent, both nodes should
|
||||||
|
// resynchronize and be able to complete the dangling commit.
|
||||||
|
func TestChanSyncOweCommitment(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
testCases := []struct {
|
||||||
|
name string
|
||||||
|
chanType channeldb.ChannelType
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "tweakless",
|
||||||
|
chanType: channeldb.SingleFunderTweaklessBit,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "anchors",
|
||||||
|
chanType: channeldb.SingleFunderTweaklessBit |
|
||||||
|
channeldb.AnchorOutputsBit,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "taproot",
|
||||||
|
chanType: channeldb.SingleFunderTweaklessBit |
|
||||||
|
channeldb.AnchorOutputsBit |
|
||||||
|
channeldb.SimpleTaprootFeatureBit,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tc := range testCases {
|
||||||
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
|
testChanSyncOweCommitment(t, tc.chanType)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func testChanSyncOweCommitmentPendingRemote(t *testing.T,
|
||||||
|
chanType channeldb.ChannelType,
|
||||||
|
) {
|
||||||
// Create a test channel which will be used for the duration of this
|
// Create a test channel which will be used for the duration of this
|
||||||
// unittest.
|
// unittest.
|
||||||
aliceChannel, bobChannel, err := CreateTestChannels(
|
aliceChannel, bobChannel, err := CreateTestChannels(t, chanType)
|
||||||
t, channeldb.SingleFunderTweaklessBit,
|
|
||||||
)
|
|
||||||
require.NoError(t, err, "unable to create test channels")
|
require.NoError(t, err, "unable to create test channels")
|
||||||
|
|
||||||
var fakeOnionBlob [lnwire.OnionPacketSize]byte
|
var fakeOnionBlob [lnwire.OnionPacketSize]byte
|
||||||
@ -3382,6 +3428,12 @@ func TestChanSyncOweCommitmentPendingRemote(t *testing.T) {
|
|||||||
bobChannel, err = restartChannel(bobChannel)
|
bobChannel, err = restartChannel(bobChannel)
|
||||||
require.NoError(t, err, "unable to restart bob")
|
require.NoError(t, err, "unable to restart bob")
|
||||||
|
|
||||||
|
// If this is a taproot channel, then since Bob just restarted, we need
|
||||||
|
// to exchange nonces once again.
|
||||||
|
if chanType.IsTaproot() {
|
||||||
|
require.NoError(t, initMusigNonce(aliceChannel, bobChannel))
|
||||||
|
}
|
||||||
|
|
||||||
// Bob signs the commitment he owes.
|
// Bob signs the commitment he owes.
|
||||||
bobNewCommit, err := bobChannel.SignNextCommitment()
|
bobNewCommit, err := bobChannel.SignNextCommitment()
|
||||||
require.NoError(t, err, "unable to sign commitment")
|
require.NoError(t, err, "unable to sign commitment")
|
||||||
@ -3407,6 +3459,38 @@ func TestChanSyncOweCommitmentPendingRemote(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestChanSyncOweCommitmentPendingRemote asserts that local updates are applied
|
||||||
|
// to the remote commit across restarts.
|
||||||
|
func TestChanSyncOweCommitmentPendingRemote(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
testCases := []struct {
|
||||||
|
name string
|
||||||
|
chanType channeldb.ChannelType
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "tweakless",
|
||||||
|
chanType: channeldb.SingleFunderTweaklessBit,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "anchors",
|
||||||
|
chanType: channeldb.SingleFunderTweaklessBit |
|
||||||
|
channeldb.AnchorOutputsBit,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "taproot",
|
||||||
|
chanType: channeldb.SingleFunderTweaklessBit |
|
||||||
|
channeldb.AnchorOutputsBit |
|
||||||
|
channeldb.SimpleTaprootFeatureBit,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tc := range testCases {
|
||||||
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
|
testChanSyncOweCommitmentPendingRemote(t, tc.chanType)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// testChanSyncOweRevocation is the internal version of
|
// testChanSyncOweRevocation is the internal version of
|
||||||
// TestChanSyncOweRevocation that is parameterized based on the type of channel
|
// TestChanSyncOweRevocation that is parameterized based on the type of channel
|
||||||
// being used in the test.
|
// being used in the test.
|
||||||
@ -3556,8 +3640,6 @@ func testChanSyncOweRevocation(t *testing.T, chanType channeldb.ChannelType) {
|
|||||||
|
|
||||||
assertAliceOwesRevoke()
|
assertAliceOwesRevoke()
|
||||||
|
|
||||||
// TODO(roasbeef): restart bob too???
|
|
||||||
|
|
||||||
// We'll continue by then allowing bob to process Alice's revocation
|
// We'll continue by then allowing bob to process Alice's revocation
|
||||||
// message.
|
// message.
|
||||||
_, _, _, _, err = bobChannel.ReceiveRevocation(aliceRevocation)
|
_, _, _, _, err = bobChannel.ReceiveRevocation(aliceRevocation)
|
||||||
@ -3606,11 +3688,19 @@ func TestChanSyncOweRevocation(t *testing.T) {
|
|||||||
|
|
||||||
testChanSyncOweRevocation(t, taprootBits)
|
testChanSyncOweRevocation(t, taprootBits)
|
||||||
})
|
})
|
||||||
|
t.Run("taproot", func(t *testing.T) {
|
||||||
|
taprootBits := channeldb.SimpleTaprootFeatureBit |
|
||||||
|
channeldb.AnchorOutputsBit |
|
||||||
|
channeldb.ZeroHtlcTxFeeBit |
|
||||||
|
channeldb.SingleFunderTweaklessBit
|
||||||
|
|
||||||
|
testChanSyncOweRevocation(t, taprootBits)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func testChanSyncOweRevocationAndCommit(t *testing.T,
|
func testChanSyncOweRevocationAndCommit(t *testing.T,
|
||||||
chanType channeldb.ChannelType) {
|
chanType channeldb.ChannelType,
|
||||||
|
) {
|
||||||
// Create a test channel which will be used for the duration of this
|
// Create a test channel which will be used for the duration of this
|
||||||
// unittest. The channel will be funded evenly with Alice having 5 BTC,
|
// unittest. The channel will be funded evenly with Alice having 5 BTC,
|
||||||
// and Bob having 5 BTC.
|
// and Bob having 5 BTC.
|
||||||
@ -3735,6 +3825,14 @@ func testChanSyncOweRevocationAndCommit(t *testing.T,
|
|||||||
bobNewCommit.HtlcSigs[i])
|
bobNewCommit.HtlcSigs[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If this is a taproot channel, then partial sig information
|
||||||
|
// should be present in the commit sig sent over. This
|
||||||
|
// signature will be re-regenerated, so we can't compare it
|
||||||
|
// with the old one.
|
||||||
|
if chanType.IsTaproot() {
|
||||||
|
require.True(t, bobReCommitSigMsg.PartialSig.IsSome())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// We expect Bob to send exactly two messages: first his revocation
|
// We expect Bob to send exactly two messages: first his revocation
|
||||||
@ -3794,8 +3892,8 @@ func TestChanSyncOweRevocationAndCommit(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func testChanSyncOweRevocationAndCommitForceTransition(t *testing.T,
|
func testChanSyncOweRevocationAndCommitForceTransition(t *testing.T,
|
||||||
chanType channeldb.ChannelType) {
|
chanType channeldb.ChannelType,
|
||||||
|
) {
|
||||||
// Create a test channel which will be used for the duration of this
|
// Create a test channel which will be used for the duration of this
|
||||||
// unittest. The channel will be funded evenly with Alice having 5 BTC,
|
// unittest. The channel will be funded evenly with Alice having 5 BTC,
|
||||||
// and Bob having 5 BTC.
|
// and Bob having 5 BTC.
|
||||||
@ -4803,8 +4901,8 @@ func TestChanAvailableBandwidth(t *testing.T) {
|
|||||||
)
|
)
|
||||||
|
|
||||||
assertBandwidthEstimateCorrect := func(aliceInitiate bool,
|
assertBandwidthEstimateCorrect := func(aliceInitiate bool,
|
||||||
numNonDustHtlcsOnCommit lntypes.WeightUnit) {
|
numNonDustHtlcsOnCommit lntypes.WeightUnit,
|
||||||
|
) {
|
||||||
// With the HTLC's added, we'll now query the AvailableBalance
|
// With the HTLC's added, we'll now query the AvailableBalance
|
||||||
// method for the current available channel bandwidth from
|
// method for the current available channel bandwidth from
|
||||||
// Alice's PoV.
|
// Alice's PoV.
|
||||||
@ -4976,8 +5074,8 @@ func TestChanAvailableBalanceNearHtlcFee(t *testing.T) {
|
|||||||
|
|
||||||
// Helper method to check the current reported balance.
|
// Helper method to check the current reported balance.
|
||||||
checkBalance := func(t *testing.T, expBalanceAlice,
|
checkBalance := func(t *testing.T, expBalanceAlice,
|
||||||
expBalanceBob lnwire.MilliSatoshi) {
|
expBalanceBob lnwire.MilliSatoshi,
|
||||||
|
) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
aliceBalance := aliceChannel.AvailableBalance()
|
aliceBalance := aliceChannel.AvailableBalance()
|
||||||
if aliceBalance != expBalanceAlice {
|
if aliceBalance != expBalanceAlice {
|
||||||
@ -6248,8 +6346,8 @@ func TestMaxPendingAmount(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func assertChannelBalances(t *testing.T, alice, bob *LightningChannel,
|
func assertChannelBalances(t *testing.T, alice, bob *LightningChannel,
|
||||||
aliceBalance, bobBalance btcutil.Amount) {
|
aliceBalance, bobBalance btcutil.Amount,
|
||||||
|
) {
|
||||||
_, _, line, _ := runtime.Caller(1)
|
_, _, line, _ := runtime.Caller(1)
|
||||||
|
|
||||||
aliceSelfBalance := alice.channelState.LocalCommitment.LocalBalance.ToSatoshis()
|
aliceSelfBalance := alice.channelState.LocalCommitment.LocalBalance.ToSatoshis()
|
||||||
@ -6940,7 +7038,8 @@ func assertInLog(t *testing.T, log *updateLog, numAdds, numFails int) {
|
|||||||
// assertInLogs asserts that the expected number of Adds and Fails occurs in
|
// assertInLogs asserts that the expected number of Adds and Fails occurs in
|
||||||
// the local and remote update log of the given channel.
|
// the local and remote update log of the given channel.
|
||||||
func assertInLogs(t *testing.T, channel *LightningChannel, numAddsLocal,
|
func assertInLogs(t *testing.T, channel *LightningChannel, numAddsLocal,
|
||||||
numFailsLocal, numAddsRemote, numFailsRemote int) {
|
numFailsLocal, numAddsRemote, numFailsRemote int,
|
||||||
|
) {
|
||||||
assertInLog(t, channel.localUpdateLog, numAddsLocal, numFailsLocal)
|
assertInLog(t, channel.localUpdateLog, numAddsLocal, numFailsLocal)
|
||||||
assertInLog(t, channel.remoteUpdateLog, numAddsRemote, numFailsRemote)
|
assertInLog(t, channel.remoteUpdateLog, numAddsRemote, numFailsRemote)
|
||||||
}
|
}
|
||||||
@ -6949,8 +7048,8 @@ func assertInLogs(t *testing.T, channel *LightningChannel, numAddsLocal,
|
|||||||
// state, and asserts that the new channel has had its logs restored to the
|
// state, and asserts that the new channel has had its logs restored to the
|
||||||
// expected state.
|
// expected state.
|
||||||
func restoreAndAssert(t *testing.T, channel *LightningChannel, numAddsLocal,
|
func restoreAndAssert(t *testing.T, channel *LightningChannel, numAddsLocal,
|
||||||
numFailsLocal, numAddsRemote, numFailsRemote int) {
|
numFailsLocal, numAddsRemote, numFailsRemote int,
|
||||||
|
) {
|
||||||
newChannel, err := NewLightningChannel(
|
newChannel, err := NewLightningChannel(
|
||||||
channel.Signer, channel.channelState,
|
channel.Signer, channel.channelState,
|
||||||
channel.sigPool,
|
channel.sigPool,
|
||||||
@ -7211,8 +7310,8 @@ func TestChannelRestoreCommitHeight(t *testing.T) {
|
|||||||
// log after a restore.
|
// log after a restore.
|
||||||
restoreAndAssertCommitHeights := func(t *testing.T,
|
restoreAndAssertCommitHeights := func(t *testing.T,
|
||||||
channel *LightningChannel, remoteLog bool, htlcIndex uint64,
|
channel *LightningChannel, remoteLog bool, htlcIndex uint64,
|
||||||
expLocal, expRemote uint64) *LightningChannel {
|
expLocal, expRemote uint64,
|
||||||
|
) *LightningChannel {
|
||||||
newChannel, err := NewLightningChannel(
|
newChannel, err := NewLightningChannel(
|
||||||
channel.Signer, channel.channelState, channel.sigPool,
|
channel.Signer, channel.channelState, channel.sigPool,
|
||||||
)
|
)
|
||||||
@ -7667,10 +7766,9 @@ func TestIdealCommitFeeRate(t *testing.T) {
|
|||||||
// inputs fed to IdealCommitFeeRate.
|
// inputs fed to IdealCommitFeeRate.
|
||||||
propertyTest := func(c *LightningChannel) func(ma maxAlloc,
|
propertyTest := func(c *LightningChannel) func(ma maxAlloc,
|
||||||
netFee, minRelayFee, maxAnchorFee fee) bool {
|
netFee, minRelayFee, maxAnchorFee fee) bool {
|
||||||
|
|
||||||
return func(ma maxAlloc, netFee, minRelayFee,
|
return func(ma maxAlloc, netFee, minRelayFee,
|
||||||
maxAnchorFee fee) bool {
|
maxAnchorFee fee,
|
||||||
|
) bool {
|
||||||
idealFeeRate := c.IdealCommitFeeRate(
|
idealFeeRate := c.IdealCommitFeeRate(
|
||||||
chainfee.SatPerKWeight(netFee),
|
chainfee.SatPerKWeight(netFee),
|
||||||
chainfee.SatPerKWeight(minRelayFee),
|
chainfee.SatPerKWeight(minRelayFee),
|
||||||
@ -7715,8 +7813,8 @@ func TestIdealCommitFeeRate(t *testing.T) {
|
|||||||
// a channel is allowed to allocate to fees. It does not take a minimum
|
// a channel is allowed to allocate to fees. It does not take a minimum
|
||||||
// fee rate into account.
|
// fee rate into account.
|
||||||
maxFeeRate := func(c *LightningChannel,
|
maxFeeRate := func(c *LightningChannel,
|
||||||
maxFeeAlloc float64) chainfee.SatPerKWeight {
|
maxFeeAlloc float64,
|
||||||
|
) chainfee.SatPerKWeight {
|
||||||
balance, weight := c.availableBalance(AdditionalHtlc)
|
balance, weight := c.availableBalance(AdditionalHtlc)
|
||||||
feeRate := c.localCommitChain.tip().feePerKw
|
feeRate := c.localCommitChain.tip().feePerKw
|
||||||
currentFee := feeRate.FeeForWeight(weight)
|
currentFee := feeRate.FeeForWeight(weight)
|
||||||
@ -7885,8 +7983,8 @@ func TestIdealCommitFeeRate(t *testing.T) {
|
|||||||
|
|
||||||
assertIdealFeeRate := func(c *LightningChannel, netFee, minRelay,
|
assertIdealFeeRate := func(c *LightningChannel, netFee, minRelay,
|
||||||
maxAnchorCommit chainfee.SatPerKWeight,
|
maxAnchorCommit chainfee.SatPerKWeight,
|
||||||
maxFeeAlloc float64, expectedFeeRate chainfee.SatPerKWeight) {
|
maxFeeAlloc float64, expectedFeeRate chainfee.SatPerKWeight,
|
||||||
|
) {
|
||||||
feeRate := c.IdealCommitFeeRate(
|
feeRate := c.IdealCommitFeeRate(
|
||||||
netFee, minRelay, maxAnchorCommit, maxFeeAlloc,
|
netFee, minRelay, maxAnchorCommit, maxFeeAlloc,
|
||||||
)
|
)
|
||||||
@ -8582,8 +8680,8 @@ func TestEvaluateView(t *testing.T) {
|
|||||||
// checkExpectedHtlcs checks that a set of htlcs that we have contains all the
|
// checkExpectedHtlcs checks that a set of htlcs that we have contains all the
|
||||||
// htlcs we expect.
|
// htlcs we expect.
|
||||||
func checkExpectedHtlcs(t *testing.T, actual []*PaymentDescriptor,
|
func checkExpectedHtlcs(t *testing.T, actual []*PaymentDescriptor,
|
||||||
expected map[uint64]bool) {
|
expected map[uint64]bool,
|
||||||
|
) {
|
||||||
if len(expected) != len(actual) {
|
if len(expected) != len(actual) {
|
||||||
t.Fatalf("expected: %v htlcs, got: %v",
|
t.Fatalf("expected: %v htlcs, got: %v",
|
||||||
len(expected), len(actual))
|
len(expected), len(actual))
|
||||||
@ -9178,13 +9276,11 @@ func TestProcessAddRemoveEntry(t *testing.T) {
|
|||||||
EntryType: test.updateType,
|
EntryType: test.updateType,
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
|
||||||
// Start both parties off with an initial
|
// Start both parties off with an initial
|
||||||
// balance. Copy by value here so that we do
|
// balance. Copy by value here so that we do
|
||||||
// not mutate the startBalance constant.
|
// not mutate the startBalance constant.
|
||||||
ourBalance, theirBalance = startBalance,
|
ourBalance, theirBalance := startBalance,
|
||||||
startBalance
|
startBalance
|
||||||
)
|
|
||||||
|
|
||||||
// Choose the processing function we need based on the
|
// Choose the processing function we need based on the
|
||||||
// update type. Process remove is used for settles,
|
// update type. Process remove is used for settles,
|
||||||
@ -9710,8 +9806,8 @@ func TestIsChannelClean(t *testing.T) {
|
|||||||
// assertCleanOrDirty is a helper function that asserts that both channels are
|
// assertCleanOrDirty is a helper function that asserts that both channels are
|
||||||
// clean if clean is true, and dirty if clean is false.
|
// clean if clean is true, and dirty if clean is false.
|
||||||
func assertCleanOrDirty(clean bool, alice, bob *LightningChannel,
|
func assertCleanOrDirty(clean bool, alice, bob *LightningChannel,
|
||||||
t *testing.T) {
|
t *testing.T,
|
||||||
|
) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
|
|
||||||
if clean {
|
if clean {
|
||||||
@ -9749,8 +9845,8 @@ func testGetDustSum(t *testing.T, chantype channeldb.ChannelType) {
|
|||||||
// Use a function closure to assert the dust sum for a passed channel's
|
// Use a function closure to assert the dust sum for a passed channel's
|
||||||
// local and remote commitments match the expected values.
|
// local and remote commitments match the expected values.
|
||||||
checkDust := func(c *LightningChannel, expLocal,
|
checkDust := func(c *LightningChannel, expLocal,
|
||||||
expRemote lnwire.MilliSatoshi) {
|
expRemote lnwire.MilliSatoshi,
|
||||||
|
) {
|
||||||
localDustSum := c.GetDustSum(
|
localDustSum := c.GetDustSum(
|
||||||
lntypes.Local, fn.None[chainfee.SatPerKWeight](),
|
lntypes.Local, fn.None[chainfee.SatPerKWeight](),
|
||||||
)
|
)
|
||||||
@ -9905,8 +10001,8 @@ func testGetDustSum(t *testing.T, chantype channeldb.ChannelType) {
|
|||||||
// deriveDummyRetributionParams is a helper function that derives a list of
|
// deriveDummyRetributionParams is a helper function that derives a list of
|
||||||
// dummy params to assist retribution creation related tests.
|
// dummy params to assist retribution creation related tests.
|
||||||
func deriveDummyRetributionParams(chanState *channeldb.OpenChannel) (uint32,
|
func deriveDummyRetributionParams(chanState *channeldb.OpenChannel) (uint32,
|
||||||
*CommitmentKeyRing, chainhash.Hash) {
|
*CommitmentKeyRing, chainhash.Hash,
|
||||||
|
) {
|
||||||
config := chanState.RemoteChanCfg
|
config := chanState.RemoteChanCfg
|
||||||
commitHash := chanState.RemoteCommitment.CommitTx.TxHash()
|
commitHash := chanState.RemoteCommitment.CommitTx.TxHash()
|
||||||
keyRing := DeriveCommitmentKeys(
|
keyRing := DeriveCommitmentKeys(
|
||||||
@ -10283,8 +10379,8 @@ func testNewBreachRetribution(t *testing.T, chanType channeldb.ChannelType) {
|
|||||||
// assertRetribution is a helper closure that checks a given breach
|
// assertRetribution is a helper closure that checks a given breach
|
||||||
// retribution has the expected values on certain fields.
|
// retribution has the expected values on certain fields.
|
||||||
assertRetribution := func(br *BreachRetribution,
|
assertRetribution := func(br *BreachRetribution,
|
||||||
localIndex, remoteIndex uint32) {
|
localIndex, remoteIndex uint32,
|
||||||
|
) {
|
||||||
require.Equal(t, txid, br.BreachTxHash)
|
require.Equal(t, txid, br.BreachTxHash)
|
||||||
require.Equal(t, chainHash, br.ChainHash)
|
require.Equal(t, chainHash, br.ChainHash)
|
||||||
require.Equal(t, breachHeight, br.BreachHeight)
|
require.Equal(t, breachHeight, br.BreachHeight)
|
||||||
@ -10399,8 +10495,8 @@ func TestExtractPayDescs(t *testing.T) {
|
|||||||
// assertPayDescMatchHTLC compares a PaymentDescriptor to a channeldb.HTLC and
|
// assertPayDescMatchHTLC compares a PaymentDescriptor to a channeldb.HTLC and
|
||||||
// asserts that the fields are matched.
|
// asserts that the fields are matched.
|
||||||
func assertPayDescMatchHTLC(t *testing.T, pd PaymentDescriptor,
|
func assertPayDescMatchHTLC(t *testing.T, pd PaymentDescriptor,
|
||||||
htlc channeldb.HTLC) {
|
htlc channeldb.HTLC,
|
||||||
|
) {
|
||||||
require := require.New(t)
|
require := require.New(t)
|
||||||
|
|
||||||
require.EqualValues(htlc.RHash, pd.RHash, "RHash")
|
require.EqualValues(htlc.RHash, pd.RHash, "RHash")
|
||||||
|
@ -419,14 +419,9 @@ func CreateTestChannels(t *testing.T, chanType channeldb.ChannelType,
|
|||||||
return channelAlice, channelBob, nil
|
return channelAlice, channelBob, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// initRevocationWindows simulates a new channel being opened within the p2p
|
// initMusigNonce is used to manually setup musig2 nonces for a new channel,
|
||||||
// network by populating the initial revocation windows of the passed
|
// outside the normal chan-reest flow.
|
||||||
// commitment state machines.
|
func initMusigNonce(chanA, chanB *LightningChannel) error {
|
||||||
func initRevocationWindows(chanA, chanB *LightningChannel) error {
|
|
||||||
// If these are taproot chanenls, then we need to also simulate sending
|
|
||||||
// either FundingLocked or ChannelReestablish by calling
|
|
||||||
// InitRemoteMusigNonces for both sides.
|
|
||||||
if chanA.channelState.ChanType.IsTaproot() {
|
|
||||||
chanANonces, err := chanA.GenMusigNonces()
|
chanANonces, err := chanA.GenMusigNonces()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -442,6 +437,21 @@ func initRevocationWindows(chanA, chanB *LightningChannel) error {
|
|||||||
if err := chanB.InitRemoteMusigNonces(chanANonces); err != nil {
|
if err := chanB.InitRemoteMusigNonces(chanANonces); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// initRevocationWindows simulates a new channel being opened within the p2p
|
||||||
|
// network by populating the initial revocation windows of the passed
|
||||||
|
// commitment state machines.
|
||||||
|
func initRevocationWindows(chanA, chanB *LightningChannel) error {
|
||||||
|
// If these are taproot chanenls, then we need to also simulate sending
|
||||||
|
// either FundingLocked or ChannelReestablish by calling
|
||||||
|
// InitRemoteMusigNonces for both sides.
|
||||||
|
if chanA.channelState.ChanType.IsTaproot() {
|
||||||
|
if err := initMusigNonce(chanA, chanB); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
aliceNextRevoke, err := chanA.NextRevocationKey()
|
aliceNextRevoke, err := chanA.NextRevocationKey()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user