From a04d9b7e70cb5520439814b1ade3417ae36bec50 Mon Sep 17 00:00:00 2001 From: Alex Vanin Date: Mon, 25 Jan 2021 23:16:14 +0300 Subject: [PATCH] [#40] container: Cleanup container size estimations at new epoch EpochProcess method should be invoked by inner ring nodes and it removes old estimations from contract storage. Signed-off-by: Alex Vanin --- container/container_contract.go | 43 +++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/container/container_contract.go b/container/container_contract.go index d9ed21e..e298940 100644 --- a/container/container_contract.go +++ b/container/container_contract.go @@ -58,6 +58,7 @@ const ( containerIDSize = 32 // SHA256 size estimateKeyPrefix = "cnr" + cleanupDelta = 3 ) var ( @@ -347,6 +348,30 @@ func ListContainerSizes(epoch int) [][]byte { return result } +func ProcessEpoch(epochNum int) { + netmapContractAddr := storage.Get(ctx, netmapContractKey).([]byte) + innerRing := contract.Call(netmapContractAddr, "innerRingList").([]irNode) + threshold := len(innerRing)/3*2 + 1 + + irKey := innerRingInvoker(innerRing) + if len(irKey) == 0 { + panic("processEpoch: this method must be invoked from inner ring") + } + + candidates := keysToDelete(epochNum) + epochID := invokeID([]interface{}{epochNum}, []byte("epoch")) + + n := vote(ctx, epochID, irKey) + if n >= threshold { + removeVotes(ctx, epochID) + + for i := range candidates { + candidate := candidates[i] + storage.Delete(ctx, candidate) + } + } +} + func Version() int { return version } @@ -625,3 +650,21 @@ func isStorageNode(key interop.PublicKey) bool { return false } + +func keysToDelete(epoch int) [][]byte { + results := [][]byte{} + + it := storage.Find(ctx, []byte(estimateKeyPrefix)) + for iterator.Next(it) { + k := iterator.Key(it).([]byte) + nbytes := k[len(estimateKeyPrefix) : len(k)-32] + + var n interface{} = nbytes + + if epoch-n.(int) > cleanupDelta { + results = append(results, k) + } + } + + return results +}