/ htlcswitch / linkfailure.go
linkfailure.go
1 package htlcswitch 2 3 import "errors" 4 5 var ( 6 // ErrLinkShuttingDown signals that the link is shutting down. 7 ErrLinkShuttingDown = errors.New("link shutting down") 8 9 // ErrLinkFailedShutdown signals that a requested shutdown failed. 10 ErrLinkFailedShutdown = errors.New("link failed to shutdown") 11 ) 12 13 // errorCode encodes the possible types of errors that will make us fail the 14 // current link. 15 type errorCode uint8 16 17 const ( 18 // ErrInternalError indicates that something internal in the link 19 // failed. In this case we will send a generic error to our peer. 20 ErrInternalError errorCode = iota 21 22 // ErrRemoteError indicates that our peer sent an error, prompting up 23 // to fail the link. 24 ErrRemoteError 25 26 // ErrRemoteUnresponsive indicates that our peer took too long to 27 // complete a commitment dance. 28 ErrRemoteUnresponsive 29 30 // ErrSyncError indicates that we failed synchronizing the state of the 31 // channel with our peer. 32 ErrSyncError 33 34 // ErrInvalidUpdate indicates that the peer send us an invalid update. 35 ErrInvalidUpdate 36 37 // ErrInvalidCommitment indicates that the remote peer sent us an 38 // invalid commitment signature. 39 ErrInvalidCommitment 40 41 // ErrInvalidRevocation indicates that the remote peer send us an 42 // invalid revocation message. 43 ErrInvalidRevocation 44 45 // ErrRecoveryError the channel was unable to be resumed, we need the 46 // remote party to force close the channel out on chain now as a 47 // result. 48 ErrRecoveryError 49 50 // ErrCircuitError indicates a duplicate keystone error was hit in the 51 // circuit map. This is non-fatal and will resolve itself (usually 52 // within several minutes). 53 ErrCircuitError 54 55 // ErrStfuViolation indicates that the quiescence protocol has been 56 // violated, either because Stfu has been sent/received at an invalid 57 // time, or that an update has been sent/received while the channel is 58 // quiesced. 59 ErrStfuViolation 60 ) 61 62 // LinkFailureAction is an enum-like type that describes the action that should 63 // be taken in response to a link failure. 64 type LinkFailureAction uint8 65 66 const ( 67 // LinkFailureForceNone indicates no action is to be taken. 68 LinkFailureForceNone LinkFailureAction = iota 69 70 // LinkFailureForceClose indicates that the channel should be force 71 // closed. 72 LinkFailureForceClose 73 74 // LinkFailureDisconnect indicates that we should disconnect in an 75 // attempt to recycle the connection. This can be useful if we think a 76 // TCP connection or state machine is stalled. 77 LinkFailureDisconnect 78 ) 79 80 // LinkFailureError encapsulates an error that will make us fail the current 81 // link. It contains the necessary information needed to determine if we should 82 // force close the channel in the process, and if any error data should be sent 83 // to the peer. 84 type LinkFailureError struct { 85 // code is the type of error this LinkFailureError encapsulates. 86 code errorCode 87 88 // FailureAction describes what we should do to fail the channel. 89 FailureAction LinkFailureAction 90 91 // PermanentFailure indicates whether this failure is permanent, and 92 // the channel should not be attempted loaded again. 93 PermanentFailure bool 94 95 // Warning denotes if this is a non-terminal error that doesn't warrant 96 // failing the channel all together. 97 Warning bool 98 99 // SendData is a byte slice that will be sent to the peer. If nil a 100 // generic error will be sent. 101 SendData []byte 102 } 103 104 // A compile time check to ensure LinkFailureError implements the error 105 // interface. 106 var _ error = (*LinkFailureError)(nil) 107 108 // Error returns a generic error for the LinkFailureError. 109 // 110 // NOTE: Part of the error interface. 111 func (e LinkFailureError) Error() string { 112 switch e.code { 113 case ErrInternalError: 114 return "internal error" 115 case ErrRemoteError: 116 return "remote error" 117 case ErrRemoteUnresponsive: 118 return "remote unresponsive" 119 case ErrSyncError: 120 return "sync error" 121 case ErrInvalidUpdate: 122 return "invalid update" 123 case ErrInvalidCommitment: 124 return "invalid commitment" 125 case ErrInvalidRevocation: 126 return "invalid revocation" 127 case ErrRecoveryError: 128 return "unable to resume channel, recovery required" 129 case ErrCircuitError: 130 return "non-fatal circuit map error" 131 case ErrStfuViolation: 132 return "quiescence protocol executed improperly" 133 default: 134 return "unknown error" 135 } 136 } 137 138 // ShouldSendToPeer indicates whether we should send an error to the peer if 139 // the link fails with this LinkFailureError. 140 func (e LinkFailureError) ShouldSendToPeer() bool { 141 switch e.code { 142 143 // Since sending an error can lead some nodes to force close the 144 // channel, create a whitelist of the failures we want to send so that 145 // newly added error codes aren't automatically sent to the remote peer. 146 case 147 ErrInternalError, 148 ErrRemoteError, 149 ErrSyncError, 150 ErrInvalidUpdate, 151 ErrInvalidCommitment, 152 ErrInvalidRevocation, 153 ErrRecoveryError: 154 155 return true 156 157 // In all other cases we will not attempt to send our peer an error. 158 default: 159 return false 160 } 161 }