From 5c414bb1d0bdd00da454a157fe97429a03088beb Mon Sep 17 00:00:00 2001 From: Wilmer Paulino Date: Thu, 9 Aug 2018 19:17:16 -0700 Subject: [PATCH] multi: make OpenChannel take in openChanReq --- pilot.go | 16 +++++++++-- rpcserver.go | 33 +++++++++++++++------- server.go | 78 ++++++++++++++++------------------------------------ 3 files changed, 59 insertions(+), 68 deletions(-) diff --git a/pilot.go b/pilot.go index 86093a6f..86c8ef5a 100644 --- a/pilot.go +++ b/pilot.go @@ -37,10 +37,20 @@ func (c *chanController) OpenChannel(target *btcec.PublicKey, // TODO(halseth): make configurable? minHtlc := lnwire.NewMSatFromSatoshis(1) - updateStream, errChan := c.server.OpenChannel( - target, amt, 0, minHtlc, feePerKw, c.private, 0, - ) + // Construct the open channel request and send it to the server to begin + // the funding workflow. + req := &openChanReq{ + targetPubkey: target, + chainHash: *activeNetParams.GenesisHash, + localFundingAmt: amt, + pushAmt: 0, + minHtlc: minHtlc, + fundingFeePerKw: feePerKw, + private: c.private, + remoteCsvDelay: 0, + } + updateStream, errChan := c.server.OpenChannel(req) select { case err := <-errChan: // If we were not able to actually open a channel to the peer diff --git a/rpcserver.go b/rpcserver.go index 87d78bb3..6f4e8e6c 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -813,11 +813,18 @@ func (r *rpcServer) OpenChannel(in *lnrpc.OpenChannelRequest, // Instruct the server to trigger the necessary events to attempt to // open a new channel. A stream is returned in place, this stream will // be used to consume updates of the state of the pending channel. - updateChan, errChan := r.server.OpenChannel( - nodePubKey, localFundingAmt, - lnwire.NewMSatFromSatoshis(remoteInitialBalance), - minHtlc, feeRate, in.Private, remoteCsvDelay, - ) + req := &openChanReq{ + targetPubkey: nodePubKey, + chainHash: *activeNetParams.GenesisHash, + localFundingAmt: localFundingAmt, + pushAmt: lnwire.NewMSatFromSatoshis(remoteInitialBalance), + minHtlc: minHtlc, + fundingFeePerKw: feeRate, + private: in.Private, + remoteCsvDelay: remoteCsvDelay, + } + + updateChan, errChan := r.server.OpenChannel(req) var outpoint wire.OutPoint out: @@ -941,12 +948,18 @@ func (r *rpcServer) OpenChannelSync(ctx context.Context, rpcsLog.Tracef("[openchannel] target sat/kw for funding tx: %v", int64(feeRate)) - updateChan, errChan := r.server.OpenChannel( - nodepubKey, localFundingAmt, - lnwire.NewMSatFromSatoshis(remoteInitialBalance), - minHtlc, feeRate, in.Private, remoteCsvDelay, - ) + req := &openChanReq{ + targetPubkey: nodepubKey, + chainHash: *activeNetParams.GenesisHash, + localFundingAmt: localFundingAmt, + pushAmt: lnwire.NewMSatFromSatoshis(remoteInitialBalance), + minHtlc: minHtlc, + fundingFeePerKw: feeRate, + private: in.Private, + remoteCsvDelay: remoteCsvDelay, + } + updateChan, errChan := r.server.OpenChannel(req) select { // If an error occurs them immediately return the error to the client. case err := <-errChan: diff --git a/server.go b/server.go index bf770092..80443f41 100644 --- a/server.go +++ b/server.go @@ -2735,77 +2735,45 @@ func (s *server) DisconnectPeer(pubKey *btcec.PublicKey) error { // peer identified by nodeKey with the passed channel funding parameters. // // NOTE: This function is safe for concurrent access. -func (s *server) OpenChannel(nodeKey *btcec.PublicKey, - localAmt btcutil.Amount, pushAmt, minHtlc lnwire.MilliSatoshi, - fundingFeePerKw lnwallet.SatPerKWeight, private bool, - remoteCsvDelay uint16) (chan *lnrpc.OpenStatusUpdate, chan error) { +func (s *server) OpenChannel( + req *openChanReq) (chan *lnrpc.OpenStatusUpdate, chan error) { - // The updateChan will have a buffer of 2, since we expect a - // ChanPending + a ChanOpen update, and we want to make sure the - // funding process is not blocked if the caller is not reading the - // updates. - updateChan := make(chan *lnrpc.OpenStatusUpdate, 2) - errChan := make(chan error, 1) - - var ( - targetPeer *peer - pubKeyBytes []byte - err error - ) - - // If the user is targeting the peer by public key, then we'll need to - // convert that into a string for our map. Otherwise, we expect them to - // target by peer ID instead. - if nodeKey != nil { - pubKeyBytes = nodeKey.SerializeCompressed() - } + // The updateChan will have a buffer of 2, since we expect a ChanPending + // + a ChanOpen update, and we want to make sure the funding process is + // not blocked if the caller is not reading the updates. + req.updates = make(chan *lnrpc.OpenStatusUpdate, 2) + req.err = make(chan error, 1) // First attempt to locate the target peer to open a channel with, if // we're unable to locate the peer then this request will fail. + pubKeyBytes := req.targetPubkey.SerializeCompressed() s.mu.RLock() - if peer, ok := s.peersByPub[string(pubKeyBytes)]; ok { - targetPeer = peer + peer, ok := s.peersByPub[string(pubKeyBytes)] + if !ok { + req.err <- fmt.Errorf("peer %x is not online", pubKeyBytes) + return req.updates, req.err } s.mu.RUnlock() - if targetPeer == nil { - errChan <- fmt.Errorf("peer is not connected NodeKey(%x)", pubKeyBytes) - return updateChan, errChan - } - // If the fee rate wasn't specified, then we'll use a default // confirmation target. - if fundingFeePerKw == 0 { + if req.fundingFeePerKw == 0 { estimator := s.cc.feeEstimator - fundingFeePerKw, err = estimator.EstimateFeePerKW(6) + feeRate, err := estimator.EstimateFeePerKW(6) if err != nil { - errChan <- err - return updateChan, errChan + req.err <- err + return req.updates, req.err } + req.fundingFeePerKw = feeRate } - // Spawn a goroutine to send the funding workflow request to the - // funding manager. This allows the server to continue handling queries - // instead of blocking on this request which is exported as a - // synchronous request to the outside world. - req := &openChanReq{ - targetPubkey: nodeKey, - chainHash: *activeNetParams.GenesisHash, - localFundingAmt: localAmt, - fundingFeePerKw: fundingFeePerKw, - pushAmt: pushAmt, - private: private, - minHtlc: minHtlc, - remoteCsvDelay: remoteCsvDelay, - updates: updateChan, - err: errChan, - } + // Spawn a goroutine to send the funding workflow request to the funding + // manager. This allows the server to continue handling queries instead + // of blocking on this request which is exported as a synchronous + // request to the outside world. + go s.fundingMgr.initFundingWorkflow(peer, req) - // TODO(roasbeef): pass in chan that's closed if/when funding succeeds - // so can track as persistent peer? - go s.fundingMgr.initFundingWorkflow(targetPeer, req) - - return updateChan, errChan + return req.updates, req.err } // Peers returns a slice of all active peers.