lnwallet: export ForceStateTransition for tests outside package

In this commit, we export the `ForceStateTransition` for tests outside
the package that need to interact with actual channel state machines.
This commit is contained in:
Olaoluwa Osuntokun 2019-03-12 19:11:09 -07:00
parent 10910318a2
commit 4645fc0c95
2 changed files with 92 additions and 91 deletions

@ -23,45 +23,6 @@ import (
"github.com/lightningnetwork/lnd/lnwire"
)
// forceStateTransition executes the necessary interaction between the two
// commitment state machines to transition to a new state locking in any
// pending updates.
func forceStateTransition(chanA, chanB *LightningChannel) error {
aliceSig, aliceHtlcSigs, err := chanA.SignNextCommitment()
if err != nil {
return err
}
if err = chanB.ReceiveNewCommitment(aliceSig, aliceHtlcSigs); err != nil {
return err
}
bobRevocation, _, err := chanB.RevokeCurrentCommitment()
if err != nil {
return err
}
bobSig, bobHtlcSigs, err := chanB.SignNextCommitment()
if err != nil {
return err
}
if _, _, _, err := chanA.ReceiveRevocation(bobRevocation); err != nil {
return err
}
if err := chanA.ReceiveNewCommitment(bobSig, bobHtlcSigs); err != nil {
return err
}
aliceRevocation, _, err := chanA.RevokeCurrentCommitment()
if err != nil {
return err
}
if _, _, _, err := chanB.ReceiveRevocation(aliceRevocation); err != nil {
return err
}
return nil
}
// createHTLC is a utility function for generating an HTLC with a given
// preimage and a given amount.
func createHTLC(id int, amount lnwire.MilliSatoshi) (*lnwire.UpdateAddHTLC, [32]byte) {
@ -440,7 +401,7 @@ func TestCheckCommitTxSize(t *testing.T) {
t.Fatalf("bob unable to receive htlc: %v", err)
}
if err := forceStateTransition(aliceChannel, bobChannel); err != nil {
if err := ForceStateTransition(aliceChannel, bobChannel); err != nil {
t.Fatalf("unable to complete state update: %v", err)
}
checkSize(aliceChannel, i+1)
@ -462,7 +423,7 @@ func TestCheckCommitTxSize(t *testing.T) {
t.Fatalf("alice unable to accept settle of outbound htlc: %v", err)
}
if err := forceStateTransition(bobChannel, aliceChannel); err != nil {
if err := ForceStateTransition(bobChannel, aliceChannel); err != nil {
t.Fatalf("unable to complete state update: %v", err)
}
checkSize(aliceChannel, i)
@ -576,10 +537,10 @@ func TestForceClose(t *testing.T) {
// Next, we'll perform two state transitions to ensure that both HTLC's
// get fully locked-in.
if err := forceStateTransition(aliceChannel, bobChannel); err != nil {
if err := ForceStateTransition(aliceChannel, bobChannel); err != nil {
t.Fatalf("Can't update the channel state: %v", err)
}
if err := forceStateTransition(bobChannel, aliceChannel); err != nil {
if err := ForceStateTransition(bobChannel, aliceChannel); err != nil {
t.Fatalf("Can't update the channel state: %v", err)
}
@ -862,7 +823,7 @@ func TestForceCloseDustOutput(t *testing.T) {
if err != nil {
t.Fatalf("bob unable to receive htlc: %v", err)
}
if err := forceStateTransition(bobChannel, aliceChannel); err != nil {
if err := ForceStateTransition(bobChannel, aliceChannel); err != nil {
t.Fatalf("Can't update the channel state: %v", err)
}
@ -875,7 +836,7 @@ func TestForceCloseDustOutput(t *testing.T) {
if err != nil {
t.Fatalf("alice unable to accept settle of outbound htlc: %v", err)
}
if err := forceStateTransition(aliceChannel, bobChannel); err != nil {
if err := ForceStateTransition(aliceChannel, bobChannel); err != nil {
t.Fatalf("Can't update the channel state: %v", err)
}
@ -967,7 +928,7 @@ func TestDustHTLCFees(t *testing.T) {
if _, err := bobChannel.ReceiveHTLC(htlc); err != nil {
t.Fatalf("bob unable to receive htlc: %v", err)
}
if err := forceStateTransition(aliceChannel, bobChannel); err != nil {
if err := ForceStateTransition(aliceChannel, bobChannel); err != nil {
t.Fatalf("Can't update the channel state: %v", err)
}
@ -1048,7 +1009,7 @@ func TestHTLCDustLimit(t *testing.T) {
if err != nil {
t.Fatalf("bob unable to receive htlc: %v", err)
}
if err := forceStateTransition(aliceChannel, bobChannel); err != nil {
if err := ForceStateTransition(aliceChannel, bobChannel); err != nil {
t.Fatalf("Can't update the channel state: %v", err)
}
@ -1082,7 +1043,7 @@ func TestHTLCDustLimit(t *testing.T) {
if err != nil {
t.Fatalf("alice unable to accept settle of outbound htlc: %v", err)
}
if err := forceStateTransition(bobChannel, aliceChannel); err != nil {
if err := ForceStateTransition(bobChannel, aliceChannel); err != nil {
t.Fatalf("state transition error: %v", err)
}
@ -1314,7 +1275,7 @@ func TestChannelBalanceDustLimit(t *testing.T) {
if err != nil {
t.Fatalf("bob unable to receive htlc: %v", err)
}
if err := forceStateTransition(aliceChannel, bobChannel); err != nil {
if err := ForceStateTransition(aliceChannel, bobChannel); err != nil {
t.Fatalf("state transition error: %v", err)
}
err = bobChannel.SettleHTLC(preimage, bobHtlcIndex, nil, nil, nil)
@ -1325,7 +1286,7 @@ func TestChannelBalanceDustLimit(t *testing.T) {
if err != nil {
t.Fatalf("alice unable to accept settle of outbound htlc: %v", err)
}
if err := forceStateTransition(bobChannel, aliceChannel); err != nil {
if err := ForceStateTransition(bobChannel, aliceChannel); err != nil {
t.Fatalf("state transition error: %v", err)
}
@ -1439,7 +1400,7 @@ func TestStateUpdatePersistence(t *testing.T) {
// Next, Alice initiates a state transition to include the HTLC's she
// added above in a new commitment state.
if err := forceStateTransition(aliceChannel, bobChannel); err != nil {
if err := ForceStateTransition(aliceChannel, bobChannel); err != nil {
t.Fatalf("unable to complete alice's state transition: %v", err)
}
@ -1447,7 +1408,7 @@ func TestStateUpdatePersistence(t *testing.T) {
// commitment transaction (but it was in Alice's, as he ACK'd her
// changes before creating a new state), Bob needs to trigger another
// state update in order to re-sync their states.
if err := forceStateTransition(bobChannel, aliceChannel); err != nil {
if err := ForceStateTransition(bobChannel, aliceChannel); err != nil {
t.Fatalf("unable to complete bob's state transition: %v", err)
}
@ -1642,10 +1603,10 @@ func TestStateUpdatePersistence(t *testing.T) {
// entries to the update log before a state transition was initiated by
// either side, both sides are required to trigger an update in order
// to lock in their changes.
if err := forceStateTransition(aliceChannelNew, bobChannelNew); err != nil {
if err := ForceStateTransition(aliceChannelNew, bobChannelNew); err != nil {
t.Fatalf("unable to update commitments: %v", err)
}
if err := forceStateTransition(bobChannelNew, aliceChannelNew); err != nil {
if err := ForceStateTransition(bobChannelNew, aliceChannelNew); err != nil {
t.Fatalf("unable to update commitments: %v", err)
}
@ -1720,7 +1681,7 @@ func TestCancelHTLC(t *testing.T) {
if err != nil {
t.Fatalf("unable to add bob htlc: %v", err)
}
if err := forceStateTransition(aliceChannel, bobChannel); err != nil {
if err := ForceStateTransition(aliceChannel, bobChannel); err != nil {
t.Fatalf("unable to create new commitment state: %v", err)
}
@ -1748,7 +1709,7 @@ func TestCancelHTLC(t *testing.T) {
// Now trigger another state transition, the HTLC should now be removed
// from both sides, with balances reflected.
if err := forceStateTransition(bobChannel, aliceChannel); err != nil {
if err := ForceStateTransition(bobChannel, aliceChannel); err != nil {
t.Fatalf("unable to create new commitment: %v", err)
}
@ -1992,7 +1953,7 @@ func TestUpdateFeeAdjustments(t *testing.T) {
// With the fee updates applied, we'll now initiate a state transition
// to ensure the fee update is locked in.
if err := forceStateTransition(aliceChannel, bobChannel); err != nil {
if err := ForceStateTransition(aliceChannel, bobChannel); err != nil {
t.Fatalf("unable to create new commitment: %v", err)
}
@ -2014,7 +1975,7 @@ func TestUpdateFeeAdjustments(t *testing.T) {
if err := bobChannel.ReceiveUpdateFee(newFee); err != nil {
t.Fatalf("unable to bob update fee: %v", err)
}
if err := forceStateTransition(aliceChannel, bobChannel); err != nil {
if err := ForceStateTransition(aliceChannel, bobChannel); err != nil {
t.Fatalf("unable to create new commitment: %v", err)
}
}
@ -2642,7 +2603,7 @@ func TestChanSyncFullySynced(t *testing.T) {
}
// Then we'll initiate a state transition to lock in this new HTLC.
if err := forceStateTransition(aliceChannel, bobChannel); err != nil {
if err := ForceStateTransition(aliceChannel, bobChannel); err != nil {
t.Fatalf("unable to complete alice's state transition: %v", err)
}
@ -2663,7 +2624,7 @@ func TestChanSyncFullySynced(t *testing.T) {
// Next, we'll complete Bob's state transition, and assert again that
// they think they're fully synced.
if err := forceStateTransition(bobChannel, aliceChannel); err != nil {
if err := ForceStateTransition(bobChannel, aliceChannel); err != nil {
t.Fatalf("unable to complete bob's state transition: %v", err)
}
assertNoChanSyncNeeded(t, aliceChannel, bobChannel)
@ -2773,7 +2734,7 @@ func TestChanSyncOweCommitment(t *testing.T) {
// With the HTLC's applied to both update logs, we'll initiate a state
// transition from Bob.
if err := forceStateTransition(bobChannel, aliceChannel); err != nil {
if err := ForceStateTransition(bobChannel, aliceChannel); err != nil {
t.Fatalf("unable to complete bob's state transition: %v", err)
}
@ -3010,7 +2971,7 @@ func TestChanSyncOweCommitment(t *testing.T) {
if err != nil {
t.Fatalf("unable to settle htlc: %v", err)
}
if err := forceStateTransition(bobChannel, aliceChannel); err != nil {
if err := ForceStateTransition(bobChannel, aliceChannel); err != nil {
t.Fatalf("unable to complete bob's state transition: %v", err)
}
@ -3075,7 +3036,7 @@ func TestChanSyncOweRevocation(t *testing.T) {
if err != nil {
t.Fatalf("unable to recv bob's htlc: %v", err)
}
if err := forceStateTransition(bobChannel, aliceChannel); err != nil {
if err := ForceStateTransition(bobChannel, aliceChannel); err != nil {
t.Fatalf("unable to complete bob's state transition: %v", err)
}
@ -3216,7 +3177,7 @@ func TestChanSyncOweRevocation(t *testing.T) {
if _, err := bobChannel.ReceiveHTLC(aliceHtlc); err != nil {
t.Fatalf("unable to recv alice's htlc: %v", err)
}
if err := forceStateTransition(aliceChannel, bobChannel); err != nil {
if err := ForceStateTransition(aliceChannel, bobChannel); err != nil {
t.Fatalf("unable to complete alice's state transition: %v", err)
}
@ -3260,7 +3221,7 @@ func TestChanSyncOweRevocationAndCommit(t *testing.T) {
if err != nil {
t.Fatalf("unable to recv bob's htlc: %v", err)
}
if err := forceStateTransition(bobChannel, aliceChannel); err != nil {
if err := ForceStateTransition(bobChannel, aliceChannel); err != nil {
t.Fatalf("unable to complete bob's state transition: %v", err)
}
@ -3429,7 +3390,7 @@ func TestChanSyncOweRevocationAndCommitForceTransition(t *testing.T) {
if err != nil {
t.Fatalf("unable to recv bob's htlc: %v", err)
}
if err := forceStateTransition(bobChannel, aliceChannel); err != nil {
if err := ForceStateTransition(bobChannel, aliceChannel); err != nil {
t.Fatalf("unable to complete bob's state transition: %v", err)
}
@ -3664,7 +3625,7 @@ func TestChanSyncFailure(t *testing.T) {
if err != nil {
t.Fatalf("unable to recv bob's htlc: %v", err)
}
err = forceStateTransition(bobChannel, aliceChannel)
err = ForceStateTransition(bobChannel, aliceChannel)
if err != nil {
t.Fatalf("unable to complete bob's state "+
"transition: %v", err)
@ -4077,7 +4038,7 @@ func TestChannelRetransmissionFeeUpdate(t *testing.T) {
if _, err := aliceChannel.ReceiveHTLC(bobHtlc); err != nil {
t.Fatalf("unable to recv bob's htlc: %v", err)
}
if err := forceStateTransition(bobChannel, aliceChannel); err != nil {
if err := ForceStateTransition(bobChannel, aliceChannel); err != nil {
t.Fatalf("unable to complete bob's state transition: %v", err)
}
}
@ -4283,7 +4244,7 @@ func TestFeeUpdateOldDiskFormat(t *testing.T) {
if _, err := bobChannel.ReceiveHTLC(htlc); err != nil {
t.Fatalf("unable to recv htlc: %v", err)
}
if err := forceStateTransition(aliceChannel, bobChannel); err != nil {
if err := ForceStateTransition(aliceChannel, bobChannel); err != nil {
t.Fatalf("unable to complete bob's state transition: %v", err)
}
@ -4380,7 +4341,7 @@ func TestChanSyncInvalidLastSecret(t *testing.T) {
}
// Then we'll initiate a state transition to lock in this new HTLC.
if err := forceStateTransition(aliceChannel, bobChannel); err != nil {
if err := ForceStateTransition(aliceChannel, bobChannel); err != nil {
t.Fatalf("unable to complete alice's state transition: %v", err)
}
@ -4452,13 +4413,13 @@ func TestChanAvailableBandwidth(t *testing.T) {
// to actually determine what the current up to date balance
// is.
if aliceInitiate {
err := forceStateTransition(aliceChannel, bobChannel)
err := ForceStateTransition(aliceChannel, bobChannel)
if err != nil {
t.Fatalf("unable to complete alice's state "+
"transition: %v", err)
}
} else {
err := forceStateTransition(bobChannel, aliceChannel)
err := ForceStateTransition(bobChannel, aliceChannel)
if err != nil {
t.Fatalf("unable to complete alice's state "+
"transition: %v", err)
@ -4538,7 +4499,7 @@ func TestChanAvailableBandwidth(t *testing.T) {
// We must do a state transition before the balance is available
// for Alice.
if err := forceStateTransition(aliceChannel, bobChannel); err != nil {
if err := ForceStateTransition(aliceChannel, bobChannel); err != nil {
t.Fatalf("unable to complete alice's state "+
"transition: %v", err)
}
@ -4968,10 +4929,10 @@ func TestChannelUnilateralCloseHtlcResolution(t *testing.T) {
if _, err := aliceChannel.ReceiveHTLC(htlcBob); err != nil {
t.Fatalf("alice unable to recv add htlc: %v", err)
}
if err := forceStateTransition(aliceChannel, bobChannel); err != nil {
if err := ForceStateTransition(aliceChannel, bobChannel); err != nil {
t.Fatalf("Can't update the channel state: %v", err)
}
if err := forceStateTransition(bobChannel, aliceChannel); err != nil {
if err := ForceStateTransition(bobChannel, aliceChannel); err != nil {
t.Fatalf("Can't update the channel state: %v", err)
}
@ -5253,7 +5214,7 @@ func TestDesyncHTLCs(t *testing.T) {
}
// Lock this HTLC in.
if err := forceStateTransition(aliceChannel, bobChannel); err != nil {
if err := ForceStateTransition(aliceChannel, bobChannel); err != nil {
t.Fatalf("unable to complete state update: %v", err)
}
@ -5283,7 +5244,7 @@ func TestDesyncHTLCs(t *testing.T) {
// Now do a state transition, which will ACK the FailHTLC, making Alice
// able to add the new HTLC.
if err := forceStateTransition(aliceChannel, bobChannel); err != nil {
if err := ForceStateTransition(aliceChannel, bobChannel); err != nil {
t.Fatalf("unable to complete state update: %v", err)
}
if _, err = aliceChannel.AddHTLC(htlc, nil); err != nil {
@ -5348,7 +5309,7 @@ func TestMaxAcceptedHTLCs(t *testing.T) {
if _, err := bobChannel.ReceiveHTLC(htlc); err != nil {
t.Fatalf("unable to recv htlc: %v", err)
}
err = forceStateTransition(aliceChannel, bobChannel)
err = ForceStateTransition(aliceChannel, bobChannel)
if err != ErrMaxHTLCNumber {
t.Fatalf("expected ErrMaxHTLCNumber, instead received: %v", err)
}
@ -5407,7 +5368,7 @@ func TestMaxPendingAmount(t *testing.T) {
if _, err := bobChannel.ReceiveHTLC(htlc); err != nil {
t.Fatalf("unable to recv htlc: %v", err)
}
err = forceStateTransition(aliceChannel, bobChannel)
err = ForceStateTransition(aliceChannel, bobChannel)
if err != ErrMaxPendingAmount {
t.Fatalf("expected ErrMaxPendingAmount, instead received: %v", err)
}
@ -5505,7 +5466,7 @@ func TestChanReserve(t *testing.T) {
// Force a state transition, making sure this HTLC is considered valid
// even though the channel reserves are not met.
if err := forceStateTransition(aliceChannel, bobChannel); err != nil {
if err := ForceStateTransition(aliceChannel, bobChannel); err != nil {
t.Fatalf("unable to complete state update: %v", err)
}
@ -5532,7 +5493,7 @@ func TestChanReserve(t *testing.T) {
if _, err := aliceChannel.ReceiveHTLC(htlc); err != nil {
t.Fatalf("unable to recv htlc: %v", err)
}
err = forceStateTransition(aliceChannel, bobChannel)
err = ForceStateTransition(aliceChannel, bobChannel)
if err != ErrBelowChanReserve {
t.Fatalf("expected ErrBelowChanReserve, instead received: %v", err)
}
@ -5580,7 +5541,7 @@ func TestChanReserve(t *testing.T) {
if _, err := bobChannel.ReceiveHTLC(htlc); err != nil {
t.Fatalf("unable to recv htlc: %v", err)
}
err = forceStateTransition(aliceChannel, bobChannel)
err = ForceStateTransition(aliceChannel, bobChannel)
if err != ErrBelowChanReserve {
t.Fatalf("expected ErrBelowChanReserve, instead received: %v", err)
}
@ -5608,7 +5569,7 @@ func TestChanReserve(t *testing.T) {
if err != nil {
t.Fatalf("unable to recv htlc: %v", err)
}
if err := forceStateTransition(aliceChannel, bobChannel); err != nil {
if err := ForceStateTransition(aliceChannel, bobChannel); err != nil {
t.Fatalf("unable to complete state update: %v", err)
}
@ -5624,7 +5585,7 @@ func TestChanReserve(t *testing.T) {
if err := aliceChannel.ReceiveHTLCSettle(preimage, aliceHtlcIndex); err != nil {
t.Fatalf("alice unable to accept settle of outbound htlc: %v", err)
}
if err := forceStateTransition(bobChannel, aliceChannel); err != nil {
if err := ForceStateTransition(bobChannel, aliceChannel); err != nil {
t.Fatalf("unable to complete state update: %v", err)
}
@ -5648,7 +5609,7 @@ func TestChanReserve(t *testing.T) {
}
// Do a last state transition, which should succeed.
if err := forceStateTransition(bobChannel, aliceChannel); err != nil {
if err := ForceStateTransition(bobChannel, aliceChannel); err != nil {
t.Fatalf("unable to complete state update: %v", err)
}
@ -5707,7 +5668,7 @@ func TestMinHTLC(t *testing.T) {
if err != nil {
t.Fatalf("error receiving htlc: %v", err)
}
err = forceStateTransition(aliceChannel, bobChannel)
err = ForceStateTransition(aliceChannel, bobChannel)
if err != ErrBelowMinHTLC {
t.Fatalf("expected ErrBelowMinHTLC, instead received: %v", err)
}
@ -5766,7 +5727,7 @@ func TestNewBreachRetributionSkipsDustHtlcs(t *testing.T) {
// With the HTLC's applied to both update logs, we'll initiate a state
// transition from Alice.
if err := forceStateTransition(bobChannel, aliceChannel); err != nil {
if err := ForceStateTransition(bobChannel, aliceChannel); err != nil {
t.Fatalf("unable to complete bob's state transition: %v", err)
}
@ -5786,7 +5747,7 @@ func TestNewBreachRetributionSkipsDustHtlcs(t *testing.T) {
t.Fatalf("unable to settle htlc: %v", err)
}
}
if err := forceStateTransition(bobChannel, aliceChannel); err != nil {
if err := ForceStateTransition(bobChannel, aliceChannel); err != nil {
t.Fatalf("unable to complete bob's state transition: %v", err)
}
@ -6088,7 +6049,7 @@ func TestChannelRestoreUpdateLogsFailedHTLC(t *testing.T) {
}
// Lock in the Add on both sides.
if err := forceStateTransition(aliceChannel, bobChannel); err != nil {
if err := ForceStateTransition(aliceChannel, bobChannel); err != nil {
t.Fatalf("unable to complete state update: %v", err)
}
@ -6203,7 +6164,7 @@ func TestDuplicateFailRejection(t *testing.T) {
t.Fatalf("unable to recv htlc: %v", err)
}
if err := forceStateTransition(aliceChannel, bobChannel); err != nil {
if err := ForceStateTransition(aliceChannel, bobChannel); err != nil {
t.Fatalf("unable to complete state update: %v", err)
}
@ -6281,7 +6242,7 @@ func TestDuplicateSettleRejection(t *testing.T) {
t.Fatalf("unable to recv htlc: %v", err)
}
if err := forceStateTransition(aliceChannel, bobChannel); err != nil {
if err := ForceStateTransition(aliceChannel, bobChannel); err != nil {
t.Fatalf("unable to complete state update: %v", err)
}

@ -492,3 +492,43 @@ func calcStaticFee(numHTLCs int) btcutil.Amount {
return feePerKw * (commitWeight +
btcutil.Amount(htlcWeight*numHTLCs)) / 1000
}
// ForceStateTransition executes the necessary interaction between the two
// commitment state machines to transition to a new state locking in any
// pending updates. This method is useful when testing interactions between two
// live state machines.
func ForceStateTransition(chanA, chanB *LightningChannel) error {
aliceSig, aliceHtlcSigs, err := chanA.SignNextCommitment()
if err != nil {
return err
}
if err = chanB.ReceiveNewCommitment(aliceSig, aliceHtlcSigs); err != nil {
return err
}
bobRevocation, _, err := chanB.RevokeCurrentCommitment()
if err != nil {
return err
}
bobSig, bobHtlcSigs, err := chanB.SignNextCommitment()
if err != nil {
return err
}
if _, _, _, err := chanA.ReceiveRevocation(bobRevocation); err != nil {
return err
}
if err := chanA.ReceiveNewCommitment(bobSig, bobHtlcSigs); err != nil {
return err
}
aliceRevocation, _, err := chanA.RevokeCurrentCommitment()
if err != nil {
return err
}
if _, _, _, err := chanB.ReceiveRevocation(aliceRevocation); err != nil {
return err
}
return nil
}