From ed0d01f92b613118bd58e0fce58d00b2066cf12e Mon Sep 17 00:00:00 2001 From: vyzo Date: Mon, 4 May 2020 09:56:51 +0300 Subject: [PATCH] add defensive checks for potentially duplicate traces --- score.go | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/score.go b/score.go index 74997bb..735b291 100644 --- a/score.go +++ b/score.go @@ -90,6 +90,7 @@ type messageDeliveries struct { type deliveryRecord struct { status int + firstSeen time.Time validated time.Time peers map[peer.ID]struct{} } @@ -511,6 +512,12 @@ func (ps *peerScore) DeliverMessage(msg *Message) { drec := ps.deliveries.getRecord(ps.msgID(msg.Message)) + // defensive check that this is the first delivery trace -- delivery status should be unknown + if drec.status != deliveryUnknown { + log.Warningf("unexpected delivery trace: message from %s was first seen %s ago and has delivery status %d", msg.ReceivedFrom, time.Now().Sub(drec.firstSeen), drec.status) + return + } + // mark the message as valid and reward mesh peers that have already forwarded it to us drec.status = deliveryValid drec.validated = time.Now() @@ -552,6 +559,12 @@ func (ps *peerScore) RejectMessage(msg *Message, reason string) { drec := ps.deliveries.getRecord(ps.msgID(msg.Message)) + // defensive check that this is the first rejection trace -- delivery status should be unknown + if drec.status != deliveryUnknown { + log.Warningf("unexpected rejection trace: message from %s was first seen %s ago and has delivery status %d", msg.ReceivedFrom, time.Now().Sub(drec.firstSeen), drec.status) + return + } + switch reason { case rejectValidationThrottled: // if we reject with "validation throttled" we don't penalize the peer(s) that forward it @@ -621,10 +634,12 @@ func (d *messageDeliveries) getRecord(id string) *deliveryRecord { return rec } - rec = &deliveryRecord{peers: make(map[peer.ID]struct{})} + now := time.Now() + + rec = &deliveryRecord{peers: make(map[peer.ID]struct{}), firstSeen: now} d.records[id] = rec - entry := &deliveryEntry{id: id, expire: time.Now().Add(TimeCacheDuration)} + entry := &deliveryEntry{id: id, expire: now.Add(TimeCacheDuration)} if d.tail != nil { d.tail.next = entry d.tail = entry