[#198] Fix expiration epoch calculation

Previous implementation does not provide 'at least'
lifetime guarantee.

Signed-off-by: Alex Vanin <a.vanin@yadro.com>
This commit is contained in:
Alexey Vanin 2022-09-01 12:21:27 +03:00 committed by Kira
parent 4dcdb8ef02
commit a1052c04db
2 changed files with 33 additions and 5 deletions

View file

@ -3,6 +3,7 @@ package uploader
import ( import (
"bytes" "bytes"
"fmt" "fmt"
"math"
"strconv" "strconv"
"time" "time"
@ -121,7 +122,18 @@ func prepareExpirationHeader(headers map[string]string, epochDurations *epochDur
} }
func updateExpirationHeader(headers map[string]string, durations *epochDurations, expDuration time.Duration) { func updateExpirationHeader(headers map[string]string, durations *epochDurations, expDuration time.Duration) {
epochDuration := durations.msPerBlock * int64(durations.blockPerEpoch) epochDuration := uint64(durations.msPerBlock) * durations.blockPerEpoch
numEpoch := expDuration.Milliseconds() / epochDuration currentEpoch := durations.currentEpoch
headers[object.SysAttributeExpEpoch] = strconv.FormatInt(int64(durations.currentEpoch)+numEpoch, 10) numEpoch := uint64(expDuration.Milliseconds()) / epochDuration
if uint64(expDuration.Milliseconds())%epochDuration != 0 {
numEpoch++
}
expirationEpoch := uint64(math.MaxUint64)
if numEpoch < math.MaxUint64-currentEpoch {
expirationEpoch = currentEpoch + numEpoch
}
headers[object.SysAttributeExpEpoch] = strconv.FormatUint(expirationEpoch, 10)
} }

View file

@ -1,6 +1,7 @@
package uploader package uploader
import ( import (
"math"
"strconv" "strconv"
"testing" "testing"
"time" "time"
@ -52,8 +53,13 @@ func TestPrepareExpirationHeader(t *testing.T) {
blockPerEpoch: 101, blockPerEpoch: 101,
} }
epochPerDay := (24 * time.Hour).Milliseconds() / int64(defaultDurations.blockPerEpoch) / defaultDurations.msPerBlock msPerBlock := defaultDurations.blockPerEpoch * uint64(defaultDurations.msPerBlock)
defaultExpEpoch := strconv.FormatInt(int64(defaultDurations.currentEpoch)+epochPerDay, 10) epochPerDay := uint64((24 * time.Hour).Milliseconds()) / msPerBlock
if uint64((24*time.Hour).Milliseconds())%msPerBlock != 0 {
epochPerDay++
}
defaultExpEpoch := strconv.FormatUint(defaultDurations.currentEpoch+epochPerDay, 10)
for _, tc := range []struct { for _, tc := range []struct {
name string name string
@ -130,6 +136,16 @@ func TestPrepareExpirationHeader(t *testing.T) {
durations: defaultDurations, durations: defaultDurations,
expected: map[string]string{object.SysAttributeExpEpoch: defaultExpEpoch}, expected: map[string]string{object.SysAttributeExpEpoch: defaultExpEpoch},
}, },
{
name: "valid max uint 64",
headers: map[string]string{utils.ExpirationRFC3339Attr: tomorrow.Format(time.RFC3339)},
durations: &epochDurations{
currentEpoch: math.MaxUint64 - 1,
msPerBlock: defaultDurations.msPerBlock,
blockPerEpoch: defaultDurations.blockPerEpoch,
},
expected: map[string]string{object.SysAttributeExpEpoch: strconv.FormatUint(uint64(math.MaxUint64), 10)},
},
{ {
name: "invalid timestamp sec", name: "invalid timestamp sec",
headers: map[string]string{utils.ExpirationTimestampAttr: "abc"}, headers: map[string]string{utils.ExpirationTimestampAttr: "abc"},