2020-04-18 08:17:59 +00:00
|
|
|
{.used.}
|
|
|
|
|
2019-02-05 12:01:10 +00:00
|
|
|
import
|
2020-04-20 18:14:39 +00:00
|
|
|
unittest, stew/byteutils,
|
2019-02-05 12:01:10 +00:00
|
|
|
nimcrypto/[keccak, hash],
|
2020-04-20 18:14:39 +00:00
|
|
|
eth/trie/[db, binary, binaries, trie_utils, branches]
|
2019-02-05 12:01:10 +00:00
|
|
|
|
|
|
|
suite "examples":
|
|
|
|
|
|
|
|
var db = newMemoryDB()
|
|
|
|
var trie = initBinaryTrie(db)
|
|
|
|
|
|
|
|
test "basic set/get":
|
2020-04-20 18:14:39 +00:00
|
|
|
trie.set("key1".toBytes(), "value1".toBytes())
|
|
|
|
trie.set("key2".toBytes(), "value2".toBytes())
|
|
|
|
check trie.get("key1".toBytes) == "value1".toBytes
|
|
|
|
check trie.get("key2".toBytes) == "value2".toBytes
|
2019-02-05 12:01:10 +00:00
|
|
|
|
|
|
|
test "check branch exists":
|
2020-04-20 18:14:39 +00:00
|
|
|
check checkIfBranchExist(db, trie.getRootHash(), "key".toBytes) == true
|
|
|
|
check checkIfBranchExist(db, trie.getRootHash(), "key1".toBytes) == true
|
|
|
|
check checkIfBranchExist(db, trie.getRootHash(), "ken".toBytes) == false
|
|
|
|
check checkIfBranchExist(db, trie.getRootHash(), "key123".toBytes) == false
|
2019-02-05 12:01:10 +00:00
|
|
|
|
|
|
|
test "branches utils":
|
2020-04-20 18:14:39 +00:00
|
|
|
var branchA = getBranch(db, trie.getRootHash(), "key1".toBytes)
|
2019-02-05 12:01:10 +00:00
|
|
|
# ==> [A, B, C1, D1]
|
|
|
|
check branchA.len == 4
|
|
|
|
|
2020-04-20 18:14:39 +00:00
|
|
|
var branchB = getBranch(db, trie.getRootHash(), "key2".toBytes)
|
2019-02-05 12:01:10 +00:00
|
|
|
# ==> [A, B, C2, D2]
|
|
|
|
check branchB.len == 4
|
|
|
|
|
2020-04-20 18:14:39 +00:00
|
|
|
check isValidBranch(branchA, trie.getRootHash(), "key1".toBytes, "value1".toBytes) == true
|
|
|
|
check isValidBranch(branchA, trie.getRootHash(), "key5".toBytes, "".toBytes) == true
|
2019-02-05 12:01:10 +00:00
|
|
|
|
|
|
|
expect InvalidNode:
|
2020-04-20 18:14:39 +00:00
|
|
|
check isValidBranch(branchB, trie.getRootHash(), "key1".toBytes, "value1".toBytes)
|
2019-02-05 12:01:10 +00:00
|
|
|
|
2020-04-20 18:14:39 +00:00
|
|
|
var x = getBranch(db, trie.getRootHash(), "key".toBytes)
|
2019-02-05 12:01:10 +00:00
|
|
|
# ==> [A]
|
|
|
|
check x.len == 1
|
|
|
|
|
|
|
|
expect InvalidKeyError:
|
2020-04-20 18:14:39 +00:00
|
|
|
x = getBranch(db, trie.getRootHash(), "key123".toBytes) # InvalidKeyError
|
2019-02-05 12:01:10 +00:00
|
|
|
|
2020-04-20 18:14:39 +00:00
|
|
|
x = getBranch(db, trie.getRootHash(), "key5".toBytes) # there is still branch for non-exist key
|
2019-02-05 12:01:10 +00:00
|
|
|
# ==> [A]
|
|
|
|
check x.len == 1
|
|
|
|
|
|
|
|
test "getWitness":
|
2020-04-20 18:14:39 +00:00
|
|
|
var branch = getWitness(db, trie.getRootHash(), "key1".toBytes)
|
2019-02-05 12:01:10 +00:00
|
|
|
# equivalent to `getBranch(db, trie.getRootHash(), "key1")`
|
|
|
|
# ==> [A, B, C1, D1]
|
|
|
|
check branch.len == 4
|
|
|
|
|
2020-04-20 18:14:39 +00:00
|
|
|
branch = getWitness(db, trie.getRootHash(), "key".toBytes)
|
2019-02-05 12:01:10 +00:00
|
|
|
# this will include additional nodes of "key2"
|
|
|
|
# ==> [A, B, C1, D1, C2, D2]
|
|
|
|
check branch.len == 6
|
|
|
|
|
2020-04-20 18:14:39 +00:00
|
|
|
branch = getWitness(db, trie.getRootHash(), "".toBytes)
|
2019-02-05 12:01:10 +00:00
|
|
|
# this will return the whole trie
|
|
|
|
# ==> [A, B, C1, D1, C2, D2]
|
|
|
|
check branch.len == 6
|
|
|
|
|
|
|
|
let beforeDeleteLen = db.totalRecordsInMemoryDB
|
|
|
|
test "verify intermediate entries existence":
|
2020-04-20 18:14:39 +00:00
|
|
|
var branchs = getWitness(db, trie.getRootHash, [])
|
2019-02-05 12:01:10 +00:00
|
|
|
# set operation create new intermediate entries
|
|
|
|
check branchs.len < beforeDeleteLen
|
|
|
|
|
|
|
|
var node = branchs[1]
|
2020-04-20 18:14:39 +00:00
|
|
|
let nodeHash = keccak256.digest(node)
|
|
|
|
var nodes = getTrieNodes(db, @(nodeHash.data))
|
2019-02-05 12:01:10 +00:00
|
|
|
check nodes.len == branchs.len - 1
|
|
|
|
|
|
|
|
test "delete sub trie":
|
|
|
|
# delete all subtrie with key prefixes "key"
|
2020-04-20 18:14:39 +00:00
|
|
|
trie.deleteSubtrie("key".toBytes)
|
|
|
|
check trie.get("key1".toBytes) == []
|
|
|
|
check trie.get("key2".toBytes) == []
|
2019-02-05 12:01:10 +00:00
|
|
|
|
|
|
|
test "prove the lie":
|
|
|
|
# `delete` and `deleteSubtrie` not actually delete the nodes
|
|
|
|
check db.totalRecordsInMemoryDB == beforeDeleteLen
|
2020-04-20 18:14:39 +00:00
|
|
|
var branchs = getWitness(db, trie.getRootHash, [])
|
2019-02-05 12:01:10 +00:00
|
|
|
check branchs.len == 0
|
|
|
|
|
|
|
|
test "dictionary syntax API":
|
|
|
|
# dictionary syntax API
|
2020-04-20 18:14:39 +00:00
|
|
|
trie["moon".toBytes] = "sun".toBytes
|
|
|
|
check "moon".toBytes in trie
|
|
|
|
check trie["moon".toBytes] == "sun".toBytes
|