github.com/decred/dcrlnd@v0.7.6/chanacceptor/rpcacceptor.go (about) 1 package chanacceptor 2 3 import ( 4 "encoding/hex" 5 "errors" 6 "fmt" 7 "sync" 8 "time" 9 10 "github.com/decred/dcrd/chaincfg/v3" 11 "github.com/decred/dcrd/dcrutil/v4" 12 "github.com/decred/dcrlnd/input" 13 "github.com/decred/dcrlnd/lnrpc" 14 "github.com/decred/dcrlnd/lnwallet/chancloser" 15 "github.com/decred/dcrlnd/lnwire" 16 ) 17 18 var ( 19 errShuttingDown = errors.New("server shutting down") 20 21 // errCustomLength is returned when our custom error's length exceeds 22 // our maximum. 23 errCustomLength = fmt.Errorf("custom error message exceeds length "+ 24 "limit: %v", maxErrorLength) 25 26 // errInvalidUpfrontShutdown is returned when we cannot parse the 27 // upfront shutdown address returned. 28 errInvalidUpfrontShutdown = fmt.Errorf("could not parse upfront " + 29 "shutdown address") 30 31 // errInsufficientReserve is returned when the reserve proposed by for 32 // a channel is less than the dust limit originally supplied. 33 errInsufficientReserve = fmt.Errorf("reserve lower than proposed dust " + 34 "limit") 35 36 // errAcceptWithError is returned when we get a response which accepts 37 // a channel but ambiguously also sets a custom error message. 38 errAcceptWithError = errors.New("channel acceptor response accepts " + 39 "channel, but also includes custom error") 40 41 // errMaxHtlcTooHigh is returned if our htlc count exceeds the number 42 // hard-set by BOLT 2. 43 errMaxHtlcTooHigh = fmt.Errorf("htlc limit exceeds spec limit of: %v", 44 input.MaxHTLCNumber/2) 45 46 // maxErrorLength is the maximum error length we allow the error we 47 // send to our peer to be. 48 maxErrorLength = 500 49 ) 50 51 // chanAcceptInfo contains a request for a channel acceptor decision, and a 52 // channel that the response should be sent on. 53 type chanAcceptInfo struct { 54 request *ChannelAcceptRequest 55 response chan *ChannelAcceptResponse 56 } 57 58 // RPCAcceptor represents the RPC-controlled variant of the ChannelAcceptor. 59 // One RPCAcceptor allows one RPC client. 60 type RPCAcceptor struct { 61 // receive is a function from which we receive channel acceptance 62 // decisions. Note that this function is expected to block. 63 receive func() (*lnrpc.ChannelAcceptResponse, error) 64 65 // send is a function which sends requests for channel acceptance 66 // decisions into our rpc stream. 67 send func(request *lnrpc.ChannelAcceptRequest) error 68 69 // requests is a channel that we send requests for a acceptor response 70 // into. 71 requests chan *chanAcceptInfo 72 73 // timeout is the amount of time we allow the channel acceptance 74 // decision to take. This time includes the time to send a query to the 75 // acceptor, and the time it takes to receive a response. 76 timeout time.Duration 77 78 // params are our current chain params. 79 params *chaincfg.Params 80 81 // done is closed when the rpc client terminates. 82 done chan struct{} 83 84 // quit is closed when lnd is shutting down. 85 quit chan struct{} 86 87 wg sync.WaitGroup 88 } 89 90 // Accept is a predicate on the ChannelAcceptRequest which is sent to the RPC 91 // client who will respond with the ultimate decision. This function passes the 92 // request into the acceptor's requests channel, and returns the response it 93 // receives, failing the request if the timeout elapses. 94 // 95 // NOTE: Part of the ChannelAcceptor interface. 96 func (r *RPCAcceptor) Accept(req *ChannelAcceptRequest) *ChannelAcceptResponse { 97 respChan := make(chan *ChannelAcceptResponse, 1) 98 99 newRequest := &chanAcceptInfo{ 100 request: req, 101 response: respChan, 102 } 103 104 // timeout is the time after which ChannelAcceptRequests expire. 105 timeout := time.After(r.timeout) 106 107 // Create a rejection response which we can use for the cases where we 108 // reject the channel. 109 rejectChannel := NewChannelAcceptResponse( 110 false, errChannelRejected, nil, 0, 0, 0, 0, 0, 0, 111 ) 112 113 // Send the request to the newRequests channel. 114 select { 115 case r.requests <- newRequest: 116 117 case <-timeout: 118 log.Errorf("RPCAcceptor returned false - reached timeout of %v", 119 r.timeout) 120 return rejectChannel 121 122 case <-r.done: 123 return rejectChannel 124 125 case <-r.quit: 126 return rejectChannel 127 } 128 129 // Receive the response and return it. If no response has been received 130 // in AcceptorTimeout, then return false. 131 select { 132 case resp := <-respChan: 133 return resp 134 135 case <-timeout: 136 log.Errorf("RPCAcceptor returned false - reached timeout of %v", 137 r.timeout) 138 return rejectChannel 139 140 case <-r.done: 141 return rejectChannel 142 143 case <-r.quit: 144 return rejectChannel 145 } 146 } 147 148 // NewRPCAcceptor creates and returns an instance of the RPCAcceptor. 149 func NewRPCAcceptor(receive func() (*lnrpc.ChannelAcceptResponse, error), 150 send func(*lnrpc.ChannelAcceptRequest) error, timeout time.Duration, 151 params *chaincfg.Params, quit chan struct{}) *RPCAcceptor { 152 153 return &RPCAcceptor{ 154 receive: receive, 155 send: send, 156 requests: make(chan *chanAcceptInfo), 157 timeout: timeout, 158 params: params, 159 done: make(chan struct{}), 160 quit: quit, 161 } 162 } 163 164 // Run is the main loop for the RPC Acceptor. This function will block until 165 // it receives the signal that lnd is shutting down, or the rpc stream is 166 // cancelled by the client. 167 func (r *RPCAcceptor) Run() error { 168 // Wait for our goroutines to exit before we return. 169 defer r.wg.Wait() 170 171 // Create a channel that responses from acceptors are sent into. 172 responses := make(chan *lnrpc.ChannelAcceptResponse) 173 174 // errChan is used by the receive loop to signal any errors that occur 175 // during reading from the stream. This is primarily used to shutdown 176 // the send loop in the case of an RPC client disconnecting. 177 errChan := make(chan error, 1) 178 179 // Start a goroutine to receive responses from the channel acceptor. 180 // We expect the receive function to block, so it must be run in a 181 // goroutine (otherwise we could not send more than one channel accept 182 // request to the client). 183 r.wg.Add(1) 184 go func() { 185 r.receiveResponses(errChan, responses) 186 r.wg.Done() 187 }() 188 189 return r.sendAcceptRequests(errChan, responses) 190 } 191 192 // receiveResponses receives responses for our channel accept requests and 193 // dispatches them into the responses channel provided, sending any errors that 194 // occur into the error channel provided. 195 func (r *RPCAcceptor) receiveResponses(errChan chan error, 196 responses chan *lnrpc.ChannelAcceptResponse) { 197 198 for { 199 resp, err := r.receive() 200 if err != nil { 201 errChan <- err 202 return 203 } 204 205 var pendingID [32]byte 206 copy(pendingID[:], resp.PendingChanId) 207 208 openChanResp := &lnrpc.ChannelAcceptResponse{ 209 Accept: resp.Accept, 210 PendingChanId: pendingID[:], 211 Error: resp.Error, 212 UpfrontShutdown: resp.UpfrontShutdown, 213 CsvDelay: resp.CsvDelay, 214 ReserveAtoms: resp.ReserveAtoms, 215 InFlightMaxMatoms: resp.InFlightMaxMatoms, 216 MaxHtlcCount: resp.MaxHtlcCount, 217 MinHtlcIn: resp.MinHtlcIn, 218 MinAcceptDepth: resp.MinAcceptDepth, 219 } 220 221 // We have received a decision for one of our channel 222 // acceptor requests. 223 select { 224 case responses <- openChanResp: 225 226 case <-r.done: 227 return 228 229 case <-r.quit: 230 return 231 } 232 } 233 } 234 235 // sendAcceptRequests handles channel acceptor requests sent to us by our 236 // Accept() function, dispatching them to our acceptor stream and coordinating 237 // return of responses to their callers. 238 func (r *RPCAcceptor) sendAcceptRequests(errChan chan error, 239 responses chan *lnrpc.ChannelAcceptResponse) error { 240 241 // Close the done channel to indicate that the acceptor is no longer 242 // listening and any in-progress requests should be terminated. 243 defer close(r.done) 244 245 // Create a map of pending channel IDs to our original open channel 246 // request and a response channel. We keep the original chanel open 247 // message so that we can validate our response against it. 248 acceptRequests := make(map[[32]byte]*chanAcceptInfo) 249 250 for { 251 select { 252 // Consume requests passed to us from our Accept() function and 253 // send them into our stream. 254 case newRequest := <-r.requests: 255 256 req := newRequest.request 257 pendingChanID := req.OpenChanMsg.PendingChannelID 258 259 // Map the channel commitment type to its RPC 260 // counterpart. 261 var commitmentType lnrpc.CommitmentType 262 if req.OpenChanMsg.ChannelType != nil { 263 channelFeatures := lnwire.RawFeatureVector( 264 *req.OpenChanMsg.ChannelType, 265 ) 266 switch { 267 case channelFeatures.OnlyContains( 268 lnwire.ScriptEnforcedLeaseRequired, 269 lnwire.AnchorsZeroFeeHtlcTxRequired, 270 lnwire.StaticRemoteKeyRequired, 271 ): 272 commitmentType = lnrpc.CommitmentType_SCRIPT_ENFORCED_LEASE 273 274 case channelFeatures.OnlyContains( 275 lnwire.AnchorsZeroFeeHtlcTxRequired, 276 lnwire.StaticRemoteKeyRequired, 277 ): 278 commitmentType = lnrpc.CommitmentType_ANCHORS 279 280 case channelFeatures.OnlyContains( 281 lnwire.StaticRemoteKeyRequired, 282 ): 283 commitmentType = lnrpc.CommitmentType_STATIC_REMOTE_KEY 284 285 case channelFeatures.OnlyContains(): 286 commitmentType = lnrpc.CommitmentType_LEGACY 287 288 default: 289 log.Warnf("Unhandled commitment type "+ 290 "in channel acceptor request: %v", 291 req.OpenChanMsg.ChannelType) 292 } 293 } 294 295 acceptRequests[pendingChanID] = newRequest 296 297 // A ChannelAcceptRequest has been received, send it to the client. 298 chanAcceptReq := &lnrpc.ChannelAcceptRequest{ 299 NodePubkey: req.Node.SerializeCompressed(), 300 ChainHash: req.OpenChanMsg.ChainHash[:], 301 PendingChanId: req.OpenChanMsg.PendingChannelID[:], 302 FundingAmt: uint64(req.OpenChanMsg.FundingAmount), 303 PushAmt: uint64(req.OpenChanMsg.PushAmount), 304 DustLimit: uint64(req.OpenChanMsg.DustLimit), 305 MaxValueInFlight: uint64(req.OpenChanMsg.MaxValueInFlight), 306 ChannelReserve: uint64(req.OpenChanMsg.ChannelReserve), 307 MinHtlc: uint64(req.OpenChanMsg.HtlcMinimum), 308 FeePerKb: uint64(req.OpenChanMsg.FeePerKiloByte), 309 CsvDelay: uint32(req.OpenChanMsg.CsvDelay), 310 MaxAcceptedHtlcs: uint32(req.OpenChanMsg.MaxAcceptedHTLCs), 311 ChannelFlags: uint32(req.OpenChanMsg.ChannelFlags), 312 CommitmentType: commitmentType, 313 } 314 315 if err := r.send(chanAcceptReq); err != nil { 316 return err 317 } 318 319 // Process newly received responses from our channel acceptor, 320 // looking the original request up in our map of requests and 321 // dispatching the response. 322 case resp := <-responses: 323 // Look up the appropriate channel to send on given the 324 // pending ID. If a channel is found, send the response 325 // over it. 326 var pendingID [32]byte 327 copy(pendingID[:], resp.PendingChanId) 328 requestInfo, ok := acceptRequests[pendingID] 329 if !ok { 330 continue 331 } 332 333 // Validate the response we have received. If it is not 334 // valid, we log our error and proceed to deliver the 335 // rejection. 336 accept, acceptErr, shutdown, err := r.validateAcceptorResponse( 337 requestInfo.request.OpenChanMsg.DustLimit, resp, 338 ) 339 if err != nil { 340 log.Errorf("Invalid acceptor response: %v", err) 341 } 342 343 requestInfo.response <- NewChannelAcceptResponse( 344 accept, acceptErr, shutdown, 345 uint16(resp.CsvDelay), 346 uint16(resp.MaxHtlcCount), 347 uint16(resp.MinAcceptDepth), 348 dcrutil.Amount(resp.ReserveAtoms), 349 lnwire.MilliAtom(resp.InFlightMaxMatoms), 350 lnwire.MilliAtom(resp.MinHtlcIn), 351 ) 352 353 // Delete the channel from the acceptRequests map. 354 delete(acceptRequests, pendingID) 355 356 // If we failed to receive from our acceptor, we exit. 357 case err := <-errChan: 358 log.Errorf("Received an error: %v, shutting down", err) 359 return err 360 361 // Exit if we are shutting down. 362 case <-r.quit: 363 return errShuttingDown 364 } 365 } 366 } 367 368 // validateAcceptorResponse validates the response we get from the channel 369 // acceptor, returning a boolean indicating whether to accept the channel, an 370 // error to send to the peer, and any validation errors that occurred. 371 func (r *RPCAcceptor) validateAcceptorResponse(dustLimit dcrutil.Amount, 372 req *lnrpc.ChannelAcceptResponse) (bool, error, lnwire.DeliveryAddress, 373 error) { 374 375 channelStr := hex.EncodeToString(req.PendingChanId) 376 377 // Check that the max htlc count is within the BOLT 2 hard-limit of 483. 378 // The initiating side should fail values above this anyway, but we 379 // catch the invalid user input here. 380 if req.MaxHtlcCount > input.MaxHTLCNumber/2 { 381 log.Errorf("Max htlc count: %v for channel: %v is greater "+ 382 "than limit of: %v", req.MaxHtlcCount, channelStr, 383 input.MaxHTLCNumber/2) 384 385 return false, errChannelRejected, nil, errMaxHtlcTooHigh 386 } 387 388 // Ensure that the reserve that has been proposed, if it is set, is at 389 // least the dust limit that was proposed by the remote peer. This is 390 // required by BOLT 2. 391 reserveAtoms := dcrutil.Amount(req.ReserveAtoms) 392 if reserveAtoms != 0 && reserveAtoms < dustLimit { 393 log.Errorf("Remote reserve: %v atoms for channel: %v must be "+ 394 "at least equal to proposed dust limit: %v", 395 req.ReserveAtoms, channelStr, dustLimit) 396 397 return false, errChannelRejected, nil, errInsufficientReserve 398 } 399 400 // Attempt to parse the upfront shutdown address provided. 401 upfront, err := chancloser.ParseUpfrontShutdownAddress( 402 req.UpfrontShutdown, r.params, 403 ) 404 if err != nil { 405 log.Errorf("Could not parse upfront shutdown for "+ 406 "%v: %v", channelStr, err) 407 408 return false, errChannelRejected, nil, errInvalidUpfrontShutdown 409 } 410 411 // Check that the custom error provided is valid. 412 if len(req.Error) > maxErrorLength { 413 return false, errChannelRejected, nil, errCustomLength 414 } 415 416 var haveCustomError = len(req.Error) != 0 417 418 switch { 419 // If accept is true, but we also have an error specified, we fail 420 // because this result is ambiguous. 421 case req.Accept && haveCustomError: 422 return false, errChannelRejected, nil, errAcceptWithError 423 424 // If we accept without an error message, we can just return a nil 425 // error. 426 case req.Accept: 427 return true, nil, upfront, nil 428 429 // If we reject the channel, and have a custom error, then we use it. 430 case haveCustomError: 431 return false, fmt.Errorf(req.Error), nil, nil 432 433 // Otherwise, we have rejected the channel with no custom error, so we 434 // just use a generic error to fail the channel. 435 default: 436 return false, errChannelRejected, nil, nil 437 } 438 } 439 440 // A compile-time constraint to ensure RPCAcceptor implements the ChannelAcceptor 441 // interface. 442 var _ ChannelAcceptor = (*RPCAcceptor)(nil)