2019-02-05 12:01:10 +00:00
|
|
|
import
|
|
|
|
unittest, random,
|
|
|
|
eth/trie/[trie_defs, db, binary],
|
2019-02-14 22:40:23 +00:00
|
|
|
./testutils
|
2019-02-05 12:01:10 +00:00
|
|
|
|
|
|
|
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 = toRange(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], kv1[1])
|
|
|
|
trie.set(kv2[0], kv2[1])
|
|
|
|
check trie.get(kv1[0]) == toRange(kv1[1])
|
|
|
|
check trie.get(kv2[0]) == toRange(kv2[1])
|
|
|
|
|
|
|
|
if will_delete:
|
|
|
|
trie.deleteSubtrie(key_to_be_deleted)
|
|
|
|
check trie.get(kv1[0]) == zeroBytesRange
|
|
|
|
check trie.get(kv2[0]) == zeroBytesRange
|
|
|
|
check trie.getRootHash() == zeroHash
|
|
|
|
else:
|
|
|
|
if will_raise_error:
|
|
|
|
try:
|
|
|
|
trie.deleteSubtrie(key_to_be_deleted)
|
|
|
|
except NodeOverrideError as E:
|
|
|
|
discard
|
|
|
|
except:
|
|
|
|
check(false)
|
|
|
|
else:
|
|
|
|
let root_hash_before_delete = trie.getRootHash()
|
|
|
|
trie.deleteSubtrie(key_to_be_deleted)
|
|
|
|
check trie.get(kv1[0]) == toRange(kv1[1])
|
|
|
|
check trie.get(kv2[0]) == toRange(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", "78")
|
|
|
|
trie.set("\x12\x34\x56\x79", "79")
|
|
|
|
|
|
|
|
let invalidKey = data[0]
|
|
|
|
let if_error = data[1]
|
|
|
|
|
|
|
|
check trie.get(invalidKey) == zeroBytesRange
|
|
|
|
|
|
|
|
if if_error:
|
|
|
|
try:
|
|
|
|
trie.delete(invalidKey)
|
|
|
|
except NodeOverrideError as E:
|
|
|
|
discard
|
|
|
|
except:
|
|
|
|
check(false)
|
|
|
|
else:
|
|
|
|
let previous_root_hash = trie.getRootHash()
|
|
|
|
trie.delete(invalidKey)
|
|
|
|
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, "old")
|
|
|
|
|
|
|
|
var current_root = trie.getRootHash()
|
|
|
|
for i in vals:
|
|
|
|
trie.set(keys[i], "old")
|
|
|
|
check current_root == trie.getRootHash()
|
|
|
|
trie.set(keys[i], "new")
|
|
|
|
check current_root != trie.getRootHash()
|
|
|
|
check trie.get(keys[i]) == toRange("new")
|
|
|
|
current_root = trie.getRootHash()
|