netann: update channel status transitions to handle manual requests
This commit is contained in:
parent
c40d291488
commit
542c89ad5d
@ -29,6 +29,12 @@ var (
|
|||||||
// the time of the request.
|
// the time of the request.
|
||||||
ErrEnableInactiveChan = errors.New("unable to enable channel which " +
|
ErrEnableInactiveChan = errors.New("unable to enable channel which " +
|
||||||
"is not currently active")
|
"is not currently active")
|
||||||
|
|
||||||
|
// ErrEnableManuallyDisabledChan signals that an automatic / background
|
||||||
|
// request to enable a channel could not be completed because the channel
|
||||||
|
// was manually disabled.
|
||||||
|
ErrEnableManuallyDisabledChan = errors.New("unable to enable channel " +
|
||||||
|
"which was manually disabled")
|
||||||
)
|
)
|
||||||
|
|
||||||
// ChanStatusConfig holds parameters and resources required by the
|
// ChanStatusConfig holds parameters and resources required by the
|
||||||
@ -219,6 +225,9 @@ func (m *ChanStatusManager) Stop() error {
|
|||||||
// channel is found to be disabled, a new announcement will be signed with the
|
// channel is found to be disabled, a new announcement will be signed with the
|
||||||
// disabled bit cleared and broadcast to the network.
|
// disabled bit cleared and broadcast to the network.
|
||||||
//
|
//
|
||||||
|
// If the channel was manually disabled and RequestEnable is called with
|
||||||
|
// manual = false, then the request will be ignored.
|
||||||
|
//
|
||||||
// NOTE: RequestEnable should only be called after a stable connection with the
|
// NOTE: RequestEnable should only be called after a stable connection with the
|
||||||
// channel's peer has lasted at least the ChanEnableTimeout. Failure to do so
|
// channel's peer has lasted at least the ChanEnableTimeout. Failure to do so
|
||||||
// may result in behavior that deviates from the expected behavior of the state
|
// may result in behavior that deviates from the expected behavior of the state
|
||||||
@ -233,6 +242,21 @@ func (m *ChanStatusManager) RequestEnable(outpoint wire.OutPoint,
|
|||||||
// by the provided outpoint. If the channel is already disabled, no action will
|
// by the provided outpoint. If the channel is already disabled, no action will
|
||||||
// be taken. Otherwise, a new announcement will be signed with the disabled bit
|
// be taken. Otherwise, a new announcement will be signed with the disabled bit
|
||||||
// set and broadcast to the network.
|
// set and broadcast to the network.
|
||||||
|
//
|
||||||
|
// The channel state will be changed to either ChanStatusDisabled or
|
||||||
|
// ChanStatusManuallyDisabled, depending on the passed-in value of manual. In
|
||||||
|
// particular, note the following state transitions:
|
||||||
|
//
|
||||||
|
// current state | manual | new state
|
||||||
|
// ---------------------------------------------------
|
||||||
|
// Disabled | false | Disabled
|
||||||
|
// ManuallyDisabled | false | ManuallyDisabled (*)
|
||||||
|
// Disabled | true | ManuallyDisabled
|
||||||
|
// ManuallyDisabled | true | ManuallyDisabled
|
||||||
|
//
|
||||||
|
// (*) If a channel was manually disabled, subsequent automatic / background
|
||||||
|
// requests to disable the channel do not change the fact that the channel
|
||||||
|
// was manually disabled.
|
||||||
func (m *ChanStatusManager) RequestDisable(outpoint wire.OutPoint,
|
func (m *ChanStatusManager) RequestDisable(outpoint wire.OutPoint,
|
||||||
manual bool) error {
|
manual bool) error {
|
||||||
|
|
||||||
@ -317,12 +341,18 @@ func (m *ChanStatusManager) statusManager() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// processEnableRequest attempts to enable the given outpoint. If the method
|
// processEnableRequest attempts to enable the given outpoint.
|
||||||
// returns nil, the status of the channel in chanStates will be
|
//
|
||||||
// ChanStatusEnabled. If the channel is not active at the time of the request,
|
// * If the channel is not active at the time of the request,
|
||||||
// ErrEnableInactiveChan will be returned. An update will be broadcast only if
|
// ErrEnableInactiveChan will be returned.
|
||||||
// the channel is currently disabled, otherwise no update will be sent on the
|
// * If the channel was in the ManuallyDisabled state and manual = false,
|
||||||
// network.
|
// the request will be ignored and ErrEnableManuallyDisabledChan will be
|
||||||
|
// returned.
|
||||||
|
// * Otherwise, the status of the channel in chanStates will be
|
||||||
|
// ChanStatusEnabled and the method will return nil.
|
||||||
|
//
|
||||||
|
// An update will be broadcast only if the channel is currently disabled,
|
||||||
|
// otherwise no update will be sent on the network.
|
||||||
func (m *ChanStatusManager) processEnableRequest(outpoint wire.OutPoint,
|
func (m *ChanStatusManager) processEnableRequest(outpoint wire.OutPoint,
|
||||||
manual bool) error {
|
manual bool) error {
|
||||||
|
|
||||||
@ -351,6 +381,12 @@ func (m *ChanStatusManager) processEnableRequest(outpoint wire.OutPoint,
|
|||||||
"disable", outpoint)
|
"disable", outpoint)
|
||||||
|
|
||||||
// We'll sign a new update if the channel is still disabled.
|
// We'll sign a new update if the channel is still disabled.
|
||||||
|
case ChanStatusManuallyDisabled:
|
||||||
|
if !manual {
|
||||||
|
return ErrEnableManuallyDisabledChan
|
||||||
|
}
|
||||||
|
fallthrough
|
||||||
|
|
||||||
case ChanStatusDisabled:
|
case ChanStatusDisabled:
|
||||||
log.Infof("Announcing channel(%v) enabled", outpoint)
|
log.Infof("Announcing channel(%v) enabled", outpoint)
|
||||||
|
|
||||||
@ -366,10 +402,12 @@ func (m *ChanStatusManager) processEnableRequest(outpoint wire.OutPoint,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// processDisableRequest attempts to disable the given outpoint. If the method
|
// processDisableRequest attempts to disable the given outpoint. If the method
|
||||||
// returns nil, the status of the channel in chanStates will be
|
// returns nil, the status of the channel in chanStates will be either
|
||||||
// ChanStatusDisabled. An update will only be sent if the channel has a status
|
// ChanStatusDisabled or ChanStatusManuallyDisabled, depending on the
|
||||||
// other than ChanStatusEnabled, otherwise no update will be sent on the
|
// passed-in value of manual.
|
||||||
// network.
|
//
|
||||||
|
// An update will only be sent if the channel has a status other than
|
||||||
|
// ChanStatusEnabled, otherwise no update will be sent on the network.
|
||||||
func (m *ChanStatusManager) processDisableRequest(outpoint wire.OutPoint,
|
func (m *ChanStatusManager) processDisableRequest(outpoint wire.OutPoint,
|
||||||
manual bool) error {
|
manual bool) error {
|
||||||
|
|
||||||
@ -378,15 +416,8 @@ func (m *ChanStatusManager) processDisableRequest(outpoint wire.OutPoint,
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
switch curState.Status {
|
status := curState.Status
|
||||||
|
if status == ChanStatusEnabled || status == ChanStatusPendingDisabled {
|
||||||
// Channel is already disabled, nothing to do.
|
|
||||||
case ChanStatusDisabled:
|
|
||||||
return nil
|
|
||||||
|
|
||||||
// We'll sign a new update disabling the channel if the current status
|
|
||||||
// is enabled or pending-inactive.
|
|
||||||
case ChanStatusEnabled, ChanStatusPendingDisabled:
|
|
||||||
log.Infof("Announcing channel(%v) disabled [requested]",
|
log.Infof("Announcing channel(%v) disabled [requested]",
|
||||||
outpoint)
|
outpoint)
|
||||||
|
|
||||||
@ -396,13 +427,19 @@ func (m *ChanStatusManager) processDisableRequest(outpoint wire.OutPoint,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the disable was requested via the manager's public interface, we
|
// Typically, a request to disable a channel via the manager's public
|
||||||
// will remove the output from our map of channel states. Typically this
|
// interface signals that the channel is being closed.
|
||||||
// signals that the channel is being closed, so this frees up the space
|
//
|
||||||
// in the map. If for some reason the channel isn't closed, the state
|
// If we don't need to keep track of a manual request to disable the
|
||||||
// will be repopulated on subsequent calls to RequestEnable or
|
// channel, then we can remove the outpoint to free up space in the map
|
||||||
// RequestDisable via a db lookup, or on startup.
|
// of channel states. If for some reason the channel isn't closed, the
|
||||||
delete(m.chanStates, outpoint)
|
// state will be repopulated on subsequent calls to the manager's public
|
||||||
|
// interface via a db lookup, or on startup.
|
||||||
|
if manual {
|
||||||
|
m.chanStates.markManuallyDisabled(outpoint)
|
||||||
|
} else if status != ChanStatusManuallyDisabled {
|
||||||
|
delete(m.chanStates, outpoint)
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user