diff --git a/encoding/bytesutil/bytes.go b/encoding/bytesutil/bytes.go index 42eb1977bc4b..209428c5f0ce 100644 --- a/encoding/bytesutil/bytes.go +++ b/encoding/bytesutil/bytes.go @@ -71,6 +71,10 @@ func SafeCopyRootAtIndex(input [][]byte, idx uint64) ([]byte, error) { // SafeCopyBytes will copy and return a non-nil byte slice, otherwise it returns nil. func SafeCopyBytes(cp []byte) []byte { if cp != nil { + if len(cp) == 32 { + copied := [32]byte(cp) + return copied[:] + } copied := make([]byte, len(cp)) copy(copied, cp) return copied diff --git a/encoding/bytesutil/bytes_test.go b/encoding/bytesutil/bytes_test.go index 35708f24f173..4b9db3fcaa57 100644 --- a/encoding/bytesutil/bytes_test.go +++ b/encoding/bytesutil/bytes_test.go @@ -2,6 +2,7 @@ package bytesutil_test import ( "bytes" + "fmt" "reflect" "testing" @@ -248,3 +249,33 @@ func TestFromBytes48Array(t *testing.T) { assert.DeepEqual(t, tt.a, a) } } + +func TestSafeCopyBytes_Copy(t *testing.T) { + slice := make([]byte, 32) + slice[0] = 'A' + + copiedSlice := bytesutil.SafeCopyBytes(slice) + + assert.NotEqual(t, fmt.Sprintf("%p", slice), fmt.Sprintf("%p", copiedSlice)) + assert.Equal(t, slice[0], copiedSlice[0]) + slice[1] = 'B' + + assert.NotEqual(t, slice[1], copiedSlice[1]) +} + +func BenchmarkSafeCopyBytes(b *testing.B) { + dSlice := make([][]byte, 900000) + for i := 0; i < 900000; i++ { + slice := make([]byte, 32) + slice[0] = 'A' + dSlice[i] = slice + } + + b.ReportAllocs() + b.ResetTimer() + b.Run("Copy Bytes", func(b *testing.B) { + cSlice := bytesutil.SafeCopy2dBytes(dSlice) + a := cSlice + _ = a + }) +}