nim-eth/tests/trie/test_bin_trie.nim

128 lines
3.9 KiB
Nim

{.used.}
import
std/[unittest, random],
stew/byteutils,
../../eth/trie/[db, binary],
./testutils
suite "binary trie":
test "different order insert":
randomize()
var kv_pairs = randKVPair()
var result = zeroHash
for _ in 0..<1: # repeat 3 times
var db = newMemoryDB()
var trie = initBinaryTrie(db)
random.shuffle(kv_pairs)
for i, c in kv_pairs:
trie.set(c.key, c.value)
let x = trie.get(c.key)
let y = c.value
check y == x
check result == zeroHash or trie.getRootHash() == result
result = trie.getRootHash()
# insert already exist key/value
trie.set(kv_pairs[0].key, kv_pairs[0].value)
check trie.getRootHash() == result
# Delete all key/value
random.shuffle(kv_pairs)
for i, c in kv_pairs:
trie.delete(c.key)
check trie.getRootHash() == zeroHash
const delSubtrieData = [
(("\x12\x34\x56\x78", "78"), ("\x12\x34\x56\x79", "79"), "\x12\x34\x56", true, false),
(("\x12\x34\x56\x78", "78"), ("\x12\x34\x56\xff", "ff"), "\x12\x34\x56", true, false),
(("\x12\x34\x56\x78", "78"), ("\x12\x34\x56\x79", "79"), "\x12\x34\x57", false, false),
(("\x12\x34\x56\x78", "78"), ("\x12\x34\x56\x79", "79"), "\x12\x34\x56\x78\x9a", false, true)
]
test "delete subtrie":
for data in delSubtrieData:
var db = newMemoryDB()
var trie = initBinaryTrie(db)
let kv1 = data[0]
let kv2 = data[1]
let key_to_be_deleted = data[2]
let will_delete = data[3]
let will_raise_error = data[4]
# First test case, delete subtrie of a kv node
trie.set(kv1[0].toBytes, kv1[1].toBytes)
trie.set(kv2[0].toBytes, kv2[1].toBytes)
check trie.get(kv1[0].toBytes) == kv1[1].toBytes
check trie.get(kv2[0].toBytes) == kv2[1].toBytes
if will_delete:
trie.deleteSubtrie(key_to_be_deleted.toBytes)
check trie.get(kv1[0].toBytes) == []
check trie.get(kv2[0].toBytes) == []
check trie.getRootHash() == zeroHash
else:
if will_raise_error:
try:
trie.deleteSubtrie(key_to_be_deleted.toBytes)
except NodeOverrideError:
discard
else:
let root_hash_before_delete = trie.getRootHash()
trie.deleteSubtrie(key_to_be_deleted.toBytes)
check trie.get(kv1[0].toBytes) == toBytes(kv1[1])
check trie.get(kv2[0].toBytes) == toBytes(kv2[1])
check trie.getRootHash() == root_hash_before_delete
const invalidKeyData = [
("\x12\x34\x56", false),
("\x12\x34\x56\x77", false),
("\x12\x34\x56\x78\x9a", true),
("\x12\x34\x56\x79\xab", true),
("\xab\xcd\xef", false)
]
test "invalid key":
for data in invalidKeyData:
var db = newMemoryDB()
var trie = initBinaryTrie(db)
trie.set("\x12\x34\x56\x78".toBytes, "78".toBytes)
trie.set("\x12\x34\x56\x79".toBytes, "79".toBytes)
let invalidKey = data[0]
let if_error = data[1]
check trie.get(invalidKey.toBytes) == []
if if_error:
try:
trie.delete(invalidKey.toBytes)
except NodeOverrideError:
discard
else:
let previous_root_hash = trie.getRootHash()
trie.delete(invalidKey.toBytes)
check previous_root_hash == trie.getRootHash()
test "update value":
let keys = randList(string, randGen(32, 32), randGen(100, 100))
let vals = randList(int, randGen(0, 99), randGen(50, 50))
var db = newMemoryDB()
var trie = initBinaryTrie(db)
for key in keys:
trie.set(key.toBytes, "old".toBytes)
var current_root = trie.getRootHash()
for i in vals:
trie.set(keys[i].toBytes, "old".toBytes)
check current_root == trie.getRootHash()
trie.set(keys[i].toBytes, "new".toBytes)
check current_root != trie.getRootHash()
check trie.get(keys[i].toBytes) == toBytes("new")
current_root = trie.getRootHash()