From 639b3420b2e5f3f5bd8ad0fa030d4af44d314d29 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Fri, 20 Sep 2024 14:26:06 -0400 Subject: [PATCH 1/2] Explicitly zero slices before reducing length --- database/batch.go | 7 ++++++- database/encdb/db.go | 2 ++ database/prefixdb/db.go | 1 + utils/set/sampleable_set.go | 4 +--- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/database/batch.go b/database/batch.go index f3187a1fa954..28e63859a424 100644 --- a/database/batch.go +++ b/database/batch.go @@ -7,7 +7,11 @@ package database -import "slices" +import ( + "slices" + + "github.com/ava-labs/avalanchego/utils" +) // Batch is a write-only database that commits changes to its host database // when Write is called. A batch cannot be used concurrently. @@ -75,6 +79,7 @@ func (b *BatchOps) Size() int { } func (b *BatchOps) Reset() { + utils.ZeroSlice(b.Ops) b.Ops = b.Ops[:0] b.size = 0 } diff --git a/database/encdb/db.go b/database/encdb/db.go index 2bdacb465ffa..f87bdd49bebc 100644 --- a/database/encdb/db.go +++ b/database/encdb/db.go @@ -13,6 +13,7 @@ import ( "golang.org/x/crypto/chacha20poly1305" "github.com/ava-labs/avalanchego/database" + "github.com/ava-labs/avalanchego/utils" "github.com/ava-labs/avalanchego/utils/hashing" ) @@ -204,6 +205,7 @@ func (b *batch) Reset() { if cap(b.ops) > len(b.ops)*database.MaxExcessCapacityFactor { b.ops = make([]database.BatchOp, 0, cap(b.ops)/database.CapacityReductionFactor) } else { + utils.ZeroSlice(b.ops) b.ops = b.ops[:0] } b.Batch.Reset() diff --git a/database/prefixdb/db.go b/database/prefixdb/db.go index b3082d9e986e..087a06c3c3b6 100644 --- a/database/prefixdb/db.go +++ b/database/prefixdb/db.go @@ -313,6 +313,7 @@ func (b *batch) Reset() { if cap(b.ops) > len(b.ops)*database.MaxExcessCapacityFactor { b.ops = make([]batchOp, 0, cap(b.ops)/database.CapacityReductionFactor) } else { + utils.ZeroSlice(b.ops) b.ops = b.ops[:0] } b.Batch.Reset() diff --git a/utils/set/sampleable_set.go b/utils/set/sampleable_set.go index efb63c2d777c..de0a707f8251 100644 --- a/utils/set/sampleable_set.go +++ b/utils/set/sampleable_set.go @@ -108,9 +108,7 @@ func (s *SampleableSet[T]) Remove(elements ...T) { // Clear empties this set func (s *SampleableSet[T]) Clear() { clear(s.indices) - for i := range s.elements { - s.elements[i] = utils.Zero[T]() - } + utils.ZeroSlice(s.elements) s.elements = s.elements[:0] } From 6f2eb52c2d2194be6ff6243313723e25de8cc369 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Fri, 20 Sep 2024 14:31:44 -0400 Subject: [PATCH 2/2] use clear --- database/batch.go | 8 ++------ database/encdb/db.go | 3 +-- database/prefixdb/db.go | 2 +- utils/set/sampleable_set.go | 2 +- utils/zero.go | 14 ++------------ 5 files changed, 7 insertions(+), 22 deletions(-) diff --git a/database/batch.go b/database/batch.go index 28e63859a424..8a37ee723693 100644 --- a/database/batch.go +++ b/database/batch.go @@ -7,11 +7,7 @@ package database -import ( - "slices" - - "github.com/ava-labs/avalanchego/utils" -) +import "slices" // Batch is a write-only database that commits changes to its host database // when Write is called. A batch cannot be used concurrently. @@ -79,7 +75,7 @@ func (b *BatchOps) Size() int { } func (b *BatchOps) Reset() { - utils.ZeroSlice(b.Ops) + clear(b.Ops) b.Ops = b.Ops[:0] b.size = 0 } diff --git a/database/encdb/db.go b/database/encdb/db.go index f87bdd49bebc..ea82b16a3659 100644 --- a/database/encdb/db.go +++ b/database/encdb/db.go @@ -13,7 +13,6 @@ import ( "golang.org/x/crypto/chacha20poly1305" "github.com/ava-labs/avalanchego/database" - "github.com/ava-labs/avalanchego/utils" "github.com/ava-labs/avalanchego/utils/hashing" ) @@ -205,7 +204,7 @@ func (b *batch) Reset() { if cap(b.ops) > len(b.ops)*database.MaxExcessCapacityFactor { b.ops = make([]database.BatchOp, 0, cap(b.ops)/database.CapacityReductionFactor) } else { - utils.ZeroSlice(b.ops) + clear(b.ops) b.ops = b.ops[:0] } b.Batch.Reset() diff --git a/database/prefixdb/db.go b/database/prefixdb/db.go index 087a06c3c3b6..e1ec8da5007e 100644 --- a/database/prefixdb/db.go +++ b/database/prefixdb/db.go @@ -313,7 +313,7 @@ func (b *batch) Reset() { if cap(b.ops) > len(b.ops)*database.MaxExcessCapacityFactor { b.ops = make([]batchOp, 0, cap(b.ops)/database.CapacityReductionFactor) } else { - utils.ZeroSlice(b.ops) + clear(b.ops) b.ops = b.ops[:0] } b.Batch.Reset() diff --git a/utils/set/sampleable_set.go b/utils/set/sampleable_set.go index de0a707f8251..a70b332a9a68 100644 --- a/utils/set/sampleable_set.go +++ b/utils/set/sampleable_set.go @@ -108,7 +108,7 @@ func (s *SampleableSet[T]) Remove(elements ...T) { // Clear empties this set func (s *SampleableSet[T]) Clear() { clear(s.indices) - utils.ZeroSlice(s.elements) + clear(s.elements) s.elements = s.elements[:0] } diff --git a/utils/zero.go b/utils/zero.go index c691ed2e653c..bb31de1c8d58 100644 --- a/utils/zero.go +++ b/utils/zero.go @@ -4,16 +4,6 @@ package utils // Returns a new instance of a T. -func Zero[T any]() T { - return *new(T) -} - -// ZeroSlice sets all values of the provided slice to the type's zero value. -// -// This can be useful to ensure that the garbage collector doesn't hold -// references to values that are no longer desired. -func ZeroSlice[T any](s []T) { - for i := range s { - s[i] = *new(T) - } +func Zero[T any]() (_ T) { + return }