lnwallet: update TestChanSyncFailure to pass with new borked update restriction
In this commit, we update the `TestChanSyncFailure` method to pass given the new behavior around updating borked channel states. In order to do this, we add a new method to allow the test to clear an existing channel state. This method may be of independent use in other areas in the codebase in the future as well.
This commit is contained in:
parent
bc72691806
commit
33ad645f8c
@ -110,7 +110,7 @@ var (
|
|||||||
|
|
||||||
// ErrChanBorked is returned when a caller attempts to mutate a borked
|
// ErrChanBorked is returned when a caller attempts to mutate a borked
|
||||||
// channel.
|
// channel.
|
||||||
ErrChanBorked = fmt.Errorf("channel mutate borked channel")
|
ErrChanBorked = fmt.Errorf("cannot mutate borked channel")
|
||||||
)
|
)
|
||||||
|
|
||||||
// ChannelType is an enum-like type that describes one of several possible
|
// ChannelType is an enum-like type that describes one of several possible
|
||||||
@ -549,6 +549,16 @@ func (c *OpenChannel) ApplyChanStatus(status ChannelStatus) error {
|
|||||||
return c.putChanStatus(status)
|
return c.putChanStatus(status)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ClearChanStatus allows the caller to clear a particular channel status from
|
||||||
|
// the primary channel status bit field. After this method returns, a call to
|
||||||
|
// HasChanStatus(status) should return false.
|
||||||
|
func (c *OpenChannel) ClearChanStatus(status ChannelStatus) error {
|
||||||
|
c.Lock()
|
||||||
|
defer c.Unlock()
|
||||||
|
|
||||||
|
return c.clearChanStatus(status)
|
||||||
|
}
|
||||||
|
|
||||||
// HasChanStatus returns true if the internal bitfield channel status of the
|
// HasChanStatus returns true if the internal bitfield channel status of the
|
||||||
// target channel has the specified status bit set.
|
// target channel has the specified status bit set.
|
||||||
func (c *OpenChannel) HasChanStatus(status ChannelStatus) bool {
|
func (c *OpenChannel) HasChanStatus(status ChannelStatus) bool {
|
||||||
@ -864,6 +874,35 @@ func (c *OpenChannel) putChanStatus(status ChannelStatus) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *OpenChannel) clearChanStatus(status ChannelStatus) error {
|
||||||
|
if err := c.Db.Update(func(tx *bbolt.Tx) error {
|
||||||
|
chanBucket, err := fetchChanBucket(
|
||||||
|
tx, c.IdentityPub, &c.FundingOutpoint, c.ChainHash,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
channel, err := fetchOpenChannel(chanBucket, &c.FundingOutpoint)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unset this bit in the bitvector on disk.
|
||||||
|
status = channel.chanStatus & ^status
|
||||||
|
channel.chanStatus = status
|
||||||
|
|
||||||
|
return putOpenChannel(chanBucket, channel)
|
||||||
|
}); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the in-memory representation to keep it in sync with the DB.
|
||||||
|
c.chanStatus = status
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// putChannel serializes, and stores the current state of the channel in its
|
// putChannel serializes, and stores the current state of the channel in its
|
||||||
// entirety.
|
// entirety.
|
||||||
func putOpenChannel(chanBucket *bbolt.Bucket, channel *OpenChannel) error {
|
func putOpenChannel(chanBucket *bbolt.Bucket, channel *OpenChannel) error {
|
||||||
|
@ -3641,6 +3641,8 @@ func TestChanSyncFailure(t *testing.T) {
|
|||||||
// advanceState is a helper method to fully advance the channel state
|
// advanceState is a helper method to fully advance the channel state
|
||||||
// by one.
|
// by one.
|
||||||
advanceState := func() {
|
advanceState := func() {
|
||||||
|
t.Helper()
|
||||||
|
|
||||||
// We'll kick off the test by having Bob send Alice an HTLC,
|
// We'll kick off the test by having Bob send Alice an HTLC,
|
||||||
// then lock it in with a state transition.
|
// then lock it in with a state transition.
|
||||||
var bobPreimage [32]byte
|
var bobPreimage [32]byte
|
||||||
@ -3672,6 +3674,8 @@ func TestChanSyncFailure(t *testing.T) {
|
|||||||
// halfAdvance is a helper method that sends a new commitment signature
|
// halfAdvance is a helper method that sends a new commitment signature
|
||||||
// from Alice to Bob, but doesn't make Bob revoke his current state.
|
// from Alice to Bob, but doesn't make Bob revoke his current state.
|
||||||
halfAdvance := func() {
|
halfAdvance := func() {
|
||||||
|
t.Helper()
|
||||||
|
|
||||||
// We'll kick off the test by having Bob send Alice an HTLC,
|
// We'll kick off the test by having Bob send Alice an HTLC,
|
||||||
// then lock it in with a state transition.
|
// then lock it in with a state transition.
|
||||||
var bobPreimage [32]byte
|
var bobPreimage [32]byte
|
||||||
@ -3707,6 +3711,8 @@ func TestChanSyncFailure(t *testing.T) {
|
|||||||
// assertLocalDataLoss checks that aliceOld and bobChannel detects that
|
// assertLocalDataLoss checks that aliceOld and bobChannel detects that
|
||||||
// Alice has lost state during sync.
|
// Alice has lost state during sync.
|
||||||
assertLocalDataLoss := func(aliceOld *LightningChannel) {
|
assertLocalDataLoss := func(aliceOld *LightningChannel) {
|
||||||
|
t.Helper()
|
||||||
|
|
||||||
aliceSyncMsg, err := ChanSyncMsg(aliceOld.channelState)
|
aliceSyncMsg, err := ChanSyncMsg(aliceOld.channelState)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to produce chan sync msg: %v", err)
|
t.Fatalf("unable to produce chan sync msg: %v", err)
|
||||||
@ -3733,6 +3739,25 @@ func TestChanSyncFailure(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// clearBorkedState is a method that allows us to clear the borked
|
||||||
|
// state that will arise after the first chan message sync. We need to
|
||||||
|
// do this in order to be able to continue to update the commitment
|
||||||
|
// state for our test scenarios.
|
||||||
|
clearBorkedState := func() {
|
||||||
|
err = aliceChannel.channelState.ClearChanStatus(
|
||||||
|
channeldb.ChanStatusLocalDataLoss | channeldb.ChanStatusBorked,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unable to update channel state: %v", err)
|
||||||
|
}
|
||||||
|
err = bobChannel.channelState.ClearChanStatus(
|
||||||
|
channeldb.ChanStatusLocalDataLoss | channeldb.ChanStatusBorked,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unable to update channel state: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Start by advancing the state.
|
// Start by advancing the state.
|
||||||
advanceState()
|
advanceState()
|
||||||
|
|
||||||
@ -3755,6 +3780,9 @@ func TestChanSyncFailure(t *testing.T) {
|
|||||||
// Make sure the up-to-date channels still are in sync.
|
// Make sure the up-to-date channels still are in sync.
|
||||||
assertNoChanSyncNeeded(t, aliceChannel, bobChannel)
|
assertNoChanSyncNeeded(t, aliceChannel, bobChannel)
|
||||||
|
|
||||||
|
// Clear the borked state before we attempt to advance.
|
||||||
|
clearBorkedState()
|
||||||
|
|
||||||
// Advance the state again, and do the same check.
|
// Advance the state again, and do the same check.
|
||||||
advanceState()
|
advanceState()
|
||||||
assertNoChanSyncNeeded(t, aliceChannel, bobChannel)
|
assertNoChanSyncNeeded(t, aliceChannel, bobChannel)
|
||||||
@ -3825,6 +3853,9 @@ func TestChanSyncFailure(t *testing.T) {
|
|||||||
// Make sure the up-to-date channels still are good.
|
// Make sure the up-to-date channels still are good.
|
||||||
assertNoChanSyncNeeded(t, aliceChannel, bobChannel)
|
assertNoChanSyncNeeded(t, aliceChannel, bobChannel)
|
||||||
|
|
||||||
|
// Clear the borked state before we attempt to advance.
|
||||||
|
clearBorkedState()
|
||||||
|
|
||||||
// Finally check that Alice is also able to detect a wrong commit point
|
// Finally check that Alice is also able to detect a wrong commit point
|
||||||
// when there's a pending remote commit.
|
// when there's a pending remote commit.
|
||||||
halfAdvance()
|
halfAdvance()
|
||||||
|
Loading…
Reference in New Issue
Block a user