From 3ca1be322ecbcea9c8d2bd4cacd8f7076a9e3c26 Mon Sep 17 00:00:00 2001 From: Olaoluwa Osuntokun Date: Wed, 19 May 2021 21:00:59 -0700 Subject: [PATCH] sidecar: allow recipient ID to be derived using base offer ticket In this commit, we fix a bug in the retransmission case for the provider. Before this commit, the provider would attempt to re-send the initial offer ticket on restart if it hadn't yet received the registered ticket. This fails as the recipient's stream ID is derived from their pubkey information that's only contained in the registered ticket. To fix this, we'll simply use the sha512 hash of the offer sig since it's known when the ticket is initially created. --- auto_sidecar.go | 45 ++++++++++++++++++++++++++------------------- 1 file changed, 26 insertions(+), 19 deletions(-) diff --git a/auto_sidecar.go b/auto_sidecar.go index c79652c..c15c666 100644 --- a/auto_sidecar.go +++ b/auto_sidecar.go @@ -3,6 +3,7 @@ package pool import ( "bytes" "context" + "crypto/sha512" "errors" "fmt" @@ -53,21 +54,24 @@ func deriveProviderStreamID(ticket *sidecar.Ticket) ([64]byte, error) { // deriveRecipientStreamID derives the stream ID of the cipher box that the // provider of the sidecar ticket will use to send messages to the receiver. -func deriveRecipientStreamID(ticket *sidecar.Ticket) [64]byte { - receiverMultisig := ticket.Recipient.NodePubKey.SerializeCompressed() - receiverNode := ticket.Recipient.MultiSigPubKey.SerializeCompressed() - - // The stream ID will be the concentration of the receiver's multi-sig - // and node keys, ignoring the first byte of each key that essentially - // communicates parity information. - var ( - streamID [64]byte - n int +func deriveRecipientStreamID(ticket *sidecar.Ticket) ([64]byte, error) { + // In order to ensure our retransmission case for the provider works + // (on start up, it resends the offered ticket in case it got the + // registered but didn't commit to disk), the provider needs to be able + // to compute the recipient's stream ID using the base offered ticket. + // + // To enable this, we'll use the sha256 of the offer sig as this is + // static for the lifetime of the entire ticket. + wireSig, err := lnwire.NewSigFromRawSignature( + ticket.Offer.SigOfferDigest.Serialize(), ) - n += copy(streamID[:], receiverMultisig[1:]) - copy(streamID[n:], receiverNode[1:]) + if err != nil { + return [64]byte{}, err + } - return streamID + streamID := sha512.Sum512(wireSig[:]) + + return streamID, nil } // deriveStreamID derives corresponding stream ID for the provider of the @@ -77,7 +81,7 @@ func deriveStreamID(ticket *sidecar.Ticket, provider bool) ([64]byte, error) { return deriveProviderStreamID(ticket) } - return deriveRecipientStreamID(ticket), nil + return deriveRecipientStreamID(ticket) } // sendSidecarPkt attempts to send a sidecar packet to the opposite party using @@ -167,15 +171,19 @@ func (a *SidecarAcceptor) autoSidecarReceiver(startingPkt *SidecarPacket) { // Before we enter our main read loop below, we'll attempt to re-create // out mailbox as the recipient. - recipientStreamID := deriveRecipientStreamID( + recipientStreamID, err := deriveRecipientStreamID( localTicket, ) + if err != nil { + log.Errorf("unable to derive recipient ID: %v", err) + return + } log.Infof("Creating receiver reply mailbox for ticket=%x, "+ "stream_id=%x", startingPkt.ReceiverTicket.ID[:], recipientStreamID[:]) - err := a.client.InitTicketCipherBox( + err = a.client.InitTicketCipherBox( context.Background(), recipientStreamID, startingPkt.ReceiverTicket, ) @@ -200,6 +208,7 @@ func (a *SidecarAcceptor) autoSidecarReceiver(startingPkt *SidecarPacket) { startingPkt.ReceiverTicket, false, ) if err != nil { + // TODO(roasbeef): back off then retry? log.Error(err) return } @@ -337,7 +346,7 @@ func (a *SidecarAcceptor) stateStepRecipient(pkt *SidecarPacket, // it. default: return nil, fmt.Errorf("unhandled receiver state transition "+ - "for ticket=%v, state=%v", pkt.ProviderTicket.ID[:], + "for ticket=%x, state=%v", pkt.ProviderTicket.ID[:], pkt.ProviderTicket.State) } } @@ -420,8 +429,6 @@ func (a *SidecarAcceptor) autoSidecarProvider(startingPkt *SidecarPacket, for { priorState := currentState - log.Infof("step=%v", currentState) - newPktState, err := a.stateStepProvider(&SidecarPacket{ CurrentState: currentState, ReceiverTicket: newTicket,