diff --git a/encoding.go b/encoding.go index d4fcd34fd..5bb3d1226 100644 --- a/encoding.go +++ b/encoding.go @@ -10,6 +10,12 @@ import ( "sync" ) +var bufPool = &sync.Pool{ + New: func() interface{} { + return new(bytes.Buffer) + }, +} + var varintPool = &sync.Pool{ New: func() interface{} { return &[binary.MaxVarintLen64]byte{} @@ -93,9 +99,16 @@ func encodeBytes(w io.Writer, bz []byte) error { // encodeBytesSlice length-prefixes the byte slice and returns it. func encodeBytesSlice(bz []byte) ([]byte, error) { - var buf bytes.Buffer - err := encodeBytes(&buf, bz) - return buf.Bytes(), err + buf := bufPool.Get().(*bytes.Buffer) + buf.Reset() + defer bufPool.Put(buf) + + err := encodeBytes(buf, bz) + + bytesCopy := make([]byte, buf.Len()) + copy(bytesCopy, buf.Bytes()) + + return bytesCopy, err } // encodeBytesSize returns the byte size of the given slice including length-prefixing. diff --git a/import.go b/import.go index 1933fddd0..b0b609832 100644 --- a/import.go +++ b/import.go @@ -119,13 +119,18 @@ func (i *Importer) Add(exportNode *ExportNode) error { return err } - var buf bytes.Buffer - err = node.writeBytes(&buf) - if err != nil { + buf := bufPool.Get().(*bytes.Buffer) + buf.Reset() + defer bufPool.Put(buf) + + if err = node.writeBytes(buf); err != nil { return err } - if err = i.batch.Set(i.tree.ndb.nodeKey(node.hash), buf.Bytes()); err != nil { + bytesCopy := make([]byte, buf.Len()) + copy(bytesCopy, buf.Bytes()) + + if err = i.batch.Set(i.tree.ndb.nodeKey(node.hash), bytesCopy); err != nil { return err } diff --git a/proof.go b/proof.go index c351faad0..cef8fba8b 100644 --- a/proof.go +++ b/proof.go @@ -55,7 +55,10 @@ func (pin ProofInnerNode) stringIndented(indent string) string { func (pin ProofInnerNode) Hash(childHash []byte) []byte { hasher := sha256.New() - buf := new(bytes.Buffer) + + buf := bufPool.Get().(*bytes.Buffer) + buf.Reset() + defer bufPool.Put(buf) err := encodeVarint(buf, int64(pin.Height)) if err == nil { @@ -145,7 +148,10 @@ func (pln ProofLeafNode) stringIndented(indent string) string { func (pln ProofLeafNode) Hash() []byte { hasher := sha256.New() - buf := new(bytes.Buffer) + + buf := bufPool.Get().(*bytes.Buffer) + buf.Reset() + defer bufPool.Put(buf) err := encodeVarint(buf, 0) if err == nil { diff --git a/proof_ics23_test.go b/proof_ics23_test.go index 25f605e13..583a960c0 100644 --- a/proof_ics23_test.go +++ b/proof_ics23_test.go @@ -151,7 +151,6 @@ func GetKey(allkeys [][]byte, loc Where) []byte { return allkeys[len(allkeys)-1] } // select a random index between 1 and allkeys-2 - // nolint:gosec idx := rand.Int()%(len(allkeys)-2) + 1 return allkeys[idx] } @@ -181,7 +180,6 @@ func BuildTree(size int) (itree *ImmutableTree, keys [][]byte, err error) { for i := 0; i < size; i++ { key := make([]byte, 4) // create random 4 byte key - // nolint:gosec rand.Read(key) value := "value_for_key:" + string(key) tree.Set(key, []byte(value)) diff --git a/testutils_test.go b/testutils_test.go index 33a84936e..e36ffe39a 100644 --- a/testutils_test.go +++ b/testutils_test.go @@ -82,7 +82,6 @@ func randBytes(length int) []byte { key := make([]byte, length) // math.rand.Read always returns err=nil // we do not need cryptographic randomness for this test: - //nolint:gosec mrand.Read(key) return key } diff --git a/tree_dotgraph.go b/tree_dotgraph.go index c6f50374d..83acd46b3 100644 --- a/tree_dotgraph.go +++ b/tree_dotgraph.go @@ -55,7 +55,7 @@ func WriteDOTGraph(w io.Writer, tree *ImmutableTree, paths []PathToLeaf) { } shortHash := graphNode.Hash[:7] - graphNode.Label = mkLabel(fmt.Sprintf("%s", node.key), 16, "sans-serif") + graphNode.Label = mkLabel(string(node.key), 16, "sans-serif") graphNode.Label += mkLabel(shortHash, 10, "monospace") graphNode.Label += mkLabel(fmt.Sprintf("version=%d", node.version), 10, "monospace")