//////////////////////////////////////////////////////////////////////////////// // Copyright © 2022 xx foundation // // // // Use of this source code is governed by a license that can be found in the // // LICENSE file. // //////////////////////////////////////////////////////////////////////////////// package single import ( "fmt" jww "github.com/spf13/jwalterweatherman" "gitlab.com/elixxir/client/cmix/identity/receptionID" "gitlab.com/elixxir/client/cmix/rounds" "gitlab.com/elixxir/client/single/message" "gitlab.com/elixxir/crypto/contact" "gitlab.com/elixxir/primitives/format" ) type callbackWrapper func(payload []byte, receptionID receptionID.EphemeralIdentity, rounds []rounds.Round, err error) // responseProcessor is registered for each potential fingerprint. Adheres to // the message.Processor interface registered with cmix.Client type responseProcessor struct { sendingID receptionID.EphemeralIdentity c *message.Collator callback callbackWrapper cy cypher tag string recipient *contact.Contact roundIDs *roundCollector } // Process decrypts a response part and adds it to the collator - returning // a full response to the callback when all parts are received. func (rsp *responseProcessor) Process(ecrMsg format.Message, receptionID receptionID.EphemeralIdentity, round rounds.Round) { decrypted, err := rsp.cy.decrypt(ecrMsg.GetContents(), ecrMsg.GetMac()) if err != nil { jww.ERROR.Printf("[SU] Failed to decrypt single-use response "+ "payload for %s to %s: %+v", rsp.tag, rsp.recipient.ID, err) return } responsePart, err := message.UnmarshalResponsePart(decrypted) if err != nil { jww.ERROR.Printf("[SU] Failed to unmarshal single-use response part "+ "payload for %s to %s: %+v", rsp.tag, rsp.recipient.ID, err) return } payload, done, err := rsp.c.Collate(responsePart) if err != nil { jww.ERROR.Printf("[SU] Failed to collate single-use response payload "+ "for %s to %s, single use may fail: %+v", rsp.tag, rsp.recipient.ID, err) return } rsp.roundIDs.add(round) if done { rsp.callback(payload, receptionID, rsp.roundIDs.getList(), nil) } } func (rsp *responseProcessor) String() string { return fmt.Sprintf("SingleUseFP(%s, %s)", rsp.sendingID, rsp.recipient.ID) }