core: fix bug in MPT pool during Update
We need to copy the result of `TryGet` method, otherwice the slice can be modified inside `Add` or `Update` methods, which leads to inconsistent MPT pool state.
This commit is contained in:
parent
36808b8904
commit
0aedfd0038
2 changed files with 23 additions and 1 deletions
|
@ -37,7 +37,10 @@ func (mp *Pool) TryGet(hash util.Uint256) ([][]byte, bool) {
|
|||
defer mp.lock.RUnlock()
|
||||
|
||||
paths, ok := mp.hashes[hash]
|
||||
return paths, ok
|
||||
// need to copy here, because we can modify existing array of paths inside the pool.
|
||||
res := make([][]byte, len(paths))
|
||||
copy(res, paths)
|
||||
return res, ok
|
||||
}
|
||||
|
||||
// GetAll returns all MPT nodes with the corresponding paths from the pool.
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package statesync
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"testing"
|
||||
|
||||
"github.com/nspcc-dev/neo-go/internal/random"
|
||||
|
@ -102,3 +103,21 @@ func TestPool_GetBatch(t *testing.T) {
|
|||
check(t, 5, 5)
|
||||
})
|
||||
}
|
||||
|
||||
func TestPool_UpdateUsingSliceFromPool(t *testing.T) {
|
||||
mp := NewPool()
|
||||
p1, _ := hex.DecodeString("0f0a0f0f0f0f0f0f0104020b02080c0a06050e070b050404060206060d07080602030b04040b050e040406030f0708060c05")
|
||||
p2, _ := hex.DecodeString("0f0a0f0f0f0f0f0f01040a0b000f04000b03090b02090b0e040f0d0b060d070e0b0b090b0906080602060c0d0f0e0d04070e")
|
||||
p3, _ := hex.DecodeString("0f0a0f0f0f0f0f0f01040b010d01080f050f000a0d0e08060c040b050800050904060f050807080a080c07040d0107080007")
|
||||
h, _ := util.Uint256DecodeStringBE("57e197679ef031bf2f0b466b20afe3f67ac04dcff80a1dc4d12dd98dd21a2511")
|
||||
mp.Add(h, p1)
|
||||
mp.Add(h, p2)
|
||||
mp.Add(h, p3)
|
||||
|
||||
toBeRemoved, ok := mp.TryGet(h)
|
||||
require.True(t, ok)
|
||||
|
||||
mp.Update(map[util.Uint256][][]byte{h: toBeRemoved}, nil)
|
||||
// test that all items were successfully removed.
|
||||
require.Equal(t, 0, len(mp.GetAll()))
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue