lnd: rpcServer now asynchronously handles bi-di sendpayment streams

This commit is contained in:
Olaoluwa Osuntokun 2016-07-21 16:22:30 -07:00
parent 979b43a3b8
commit 35bca369e7
No known key found for this signature in database
GPG Key ID: 9CC5B105D03521A2

@ -426,45 +426,57 @@ func (r *rpcServer) PendingChannels(ctx context.Context,
// bi-directional stream allowing clients to rapidly send payments through the // bi-directional stream allowing clients to rapidly send payments through the
// Lightning Network with a single persistent connection. // Lightning Network with a single persistent connection.
func (r *rpcServer) SendPayment(paymentStream lnrpc.Lightning_SendPaymentServer) error { func (r *rpcServer) SendPayment(paymentStream lnrpc.Lightning_SendPaymentServer) error {
errChan := make(chan error, 1)
for { for {
// Receive the next pending payment within the stream sent by select {
// the client. If we read the EOF sentinel, then the client has case err := <-errChan:
// closed the stream, and we can exit normally.
nextPayment, err := paymentStream.Recv()
if err == io.EOF {
return nil
} else if err != nil {
return err return err
} default:
// Receive the next pending payment within the stream sent by
// the client. If we read the EOF sentinel, then the client has
// closed the stream, and we can exit normally.
nextPayment, err := paymentStream.Recv()
if err == io.EOF {
return nil
} else if err != nil {
return err
}
// Craft an HTLC packet to send to the routing sub-system. The // Craft an HTLC packet to send to the routing sub-system. The
// meta-data within this packet will be used to route the // meta-data within this packet will be used to route the
// payment through the network. // payment through the network.
htlcAdd := &lnwire.HTLCAddRequest{ htlcAdd := &lnwire.HTLCAddRequest{
Amount: lnwire.CreditsAmount(nextPayment.Amt), Amount: lnwire.CreditsAmount(nextPayment.Amt),
RedemptionHashes: [][32]byte{debugHash}, RedemptionHashes: [][32]byte{debugHash},
} }
destAddr, err := wire.NewShaHash(nextPayment.Dest) destAddr, err := wire.NewShaHash(nextPayment.Dest)
if err != nil { if err != nil {
return err return err
} }
htlcPkt := &htlcPacket{ htlcPkt := &htlcPacket{
dest: *destAddr, dest: *destAddr,
msg: htlcAdd, msg: htlcAdd,
} }
// Finally, send this next packet to the routing layer in order // TODO(roasbeef): semaphore to limit num outstanding
// to complete the next payment. // goroutines.
// TODO(roasbeef): this should go through the L3 router once go func() {
// multi-hop is in place. // Finally, send this next packet to the routing layer in order
if err := r.server.htlcSwitch.SendHTLC(htlcPkt); err != nil { // to complete the next payment.
return err // TODO(roasbeef): this should go through the L3 router once
} // multi-hop is in place.
if err := r.server.htlcSwitch.SendHTLC(htlcPkt); err != nil {
errChan <- err
return
}
// TODO(roasbeef): proper responses // TODO(roasbeef): proper responses
resp := &lnrpc.SendResponse{} resp := &lnrpc.SendResponse{}
if err := paymentStream.Send(resp); err != nil { if err := paymentStream.Send(resp); err != nil {
return err errChan <- err
return
}
}()
} }
} }