From 639b3420b2e5f3f5bd8ad0fa030d4af44d314d29 Mon Sep 17 00:00:00 2001
From: Stephen Buttolph <stephen@avalabs.org>
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 <stephen@avalabs.org>
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
 }