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)