From ac5d2f94d3413143a8d0a46742de8ce9eeeb1b2c Mon Sep 17 00:00:00 2001 From: Roman Khimov Date: Sun, 22 Sep 2019 20:11:34 +0300 Subject: [PATCH] storage: fix BoltDB batched Put() It must copy both the value and the key because they can be reused for other purposes between Put() and PutBatch(). This actually happens with values in headers processing, leading to wrong data being written into the DB. Extend the batch test to check for that. --- pkg/core/storage/boltdb_store.go | 6 +++++- pkg/core/storage/boltdb_store_test.go | 10 ++++++++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/pkg/core/storage/boltdb_store.go b/pkg/core/storage/boltdb_store.go index e63ec95e0..ffa1d4ecb 100644 --- a/pkg/core/storage/boltdb_store.go +++ b/pkg/core/storage/boltdb_store.go @@ -36,7 +36,11 @@ func (b *BoltDBBatch) Len() int { // Put implements the Batch interface. func (b *BoltDBBatch) Put(k, v []byte) { - b.mem[&k] = v + vcopy := make([]byte, len(v)) + copy(vcopy, v) + kcopy := make([]byte, len(k)) + copy(kcopy, k) + b.mem[&kcopy] = vcopy } // NewBoltDBStore returns a new ready to use BoltDB storage with created bucket. diff --git a/pkg/core/storage/boltdb_store_test.go b/pkg/core/storage/boltdb_store_test.go index 51128b749..ac23d136a 100644 --- a/pkg/core/storage/boltdb_store_test.go +++ b/pkg/core/storage/boltdb_store_test.go @@ -26,11 +26,17 @@ func TestBoltDBBatch_Len(t *testing.T) { func TestBoltDBBatch_PutBatchAndGet(t *testing.T) { key := []byte("foo") + keycopy := make([]byte, len(key)) + copy(keycopy, key) value := []byte("bar") - batch := &BoltDBBatch{mem: map[*[]byte][]byte{&key: value}} - + valuecopy := make([]byte, len(value)) + copy(valuecopy, value) boltDBStore := openStore(t) + batch := boltDBStore.Batch() + batch.Put(keycopy, valuecopy) + copy(valuecopy, key) + copy(keycopy, value) errPut := boltDBStore.PutBatch(batch) assert.Nil(t, errPut, "Error while PutBatch")