diff --git a/channels/send.go b/channels/send.go index 9b5b4fdb5fed58078168286e553ad7dc5dc78137..7b46152bb07b801fcd23fcd649829065d4e654db 100644 --- a/channels/send.go +++ b/channels/send.go @@ -10,6 +10,7 @@ package channels import ( "crypto/ed25519" "github.com/pkg/errors" + jww "github.com/spf13/jwalterweatherman" "gitlab.com/elixxir/client/cmix" "gitlab.com/elixxir/client/cmix/rounds" cryptoChannel "gitlab.com/elixxir/crypto/channel" @@ -115,6 +116,11 @@ func (m *manager) SendGeneric(channelID *id.ID, messageType MessageType, r, ephid, err := ch.broadcast.BroadcastWithAssembler(assemble, params) if err != nil { + errDenote := m.st.failedSend(uuid) + if errDenote != nil { + jww.ERROR.Printf("Failed to update for a failed send to "+ + "%s: %+v", channelID, err) + } return cryptoChannel.MessageID{}, rounds.Round{}, ephemeral.Id{}, err } err = m.st.send(uuid, msgId, r) @@ -192,8 +198,16 @@ func (m *manager) SendAdminGeneric(privKey rsa.PrivateKey, channelID *id.ID, r, ephid, err := ch.broadcast.BroadcastRSAToPublicWithAssembler(privKey, assemble, params) + if err != nil { + errDenote := m.st.failedSend(uuid) + if errDenote != nil { + jww.ERROR.Printf("Failed to update for a failed send to "+ + "%s: %+v", channelID, err) + } + return cryptoChannel.MessageID{}, rounds.Round{}, ephemeral.Id{}, err + } - err = m.st.sendAdmin(uuid, msgId, r) + err = m.st.send(uuid, msgId, r) if err != nil { return cryptoChannel.MessageID{}, rounds.Round{}, ephemeral.Id{}, err } diff --git a/channels/sendTracker.go b/channels/sendTracker.go index 0678993a754739b49ac3d7e0b56c6d2eff8d622b..0c6aecb4c5c2f6b21b013700b56b5d6f22f7ec91 100644 --- a/channels/sendTracker.go +++ b/channels/sendTracker.go @@ -274,22 +274,17 @@ func (st *sendTracker) send(uuid uint64, msgID cryptoChannel.MessageID, return nil } -// sendAdmin tracks a generic sendAdmin message -func (st *sendTracker) sendAdmin(uuid uint64, msgID cryptoChannel.MessageID, - round rounds.Round) error { +// send tracks a generic send message +func (st *sendTracker) failedSend(uuid uint64) error { // update the on disk message status - t, err := st.handleSend(uuid, msgID, round) + t, err := st.handleSendFailed(uuid) if err != nil { return err } - // Modify the timestamp to reduce the chance message order will be ambiguous - ts := mutateTimestamp(round.Timestamps[states.QUEUED], msgID) - //update the message on the UI - go st.updateStatus(t.UUID, msgID, ts, round, Sent) - + go st.updateStatus(t.UUID, cryptoChannel.MessageID{}, time.Time{}, rounds.Round{}, Failed) return nil } @@ -329,8 +324,32 @@ func (st *sendTracker) handleSend(uuid uint64, st.net.GetRoundResults(getRoundResultsTimeout, rr.callback, rr.round) }*/ + delete(st.unsent, uuid) + + //store the changed list to disk + err := st.store() + if err != nil { + jww.FATAL.Panicf(err.Error()) + } + + return t, nil +} + +// handleSendFailed does the nity gritty of editing internal structures +func (st *sendTracker) handleSendFailed(uuid uint64) (*tracked, error) { + st.mux.Lock() + defer st.mux.Unlock() + + //check if in unsent + t, exists := st.unsent[uuid] + if !exists { + return nil, errors.New("cannot handle send on an unprepared message") + } + + delete(st.unsent, uuid) + //store the changed list to disk - err := st.storeSent() + err := st.storeUnsent() if err != nil { jww.FATAL.Panicf(err.Error()) } diff --git a/channels/sendTracker_test.go b/channels/sendTracker_test.go index a90926f33ea427a4f26d5b132c90cf6df7e0bc7e..5210b20e6c0598f5c8bf16e831a9b5b9e3c3dda6 100644 --- a/channels/sendTracker_test.go +++ b/channels/sendTracker_test.go @@ -122,10 +122,10 @@ func TestSendTracker_MessageReceive(t *testing.T) { } } -// Test sendAdmin function, confirming that data is stored appropriately +// Test failedSend function, confirming that data is stored appropriately // and callbacks are called -func TestSendTracker_sendAdmin(t *testing.T) { - triggerCh := make(chan bool) +func TestSendTracker_failedSend(t *testing.T) { + triggerCh := make(chan SentStatus) kv := versioned.NewKV(ekv.MakeMemstore()) @@ -137,7 +137,7 @@ func TestSendTracker_sendAdmin(t *testing.T) { updateStatus := func(uuid uint64, messageID cryptoChannel.MessageID, timestamp time.Time, round rounds.Round, status SentStatus) { - triggerCh <- true + triggerCh <- status } st := loadSendTracker(&mockClient{}, kv, nil, adminTrigger, updateStatus) @@ -155,39 +155,38 @@ func TestSendTracker_sendAdmin(t *testing.T) { t.Fatalf(err.Error()) } - err = st.sendAdmin(uuid, mid, rounds.Round{ - ID: rid, - State: 2, - }) + err = st.failedSend(uuid) if err != nil { t.Fatalf(err.Error()) } timeout := time.NewTicker(time.Second * 5) select { - case <-triggerCh: + case s := <-triggerCh: + if s != Failed { + t.Fatalf("Did not receive failed from failed message") + } t.Log("Received over trigger chan") case <-timeout.C: t.Fatal("Timed out waiting for trigger chan") } trackedRound, ok := st.byRound[rid] - if !ok { - t.Fatal("Should have found a tracked round") + if ok { + t.Fatal("Should not have found a tracked round") } - if len(trackedRound) != 1 { + if len(trackedRound) != 0 { t.Fatal("Did not find expected number of trackedRounds") } - if trackedRound[0].MsgID != mid { - t.Fatalf("Did not find expected message ID in trackedRounds") - } - trackedMsg, ok := st.byMessageID[mid] - if !ok { - t.Error("Should have found tracked message") + _, ok = st.byMessageID[mid] + if ok { + t.Error("Should not have found tracked message") } - if trackedMsg.MsgID != mid { - t.Fatalf("Did not find expected message ID in byMessageID") + + _, ok = st.unsent[uuid] + if ok { + t.Fatal("Should not have found an unsent") } }