Merge pull request #3401 from wpaulino/channel-initiator-max-fee
htlcswitch: avoid proposing fee updates exceeding max fee allowed
This commit is contained in:
6 files changed
+125
-56
No files matched your search
+72
-51
@@ -1686,6 +1686,7 @@ func newSingleLinkTestHarness(chanAmt, chanReserve btcutil.Amount) (
|
||||
MinFeeUpdateTimeout: 30 * time.Minute,
|
||||
MaxFeeUpdateTimeout: 40 * time.Minute,
|
||||
MaxOutgoingCltvExpiry: DefaultMaxOutgoingCltvExpiry,
|
||||
MaxFeeAllocation: DefaultMaxLinkFeeAllocation,
|
||||
}
|
||||
|
||||
const startingHeight = 100
|
||||
@@ -3736,9 +3737,10 @@ func TestChannelLinkUpdateCommitFee(t *testing.T) {
|
||||
// First, we'll create our traditional three hop network. We'll only be
|
||||
// interacting with and asserting the state of two of the end points
|
||||
// for this test.
|
||||
const aliceInitialBalance = btcutil.SatoshiPerBitcoin * 3
|
||||
channels, cleanUp, _, err := createClusterChannels(
|
||||
btcutil.SatoshiPerBitcoin*3,
|
||||
btcutil.SatoshiPerBitcoin*5)
|
||||
aliceInitialBalance, btcutil.SatoshiPerBitcoin*5,
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to create channel: %v", err)
|
||||
}
|
||||
@@ -3757,8 +3759,15 @@ func TestChannelLinkUpdateCommitFee(t *testing.T) {
|
||||
{"alice", "bob", &lnwire.FundingLocked{}, false},
|
||||
{"bob", "alice", &lnwire.FundingLocked{}, false},
|
||||
|
||||
// First fee update.
|
||||
{"alice", "bob", &lnwire.UpdateFee{}, false},
|
||||
{"alice", "bob", &lnwire.CommitSig{}, false},
|
||||
{"bob", "alice", &lnwire.RevokeAndAck{}, false},
|
||||
{"bob", "alice", &lnwire.CommitSig{}, false},
|
||||
{"alice", "bob", &lnwire.RevokeAndAck{}, false},
|
||||
|
||||
// Second fee update.
|
||||
{"alice", "bob", &lnwire.UpdateFee{}, false},
|
||||
{"alice", "bob", &lnwire.CommitSig{}, false},
|
||||
{"bob", "alice", &lnwire.RevokeAndAck{}, false},
|
||||
{"bob", "alice", &lnwire.CommitSig{}, false},
|
||||
@@ -3775,62 +3784,73 @@ func TestChannelLinkUpdateCommitFee(t *testing.T) {
|
||||
defer n.stop()
|
||||
defer n.feeEstimator.Stop()
|
||||
|
||||
// For the sake of this test, we'll reset the timer to fire in a second
|
||||
// so that Alice's link queries for a new network fee.
|
||||
n.aliceChannelLink.updateFeeTimer.Reset(time.Millisecond)
|
||||
|
||||
startingFeeRate := channels.aliceToBob.CommitFeeRate()
|
||||
|
||||
// Next, we'll send the first fee rate response to Alice.
|
||||
select {
|
||||
case n.feeEstimator.byteFeeIn <- startingFeeRate:
|
||||
case <-time.After(time.Second * 5):
|
||||
t.Fatalf("alice didn't query for the new network fee")
|
||||
// triggerFeeUpdate is a helper closure to determine whether a fee
|
||||
// update was triggered and completed properly.
|
||||
triggerFeeUpdate := func(feeEstimate, newFeeRate lnwallet.SatPerKWeight,
|
||||
shouldUpdate bool) {
|
||||
|
||||
t.Helper()
|
||||
|
||||
// Record the fee rates before the links process the fee update
|
||||
// to test the case where a fee update isn't triggered.
|
||||
aliceBefore := channels.aliceToBob.CommitFeeRate()
|
||||
bobBefore := channels.bobToAlice.CommitFeeRate()
|
||||
|
||||
// For the sake of this test, we'll reset the timer so that
|
||||
// Alice's link queries for a new network fee.
|
||||
n.aliceChannelLink.updateFeeTimer.Reset(time.Millisecond)
|
||||
|
||||
// Next, we'll send the first fee rate response to Alice.
|
||||
select {
|
||||
case n.feeEstimator.byteFeeIn <- feeEstimate:
|
||||
case <-time.After(time.Second * 5):
|
||||
t.Fatalf("alice didn't query for the new network fee")
|
||||
}
|
||||
|
||||
// Give the links some time to process the fee update.
|
||||
time.Sleep(time.Second)
|
||||
|
||||
// Record the fee rates after the links have processed the fee
|
||||
// update and ensure they are correct based on whether a fee
|
||||
// update should have been triggered.
|
||||
aliceAfter := channels.aliceToBob.CommitFeeRate()
|
||||
bobAfter := channels.bobToAlice.CommitFeeRate()
|
||||
|
||||
switch {
|
||||
case shouldUpdate && aliceAfter != newFeeRate:
|
||||
t.Fatalf("alice's fee rate didn't change: expected %v, "+
|
||||
"got %v", newFeeRate, aliceAfter)
|
||||
|
||||
case shouldUpdate && bobAfter != newFeeRate:
|
||||
t.Fatalf("bob's fee rate didn't change: expected %v, "+
|
||||
"got %v", newFeeRate, bobAfter)
|
||||
|
||||
case !shouldUpdate && aliceAfter != aliceBefore:
|
||||
t.Fatalf("alice's fee rate shouldn't have changed: "+
|
||||
"expected %v, got %v", aliceAfter, aliceAfter)
|
||||
|
||||
case !shouldUpdate && bobAfter != bobBefore:
|
||||
t.Fatalf("bob's fee rate shouldn't have changed: "+
|
||||
"expected %v, got %v", bobBefore, bobAfter)
|
||||
}
|
||||
}
|
||||
|
||||
time.Sleep(time.Second)
|
||||
// Triggering the link to update the fee of the channel with the same
|
||||
// fee rate should not send a fee update.
|
||||
triggerFeeUpdate(startingFeeRate, startingFeeRate, false)
|
||||
|
||||
// The fee rate on the alice <-> bob channel should still be the same
|
||||
// on both sides.
|
||||
aliceFeeRate := channels.aliceToBob.CommitFeeRate()
|
||||
bobFeeRate := channels.bobToAlice.CommitFeeRate()
|
||||
if aliceFeeRate != startingFeeRate {
|
||||
t.Fatalf("alice's fee rate shouldn't have changed: "+
|
||||
"expected %v, got %v", aliceFeeRate, startingFeeRate)
|
||||
}
|
||||
if bobFeeRate != startingFeeRate {
|
||||
t.Fatalf("bob's fee rate shouldn't have changed: "+
|
||||
"expected %v, got %v", bobFeeRate, startingFeeRate)
|
||||
}
|
||||
|
||||
// We'll reset the timer once again to ensure Alice's link queries for a
|
||||
// new network fee.
|
||||
n.aliceChannelLink.updateFeeTimer.Reset(time.Millisecond)
|
||||
|
||||
// Next, we'll set up a deliver a fee rate that's triple the current
|
||||
// fee rate. This should cause the Alice (the initiator) to trigger a
|
||||
// fee update.
|
||||
// Triggering the link to update the fee of the channel with a much
|
||||
// larger fee rate _should_ send a fee update.
|
||||
newFeeRate := startingFeeRate * 3
|
||||
select {
|
||||
case n.feeEstimator.byteFeeIn <- newFeeRate:
|
||||
case <-time.After(time.Second * 5):
|
||||
t.Fatalf("alice didn't query for the new network fee")
|
||||
}
|
||||
triggerFeeUpdate(newFeeRate, newFeeRate, true)
|
||||
|
||||
time.Sleep(time.Second)
|
||||
|
||||
// At this point, Alice should've triggered a new fee update that
|
||||
// increased the fee rate to match the new rate.
|
||||
aliceFeeRate = channels.aliceToBob.CommitFeeRate()
|
||||
bobFeeRate = channels.bobToAlice.CommitFeeRate()
|
||||
if aliceFeeRate != newFeeRate {
|
||||
t.Fatalf("alice's fee rate didn't change: expected %v, got %v",
|
||||
newFeeRate, aliceFeeRate)
|
||||
}
|
||||
if bobFeeRate != newFeeRate {
|
||||
t.Fatalf("bob's fee rate didn't change: expected %v, got %v",
|
||||
newFeeRate, aliceFeeRate)
|
||||
}
|
||||
// Triggering the link to update the fee of the channel with a fee rate
|
||||
// that exceeds its maximum fee allocation should result in a fee rate
|
||||
// corresponding to the maximum fee allocation.
|
||||
const maxFeeRate lnwallet.SatPerKWeight = 207182320
|
||||
triggerFeeUpdate(maxFeeRate+1, maxFeeRate, true)
|
||||
}
|
||||
|
||||
// TestChannelLinkAcceptDuplicatePayment tests that if a link receives an
|
||||
@@ -4232,6 +4252,7 @@ func (h *persistentLinkHarness) restartLink(
|
||||
// Set any hodl flags requested for the new link.
|
||||
HodlMask: hodl.MaskFromFlags(hodlFlags...),
|
||||
MaxOutgoingCltvExpiry: DefaultMaxOutgoingCltvExpiry,
|
||||
MaxFeeAllocation: DefaultMaxLinkFeeAllocation,
|
||||
}
|
||||
|
||||
const startingHeight = 100
|
||||
|
||||
Reference in new issue
Block a user