diff --git a/pkg/core/mpt/base.go b/pkg/core/mpt/base.go index 1c4ebd8a6..c81bfe6be 100644 --- a/pkg/core/mpt/base.go +++ b/pkg/core/mpt/base.go @@ -63,7 +63,7 @@ func (b *BaseNode) updateHash(n Node) { // updateCache updates hash and bytes fields for this BaseNode. func (b *BaseNode) updateBytes(n Node) { - buf := io.NewBufBinWriter() + buf := io.NewBufBinWriterPreAlloc(b.bytes) encodeNodeWithType(n, buf.BinWriter) b.bytes = buf.Bytes() b.bytesValid = true diff --git a/pkg/core/mpt/trie.go b/pkg/core/mpt/trie.go index 751b1b2f3..acc11639c 100644 --- a/pkg/core/mpt/trie.go +++ b/pkg/core/mpt/trie.go @@ -418,31 +418,29 @@ func (t *Trie) updateRefCount(h util.Uint256) int32 { func (t *Trie) addRef(h util.Uint256, bs []byte) { node := t.refcount[h] if node == nil { + data := make([]byte, len(bs)) + copy(data, bs) t.refcount[h] = &cachedNode{ refcount: 1, - bytes: bs, + bytes: data, } return } node.refcount++ - if node.bytes == nil { - node.bytes = bs - } } func (t *Trie) removeRef(h util.Uint256, bs []byte) { node := t.refcount[h] if node == nil { + data := make([]byte, len(bs)) + copy(data, bs) t.refcount[h] = &cachedNode{ refcount: -1, - bytes: bs, + bytes: data, } return } node.refcount-- - if node.bytes == nil { - node.bytes = bs - } } func (t *Trie) getFromStore(h util.Uint256) (Node, error) { @@ -462,7 +460,8 @@ func (t *Trie) getFromStore(h util.Uint256) (Node, error) { data = data[:len(data)-4] node := t.refcount[h] if node != nil { - node.bytes = data + node.bytes = make([]byte, len(data)) + copy(node.bytes, data) node.initial = int32(r.ReadU32LE()) } } diff --git a/pkg/io/binaryBufWriter.go b/pkg/io/binaryBufWriter.go index 7015082e1..3e1245d3a 100644 --- a/pkg/io/binaryBufWriter.go +++ b/pkg/io/binaryBufWriter.go @@ -19,6 +19,12 @@ func NewBufBinWriter() *BufBinWriter { return &BufBinWriter{BinWriter: NewBinWriterFromIO(b), buf: b} } +// NewBufBinWriterPreAlloc makes a BufBinWriter using preallocated buffer. +func NewBufBinWriterPreAlloc(buf []byte) *BufBinWriter { + b := bytes.NewBuffer(buf[:0]) + return &BufBinWriter{BinWriter: NewBinWriterFromIO(b), buf: b} +} + // Len returns the number of bytes of the unread portion of the buffer. func (bw *BufBinWriter) Len() int { return bw.buf.Len()