Trie simplification. (#2815)

* switch to simple codec, trie broken for now

* Actualy use trie_root_noext

* align some hash, failing test on EMCH comment

* Fix trie code over layout instead of hash, revert legacy code for legacy
mainnet ??

* stub behind LayOut

* fix no_std

* temp solution for legacy trie behind feature legacy-key in various crate

* use remote project

* rc client db need prefix

* update trie deps

* bum spec runtime version

* Removing legacy as default.

* Switch mode to non legacy.

* bump runtime version

* Remove legacy trie compatibility features.

* fix warning

* bump version

* change hash on new test.

* Move dependency (#11 trie PR) patched to a parity repo.
Bench reverted to correct hasher.
Some renaming and doc improvments.

* ChildBitmap renaming to BitMap.

* Renaming of LayOut to Layout.

* formatting.

* Removing abreviation such as _ix nb_ or bm.

* Update deps and apply renaming 'Buff' -> 'Buffer'.

* Align to latest trie crates naming changes.

* Update trie dependency.

* Update trie dependency.

* change block_import test hash

* update trie deps (trie use new scale codec but it does not seems to be
an issue).

* update to use latest trie version (no mgmt of multiple radix).

* tabify

* Restoring test to 10 000.

* Use published crate, trie bench is currently down until publishing
(require another pr to update version).

* Update trie-bench.
This commit is contained in:
cheme
2019-08-02 19:51:59 +02:00
committed by Gavin Wood
parent 7927e80bc6
commit da8b91ae7b
43 changed files with 892 additions and 590 deletions
+93 -70
View File
@@ -217,6 +217,11 @@ name = "bitvec"
version = "0.11.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "bitvec"
version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "blake2"
version = "0.8.0"
@@ -302,6 +307,11 @@ name = "bumpalo"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "byte-slice-cast"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "byte-tools"
version = "0.2.0"
@@ -685,19 +695,6 @@ dependencies = [
"syn 0.15.42 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "derive_more"
version = "0.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.15.42 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "difference"
version = "2.0.0"
@@ -1118,12 +1115,12 @@ dependencies = [
[[package]]
name = "hash-db"
version = "0.14.0"
version = "0.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "hash256-std-hasher"
version = "0.14.0"
version = "0.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"crunchy 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1485,11 +1482,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "keccak-hasher"
version = "0.14.0"
version = "0.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"hash-db 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
"hash256-std-hasher 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
"hash-db 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
"hash256-std-hasher 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
"tiny-keccak 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -2070,10 +2067,10 @@ dependencies = [
[[package]]
name = "memory-db"
version = "0.14.0"
version = "0.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"hash-db 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
"hash-db 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
"hashmap_core 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-util-mem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -2309,7 +2306,7 @@ dependencies = [
"substrate-state-machine 2.0.0",
"substrate-test-client 2.0.0",
"substrate-trie 2.0.0",
"trie-root 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
"trie-root 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
"wabt 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -2404,7 +2401,7 @@ dependencies = [
"substrate-service 2.0.0",
"substrate-transaction-pool 2.0.0",
"tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)",
"trie-root 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
"trie-root 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
"vergen 3.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -2632,6 +2629,18 @@ dependencies = [
"unsigned-varint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "parity-scale-codec"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"arrayvec 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
"bitvec 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
"byte-slice-cast 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
"vecarray 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "parity-send-wrapper"
version = "0.1.0"
@@ -3570,7 +3579,7 @@ name = "sr-io"
version = "2.0.0"
dependencies = [
"environmental 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"hash-db 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
"hash-db 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libsecp256k1 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-codec 4.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -4131,12 +4140,12 @@ dependencies = [
[[package]]
name = "strum"
version = "0.14.0"
version = "0.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "strum_macros"
version = "0.14.0"
version = "0.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -4247,7 +4256,7 @@ dependencies = [
"env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
"fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
"futures-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)",
"hash-db 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
"hash-db 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
"hex-literal 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"kvdb 0.1.0 (git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d)",
"kvdb-memorydb 0.1.0 (git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d)",
@@ -4274,7 +4283,7 @@ name = "substrate-client-db"
version = "2.0.0"
dependencies = [
"env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
"hash-db 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
"hash-db 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
"kvdb 0.1.0 (git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d)",
"kvdb-memorydb 0.1.0 (git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d)",
"kvdb-rocksdb 0.1.4 (git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d)",
@@ -4463,7 +4472,7 @@ version = "2.0.0"
dependencies = [
"assert_matches 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"derive_more 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
"derive_more 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)",
"hex-literal 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libsecp256k1 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -4545,8 +4554,8 @@ version = "2.0.0"
dependencies = [
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"sr-primitives 2.0.0",
"strum 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
"strum_macros 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
"strum 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
"strum_macros 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
"substrate-primitives 2.0.0",
]
@@ -4668,8 +4677,8 @@ dependencies = [
"byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"criterion 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"ed25519-dalek 1.0.0-pre.1 (registry+https://github.com/rust-lang/crates.io-index)",
"hash-db 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
"hash256-std-hasher 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
"hash-db 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
"hash256-std-hasher 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
"hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"hex-literal 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"impl-serde 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -4830,7 +4839,7 @@ dependencies = [
name = "substrate-state-machine"
version = "2.0.0"
dependencies = [
"hash-db 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
"hash-db 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
"hex-literal 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -4839,8 +4848,8 @@ dependencies = [
"substrate-panic-handler 2.0.0",
"substrate-primitives 2.0.0",
"substrate-trie 2.0.0",
"trie-db 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
"trie-root 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
"trie-db 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
"trie-root 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -4869,7 +4878,7 @@ name = "substrate-test-client"
version = "2.0.0"
dependencies = [
"futures-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)",
"hash-db 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
"hash-db 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-codec 4.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"sr-primitives 2.0.0",
"substrate-client 2.0.0",
@@ -4887,6 +4896,7 @@ version = "2.0.0"
dependencies = [
"cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
"memory-db 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-codec 4.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
"sr-io 2.0.0",
@@ -4910,7 +4920,7 @@ dependencies = [
"substrate-test-runtime-client 2.0.0",
"substrate-trie 2.0.0",
"substrate-wasm-builder-runner 1.0.2",
"trie-db 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
"trie-db 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -4962,17 +4972,17 @@ name = "substrate-trie"
version = "2.0.0"
dependencies = [
"criterion 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"hash-db 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
"hash-db 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
"hex-literal 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"keccak-hasher 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
"memory-db 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
"keccak-hasher 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
"memory-db 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-codec 4.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"sr-std 2.0.0",
"substrate-primitives 2.0.0",
"trie-bench 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
"trie-db 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
"trie-root 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
"trie-standardmap 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
"trie-bench 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)",
"trie-db 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
"trie-root 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
"trie-standardmap 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -5389,26 +5399,26 @@ dependencies = [
[[package]]
name = "trie-bench"
version = "0.14.0"
version = "0.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"criterion 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"hash-db 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
"keccak-hasher 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
"memory-db 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-codec 4.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"trie-db 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
"trie-root 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
"trie-standardmap 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
"hash-db 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
"keccak-hasher 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
"memory-db 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-scale-codec 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"trie-db 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
"trie-root 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
"trie-standardmap 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "trie-db"
version = "0.14.0"
version = "0.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"elastic-array 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)",
"hash-db 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
"hash-db 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
"hashmap_core 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -5416,19 +5426,19 @@ dependencies = [
[[package]]
name = "trie-root"
version = "0.14.0"
version = "0.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"hash-db 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
"hash-db 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "trie-standardmap"
version = "0.14.0"
version = "0.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"hash-db 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
"keccak-hasher 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
"hash-db 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
"keccak-hasher 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -5578,6 +5588,16 @@ name = "vec_map"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "vecarray"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"parity-codec 4.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
"typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "vergen"
version = "3.0.4"
@@ -5971,6 +5991,7 @@ dependencies = [
"checksum bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3d155346769a6855b86399e9bc3814ab343cd3d62c7e985113d46a0ec3c281fd"
"checksum bitmask 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5da9b3d9f6f585199287a473f4f8dfab6566cf827d15c00c219f53c645687ead"
"checksum bitvec 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b67491e1cc6f37da6c4415cd743cb8d2e2c65388acc91ca3094a054cbf3cbd0c"
"checksum bitvec 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9633b74910e1870f50f5af189b08487195cdb83c0e27a71d6f64d5e09dd0538b"
"checksum blake2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "91721a6330935673395a0607df4d49a9cb90ae12d259f1b3e0a3f6e1d486872e"
"checksum blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "5d6d530bdd2d52966a6d03b7a964add7ae1a288d25214066fd4b600f0f796400"
"checksum block-buffer 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1339a1042f5d9f295737ad4d9a6ab6bf81c84a933dba110b9200cd6d1448b814"
@@ -5981,6 +6002,7 @@ dependencies = [
"checksum bstr 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "e0a692f1c740e7e821ca71a22cf99b9b2322dfa94d10f71443befb1797b3946a"
"checksum build-helper 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bdce191bf3fa4995ce948c8c83b4640a1745457a149e73c6db75b4ffe36aad5f"
"checksum bumpalo 2.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2cd43d82f27d68911e6ee11ee791fb248f138f5d69424dc02e098d4f152b0b05"
"checksum byte-slice-cast 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7cbcbf18128ec71d8d4a0d054461ec59fff5b75b7d10a4c9b7c7cb1a379c3e77"
"checksum byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "560c32574a12a89ecd91f5e742165893f86e3ab98d21f8ea548658eb9eef5f40"
"checksum byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7"
"checksum byteorder 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0fc10e8cc6b2580fda3f36eb6dc5316657f812a3df879a44a66fc9f0fdbc4855"
@@ -6024,7 +6046,6 @@ dependencies = [
"checksum curve25519-dalek 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5d4b820e8711c211745880150f5fac78ab07d6e3851d8ce9f5a02cedc199174c"
"checksum data-encoding 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f4f47ca1860a761136924ddd2422ba77b2ea54fe8cc75b9040804a0d9d32ad97"
"checksum derive_more 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6d944ac6003ed268757ef1ee686753b57efc5fcf0ebe7b64c9fc81e7e32ff839"
"checksum derive_more 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a141330240c921ec6d074a3e188a7c7ef95668bb95e7d44fa0e5778ec2a7afe"
"checksum difference 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198"
"checksum digest 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e5b29bf156f3f4b3c4f610a25ff69370616ae6e0657d416de22645483e72af0a"
"checksum digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5"
@@ -6073,8 +6094,8 @@ dependencies = [
"checksum glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
"checksum globset 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "925aa2cac82d8834e2b2a4415b6f6879757fb5c0928fc445ae76461a12eed8f2"
"checksum h2 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)" = "a5b34c246847f938a410a03c5458c7fee2274436675e76d8b903c08efc29c462"
"checksum hash-db 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c4a2710506bcc28e53b6d48d9686b233a31ad831597da7de91e6112a2fc8f260"
"checksum hash256-std-hasher 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff4a5dcbaf4fe8977852851d137546bcad8679c9582f170032ca35b30701138e"
"checksum hash-db 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "32c87fec93c4a2d264483ef843ac1930ae7c7999d97d73721305a5188b4c23a4"
"checksum hash256-std-hasher 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "16293646125e09e5bc216d9f73fa81ab31c4f97007d56c036bbf15a58e970540"
"checksum hashbrown 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "3bae29b6653b3412c2e71e9d486db9f9df5d701941d86683005efb9f2d28e3da"
"checksum hashmap_core 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "8e04cb7a5051270ef3fa79f8c7604d581ecfa73d520e74f554e45541c4b5881a"
"checksum heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1679e6ea370dee694f91f1dc469bf94cf8f52051d147aec3e1f9497c6fc22461"
@@ -6112,7 +6133,7 @@ dependencies = [
"checksum jsonrpc-server-utils 12.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d7aac8e0029d19582b68c9fd498d18bdcf0846612c968acc93b6e5ae67eea4e0"
"checksum jsonrpc-ws-server 12.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "698fee4fcaf09a5927b7e39dd8a8136a102b343cebacaa351fc4def01a050a5b"
"checksum keccak 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "67c21572b4949434e4fc1e1978b99c5f77064153c59d998bf13ecd96fb5ecba7"
"checksum keccak-hasher 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3767172fe16797c41f975f12f38247964ace8e5e1a2539b82d5e19f9106b1cb9"
"checksum keccak-hasher 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3bf18164fd7ce989041f8fc4a1ae72a8bd1bec3575f2aeaf1d4968fc053aabef"
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
"checksum kvdb 0.1.0 (git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d)" = "<none>"
"checksum kvdb-memorydb 0.1.0 (git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d)" = "<none>"
@@ -6157,7 +6178,7 @@ dependencies = [
"checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08"
"checksum memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e"
"checksum memoffset 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ce6075db033bbbb7ee5a0bbd3a3186bbae616f57fb001c485c7ff77955f8177f"
"checksum memory-db 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "896b24d1a9850e7a25b070d552f311cbb8735214456efa222dcc4c431073c215"
"checksum memory-db 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a688133a81c915553c1dd9c3e859949f43a854cb8f8773e690e849b53b1f89f0"
"checksum memory_units 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "71d96e3f3c0b6325d8ccd83c33b28acb183edcb6c67938ba104ec546854b0882"
"checksum merlin 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "66448a173ad394ef5ebf734efa724f3644dcffda083b1e89979da4461ddac079"
"checksum mime 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ba626b8a6de5da682e1caa06bdb42a335aee5a84db8e5046a3e8ab17ba0a3ae0"
@@ -6195,6 +6216,7 @@ dependencies = [
"checksum parity-codec-derive 3.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "00a486fd383382ddcb2de928364b1f82571c1e48274fc43b7667a4738ee4056c"
"checksum parity-multiaddr 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "045b3c7af871285146300da35b1932bb6e4639b66c7c98e85d06a32cbc4e8fa7"
"checksum parity-multihash 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "df3a17dc27848fd99e4f87eb0f8c9baba6ede0a6d555400c850ca45254ef4ce3"
"checksum parity-scale-codec 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7b72212671aded3ca515379ea16aa774289e06cd595c7e31f06afdc48d6516e3"
"checksum parity-send-wrapper 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aa9777aa91b8ad9dd5aaa04a9b6bcb02c7f1deb952fca5a66034d5e63afc5c6f"
"checksum parity-util-mem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2005637ccf93dbb60c85081ccaaf3f945f573da48dcc79f27f9646caa3ec1dc"
"checksum parity-wasm 0.31.3 (registry+https://github.com/rust-lang/crates.io-index)" = "511379a8194230c2395d2f5fa627a5a7e108a9f976656ce723ae68fca4097bfc"
@@ -6305,8 +6327,8 @@ dependencies = [
"checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550"
"checksum structopt 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "16c2cdbf9cc375f15d1b4141bc48aeef444806655cd0e904207edc8d68d86ed7"
"checksum structopt-derive 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "53010261a84b37689f9ed7d395165029f9cc7abb9f56bbfe86bee2597ed25107"
"checksum strum 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1810e25f576e7ffce1ff5243b37066da5ded0310b3274c20baaeccb1145b2806"
"checksum strum_macros 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "572a2f4e53dd4c3483fd79e5cc10ddd773a3acb1169bbfe8762365e107110579"
"checksum strum 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e5d1c33039533f051704951680f1adfd468fd37ac46816ded0d9ee068e60f05f"
"checksum strum_macros 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "47cd23f5c7dee395a00fa20135e2ec0fffcdfa151c56182966d7a3261343432e"
"checksum substrate-bip39 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d69ace596e9ca97837cc41f8edcfc4e0a997f227d5fc153d1010b60a0fe9acda"
"checksum substrate-wasm-builder-runner 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f52ecbff6cc3d6e5c6401828e15937b680f459d6803ce238f01fe615bc40d071"
"checksum subtle 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee"
@@ -6345,10 +6367,10 @@ dependencies = [
"checksum tokio-uds 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "037ffc3ba0e12a0ab4aca92e5234e0dedeb48fddf6ccd260f1f150a36a9f2445"
"checksum toml 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b8c96d7873fa7ef8bdeb3a9cda3ac48389b4154f32b9803b4bc26220b677b039"
"checksum traitobject 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "efd1f82c56340fdf16f2a953d7bda4f8fdffba13d93b00844c25572110b26079"
"checksum trie-bench 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "401abff5ad06075d2c65d1eedeaaa70616d0df268f3186a82cf1aa2d798977d7"
"checksum trie-db 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1803d8ff63ec3743bee883aacf3df74c524ffab188d9abebe18ded4da0dcd5d4"
"checksum trie-root 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "226f4b2e7bc6a71172ffe7f137385cf63833de7c684059dde7520ddbf1fb04f4"
"checksum trie-standardmap 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b65b79aee5dcdcc7247fdd811f7e26b47e65ecc17f776ecf5db8e8fd46db3b54"
"checksum trie-bench 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a1861db0e69cc3d650083ca1e70e6f5aeb871491409abc0efaf321dff48df24a"
"checksum trie-db 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9b65d609ae631d808c6c1cc23a622733d5a0b66a7d67e9f5cd5171562a1f4cb5"
"checksum trie-root 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c31b0eaa64e50d686c89e6d4817ed33cb18cfa249e9071b7918b18ecfacc7867"
"checksum trie-standardmap 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "64fda153c00484d640bc91334624be22ead0e5baca917d9fd53ff29bdebcf9b2"
"checksum try-lock 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e604eb7b43c06650e854be16a2a03155743d3752dd1c943f6829e26b7a36e382"
"checksum trybuild 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)" = "f2e8e773ac21d176ee05243456b9f1a942cd1a586dab188ced05b8e8d58dc635"
"checksum twofish 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712d261e83e727c8e2dbb75dacac67c36e35db36a958ee504f2164fc052434e1"
@@ -6370,6 +6392,7 @@ dependencies = [
"checksum utf8-ranges 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "9d50aa7650df78abf942826607c62468ce18d9019673d4a2ebe1865dbb96ffde"
"checksum vcpkg 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "33dd455d0f96e90a75803cfeb7f948768c08d70a6de9a8d2362461935698bf95"
"checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a"
"checksum vecarray 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d4d68a73b7d7d950c6558b6009e9fba229fb67562bda9fd02198f614f4ecf83f"
"checksum vergen 3.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "6aba5e34f93dc7051dfad05b98a18e9156f27e7b431fe1d2398cb6061c0a1dba"
"checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd"
"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
+1 -1
View File
@@ -17,7 +17,7 @@ state-machine = { package = "substrate-state-machine", path = "../state-machine"
keyring = { package = "substrate-keyring", path = "../keyring", optional = true }
trie = { package = "substrate-trie", path = "../trie", optional = true }
substrate-telemetry = { path = "../telemetry", optional = true }
hash-db = { version = "0.14.0", default-features = false }
hash-db = { version = "0.15.0", default-features = false }
kvdb = { git = "https://github.com/paritytech/parity-common", optional = true, rev="b0317f649ab2c665b7987b8475878fc4d2e1f81d" }
parity-codec = { version = "4.1.1", default-features = false, features = ["derive"] }
primitives = { package = "substrate-primitives", path = "../primitives", default-features = false }
+1 -1
View File
@@ -12,7 +12,7 @@ kvdb = { git = "https://github.com/paritytech/parity-common", rev="b0317f649ab2c
kvdb-rocksdb = { git = "https://github.com/paritytech/parity-common", rev="b0317f649ab2c665b7987b8475878fc4d2e1f81d", optional = true }
kvdb-memorydb = { git = "https://github.com/paritytech/parity-common", rev="b0317f649ab2c665b7987b8475878fc4d2e1f81d" }
linked-hash-map = "0.5"
hash-db = { version = "0.14.0" }
hash-db = { version = "0.15.0" }
primitives = { package = "substrate-primitives", path = "../../primitives" }
sr-primitives = { path = "../../sr-primitives" }
client = { package = "substrate-client", path = "../../client" }
+51 -38
View File
@@ -43,7 +43,7 @@ use client::blockchain::HeaderBackend;
use client::ExecutionStrategies;
use client::backend::{StorageCollection, ChildStorageCollection};
use parity_codec::{Decode, Encode};
use hash_db::Hasher;
use hash_db::{Hasher, Prefix};
use kvdb::{KeyValueDB, DBTransaction};
use trie::{MemoryDB, PrefixedMemoryDB, prefixed_key};
use parking_lot::{Mutex, RwLock};
@@ -507,7 +507,7 @@ struct StorageDb<Block: BlockT> {
}
impl<Block: BlockT> state_machine::Storage<Blake2Hasher> for StorageDb<Block> {
fn get(&self, key: &H256, prefix: &[u8]) -> Result<Option<DBValue>, String> {
fn get(&self, key: &H256, prefix: Prefix) -> Result<Option<DBValue>, String> {
let key = prefixed_key::<Blake2Hasher>(key, prefix);
self.state_db.get(&key, self).map(|r| r.map(|v| DBValue::from_slice(&v)))
.map_err(|e| format!("Database backend error: {:?}", e))
@@ -535,7 +535,7 @@ impl DbGenesisStorage {
}
impl state_machine::Storage<Blake2Hasher> for DbGenesisStorage {
fn get(&self, _key: &H256, _prefix: &[u8]) -> Result<Option<DBValue>, String> {
fn get(&self, _key: &H256, _prefix: Prefix) -> Result<Option<DBValue>, String> {
Ok(None)
}
}
@@ -675,7 +675,7 @@ impl<Block> state_machine::ChangesTrieStorage<Blake2Hasher, NumberFor<Block>>
where
Block: BlockT<Hash=H256>,
{
fn get(&self, key: &H256, _prefix: &[u8]) -> Result<Option<DBValue>, String> {
fn get(&self, key: &H256, _prefix: Prefix) -> Result<Option<DBValue>, String> {
self.db.get(columns::CHANGES_TRIE, &key[..])
.map_err(|err| format!("{}", err))
}
@@ -1428,7 +1428,7 @@ where Block: BlockT<Hash=H256> {}
#[cfg(test)]
mod tests {
use hash_db::HashDB;
use hash_db::{HashDB, EMPTY_PREFIX};
use super::*;
use crate::columns;
use client::backend::Backend as BTrait;
@@ -1654,7 +1654,7 @@ mod tests {
op.reset_storage(storage.iter().cloned().collect(), Default::default()).unwrap();
key = op.db_updates.insert(&[], b"hello");
key = op.db_updates.insert(EMPTY_PREFIX, b"hello");
op.set_block_data(
header,
Some(vec![]),
@@ -1663,8 +1663,10 @@ mod tests {
).unwrap();
backend.commit_operation(op).unwrap();
assert_eq!(backend.storage.db.get(columns::STATE, key.as_bytes()).unwrap().unwrap(), &b"hello"[..]);
assert_eq!(backend.storage.db.get(
columns::STATE,
&trie::prefixed_key::<Blake2Hasher>(&key, EMPTY_PREFIX)
).unwrap().unwrap(), &b"hello"[..]);
hash
};
@@ -1688,8 +1690,8 @@ mod tests {
).0.into();
let hash = header.hash();
op.db_updates.insert(&[], b"hello");
op.db_updates.remove(&key, &[]);
op.db_updates.insert(EMPTY_PREFIX, b"hello");
op.db_updates.remove(&key, EMPTY_PREFIX);
op.set_block_data(
header,
Some(vec![]),
@@ -1698,8 +1700,10 @@ mod tests {
).unwrap();
backend.commit_operation(op).unwrap();
assert_eq!(backend.storage.db.get(columns::STATE, key.as_bytes()).unwrap().unwrap(), &b"hello"[..]);
assert_eq!(backend.storage.db.get(
columns::STATE,
&trie::prefixed_key::<Blake2Hasher>(&key, EMPTY_PREFIX)
).unwrap().unwrap(), &b"hello"[..]);
hash
};
@@ -1723,7 +1727,7 @@ mod tests {
).0.into();
let hash = header.hash();
op.db_updates.remove(&key, &[]);
op.db_updates.remove(&key, EMPTY_PREFIX);
op.set_block_data(
header,
Some(vec![]),
@@ -1733,7 +1737,11 @@ mod tests {
backend.commit_operation(op).unwrap();
assert!(backend.storage.db.get(columns::STATE, key.as_bytes()).unwrap().is_some());
assert!(backend.storage.db.get(
columns::STATE,
&trie::prefixed_key::<Blake2Hasher>(&key, EMPTY_PREFIX)
).unwrap().is_some());
hash
};
@@ -1764,14 +1772,19 @@ mod tests {
).unwrap();
backend.commit_operation(op).unwrap();
assert!(backend.storage.db.get(columns::STATE, key.as_bytes()).unwrap().is_none());
assert!(backend.storage.db.get(
columns::STATE,
&trie::prefixed_key::<Blake2Hasher>(&key, EMPTY_PREFIX)
).unwrap().is_none());
}
backend.finalize_block(BlockId::Number(1), None).unwrap();
backend.finalize_block(BlockId::Number(2), None).unwrap();
backend.finalize_block(BlockId::Number(3), None).unwrap();
assert!(backend.storage.db.get(columns::STATE, key.as_bytes()).unwrap().is_none());
assert!(backend.storage.db.get(
columns::STATE,
&trie::prefixed_key::<Blake2Hasher>(&key, EMPTY_PREFIX)
).unwrap().is_none());
}
#[test]
@@ -1789,7 +1802,7 @@ mod tests {
assert_eq!(backend.changes_tries_storage.root(&anchor, block), Ok(Some(changes_root)));
for (key, (val, _)) in changes_trie_update.drain() {
assert_eq!(backend.changes_trie_storage().unwrap().get(&key, &[]), Ok(Some(val)));
assert_eq!(backend.changes_trie_storage().unwrap().get(&key, EMPTY_PREFIX), Ok(Some(val)));
}
};
@@ -1915,23 +1928,23 @@ mod tests {
let mut tx = DBTransaction::new();
backend.changes_tries_storage.prune(&config, &mut tx, Default::default(), 12);
backend.storage.db.write(tx).unwrap();
assert!(backend.changes_tries_storage.get(&root1, &[]).unwrap().is_none());
assert!(backend.changes_tries_storage.get(&root2, &[]).unwrap().is_none());
assert!(backend.changes_tries_storage.get(&root3, &[]).unwrap().is_none());
assert!(backend.changes_tries_storage.get(&root4, &[]).unwrap().is_none());
assert!(backend.changes_tries_storage.get(&root5, &[]).unwrap().is_some());
assert!(backend.changes_tries_storage.get(&root6, &[]).unwrap().is_some());
assert!(backend.changes_tries_storage.get(&root7, &[]).unwrap().is_some());
assert!(backend.changes_tries_storage.get(&root8, &[]).unwrap().is_some());
assert!(backend.changes_tries_storage.get(&root1, EMPTY_PREFIX).unwrap().is_none());
assert!(backend.changes_tries_storage.get(&root2, EMPTY_PREFIX).unwrap().is_none());
assert!(backend.changes_tries_storage.get(&root3, EMPTY_PREFIX).unwrap().is_none());
assert!(backend.changes_tries_storage.get(&root4, EMPTY_PREFIX).unwrap().is_none());
assert!(backend.changes_tries_storage.get(&root5, EMPTY_PREFIX).unwrap().is_some());
assert!(backend.changes_tries_storage.get(&root6, EMPTY_PREFIX).unwrap().is_some());
assert!(backend.changes_tries_storage.get(&root7, EMPTY_PREFIX).unwrap().is_some());
assert!(backend.changes_tries_storage.get(&root8, EMPTY_PREFIX).unwrap().is_some());
// now simulate finalization of block#16, causing prune of tries at #5..#8
let mut tx = DBTransaction::new();
backend.changes_tries_storage.prune(&config, &mut tx, Default::default(), 16);
backend.storage.db.write(tx).unwrap();
assert!(backend.changes_tries_storage.get(&root5, &[]).unwrap().is_none());
assert!(backend.changes_tries_storage.get(&root6, &[]).unwrap().is_none());
assert!(backend.changes_tries_storage.get(&root7, &[]).unwrap().is_none());
assert!(backend.changes_tries_storage.get(&root8, &[]).unwrap().is_none());
assert!(backend.changes_tries_storage.get(&root5, EMPTY_PREFIX).unwrap().is_none());
assert!(backend.changes_tries_storage.get(&root6, EMPTY_PREFIX).unwrap().is_none());
assert!(backend.changes_tries_storage.get(&root7, EMPTY_PREFIX).unwrap().is_none());
assert!(backend.changes_tries_storage.get(&root8, EMPTY_PREFIX).unwrap().is_none());
// now "change" pruning mode to archive && simulate finalization of block#20
// => no changes tries are pruned, because we never prune in archive mode
@@ -1939,10 +1952,10 @@ mod tests {
let mut tx = DBTransaction::new();
backend.changes_tries_storage.prune(&config, &mut tx, Default::default(), 20);
backend.storage.db.write(tx).unwrap();
assert!(backend.changes_tries_storage.get(&root9, &[]).unwrap().is_some());
assert!(backend.changes_tries_storage.get(&root10, &[]).unwrap().is_some());
assert!(backend.changes_tries_storage.get(&root11, &[]).unwrap().is_some());
assert!(backend.changes_tries_storage.get(&root12, &[]).unwrap().is_some());
assert!(backend.changes_tries_storage.get(&root9, EMPTY_PREFIX).unwrap().is_some());
assert!(backend.changes_tries_storage.get(&root10, EMPTY_PREFIX).unwrap().is_some());
assert!(backend.changes_tries_storage.get(&root11, EMPTY_PREFIX).unwrap().is_some());
assert!(backend.changes_tries_storage.get(&root12, EMPTY_PREFIX).unwrap().is_some());
}
#[test]
@@ -1981,15 +1994,15 @@ mod tests {
let mut tx = DBTransaction::new();
backend.changes_tries_storage.prune(&config, &mut tx, block5, 5);
backend.storage.db.write(tx).unwrap();
assert!(backend.changes_tries_storage.get(&root1, &[]).unwrap().is_none());
assert!(backend.changes_tries_storage.get(&root2, &[]).unwrap().is_some());
assert!(backend.changes_tries_storage.get(&root1, EMPTY_PREFIX).unwrap().is_none());
assert!(backend.changes_tries_storage.get(&root2, EMPTY_PREFIX).unwrap().is_some());
// now simulate finalization of block#6, causing prune of tries at #2
let mut tx = DBTransaction::new();
backend.changes_tries_storage.prune(&config, &mut tx, block6, 6);
backend.storage.db.write(tx).unwrap();
assert!(backend.changes_tries_storage.get(&root2, &[]).unwrap().is_none());
assert!(backend.changes_tries_storage.get(&root3, &[]).unwrap().is_some());
assert!(backend.changes_tries_storage.get(&root2, EMPTY_PREFIX).unwrap().is_none());
assert!(backend.changes_tries_storage.get(&root3, EMPTY_PREFIX).unwrap().is_some());
}
#[test]
+2 -1
View File
@@ -78,7 +78,8 @@ pub fn compute_root<Header, Hasher, I>(
Hasher::Out: Ord,
I: IntoIterator<Item=ClientResult<Option<Header::Hash>>>,
{
Ok(trie::trie_root::<Hasher, _, _, _>(
use trie::TrieConfiguration;
Ok(trie::trie_types::Layout::<Hasher>::trie_root(
build_pairs::<Header, I>(cht_size, cht_num, hashes)?
))
}
+2 -2
View File
@@ -57,7 +57,7 @@ use state_machine::{
ChangesTrieRootsStorage, ChangesTrieStorage,
key_changes, key_changes_proof, OverlayedChanges, NeverOffchainExt,
};
use hash_db::Hasher;
use hash_db::{Hasher, Prefix};
use crate::backend::{
self, BlockImportOperation, PrunableStateChangesTrieStorage,
@@ -614,7 +614,7 @@ impl<B, E, Block, RA> Client<B, E, Block, RA> where
}
impl<'a, Block: BlockT> ChangesTrieStorage<Blake2Hasher, NumberFor<Block>> for AccessedRootsRecorder<'a, Block> {
fn get(&self, key: &H256, prefix: &[u8]) -> Result<Option<DBValue>, String> {
fn get(&self, key: &H256, prefix: Prefix) -> Result<Option<DBValue>, String> {
self.storage.get(key, prefix)
}
}
+3 -2
View File
@@ -71,11 +71,12 @@ mod tests {
state_root: Hash,
txs: Vec<Transfer>
) -> (Vec<u8>, Hash) {
use trie::ordered_trie_root;
use trie::{TrieConfiguration, trie_types::Layout};
let transactions = txs.into_iter().map(|tx| tx.into_signed_tx()).collect::<Vec<_>>();
let extrinsics_root = ordered_trie_root::<Blake2Hasher, _, _>(transactions.iter().map(Encode::encode)).into();
let iter = transactions.iter().map(Encode::encode);
let extrinsics_root = Layout::<Blake2Hasher>::ordered_trie_root(iter).into();
let mut header = Header {
parent_hash,
+3 -3
View File
@@ -25,7 +25,7 @@ use sr_primitives::traits::{Block as BlockT, Header as HeaderT, Zero, NumberFor}
use sr_primitives::{Justification, StorageOverlay, ChildrenStorageOverlay};
use state_machine::backend::{Backend as StateBackend, InMemory};
use state_machine::{self, InMemoryChangesTrieStorage, ChangesTrieAnchorBlockId};
use hash_db::Hasher;
use hash_db::{Hasher, Prefix};
use trie::MemoryDB;
use consensus::well_known_cache_keys::Id as CacheKeyId;
@@ -755,8 +755,8 @@ impl<Block, H> state_machine::ChangesTrieStorage<H, NumberFor<Block>> for Change
Block: BlockT,
H: Hasher,
{
fn get(&self, _key: &H::Out, _prefix: &[u8]) -> Result<Option<state_machine::DBValue>, String> {
Err("Dummy implementation".into())
fn get(&self, key: &H::Out, prefix: Prefix) -> Result<Option<state_machine::DBValue>, String> {
self.0.get(key, prefix)
}
}
+5 -4
View File
@@ -21,7 +21,7 @@ use std::collections::BTreeMap;
use std::marker::PhantomData;
use std::future::Future;
use hash_db::{HashDB, Hasher};
use hash_db::{HashDB, Hasher, EMPTY_PREFIX};
use parity_codec::{Decode, Encode};
use primitives::{ChangesTrieConfiguration, convert_hash};
use sr_primitives::traits::{
@@ -333,7 +333,7 @@ impl<E, H, B: BlockT, S: BlockchainStorage<B>, F> LightDataChecker<E, H, B, S, F
// we share the storage for multiple checks, do it here
let mut cht_root = H::Out::default();
cht_root.as_mut().copy_from_slice(local_cht_root.as_ref());
if !storage.contains(&cht_root, &[]) {
if !storage.contains(&cht_root, EMPTY_PREFIX) {
return Err(ClientError::InvalidCHTProof.into());
}
@@ -610,8 +610,9 @@ pub mod tests {
}
fn header_with_computed_extrinsics_root(extrinsics: Vec<Extrinsic>) -> Header {
let extrinsics_root =
trie::ordered_trie_root::<Blake2Hasher, _, _>(extrinsics.iter().map(Encode::encode));
use trie::{TrieConfiguration, trie_types::Layout};
let iter = extrinsics.iter().map(Encode::encode);
let extrinsics_root = Layout::<Blake2Hasher>::ordered_trie_root(iter);
// only care about `extrinsics_root`
Header::new(0, extrinsics_root, H256::zero(), H256::zero(), Default::default())
+1 -1
View File
@@ -5,7 +5,7 @@ authors = ["Parity Technologies <admin@parity.io>"]
edition = "2018"
[dependencies]
derive_more = "0.15.0"
derive_more = "0.14.0"
parity-codec = "4.1.1"
runtime_io = { package = "sr-io", path = "../sr-io" }
primitives = { package = "substrate-primitives", path = "../primitives" }
+4 -3
View File
@@ -32,7 +32,7 @@ use primitives::offchain;
use primitives::hexdisplay::HexDisplay;
use primitives::sandbox as sandbox_primitives;
use primitives::{H256, Blake2Hasher};
use trie::ordered_trie_root;
use trie::{TrieConfiguration, trie_types::Layout};
use crate::sandbox;
use crate::allocator;
use log::trace;
@@ -528,7 +528,7 @@ impl_function_executor!(this: FunctionExecutor<'e, E>,
)
)
.collect::<Result<Vec<_>>>()?;
let r = ordered_trie_root::<Blake2Hasher, _, _>(values.into_iter());
let r = Layout::<Blake2Hasher>::ordered_trie_root(values.into_iter());
this.memory.set(result, &r[..])
.map_err(|_| "Invalid attempt to set memory in ext_blake2_256_enumerated_trie_root")?;
Ok(())
@@ -1629,10 +1629,11 @@ mod tests {
#[test]
fn enumerated_trie_root_should_work() {
let mut ext = TestExternalities::<Blake2Hasher>::default();
let trie_input = vec![b"zero".to_vec(), b"one".to_vec(), b"two".to_vec()];
let test_code = WASM_BINARY;
assert_eq!(
WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_enumerated_trie_root", &[]).unwrap(),
ordered_trie_root::<Blake2Hasher, _, _>(vec![b"zero".to_vec(), b"one".to_vec(), b"two".to_vec()].iter()).as_fixed_bytes().encode()
Layout::<Blake2Hasher>::ordered_trie_root(trie_input.iter()).as_fixed_bytes().encode()
);
}
+2 -2
View File
@@ -8,5 +8,5 @@ edition = "2018"
primitives = { package = "substrate-primitives", path = "../primitives" }
sr-primitives = { path = "../sr-primitives" }
lazy_static = { version = "1.0" }
strum = "0.14.0"
strum_macros = "0.14.0"
strum = "0.15.0"
strum_macros = "0.15.0"
+2 -2
View File
@@ -14,8 +14,8 @@ byteorder = { version = "1.3.1", default-features = false }
primitive-types = { version = "0.4.0", default-features = false, features = ["codec"] }
impl-serde = { version = "0.1", optional = true }
wasmi = { version = "0.5.0", optional = true }
hash-db = { version = "0.14.0", default-features = false }
hash256-std-hasher = { version = "0.14.0", default-features = false }
hash-db = { version = "0.15.0", default-features = false }
hash256-std-hasher = { version = "0.15.0", default-features = false }
ed25519-dalek = { version = "1.0.0-pre.1", optional = true }
base58 = { version = "0.1", optional = true }
blake2-rfc = { version = "0.2.18", optional = true }
+1 -1
View File
@@ -12,7 +12,7 @@ rustc_version = "0.2"
rstd = { package = "sr-std", path = "../sr-std", default-features = false }
primitives = { package = "substrate-primitives", path = "../primitives", default-features = false }
codec = { package = "parity-codec", version = "4.1.1", default-features = false }
hash-db = { version = "0.14.0", default-features = false }
hash-db = { version = "0.15.0", default-features = false }
libsecp256k1 = { version = "0.2.1", optional = true }
tiny-keccak = { version = "1.4.2", optional = true }
environmental = { version = "1.0.1", optional = true }
+4 -3
View File
@@ -29,6 +29,7 @@ pub use substrate_state_machine::{
use environmental::environmental;
use primitives::{offchain, hexdisplay::HexDisplay, H256};
use trie::{TrieConfiguration, trie_types::Layout};
#[cfg(feature = "std")]
use std::collections::HashMap;
@@ -169,7 +170,7 @@ impl StorageApi for () {
H: Hasher,
H::Out: Ord,
{
trie::ordered_trie_root::<H, _, _>(input.iter())
Layout::<H>::ordered_trie_root(input)
}
fn trie_root<H, I, A, B>(input: I) -> H::Out
@@ -180,7 +181,7 @@ impl StorageApi for () {
H: Hasher,
H::Out: Ord,
{
trie::trie_root::<H, _, _, _>(input)
Layout::<H>::trie_root(input)
}
fn ordered_trie_root<H, I, A>(input: I) -> H::Out
@@ -190,7 +191,7 @@ impl StorageApi for () {
H: Hasher,
H::Out: Ord,
{
trie::ordered_trie_root::<H, _, _>(input)
Layout::<H>::ordered_trie_root(input)
}
}
+6 -3
View File
@@ -8,9 +8,9 @@ edition = "2018"
[dependencies]
log = "0.4"
parking_lot = "0.8.0"
hash-db = "0.14.0"
trie-db = "0.14.0"
trie-root = "0.14.0"
hash-db = "0.15.0"
trie-db = "0.15.0"
trie-root = "0.15.0"
trie = { package = "substrate-trie", path = "../trie" }
primitives = { package = "substrate-primitives", path = "../primitives" }
panic-handler = { package = "substrate-panic-handler", path = "../panic-handler" }
@@ -19,3 +19,6 @@ num-traits = "0.2"
[dev-dependencies]
hex-literal = "0.2.0"
[features]
default = []
+5 -4
View File
@@ -24,7 +24,8 @@ use log::warn;
use hash_db::Hasher;
use crate::trie_backend::TrieBackend;
use crate::trie_backend_essence::TrieBackendStorage;
use trie::{TrieDBMut, TrieMut, MemoryDB, trie_root, child_trie_root, default_child_trie_root};
use trie::{TrieMut, MemoryDB, child_trie_root, default_child_trie_root, TrieConfiguration};
use trie::trie_types::{TrieDBMut, Layout};
/// A state backend is used to read state data and can have changes committed
/// to it.
@@ -315,7 +316,7 @@ impl<H: Hasher> Backend<H> for InMemory<H> {
.flat_map(|map| map.iter().map(|(k, v)| (k.clone(), Some(v.clone()))));
let transaction: Vec<_> = delta.into_iter().collect();
let root = trie_root::<H, _, _, _>(existing_pairs.chain(transaction.iter().cloned())
let root = Layout::<H>::trie_root(existing_pairs.chain(transaction.iter().cloned())
.collect::<HashMap<_, _>>()
.into_iter()
.filter_map(|(k, maybe_val)| maybe_val.map(|val| (k, val)))
@@ -338,7 +339,7 @@ impl<H: Hasher> Backend<H> for InMemory<H> {
.flat_map(|map| map.iter().map(|(k, v)| (k.clone(), Some(v.clone()))));
let transaction: Vec<_> = delta.into_iter().collect();
let root = child_trie_root::<H, _, _, _>(
let root = child_trie_root::<Layout<H>, _, _, _>(
&storage_key,
existing_pairs.chain(transaction.iter().cloned())
.collect::<HashMap<_, _>>()
@@ -348,7 +349,7 @@ impl<H: Hasher> Backend<H> for InMemory<H> {
let full_transaction = transaction.into_iter().map(|(k, v)| (Some(storage_key.clone()), k, v)).collect();
let is_default = root == default_child_trie_root::<H>(&storage_key);
let is_default = root == default_child_trie_root::<Layout<H>>(&storage_key);
(root, is_default, full_transaction)
}
+5 -3
View File
@@ -20,7 +20,8 @@ use std::collections::HashMap;
use std::iter::FromIterator;
use crate::backend::{Backend, InMemory};
use hash_db::Hasher;
use trie::trie_root;
use trie::TrieConfiguration;
use trie::trie_types::Layout;
use primitives::offchain;
use primitives::storage::well_known_keys::is_child_storage_key;
use super::{ChildStorageKey, Externalities};
@@ -149,7 +150,7 @@ impl<H: Hasher> Externalities<H> for BasicExternalities where H::Out: Ord {
fn chain_id(&self) -> u64 { 42 }
fn storage_root(&mut self) -> H::Out {
trie_root::<H, _, _, _>(self.top.clone())
Layout::<H>::trie_root(self.top.clone())
}
fn child_storage_root(&mut self, storage_key: ChildStorageKey<H>) -> Vec<u8> {
@@ -186,7 +187,8 @@ mod tests {
ext.set_storage(b"doe".to_vec(), b"reindeer".to_vec());
ext.set_storage(b"dog".to_vec(), b"puppy".to_vec());
ext.set_storage(b"dogglesworth".to_vec(), b"cat".to_vec());
const ROOT: [u8; 32] = hex!("0b41e488cccbd67d1f1089592c2c235f5c5399b053f7fe9152dd4b5f279914cd");
const ROOT: [u8; 32] = hex!("39245109cef3758c2eed2ccba8d9b370a917850af3824bc8348d505df2c298fa");
assert_eq!(ext.storage_root(), H256::from(ROOT));
}
@@ -20,7 +20,7 @@
use std::cell::RefCell;
use std::collections::VecDeque;
use parity_codec::{Decode, Encode};
use hash_db::{HashDB, Hasher};
use hash_db::{HashDB, Hasher, EMPTY_PREFIX};
use num_traits::One;
use trie::{Recorder, MemoryDB};
use crate::changes_trie::{AnchorBlockId, Configuration, RootsStorage, Storage, BlockNumber};
@@ -115,7 +115,7 @@ pub fn key_changes_proof_check<S: RootsStorage<H, Number>, H: Hasher, Number: Bl
let mut proof_db = MemoryDB::<H>::default();
for item in proof {
proof_db.insert(&[], &item);
proof_db.insert(EMPTY_PREFIX, &item);
}
let proof_db = InMemoryStorage::with_db(proof_db);
@@ -46,14 +46,15 @@ pub use self::storage::InMemoryStorage;
pub use self::changes_iterator::{key_changes, key_changes_proof, key_changes_proof_check};
pub use self::prune::{prune, oldest_non_pruned_trie};
use hash_db::Hasher;
use hash_db::{Hasher, Prefix};
use crate::backend::Backend;
use num_traits::{One, Zero};
use parity_codec::{Decode, Encode};
use primitives;
use crate::changes_trie::build::prepare_input;
use crate::overlayed_changes::OverlayedChanges;
use trie::{MemoryDB, TrieDBMut, TrieMut, DBValue};
use trie::{MemoryDB, DBValue, TrieMut};
use trie::trie_types::TrieDBMut;
/// Changes that are made outside of extrinsics are marked with this index;
pub const NO_EXTRINSIC_INDEX: u32 = 0xffffffff;
@@ -108,7 +109,7 @@ pub trait RootsStorage<H: Hasher, Number: BlockNumber>: Send + Sync {
/// Changes trie storage. Provides access to trie roots and trie nodes.
pub trait Storage<H: Hasher, Number: BlockNumber>: RootsStorage<H, Number> {
/// Get a trie node.
fn get(&self, key: &H::Out, prefix: &[u8]) -> Result<Option<DBValue>, String>;
fn get(&self, key: &H::Out, prefix: Prefix) -> Result<Option<DBValue>, String>;
}
/// Changes trie storage -> trie backend essence adapter.
@@ -117,7 +118,7 @@ pub struct TrieBackendStorageAdapter<'a, H: Hasher, Number: BlockNumber>(pub &'a
impl<'a, H: Hasher, N: BlockNumber> crate::TrieBackendStorage<H> for TrieBackendStorageAdapter<'a, H, N> {
type Overlay = trie::MemoryDB<H>;
fn get(&self, key: &H::Out, prefix: &[u8]) -> Result<Option<DBValue>, String> {
fn get(&self, key: &H::Out, prefix: Prefix) -> Result<Option<DBValue>, String> {
self.0.get(key, prefix)
}
}
@@ -17,7 +17,7 @@
//! Changes trie storage utilities.
use std::collections::BTreeMap;
use hash_db::Hasher;
use hash_db::{Hasher, Prefix};
use trie::DBValue;
use trie::MemoryDB;
use parking_lot::RwLock;
@@ -101,7 +101,7 @@ impl<H: Hasher, Number: BlockNumber> InMemoryStorage<H, Number> {
pub fn remove_from_storage(&self, keys: &HashSet<H::Out>) {
let mut data = self.data.write();
for key in keys {
data.mdb.remove_and_purge(key, &[]);
data.mdb.remove_and_purge(key, hash_db::EMPTY_PREFIX);
}
}
@@ -132,7 +132,7 @@ impl<H: Hasher, Number: BlockNumber> RootsStorage<H, Number> for InMemoryStorage
}
impl<H: Hasher, Number: BlockNumber> Storage<H, Number> for InMemoryStorage<H, Number> {
fn get(&self, key: &H::Out, prefix: &[u8]) -> Result<Option<DBValue>, String> {
fn get(&self, key: &H::Out, prefix: Prefix) -> Result<Option<DBValue>, String> {
MemoryDB::<H>::get(&self.data.read().mdb, key, prefix)
}
}
@@ -151,7 +151,7 @@ impl<'a, H, Number, S> TrieBackendStorage<H> for TrieBackendAdapter<'a, H, Numbe
{
type Overlay = MemoryDB<H>;
fn get(&self, key: &H::Out, prefix: &[u8]) -> Result<Option<DBValue>, String> {
fn get(&self, key: &H::Out, prefix: Prefix) -> Result<Option<DBValue>, String> {
self.storage.get(key, prefix)
}
}
+8 -3
View File
@@ -25,6 +25,7 @@ use hash_db::Hasher;
use primitives::offchain;
use primitives::storage::well_known_keys::is_child_storage_key;
use trie::{MemoryDB, default_child_trie_root};
use trie::trie_types::Layout;
const EXT_NOT_ALLOWED_TO_FAIL: &str = "Externalities not allowed to fail within runtime";
@@ -297,7 +298,7 @@ where
self
.storage(storage_key.as_ref())
.unwrap_or(
default_child_trie_root::<H>(storage_key.as_ref())
default_child_trie_root::<Layout<H>>(storage_key.as_ref())
)
} else {
let storage_key = storage_key.as_ref();
@@ -394,8 +395,10 @@ mod tests {
let storage = TestChangesTrieStorage::with_blocks(vec![(99, Default::default())]);
let backend = TestBackend::default();
let mut ext = TestExt::new(&mut overlay, &backend, Some(&storage), None);
let root = hex!("bb0c2ef6e1d36d5490f9766cfcc7dfe2a6ca804504c3bb206053890d6dd02376").into();
assert_eq!(ext.storage_changes_root(Default::default()).unwrap(),
Some(hex!("5b829920b9c8d554a19ee2a1ba593c4f2ee6fc32822d083e04236d693e8358d5").into()));
Some(root));
}
#[test]
@@ -405,7 +408,9 @@ mod tests {
let storage = TestChangesTrieStorage::with_blocks(vec![(99, Default::default())]);
let backend = TestBackend::default();
let mut ext = TestExt::new(&mut overlay, &backend, Some(&storage), None);
let root = hex!("96f5aae4690e7302737b6f9b7f8567d5bbb9eac1c315f80101235a92d9ec27f4").into();
assert_eq!(ext.storage_changes_root(Default::default()).unwrap(),
Some(hex!("bcf494e41e29a15c9ae5caa053fe3cb8b446ee3e02a254efbdec7a19235b76e4").into()));
Some(root));
}
}
+3 -2
View File
@@ -38,7 +38,8 @@ mod trie_backend;
mod trie_backend_essence;
use overlayed_changes::OverlayedChangeSet;
pub use trie::{TrieMut, TrieDBMut, DBValue, MemoryDB};
pub use trie::{TrieMut, DBValue, MemoryDB};
pub use trie::trie_types::{Layout, TrieDBMut};
pub use testing::TestExternalities;
pub use basic::BasicExternalities;
pub use ext::Ext;
@@ -71,7 +72,7 @@ pub struct ChildStorageKey<'a, H: Hasher> {
impl<'a, H: Hasher> ChildStorageKey<'a, H> {
fn new(storage_key: Cow<'a, [u8]>) -> Option<Self> {
if !trie::is_child_trie_key_valid::<H>(&storage_key) {
if !trie::is_child_trie_key_valid::<Layout<H>>(&storage_key) {
return None;
}
@@ -372,7 +372,8 @@ mod tests {
Some(&changes_trie_storage),
crate::NeverOffchainExt::new(),
);
const ROOT: [u8; 32] = hex!("0b41e488cccbd67d1f1089592c2c235f5c5399b053f7fe9152dd4b5f279914cd");
const ROOT: [u8; 32] = hex!("39245109cef3758c2eed2ccba8d9b370a917850af3824bc8348d505df2c298fa");
assert_eq!(ext.storage_root(), H256::from(ROOT));
}
@@ -18,13 +18,13 @@
use std::{cell::RefCell, rc::Rc};
use log::debug;
use hash_db::Hasher;
use hash_db::HashDB;
use hash_db::{Hasher, HashDB, EMPTY_PREFIX};
use trie::{
MemoryDB, PrefixedMemoryDB, TrieError, default_child_trie_root,
MemoryDB, PrefixedMemoryDB, default_child_trie_root,
read_trie_value_with, read_child_trie_value_with, record_all_keys
};
pub use trie::Recorder;
pub use trie::trie_types::{Layout, TrieError};
use crate::trie_backend::TrieBackend;
use crate::trie_backend_essence::{Ephemeral, TrieBackendEssence, TrieBackendStorage};
use crate::{Error, ExecutionError, Backend};
@@ -50,11 +50,21 @@ impl<'a, S, H> ProvingBackendEssence<'a, S, H>
let map_e = |e| format!("Trie lookup error: {}", e);
read_trie_value_with::<H, _, Ephemeral<S, H>>(&eph, self.backend.root(), key, &mut *self.proof_recorder).map_err(map_e)
read_trie_value_with::<Layout<H>, _, Ephemeral<S, H>>(
&eph,
self.backend.root(),
key,
&mut *self.proof_recorder
).map_err(map_e)
}
pub fn child_storage(&mut self, storage_key: &[u8], key: &[u8]) -> Result<Option<Vec<u8>>, String> {
let root = self.storage(storage_key)?.unwrap_or(default_child_trie_root::<H>(storage_key));
pub fn child_storage(
&mut self,
storage_key: &[u8],
key: &[u8]
) -> Result<Option<Vec<u8>>, String> {
let root = self.storage(storage_key)?
.unwrap_or(default_child_trie_root::<Layout<H>>(storage_key));
let mut read_overlay = S::Overlay::default();
let eph = Ephemeral::new(
@@ -64,7 +74,13 @@ impl<'a, S, H> ProvingBackendEssence<'a, S, H>
let map_e = |e| format!("Trie lookup error: {}", e);
read_child_trie_value_with(storage_key, &eph, &root, key, &mut *self.proof_recorder).map_err(map_e)
read_child_trie_value_with::<Layout<H>, _, _>(
storage_key,
&eph,
&root,
key,
&mut *self.proof_recorder
).map_err(map_e)
}
pub fn record_all_keys(&mut self) {
@@ -76,7 +92,7 @@ impl<'a, S, H> ProvingBackendEssence<'a, S, H>
let mut iter = move || -> Result<(), Box<TrieError<H::Out>>> {
let root = self.backend.root();
record_all_keys::<H, _>(&eph, root, &mut *self.proof_recorder)
record_all_keys::<Layout<H>, _>(&eph, root, &mut *self.proof_recorder)
};
if let Err(e) = iter() {
@@ -199,7 +215,7 @@ where
{
let db = create_proof_check_backend_storage(proof);
if db.contains(&root, &[]) {
if db.contains(&root, EMPTY_PREFIX) {
Ok(TrieBackend::new(db, root))
} else {
Err(Box::new(ExecutionError::InvalidProof))
@@ -215,7 +231,7 @@ where
{
let mut db = MemoryDB::default();
for item in proof {
db.insert(&[], &item);
db.insert(EMPTY_PREFIX, &item);
}
db
}
@@ -307,7 +323,7 @@ mod tests {
let mut in_memory = in_memory.update(contents);
let in_memory_root = in_memory.full_storage_root::<_, Vec<_>, _>(
::std::iter::empty(),
in_memory.child_storage_keys().map(|k|(k.to_vec(), Vec::new()))
in_memory.child_storage_keys().map(|k|(k.to_vec(), Vec::new()))
).0;
(0..64).for_each(|i| assert_eq!(
in_memory.storage(&[i]).unwrap().unwrap(),
+1 -1
View File
@@ -277,7 +277,7 @@ mod tests {
ext.set_storage(b"doe".to_vec(), b"reindeer".to_vec());
ext.set_storage(b"dog".to_vec(), b"puppy".to_vec());
ext.set_storage(b"dogglesworth".to_vec(), b"cat".to_vec());
const ROOT: [u8; 32] = hex!("cc65c26c37ebd4abcdeb3f1ecd727527051620779a2f6c809bac0f8a87dbb816");
const ROOT: [u8; 32] = hex!("2a340d3dfd52f5992c6b117e9e45f479e6da5afffafeb26ab619cf137a95aeb8");
assert_eq!(ext.storage_root(), H256::from(ROOT));
}
@@ -18,7 +18,8 @@
use log::{warn, debug};
use hash_db::Hasher;
use trie::{TrieDB, TrieError, Trie, delta_trie_root, default_child_trie_root, child_delta_trie_root};
use trie::{Trie, delta_trie_root, default_child_trie_root, child_delta_trie_root};
use trie::trie_types::{TrieDB, TrieError, Layout};
use crate::trie_backend_essence::{TrieBackendEssence, TrieBackendStorage, Ephemeral};
use crate::Backend;
@@ -137,7 +138,7 @@ impl<S: TrieBackendStorage<H>, H: Hasher> Backend<H> for TrieBackend<S, H> where
&mut write_overlay,
);
match delta_trie_root::<H, _, _, _, _>(&mut eph, root, delta) {
match delta_trie_root::<Layout<H>, _, _, _, _>(&mut eph, root, delta) {
Ok(ret) => root = ret,
Err(e) => warn!(target: "trie", "Failed to write to trie: {}", e),
}
@@ -151,11 +152,11 @@ impl<S: TrieBackendStorage<H>, H: Hasher> Backend<H> for TrieBackend<S, H> where
I: IntoIterator<Item=(Vec<u8>, Option<Vec<u8>>)>,
H::Out: Ord
{
let default_root = default_child_trie_root::<H>(storage_key);
let default_root = default_child_trie_root::<Layout<H>>(storage_key);
let mut write_overlay = S::Overlay::default();
let mut root = match self.storage(storage_key) {
Ok(value) => value.unwrap_or(default_child_trie_root::<H>(storage_key)),
Ok(value) => value.unwrap_or(default_child_trie_root::<Layout<H>>(storage_key)),
Err(e) => {
warn!(target: "trie", "Failed to read child storage root: {}", e);
default_root.clone()
@@ -168,7 +169,12 @@ impl<S: TrieBackendStorage<H>, H: Hasher> Backend<H> for TrieBackend<S, H> where
&mut write_overlay,
);
match child_delta_trie_root::<H, _, _, _, _>(storage_key, &mut eph, root.clone(), delta) {
match child_delta_trie_root::<Layout<H>, _, _, _, _>(
storage_key,
&mut eph,
root.clone(),
delta
) {
Ok(ret) => root = ret,
Err(e) => warn!(target: "trie", "Failed to write to trie: {}", e),
}
@@ -189,7 +195,8 @@ pub mod tests {
use std::collections::HashSet;
use primitives::{Blake2Hasher, H256};
use parity_codec::Encode;
use trie::{TrieMut, TrieDBMut, PrefixedMemoryDB};
use trie::{TrieMut, PrefixedMemoryDB};
use trie::trie_types::TrieDBMut;
use super::*;
fn test_db() -> (PrefixedMemoryDB<Blake2Hasher>, H256) {
@@ -20,17 +20,17 @@
use std::ops::Deref;
use std::sync::Arc;
use log::{debug, warn};
use hash_db::{self, Hasher};
use trie::{
TrieDB, Trie, MemoryDB, PrefixedMemoryDB, DBValue, TrieError,
default_child_trie_root, read_trie_value, read_child_trie_value, for_keys_in_child_trie,
};
use hash_db::{self, Hasher, EMPTY_PREFIX, Prefix};
use trie::{Trie, MemoryDB, PrefixedMemoryDB, DBValue,
default_child_trie_root, read_trie_value, read_child_trie_value,
for_keys_in_child_trie};
use trie::trie_types::{TrieDB, TrieError, Layout};
use crate::backend::Consolidate;
/// Patricia trie-based storage trait.
pub trait Storage<H: Hasher>: Send + Sync {
/// Get a trie node.
fn get(&self, key: &H::Out, prefix: &[u8]) -> Result<Option<DBValue>, String>;
fn get(&self, key: &H::Out, prefix: Prefix) -> Result<Option<DBValue>, String>;
}
/// Patricia trie-based pairs storage essence.
@@ -73,12 +73,13 @@ impl<S: TrieBackendStorage<H>, H: Hasher> TrieBackendEssence<S, H> {
let map_e = |e| format!("Trie lookup error: {}", e);
read_trie_value(&eph, &self.root, key).map_err(map_e)
read_trie_value::<Layout<H>, _>(&eph, &self.root, key).map_err(map_e)
}
/// Get the value of child storage at given key.
pub fn child_storage(&self, storage_key: &[u8], key: &[u8]) -> Result<Option<Vec<u8>>, String> {
let root = self.storage(storage_key)?.unwrap_or(default_child_trie_root::<H>(storage_key));
let root = self.storage(storage_key)?
.unwrap_or(default_child_trie_root::<Layout<H>>(storage_key));
let mut read_overlay = S::Overlay::default();
let eph = Ephemeral {
@@ -88,13 +89,13 @@ impl<S: TrieBackendStorage<H>, H: Hasher> TrieBackendEssence<S, H> {
let map_e = |e| format!("Trie lookup error: {}", e);
read_child_trie_value(storage_key, &eph, &root, key).map_err(map_e)
read_child_trie_value::<Layout<H>, _>(storage_key, &eph, &root, key).map_err(map_e)
}
/// Retrieve all entries keys of child storage and call `f` for each of those keys.
pub fn for_keys_in_child_storage<F: FnMut(&[u8])>(&self, storage_key: &[u8], f: F) {
let root = match self.storage(storage_key) {
Ok(v) => v.unwrap_or(default_child_trie_root::<H>(storage_key)),
Ok(v) => v.unwrap_or(default_child_trie_root::<Layout<H>>(storage_key)),
Err(e) => {
debug!(target: "trie", "Error while iterating child storage: {}", e);
return;
@@ -107,7 +108,12 @@ impl<S: TrieBackendStorage<H>, H: Hasher> TrieBackendEssence<S, H> {
overlay: &mut read_overlay,
};
if let Err(e) = for_keys_in_child_trie::<H, _, Ephemeral<S, H>>(storage_key, &eph, &root, f) {
if let Err(e) = for_keys_in_child_trie::<Layout<H>, _, Ephemeral<S, H>>(
storage_key,
&eph,
&root,
f,
) {
debug!(target: "trie", "Error while iterating child storage: {}", e);
}
}
@@ -186,10 +192,10 @@ impl<'a,
for Ephemeral<'a, S, H>
{
fn get(&self, key: &H::Out) -> Option<DBValue> {
if let Some(val) = hash_db::HashDB::get(self.overlay, key, &[]) {
if let Some(val) = hash_db::HashDB::get(self.overlay, key, EMPTY_PREFIX) {
Some(val)
} else {
match self.storage.get(&key, &[]) {
match self.storage.get(&key, EMPTY_PREFIX) {
Ok(x) => x,
Err(e) => {
warn!(target: "trie", "Failed to read from DB: {}", e);
@@ -200,15 +206,15 @@ impl<'a,
}
fn contains(&self, key: &H::Out) -> bool {
hash_db::HashDB::get(self, key, &[]).is_some()
hash_db::HashDB::get(self, key, EMPTY_PREFIX).is_some()
}
fn emplace(&mut self, key: H::Out, value: DBValue) {
hash_db::HashDB::emplace(self.overlay, key, &[], value)
hash_db::HashDB::emplace(self.overlay, key, EMPTY_PREFIX, value)
}
fn remove(&mut self, key: &H::Out) {
hash_db::HashDB::remove(self.overlay, key, &[])
hash_db::HashDB::remove(self.overlay, key, EMPTY_PREFIX)
}
}
@@ -228,7 +234,7 @@ impl<'a,
> hash_db::HashDB<H, DBValue>
for Ephemeral<'a, S, H>
{
fn get(&self, key: &H::Out, prefix: &[u8]) -> Option<DBValue> {
fn get(&self, key: &H::Out, prefix: Prefix) -> Option<DBValue> {
if let Some(val) = hash_db::HashDB::get(self.overlay, key, prefix) {
Some(val)
} else {
@@ -242,19 +248,19 @@ impl<'a,
}
}
fn contains(&self, key: &H::Out, prefix: &[u8]) -> bool {
fn contains(&self, key: &H::Out, prefix: Prefix) -> bool {
hash_db::HashDB::get(self, key, prefix).is_some()
}
fn insert(&mut self, prefix: &[u8], value: &[u8]) -> H::Out {
fn insert(&mut self, prefix: Prefix, value: &[u8]) -> H::Out {
hash_db::HashDB::insert(self.overlay, prefix, value)
}
fn emplace(&mut self, key: H::Out, prefix: &[u8], value: DBValue) {
fn emplace(&mut self, key: H::Out, prefix: Prefix, value: DBValue) {
hash_db::HashDB::emplace(self.overlay, key, prefix, value)
}
fn remove(&mut self, key: &H::Out, prefix: &[u8]) {
fn remove(&mut self, key: &H::Out, prefix: Prefix) {
hash_db::HashDB::remove(self.overlay, key, prefix)
}
}
@@ -265,8 +271,8 @@ impl<'a,
> hash_db::HashDBRef<H, DBValue>
for Ephemeral<'a, S, H>
{
fn get(&self, key: &H::Out, prefix: &[u8]) -> Option<DBValue> { hash_db::HashDB::get(self, key, prefix) }
fn contains(&self, key: &H::Out, prefix: &[u8]) -> bool { hash_db::HashDB::contains(self, key, prefix) }
fn get(&self, key: &H::Out, prefix: Prefix) -> Option<DBValue> { hash_db::HashDB::get(self, key, prefix) }
fn contains(&self, key: &H::Out, prefix: Prefix) -> bool { hash_db::HashDB::contains(self, key, prefix) }
}
/// Key-value pairs storage that is used by trie backend essence.
@@ -274,14 +280,14 @@ pub trait TrieBackendStorage<H: Hasher>: Send + Sync {
/// Type of in-memory overlay.
type Overlay: hash_db::HashDB<H, DBValue> + Default + Consolidate;
/// Get the value stored at key.
fn get(&self, key: &H::Out, prefix: &[u8]) -> Result<Option<DBValue>, String>;
fn get(&self, key: &H::Out, prefix: Prefix) -> Result<Option<DBValue>, String>;
}
// This implementation is used by normal storage trie clients.
impl<H: Hasher> TrieBackendStorage<H> for Arc<dyn Storage<H>> {
type Overlay = PrefixedMemoryDB<H>;
fn get(&self, key: &H::Out, prefix: &[u8]) -> Result<Option<DBValue>, String> {
fn get(&self, key: &H::Out, prefix: Prefix) -> Result<Option<DBValue>, String> {
Storage::<H>::get(self.deref(), key, prefix)
}
}
@@ -290,7 +296,7 @@ impl<H: Hasher> TrieBackendStorage<H> for Arc<dyn Storage<H>> {
impl<H: Hasher> TrieBackendStorage<H> for PrefixedMemoryDB<H> {
type Overlay = PrefixedMemoryDB<H>;
fn get(&self, key: &H::Out, prefix: &[u8]) -> Result<Option<DBValue>, String> {
fn get(&self, key: &H::Out, prefix: Prefix) -> Result<Option<DBValue>, String> {
Ok(hash_db::HashDB::get(self, key, prefix))
}
}
@@ -298,7 +304,7 @@ impl<H: Hasher> TrieBackendStorage<H> for PrefixedMemoryDB<H> {
impl<H: Hasher> TrieBackendStorage<H> for MemoryDB<H> {
type Overlay = MemoryDB<H>;
fn get(&self, key: &H::Out, prefix: &[u8]) -> Result<Option<DBValue>, String> {
fn get(&self, key: &H::Out, prefix: Prefix) -> Result<Option<DBValue>, String> {
Ok(hash_db::HashDB::get(self, key, prefix))
}
}
+1 -1
View File
@@ -10,7 +10,7 @@ client-db = { package = "substrate-client-db", path = "../client/db", features =
consensus = { package = "substrate-consensus-common", path = "../consensus/common" }
executor = { package = "substrate-executor", path = "../executor" }
futures-preview = "0.3.0-alpha.17"
hash-db = "0.14.0"
hash-db = "0.15.0"
keyring = { package = "substrate-keyring", path = "../keyring" }
parity-codec = "4.1.1"
primitives = { package = "substrate-primitives", path = "../primitives" }
+3 -1
View File
@@ -21,7 +21,8 @@ sr-primitives = { path = "../sr-primitives", default-features = false }
runtime_version = { package = "sr-version", path = "../sr-version", default-features = false }
runtime_support = { package = "srml-support", path = "../../srml/support", default-features = false }
substrate-trie = { path = "../trie", default-features = false }
trie-db = { version = "0.14.0", default-features = false }
trie-db = { version = "0.15.0", default-features = false }
memory-db = { version = "0.15.0", default-features = false }
offchain-primitives = { package = "substrate-offchain-primitives", path = "../offchain/primitives", default-features = false}
executive = { package = "srml-executive", path = "../../srml/executive", default-features = false }
cfg-if = "0.1.6"
@@ -60,6 +61,7 @@ std = [
"primitives/std",
"substrate-trie/std",
"trie-db/std",
"memory-db/std",
"offchain-primitives/std",
"executive/std",
"srml-babe/std",
+16 -11
View File
@@ -27,7 +27,8 @@ use parity_codec::{Encode, Decode, Input};
use primitives::Blake2Hasher;
use trie_db::{TrieMut, Trie};
use substrate_trie::{TrieDB, TrieDBMut, PrefixedMemoryDB};
use substrate_trie::PrefixedMemoryDB;
use substrate_trie::trie_types::{TrieDB, TrieDBMut};
use substrate_client::{
runtime_api as client_api, block_builder::api as block_builder_api, decl_runtime_apis,
@@ -394,20 +395,24 @@ fn code_using_trie() -> u64 {
for i in 0..v.len() {
let key: &[u8]= &v[i].0;
let val: &[u8] = &v[i].1;
t.insert(key, val).expect("static input");
if !t.insert(key, val).is_ok() {
return 101;
}
}
t
};
let trie = TrieDB::<Blake2Hasher>::new(&mdb, &root).expect("on memory with static content");
let iter = trie.iter().expect("static input");
let mut iter_pairs = Vec::new();
for pair in iter {
let (key, value) = pair.expect("on memory with static content");
iter_pairs.push((key, value.to_vec()));
}
iter_pairs.len() as u64
if let Ok(trie) = TrieDB::<Blake2Hasher>::new(&mdb, &root) {
if let Ok(iter) = trie.iter() {
let mut iter_pairs = Vec::new();
for pair in iter {
if let Ok((key, value)) = pair {
iter_pairs.push((key, value.to_vec()));
}
}
iter_pairs.len() as u64
} else { 102 }
} else { 103 }
}
#[cfg(not(feature = "std"))]
+7 -7
View File
@@ -14,16 +14,16 @@ harness = false
[dependencies]
codec = { package = "parity-codec", version = "4.1.1", default-features = false }
rstd = { package = "sr-std", path = "../sr-std", default-features = false }
hash-db = { version = "0.14.0", default-features = false }
trie-db = { version = "0.14.0", default-features = false }
trie-root = { version = "0.14.0", default-features = false }
memory-db = { version = "0.14.0", default-features = false }
hash-db = { version = "0.15.0", default-features = false }
trie-db = { version = "0.15.0", default-features = false }
trie-root = { version = "0.15.0", default-features = false }
memory-db = { version = "0.15.0", default-features = false }
primitives = { package = "substrate-primitives", path = "../primitives", default-features = false }
[dev-dependencies]
trie-bench = { version = "0.14.0" }
trie-standardmap = { version = "0.14.0" }
keccak-hasher = { version = "0.14.0" }
trie-bench = { version = "0.16.0" }
trie-standardmap = { version = "0.15.0" }
keccak-hasher = { version = "0.15.0" }
criterion = "0.2"
hex-literal = "0.2.0"
+2 -4
View File
@@ -20,13 +20,11 @@ criterion_main!(benches);
fn benchmark(c: &mut Criterion) {
trie_bench::standard_benchmark::<
primitives::Blake2Hasher,
substrate_trie::NodeCodec<primitives::Blake2Hasher>,
substrate_trie::Layout<primitives::Blake2Hasher>,
substrate_trie::TrieStream,
>(c, "substrate-blake2");
trie_bench::standard_benchmark::<
keccak_hasher::KeccakHasher,
substrate_trie::NodeCodec<keccak_hasher::KeccakHasher>,
substrate_trie::Layout<primitives::Blake2Hasher>,
substrate_trie::TrieStream,
>(c, "substrate-keccak");
}
+221 -204
View File
@@ -33,57 +33,104 @@ pub use trie_stream::TrieStream;
/// The Substrate format implementation of `NodeCodec`.
pub use node_codec::NodeCodec;
/// Various re-exports from the `trie-db` crate.
pub use trie_db::{Trie, TrieMut, DBValue, Recorder, Query};
pub use trie_db::{Trie, TrieMut, DBValue, Recorder, CError,
Query, TrieLayout, TrieConfiguration, nibble_ops};
/// Various re-exports from the `memory-db` crate.
pub use memory_db::{KeyFunction, prefixed_key};
pub use memory_db::KeyFunction;
pub use memory_db::prefixed_key;
/// Various re-exports from the `hash-db` crate.
pub use hash_db::HashDB as HashDBT;
pub use hash_db::{HashDB as HashDBT, EMPTY_PREFIX};
/// As in `trie_db`, but less generic, error type for the crate.
pub type TrieError<H> = trie_db::TrieError<H, Error>;
/// As in `hash_db`, but less generic, trait exposed.
#[derive(Default)]
/// substrate trie layout
pub struct Layout<H>(rstd::marker::PhantomData<H>);
impl<H: Hasher> TrieLayout for Layout<H> {
const USE_EXTENSION: bool = false;
type Hash = H;
type Codec = NodeCodec<Self::Hash>;
}
impl<H: Hasher> TrieConfiguration for Layout<H> {
fn trie_root<I, A, B>(input: I) -> <Self::Hash as Hasher>::Out where
I: IntoIterator<Item = (A, B)>,
A: AsRef<[u8]> + Ord,
B: AsRef<[u8]>,
{
trie_root::trie_root_no_extension::<H, TrieStream, _, _, _>(input)
}
fn trie_root_unhashed<I, A, B>(input: I) -> Vec<u8> where
I: IntoIterator<Item = (A, B)>,
A: AsRef<[u8]> + Ord,
B: AsRef<[u8]>,
{
trie_root::unhashed_trie_no_extension::<H, TrieStream, _, _, _>(input)
}
fn encode_index(input: u32) -> Vec<u8> {
codec::Encode::encode(&codec::Compact(input))
}
}
/// TrieDB error over `TrieConfiguration` trait.
pub type TrieError<L> = trie_db::TrieError<TrieHash<L>, CError<L>>;
/// Reexport from `hash_db`, with genericity set for `Hasher` trait.
pub trait AsHashDB<H: Hasher>: hash_db::AsHashDB<H, trie_db::DBValue> {}
impl<H: Hasher, T: hash_db::AsHashDB<H, trie_db::DBValue>> AsHashDB<H> for T {}
/// As in `hash_db`, but less generic, trait exposed.
/// Reexport from `hash_db`, with genericity set for `Hasher` trait.
pub type HashDB<'a, H> = dyn hash_db::HashDB<H, trie_db::DBValue> + 'a;
/// As in `hash_db`, but less generic, trait exposed.
/// Reexport from `hash_db`, with genericity set for key only.
pub type PlainDB<'a, K> = dyn hash_db::PlainDB<K, trie_db::DBValue> + 'a;
/// As in `memory_db::MemoryDB` that uses prefixed storage key scheme.
/// Reexport from `hash_db`, with genericity set for `Hasher` trait.
/// This uses a `KeyFunction` for prefixing keys internally (avoiding
/// key conflict for non random keys).
pub type PrefixedMemoryDB<H> = memory_db::MemoryDB<H, memory_db::PrefixedKey<H>, trie_db::DBValue>;
/// As in `memory_db::MemoryDB` that uses prefixed storage key scheme.
/// Reexport from `hash_db`, with genericity set for `Hasher` trait.
/// This uses the `KeyFunction` for prefixing keys internally (avoiding
/// This uses a noops `KeyFunction` (key addressing must be hashed or using
/// an encoding scheme that avoid key conflict).
pub type MemoryDB<H> = memory_db::MemoryDB<H, memory_db::HashKey<H>, trie_db::DBValue>;
/// As in `memory_db`, but less generic, trait exposed.
/// Reexport from `hash_db`, with genericity set for `Hasher` trait.
pub type GenericMemoryDB<H, KF> = memory_db::MemoryDB<H, KF, trie_db::DBValue>;
/// Persistent trie database read-access interface for the a given hasher.
pub type TrieDB<'a, H> = trie_db::TrieDB<'a, H, NodeCodec<H>>;
pub type TrieDB<'a, L> = trie_db::TrieDB<'a, L>;
/// Persistent trie database write-access interface for the a given hasher.
pub type TrieDBMut<'a, H> = trie_db::TrieDBMut<'a, H, NodeCodec<H>>;
pub type TrieDBMut<'a, L> = trie_db::TrieDBMut<'a, L>;
/// Querying interface, as in `trie_db` but less generic.
pub type Lookup<'a, H, Q> = trie_db::Lookup<'a, H, NodeCodec<H>, Q>;
pub type Lookup<'a, L, Q> = trie_db::Lookup<'a, L, Q>;
/// Hash type for a trie layout.
pub type TrieHash<L> = <<L as TrieLayout>::Hash as Hasher>::Out;
/// Determine a trie root given its ordered contents, closed form.
pub fn trie_root<H: Hasher, I, A, B>(input: I) -> H::Out where
I: IntoIterator<Item = (A, B)>,
A: AsRef<[u8]> + Ord,
B: AsRef<[u8]>,
{
trie_root::trie_root::<H, TrieStream, _, _, _>(input)
/// This module is for non generic definition of trie type.
/// Only the `Hasher` trait is generic in this case.
pub mod trie_types {
pub type Layout<H> = super::Layout<H>;
/// Persistent trie database read-access interface for the a given hasher.
pub type TrieDB<'a, H> = super::TrieDB<'a, Layout<H>>;
/// Persistent trie database write-access interface for the a given hasher.
pub type TrieDBMut<'a, H> = super::TrieDBMut<'a, Layout<H>>;
/// Querying interface, as in `trie_db` but less generic.
pub type Lookup<'a, H, Q> = trie_db::Lookup<'a, Layout<H>, Q>;
/// As in `trie_db`, but less generic, error type for the crate.
pub type TrieError<H> = trie_db::TrieError<H, super::Error>;
}
/// Determine a trie root given a hash DB and delta values.
pub fn delta_trie_root<H: Hasher, I, A, B, DB>(
pub fn delta_trie_root<L: TrieConfiguration, I, A, B, DB>(
db: &mut DB,
mut root: H::Out,
mut root: TrieHash<L>,
delta: I
) -> Result<H::Out, Box<TrieError<H::Out>>> where
) -> Result<TrieHash<L>, Box<TrieError<L>>> where
I: IntoIterator<Item = (A, Option<B>)>,
A: AsRef<[u8]> + Ord,
B: AsRef<[u8]>,
DB: hash_db::HashDB<H, trie_db::DBValue>,
DB: hash_db::HashDB<L::Hash, trie_db::DBValue>,
{
{
let mut trie = TrieDBMut::<H>::from_existing(&mut *db, &mut root)?;
let mut trie = TrieDBMut::<L>::from_existing(&mut *db, &mut root)?;
for (key, change) in delta {
match change {
@@ -97,45 +144,26 @@ pub fn delta_trie_root<H: Hasher, I, A, B, DB>(
}
/// Read a value from the trie.
pub fn read_trie_value<H: Hasher, DB: hash_db::HashDBRef<H, trie_db::DBValue>>(
pub fn read_trie_value<L: TrieConfiguration, DB: hash_db::HashDBRef<L::Hash, trie_db::DBValue>>(
db: &DB,
root: &H::Out,
root: &TrieHash<L>,
key: &[u8]
) -> Result<Option<Vec<u8>>, Box<TrieError<H::Out>>> {
Ok(TrieDB::<H>::new(&*db, root)?.get(key).map(|x| x.map(|val| val.to_vec()))?)
) -> Result<Option<Vec<u8>>, Box<TrieError<L>>> {
Ok(TrieDB::<L>::new(&*db, root)?.get(key).map(|x| x.map(|val| val.to_vec()))?)
}
/// Read a value from the trie with given Query.
pub fn read_trie_value_with<H: Hasher, Q: Query<H, Item=DBValue>, DB: hash_db::HashDBRef<H, trie_db::DBValue>>(
pub fn read_trie_value_with<
L: TrieConfiguration,
Q: Query<L::Hash, Item=DBValue>,
DB: hash_db::HashDBRef<L::Hash, trie_db::DBValue>
>(
db: &DB,
root: &H::Out,
root: &TrieHash<L>,
key: &[u8],
query: Q
) -> Result<Option<Vec<u8>>, Box<TrieError<H::Out>>> {
Ok(TrieDB::<H>::new(&*db, root)?.get_with(key, query).map(|x| x.map(|val| val.to_vec()))?)
}
/// Determine a trie root node's data given its ordered contents, closed form.
pub fn unhashed_trie<H: Hasher, I, A, B>(input: I) -> Vec<u8> where
I: IntoIterator<Item = (A, B)>,
A: AsRef<[u8]> + Ord,
B: AsRef<[u8]>,
{
trie_root::unhashed_trie::<H, TrieStream, _, _, _>(input)
}
/// A trie root formed from the items, with keys attached according to their
/// compact-encoded index (using `parity-codec` crate).
pub fn ordered_trie_root<H: Hasher, I, A>(input: I) -> H::Out
where
I: IntoIterator<Item = A>,
A: AsRef<[u8]>,
{
trie_root::<H, _, _, _>(input
.into_iter()
.enumerate()
.map(|(i, v)| (codec::Encode::encode(&codec::Compact(i as u32)), v))
)
) -> Result<Option<Vec<u8>>, Box<TrieError<L>>> {
Ok(TrieDB::<L>::new(&*db, root)?.get_with(key, query).map(|x| x.map(|val| val.to_vec()))?)
}
/// Determine whether a child trie key is valid.
@@ -143,7 +171,7 @@ where
/// For now, the only valid child trie key is `:child_storage:default:`.
///
/// `child_trie_root` and `child_delta_trie_root` can panic if invalid value is provided to them.
pub fn is_child_trie_key_valid<H: Hasher>(storage_key: &[u8]) -> bool {
pub fn is_child_trie_key_valid<L: TrieConfiguration>(storage_key: &[u8]) -> bool {
use primitives::storage::well_known_keys;
let has_right_prefix = storage_key.starts_with(b":child_storage:default:");
if has_right_prefix {
@@ -158,37 +186,42 @@ pub fn is_child_trie_key_valid<H: Hasher>(storage_key: &[u8]) -> bool {
}
/// Determine the default child trie root.
pub fn default_child_trie_root<H: Hasher>(_storage_key: &[u8]) -> Vec<u8> {
trie_root::<H, _, Vec<u8>, Vec<u8>>(core::iter::empty()).as_ref().iter().cloned().collect()
pub fn default_child_trie_root<L: TrieConfiguration>(_storage_key: &[u8]) -> Vec<u8> {
L::trie_root::<_, Vec<u8>, Vec<u8>>(core::iter::empty()).as_ref().iter().cloned().collect()
}
/// Determine a child trie root given its ordered contents, closed form. H is the default hasher, but a generic
/// implementation may ignore this type parameter and use other hashers.
pub fn child_trie_root<H: Hasher, I, A, B>(_storage_key: &[u8], input: I) -> Vec<u8> where
I: IntoIterator<Item = (A, B)>,
A: AsRef<[u8]> + Ord,
B: AsRef<[u8]>,
/// Determine a child trie root given its ordered contents, closed form. H is the default hasher,
/// but a generic implementation may ignore this type parameter and use other hashers.
pub fn child_trie_root<L: TrieConfiguration, I, A, B>(_storage_key: &[u8], input: I) -> Vec<u8>
where
I: IntoIterator<Item = (A, B)>,
A: AsRef<[u8]> + Ord,
B: AsRef<[u8]>,
{
trie_root::<H, _, _, _>(input).as_ref().iter().cloned().collect()
L::trie_root(input).as_ref().iter().cloned().collect()
}
/// Determine a child trie root given a hash DB and delta values. H is the default hasher, but a generic implementation may ignore this type parameter and use other hashers.
pub fn child_delta_trie_root<H: Hasher, I, A, B, DB>(
/// Determine a child trie root given a hash DB and delta values. H is the default hasher,
/// but a generic implementation may ignore this type parameter and use other hashers.
pub fn child_delta_trie_root<L: TrieConfiguration, I, A, B, DB>(
_storage_key: &[u8],
db: &mut DB,
root_vec: Vec<u8>,
delta: I
) -> Result<Vec<u8>, Box<TrieError<H::Out>>> where
I: IntoIterator<Item = (A, Option<B>)>,
A: AsRef<[u8]> + Ord,
B: AsRef<[u8]>,
DB: hash_db::HashDB<H, trie_db::DBValue> + hash_db::PlainDB<H::Out, trie_db::DBValue>,
) -> Result<Vec<u8>, Box<TrieError<L>>>
where
I: IntoIterator<Item = (A, Option<B>)>,
A: AsRef<[u8]> + Ord,
B: AsRef<[u8]>,
DB: hash_db::HashDB<L::Hash, trie_db::DBValue>
+ hash_db::PlainDB<TrieHash<L>, trie_db::DBValue>,
{
let mut root = H::Out::default();
root.as_mut().copy_from_slice(&root_vec); // root is fetched from DB, not writable by runtime, so it's always valid.
let mut root = TrieHash::<L>::default();
// root is fetched from DB, not writable by runtime, so it's always valid.
root.as_mut().copy_from_slice(&root_vec);
{
let mut trie = TrieDBMut::<H>::from_existing(&mut *db, &mut root)?;
let mut trie = TrieDBMut::<L>::from_existing(&mut *db, &mut root)?;
for (key, change) in delta {
match change {
@@ -202,18 +235,21 @@ pub fn child_delta_trie_root<H: Hasher, I, A, B, DB>(
}
/// Call `f` for all keys in a child trie.
pub fn for_keys_in_child_trie<H: Hasher, F: FnMut(&[u8]), DB>(
pub fn for_keys_in_child_trie<L: TrieConfiguration, F: FnMut(&[u8]), DB>(
_storage_key: &[u8],
db: &DB,
root_slice: &[u8],
mut f: F
) -> Result<(), Box<TrieError<H::Out>>> where
DB: hash_db::HashDBRef<H, trie_db::DBValue> + hash_db::PlainDBRef<H::Out, trie_db::DBValue>,
) -> Result<(), Box<TrieError<L>>>
where
DB: hash_db::HashDBRef<L::Hash, trie_db::DBValue>
+ hash_db::PlainDBRef<TrieHash<L>, trie_db::DBValue>,
{
let mut root = H::Out::default();
root.as_mut().copy_from_slice(root_slice); // root is fetched from DB, not writable by runtime, so it's always valid.
let mut root = TrieHash::<L>::default();
// root is fetched from DB, not writable by runtime, so it's always valid.
root.as_mut().copy_from_slice(root_slice);
let trie = TrieDB::<H>::new(&*db, &root)?;
let trie = TrieDB::<L>::new(&*db, &root)?;
let iter = trie.iter()?;
for x in iter {
@@ -225,14 +261,14 @@ pub fn for_keys_in_child_trie<H: Hasher, F: FnMut(&[u8]), DB>(
}
/// Record all keys for a given root.
pub fn record_all_keys<H: Hasher, DB>(
pub fn record_all_keys<L: TrieConfiguration, DB>(
db: &DB,
root: &H::Out,
recorder: &mut Recorder<H::Out>
) -> Result<(), Box<TrieError<H::Out>>> where
DB: hash_db::HashDBRef<H, trie_db::DBValue>
root: &TrieHash<L>,
recorder: &mut Recorder<TrieHash<L>>
) -> Result<(), Box<TrieError<L>>> where
DB: hash_db::HashDBRef<L::Hash, trie_db::DBValue>
{
let trie = TrieDB::<H>::new(&*db, root)?;
let trie = TrieDB::<L>::new(&*db, root)?;
let iter = trie.iter()?;
for x in iter {
@@ -248,84 +284,49 @@ pub fn record_all_keys<H: Hasher, DB>(
}
/// Read a value from the child trie.
pub fn read_child_trie_value<H: Hasher, DB>(
pub fn read_child_trie_value<L: TrieConfiguration, DB>(
_storage_key: &[u8],
db: &DB,
root_slice: &[u8],
key: &[u8]
) -> Result<Option<Vec<u8>>, Box<TrieError<H::Out>>> where
DB: hash_db::HashDBRef<H, trie_db::DBValue> + hash_db::PlainDBRef<H::Out, trie_db::DBValue>,
) -> Result<Option<Vec<u8>>, Box<TrieError<L>>>
where
DB: hash_db::HashDBRef<L::Hash, trie_db::DBValue>
+ hash_db::PlainDBRef<TrieHash<L>, trie_db::DBValue>,
{
let mut root = H::Out::default();
root.as_mut().copy_from_slice(root_slice); // root is fetched from DB, not writable by runtime, so it's always valid.
let mut root = TrieHash::<L>::default();
// root is fetched from DB, not writable by runtime, so it's always valid.
root.as_mut().copy_from_slice(root_slice);
Ok(TrieDB::<H>::new(&*db, &root)?.get(key).map(|x| x.map(|val| val.to_vec()))?)
Ok(TrieDB::<L>::new(&*db, &root)?.get(key).map(|x| x.map(|val| val.to_vec()))?)
}
/// Read a value from the child trie with given query.
pub fn read_child_trie_value_with<H: Hasher, Q: Query<H, Item=DBValue>, DB>(
pub fn read_child_trie_value_with<L: TrieConfiguration, Q: Query<L::Hash, Item=DBValue>, DB>(
_storage_key: &[u8],
db: &DB,
root_slice: &[u8],
key: &[u8],
query: Q
) -> Result<Option<Vec<u8>>, Box<TrieError<H::Out>>> where
DB: hash_db::HashDBRef<H, trie_db::DBValue> + hash_db::PlainDBRef<H::Out, trie_db::DBValue>,
) -> Result<Option<Vec<u8>>, Box<TrieError<L>>>
where
DB: hash_db::HashDBRef<L::Hash, trie_db::DBValue>
+ hash_db::PlainDBRef<TrieHash<L>, trie_db::DBValue>,
{
let mut root = H::Out::default();
root.as_mut().copy_from_slice(root_slice); // root is fetched from DB, not writable by runtime, so it's always valid.
let mut root = TrieHash::<L>::default();
// root is fetched from DB, not writable by runtime, so it's always valid.
root.as_mut().copy_from_slice(root_slice);
Ok(TrieDB::<H>::new(&*db, &root)?.get_with(key, query).map(|x| x.map(|val| val.to_vec()))?)
Ok(TrieDB::<L>::new(&*db, &root)?.get_with(key, query).map(|x| x.map(|val| val.to_vec()))?)
}
// Utilities (not exported):
const EMPTY_TRIE: u8 = 0;
const LEAF_NODE_OFFSET: u8 = 1;
const LEAF_NODE_BIG: u8 = 127;
const EXTENSION_NODE_OFFSET: u8 = 128;
const EXTENSION_NODE_BIG: u8 = 253;
const BRANCH_NODE_NO_VALUE: u8 = 254;
const BRANCH_NODE_WITH_VALUE: u8 = 255;
const LEAF_NODE_THRESHOLD: u8 = LEAF_NODE_BIG - LEAF_NODE_OFFSET;
const EXTENSION_NODE_THRESHOLD: u8 = EXTENSION_NODE_BIG - EXTENSION_NODE_OFFSET; //125
const LEAF_NODE_SMALL_MAX: u8 = LEAF_NODE_BIG - 1;
const EXTENSION_NODE_SMALL_MAX: u8 = EXTENSION_NODE_BIG - 1;
fn take<'a>(input: &mut &'a[u8], count: usize) -> Option<&'a[u8]> {
if input.len() < count {
return None
}
let r = &(*input)[..count];
*input = &(*input)[count..];
Some(r)
}
fn partial_to_key(partial: &[u8], offset: u8, big: u8) -> Vec<u8> {
let nibble_count = (partial.len() - 1) * 2 + if partial[0] & 16 == 16 { 1 } else { 0 };
let (first_byte_small, big_threshold) = (offset, (big - offset) as usize);
let mut output = [first_byte_small + nibble_count.min(big_threshold) as u8].to_vec();
if nibble_count >= big_threshold { output.push((nibble_count - big_threshold) as u8) }
if nibble_count % 2 == 1 {
output.push(partial[0] & 0x0f);
}
output.extend_from_slice(&partial[1..]);
output
}
fn branch_node(has_value: bool, has_children: impl Iterator<Item = bool>) -> [u8; 3] {
let first = if has_value {
BRANCH_NODE_WITH_VALUE
} else {
BRANCH_NODE_NO_VALUE
};
let mut bitmap: u16 = 0;
let mut cursor: u16 = 1;
for v in has_children {
if v { bitmap |= cursor }
cursor <<= 1;
}
[first, (bitmap % 256 ) as u8, (bitmap / 256 ) as u8]
/// Constants used into trie simplification codec.
mod trie_constants {
pub const EMPTY_TRIE: u8 = 0;
pub const NIBBLE_SIZE_BOUND: usize = u16::max_value() as usize;
pub const LEAF_PREFIX_MASK: u8 = 0b_01 << 6;
pub const BRANCH_WITHOUT_MASK: u8 = 0b_10 << 6;
pub const BRANCH_WITH_MASK: u8 = 0b_11 << 6;
}
#[cfg(test)]
@@ -334,19 +335,25 @@ mod tests {
use codec::{Encode, Compact};
use primitives::Blake2Hasher;
use hash_db::{HashDB, Hasher};
use trie_db::{DBValue, TrieMut, Trie};
use trie_db::{DBValue, TrieMut, Trie, NodeCodec as NodeCodecT};
use trie_standardmap::{Alphabet, ValueMode, StandardMap};
use hex_literal::hex;
fn check_equivalent(input: &Vec<(&[u8], &[u8])>) {
type Layout = super::Layout<Blake2Hasher>;
fn hashed_null_node<T: TrieConfiguration>() -> TrieHash<T> {
<T::Codec as NodeCodecT<_>>::hashed_null_node()
}
fn check_equivalent<T: TrieConfiguration>(input: &Vec<(&[u8], &[u8])>) {
{
let closed_form = trie_root::<Blake2Hasher, _, _, _>(input.clone());
let d = unhashed_trie::<Blake2Hasher, _, _, _>(input.clone());
let closed_form = T::trie_root(input.clone());
let d = T::trie_root_unhashed(input.clone());
println!("Data: {:#x?}, {:#x?}", d, Blake2Hasher::hash(&d[..]));
let persistent = {
let mut memdb = MemoryDB::default();
let mut root = Default::default();
let mut t = TrieDBMut::<Blake2Hasher>::new(&mut memdb, &mut root);
let mut t = TrieDBMut::<T>::new(&mut memdb, &mut root);
for (x, y) in input.iter().rev() {
t.insert(x, y).unwrap();
}
@@ -356,20 +363,22 @@ mod tests {
}
}
fn check_iteration(input: &Vec<(&[u8], &[u8])>) {
fn check_iteration<T: TrieConfiguration>(input: &Vec<(&[u8], &[u8])>) {
let mut memdb = MemoryDB::default();
let mut root = Default::default();
{
let mut t = TrieDBMut::<Blake2Hasher>::new(&mut memdb, &mut root);
let mut t = TrieDBMut::<T>::new(&mut memdb, &mut root);
for (x, y) in input.clone() {
t.insert(x, y).unwrap();
}
}
{
let t = TrieDB::<Blake2Hasher>::new(&mut memdb, &root).unwrap();
let t = TrieDB::<T>::new(&mut memdb, &root).unwrap();
assert_eq!(
input.iter().map(|(i, j)| (i.to_vec(), j.to_vec())).collect::<Vec<_>>(),
t.iter().unwrap().map(|x| x.map(|y| (y.0, y.1.to_vec())).unwrap()).collect::<Vec<_>>()
t.iter().unwrap()
.map(|x| x.map(|y| (y.0, y.1.to_vec())).unwrap())
.collect::<Vec<_>>()
);
}
}
@@ -377,11 +386,11 @@ mod tests {
#[test]
fn default_trie_root() {
let mut db = MemoryDB::default();
let mut root = <Blake2Hasher as Hasher>::Out::default();
let mut empty = TrieDBMut::<Blake2Hasher>::new(&mut db, &mut root);
let mut root = TrieHash::<Layout>::default();
let mut empty = TrieDBMut::<Layout>::new(&mut db, &mut root);
empty.commit();
let root1 = empty.root().as_ref().to_vec();
let root2: Vec<u8> = trie_root::<Blake2Hasher, _, Vec<u8>, Vec<u8>>(
let root2: Vec<u8> = Layout::trie_root::<_, Vec<u8>, Vec<u8>>(
std::iter::empty(),
).as_ref().iter().cloned().collect();
@@ -391,29 +400,35 @@ mod tests {
#[test]
fn empty_is_equivalent() {
let input: Vec<(&[u8], &[u8])> = vec![];
check_equivalent(&input);
check_iteration(&input);
check_equivalent::<Layout>(&input);
check_iteration::<Layout>(&input);
}
#[test]
fn leaf_is_equivalent() {
let input: Vec<(&[u8], &[u8])> = vec![(&[0xaa][..], &[0xbb][..])];
check_equivalent(&input);
check_iteration(&input);
check_equivalent::<Layout>(&input);
check_iteration::<Layout>(&input);
}
#[test]
fn branch_is_equivalent() {
let input: Vec<(&[u8], &[u8])> = vec![(&[0xaa][..], &[0x10][..]), (&[0xba][..], &[0x11][..])];
check_equivalent(&input);
check_iteration(&input);
let input: Vec<(&[u8], &[u8])> = vec![
(&[0xaa][..], &[0x10][..]),
(&[0xba][..], &[0x11][..]),
];
check_equivalent::<Layout>(&input);
check_iteration::<Layout>(&input);
}
#[test]
fn extension_and_branch_is_equivalent() {
let input: Vec<(&[u8], &[u8])> = vec![(&[0xaa][..], &[0x10][..]), (&[0xab][..], &[0x11][..])];
check_equivalent(&input);
check_iteration(&input);
let input: Vec<(&[u8], &[u8])> = vec![
(&[0xaa][..], &[0x10][..]),
(&[0xab][..], &[0x11][..]),
];
check_equivalent::<Layout>(&input);
check_iteration::<Layout>(&input);
}
#[test]
@@ -428,8 +443,8 @@ mod tests {
let mut d = st.make();
d.sort_unstable_by(|&(ref a, _), &(ref b, _)| a.cmp(b));
let dr = d.iter().map(|v| (&v.0[..], &v.1[..])).collect();
check_equivalent(&dr);
check_iteration(&dr);
check_equivalent::<Layout>(&dr);
check_iteration::<Layout>(&dr);
}
#[test]
@@ -439,8 +454,8 @@ mod tests {
(&[0xaa, 0xaa][..], &[0xaa][..]),
(&[0xaa, 0xbb][..], &[0xab][..])
];
check_equivalent(&input);
check_iteration(&input);
check_equivalent::<Layout>(&input);
check_iteration::<Layout>(&input);
}
#[test]
@@ -453,8 +468,8 @@ mod tests {
(&[0xbb, 0xbb][..], &[0xbb][..]),
(&[0xbb, 0xcc][..], &[0xbc][..]),
];
check_equivalent(&input);
check_iteration(&input);
check_equivalent::<Layout>(&input);
check_iteration::<Layout>(&input);
}
#[test]
@@ -463,8 +478,8 @@ mod tests {
(&[0xaa][..], &b"ABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABC"[..]),
(&[0xba][..], &[0x11][..]),
];
check_equivalent(&input);
check_iteration(&input);
check_equivalent::<Layout>(&input);
check_iteration::<Layout>(&input);
}
#[test]
@@ -473,16 +488,16 @@ mod tests {
(&[0xaa][..], &b"ABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABC"[..]),
(&[0xba][..], &b"ABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABC"[..])
];
check_equivalent(&input);
check_iteration(&input);
check_equivalent::<Layout>(&input);
check_iteration::<Layout>(&input);
}
fn populate_trie<'db>(
db: &'db mut dyn HashDB<Blake2Hasher, DBValue>,
root: &'db mut <Blake2Hasher as Hasher>::Out,
fn populate_trie<'db, T: TrieConfiguration>(
db: &'db mut dyn HashDB<T::Hash, DBValue>,
root: &'db mut TrieHash<T>,
v: &[(Vec<u8>, Vec<u8>)]
) -> TrieDBMut<'db, Blake2Hasher> {
let mut t = TrieDBMut::<Blake2Hasher>::new(db, root);
) -> TrieDBMut<'db, T> {
let mut t = TrieDBMut::<T>::new(db, root);
for i in 0..v.len() {
let key: &[u8]= &v[i].0;
let val: &[u8] = &v[i].1;
@@ -491,7 +506,10 @@ mod tests {
t
}
fn unpopulate_trie<'db>(t: &mut TrieDBMut<'db, Blake2Hasher>, v: &[(Vec<u8>, Vec<u8>)]) {
fn unpopulate_trie<'db, T: TrieConfiguration>(
t: &mut TrieDBMut<'db, T>,
v: &[(Vec<u8>, Vec<u8>)],
) {
for i in v {
let key: &[u8]= &i.0;
t.remove(key).unwrap();
@@ -513,10 +531,10 @@ mod tests {
count: 100,
}.make_with(seed.as_fixed_bytes_mut());
let real = trie_root::<Blake2Hasher,_, _, _>(x.clone());
let real = Layout::trie_root(x.clone());
let mut memdb = MemoryDB::default();
let mut root = Default::default();
let mut memtrie = populate_trie(&mut memdb, &mut root, &x);
let mut memtrie = populate_trie::<Layout>(&mut memdb, &mut root, &x);
memtrie.commit();
if *memtrie.root() != real {
@@ -528,17 +546,18 @@ mod tests {
}
}
assert_eq!(*memtrie.root(), real);
unpopulate_trie(&mut memtrie, &x);
unpopulate_trie::<Layout>(&mut memtrie, &x);
memtrie.commit();
if *memtrie.root() != <NodeCodec<Blake2Hasher> as trie_db::NodeCodec<Blake2Hasher>>::hashed_null_node() {
let hashed_null_node = hashed_null_node::<Layout>();
if *memtrie.root() != hashed_null_node {
println!("- TRIE MISMATCH");
println!("");
println!("{:?} vs {:?}", memtrie.root(), <NodeCodec<Blake2Hasher> as trie_db::NodeCodec<Blake2Hasher>>::hashed_null_node());
println!("{:?} vs {:?}", memtrie.root(), hashed_null_node);
for i in &x {
println!("{:#x?} -> {:#x?}", i.0, i.1);
}
}
assert_eq!(*memtrie.root(), <NodeCodec<Blake2Hasher> as trie_db::NodeCodec<Blake2Hasher>>::hashed_null_node());
assert_eq!(*memtrie.root(), hashed_null_node);
}
}
@@ -549,7 +568,7 @@ mod tests {
#[test]
fn codec_trie_empty() {
let input: Vec<(&[u8], &[u8])> = vec![];
let trie = unhashed_trie::<Blake2Hasher, _, _, _>(input);
let trie = Layout::trie_root_unhashed::<_, _, _>(input);
println!("trie: {:#x?}", trie);
assert_eq!(trie, vec![0x0]);
}
@@ -559,11 +578,10 @@ mod tests {
let input = vec![
(vec![0xaa], vec![0xbb])
];
let trie = unhashed_trie::<Blake2Hasher, _, _, _>(input);
let trie = Layout::trie_root_unhashed::<_, _, _>(input);
println!("trie: {:#x?}", trie);
assert_eq!(trie, vec![
0x03, // leaf (0x01) with (+) key of 2 nibbles (0x02)
0x42, // leaf 0x40 (2^6) with (+) key of 2 nibbles (0x02)
0xaa, // key data
to_compact(1), // length of value in bytes as Compact
0xbb // value data
@@ -573,21 +591,20 @@ mod tests {
#[test]
fn codec_trie_two_tuples_disjoint_keys() {
let input = vec![(&[0x48, 0x19], &[0xfe]), (&[0x13, 0x14], &[0xff])];
let trie = unhashed_trie::<Blake2Hasher, _, _, _>(input);
let trie = Layout::trie_root_unhashed::<_, _, _>(input);
println!("trie: {:#x?}", trie);
let mut ex = Vec::<u8>::new();
ex.push(0xfe); // branch, no value
ex.push(0x80); // branch, no value (0b_10..) no nibble
ex.push(0x12); // slots 1 & 4 are taken from 0-7
ex.push(0x00); // no slots from 8-15
ex.push(to_compact(0x05)); // first slot: LEAF, 5 bytes long.
ex.push(0x04); // leaf with 3 nibbles
ex.push(0x43); // leaf 0x40 with 3 nibbles
ex.push(0x03); // first nibble
ex.push(0x14); // second & third nibble
ex.push(to_compact(0x01)); // 1 byte data
ex.push(0xff); // value data
ex.push(to_compact(0x05)); // second slot: LEAF, 5 bytes long.
ex.push(0x04); // leaf with 3 nibbles
ex.push(0x43); // leaf with 3 nibbles
ex.push(0x08); // first nibble
ex.push(0x19); // second & third nibble
ex.push(to_compact(0x01)); // 1 byte data
@@ -605,9 +622,9 @@ mod tests {
let mut mdb = MemoryDB::default();
let mut root = Default::default();
let _ = populate_trie(&mut mdb, &mut root, &pairs);
let _ = populate_trie::<Layout>(&mut mdb, &mut root, &pairs);
let trie = TrieDB::<Blake2Hasher>::new(&mdb, &root).unwrap();
let trie = TrieDB::<Layout>::new(&mdb, &root).unwrap();
let iter = trie.iter().unwrap();
let mut iter_pairs = Vec::new();
+178 -68
View File
@@ -18,72 +18,95 @@
use rstd::marker::PhantomData;
use rstd::vec::Vec;
use rstd::borrow::Borrow;
use codec::{Encode, Decode, Compact};
use hash_db::Hasher;
use trie_db::{self, DBValue, NibbleSlice, node::Node, ChildReference};
use trie_db::{self, NibbleSlice, node::Node, ChildReference,
nibble_ops, Partial, NodeCodec as NodeCodecT};
use crate::error::Error;
use super::{EMPTY_TRIE, LEAF_NODE_OFFSET, LEAF_NODE_BIG, EXTENSION_NODE_OFFSET,
EXTENSION_NODE_BIG, take, partial_to_key, node_header::NodeHeader, branch_node};
use crate::trie_constants;
use super::{node_header::{NodeHeader, NodeKind}};
fn take<'a>(input: &mut &'a[u8], count: usize) -> Option<&'a[u8]> {
if input.len() < count {
return None
}
let r = &(*input)[..count];
*input = &(*input)[count..];
Some(r)
}
/// Concrete implementation of a `NodeCodec` with Parity Codec encoding, generic over the `Hasher`
#[derive(Default, Clone)]
pub struct NodeCodec<H: Hasher>(PhantomData<H>);
pub struct NodeCodec<H>(PhantomData<H>);
impl<H: Hasher> trie_db::NodeCodec<H> for NodeCodec<H> {
impl<H: Hasher> NodeCodecT<H> for NodeCodec<H> {
type Error = Error;
fn hashed_null_node() -> H::Out {
H::hash(&[0u8][..])
fn hashed_null_node() -> <H as Hasher>::Out {
H::hash(<Self as NodeCodecT<_>>::empty_node())
}
fn decode(data: &[u8]) -> ::rstd::result::Result<Node, Self::Error> {
use Error::BadFormat;
fn decode(data: &[u8]) -> rstd::result::Result<Node, Self::Error> {
let input = &mut &*data;
match NodeHeader::decode(input).ok_or(BadFormat)? {
let head = NodeHeader::decode(input).ok_or(Error::BadFormat)?;
match head {
NodeHeader::Null => Ok(Node::Empty),
NodeHeader::Branch(has_value) => {
let bitmap = u16::decode(input).ok_or(BadFormat)?;
NodeHeader::Branch(has_value, nibble_count) => {
let padding = nibble_count % nibble_ops::NIBBLE_PER_BYTE != 0;
// check that the padding is valid (if any)
if padding && nibble_ops::pad_left(input[0]) != 0 {
return Err(Error::BadFormat);
}
let nibble_data = take(
input,
(nibble_count + (nibble_ops::NIBBLE_PER_BYTE - 1)) / nibble_ops::NIBBLE_PER_BYTE,
).ok_or(Error::BadFormat)?;
let nibble_slice = NibbleSlice::new_offset(
nibble_data,
nibble_ops::number_padding(nibble_count),
);
let bitmap_slice = take(input, BITMAP_LENGTH).ok_or(Error::BadFormat)?;
let bitmap = Bitmap::decode(&bitmap_slice[..])?;
let value = if has_value {
let count = <Compact<u32>>::decode(input).ok_or(BadFormat)?.0 as usize;
Some(take(input, count).ok_or(BadFormat)?)
let count = <Compact<u32>>::decode(input).ok_or(Error::BadFormat)?.0 as usize;
Some(take(input, count).ok_or(Error::BadFormat)?)
} else {
None
};
let mut children = [None; 16];
let mut pot_cursor = 1;
for i in 0..16 {
if bitmap & pot_cursor != 0 {
let count = <Compact<u32>>::decode(input).ok_or(BadFormat)?.0 as usize;
children[i] = Some(take(input, count).ok_or(BadFormat)?);
for i in 0..nibble_ops::NIBBLE_LENGTH {
if bitmap.value_at(i) {
let count = <Compact<u32>>::decode(input).ok_or(Error::BadFormat)?.0 as usize;
children[i] = Some(take(input, count).ok_or(Error::BadFormat)?);
}
pot_cursor <<= 1;
}
Ok(Node::Branch(children, value))
}
NodeHeader::Extension(nibble_count) => {
if nibble_count % 2 == 1 && input[0] & 0xf0 != 0x00 {
return Err(BadFormat);
}
let nibble_data = take(input, (nibble_count + 1) / 2).ok_or(BadFormat)?;
let nibble_slice = NibbleSlice::new_offset(nibble_data, nibble_count % 2);
let count = <Compact<u32>>::decode(input).ok_or(BadFormat)?.0 as usize;
Ok(Node::Extension(nibble_slice, take(input, count).ok_or(BadFormat)?))
Ok(Node::NibbledBranch(nibble_slice, children, value))
}
NodeHeader::Leaf(nibble_count) => {
if nibble_count % 2 == 1 && input[0] & 0xf0 != 0x00 {
return Err(BadFormat);
let padding = nibble_count % nibble_ops::NIBBLE_PER_BYTE != 0;
// check that the padding is valid (if any)
if padding && nibble_ops::pad_left(input[0]) != 0 {
return Err(Error::BadFormat);
}
let nibble_data = take(input, (nibble_count + 1) / 2).ok_or(BadFormat)?;
let nibble_slice = NibbleSlice::new_offset(nibble_data, nibble_count % 2);
let count = <Compact<u32>>::decode(input).ok_or(BadFormat)?.0 as usize;
Ok(Node::Leaf(nibble_slice, take(input, count).ok_or(BadFormat)?))
let nibble_data = take(
input,
(nibble_count + (nibble_ops::NIBBLE_PER_BYTE - 1)) / nibble_ops::NIBBLE_PER_BYTE,
).ok_or(Error::BadFormat)?;
let nibble_slice = NibbleSlice::new_offset(
nibble_data,
nibble_ops::number_padding(nibble_count),
);
let count = <Compact<u32>>::decode(input).ok_or(Error::BadFormat)?.0 as usize;
Ok(Node::Leaf(nibble_slice, take(input, count).ok_or(Error::BadFormat)?))
}
}
}
fn try_decode_hash(data: &[u8]) -> Option<H::Out> {
fn try_decode_hash(data: &[u8]) -> Option<<H as Hasher>::Out> {
if data.len() == H::LENGTH {
let mut r = H::Out::default();
let mut r = <H as Hasher>::Out::default();
r.as_mut().copy_from_slice(data);
Some(r)
} else {
@@ -92,53 +115,140 @@ impl<H: Hasher> trie_db::NodeCodec<H> for NodeCodec<H> {
}
fn is_empty_node(data: &[u8]) -> bool {
data == &[EMPTY_TRIE][..]
}
fn empty_node() -> Vec<u8> {
[EMPTY_TRIE].to_vec()
data == <Self as NodeCodecT<_>>::empty_node()
}
// FIXME: refactor this so that `partial` isn't already encoded with HPE. Should just be an `impl Iterator<Item=u8>`.
fn leaf_node(partial: &[u8], value: &[u8]) -> Vec<u8> {
let mut output = partial_to_key(partial, LEAF_NODE_OFFSET, LEAF_NODE_BIG);
fn empty_node() -> &'static [u8] {
&[trie_constants::EMPTY_TRIE]
}
fn leaf_node(partial: Partial, value: &[u8]) -> Vec<u8> {
let mut output = partial_encode(partial, NodeKind::Leaf);
value.encode_to(&mut output);
output
}
// FIXME: refactor this so that `partial` isn't already encoded with HPE. Should just be an `impl Iterator<Item=u8>`.
fn ext_node(partial: &[u8], child: ChildReference<H::Out>) -> Vec<u8> {
let mut output = partial_to_key(partial, EXTENSION_NODE_OFFSET, EXTENSION_NODE_BIG);
match child {
ChildReference::Hash(h) =>
h.as_ref().encode_to(&mut output),
ChildReference::Inline(inline_data, len) =>
(&AsRef::<[u8]>::as_ref(&inline_data)[..len]).encode_to(&mut output),
};
output
fn extension_node(
_partial: impl Iterator<Item = u8>,
_nbnibble: usize,
_child: ChildReference<<H as Hasher>::Out>,
) -> Vec<u8> {
unreachable!()
}
fn branch_node<I>(children: I, maybe_value: Option<DBValue>) -> Vec<u8>
where I: IntoIterator<Item=Option<ChildReference<H::Out>>> + Iterator<Item=Option<ChildReference<H::Out>>>
{
let mut output = [0, 0, 0].to_vec();
let have_value = if let Some(value) = maybe_value {
(&*value).encode_to(&mut output);
true
fn branch_node(
_children: impl Iterator<Item = impl Borrow<Option<ChildReference<<H as Hasher>::Out>>>>,
_maybe_value: Option<&[u8]>,
) -> Vec<u8> {
unreachable!()
}
fn branch_node_nibbled(
partial: impl Iterator<Item = u8>,
number_nibble: usize,
children: impl Iterator<Item = impl Borrow<Option<ChildReference<<H as Hasher>::Out>>>>,
maybe_value: Option<&[u8]>,
) -> Vec<u8> {
let mut output = if maybe_value.is_some() {
partial_from_iterator_encode(partial, number_nibble, NodeKind::BranchWithValue)
} else {
false
partial_from_iterator_encode(partial, number_nibble, NodeKind::BranchNoValue)
};
let prefix = branch_node(have_value, children.map(|maybe_child| match maybe_child {
let bitmap_index = output.len();
let mut bitmap: [u8; BITMAP_LENGTH] = [0; BITMAP_LENGTH];
(0..BITMAP_LENGTH).for_each(|_|output.push(0));
if let Some(value) = maybe_value {
value.encode_to(&mut output);
};
Bitmap::encode(children.map(|maybe_child| match maybe_child.borrow() {
Some(ChildReference::Hash(h)) => {
h.as_ref().encode_to(&mut output);
true
}
Some(ChildReference::Inline(inline_data, len)) => {
(&AsRef::<[u8]>::as_ref(&inline_data)[..len]).encode_to(&mut output);
&Some(ChildReference::Inline(inline_data, len)) => {
inline_data.as_ref()[..len].encode_to(&mut output);
true
}
None => false,
}));
output[0..3].copy_from_slice(&prefix[..]);
}), bitmap.as_mut());
output[bitmap_index..bitmap_index + BITMAP_LENGTH]
.copy_from_slice(&bitmap.as_ref()[..BITMAP_LENGTH]);
output
}
}
// utils
/// Encode and allocate node type header (type and size), and partial value.
/// It uses an iterator over encoded partial bytes as input.
fn partial_from_iterator_encode<I: Iterator<Item = u8>>(
partial: I,
nibble_count: usize,
node_kind: NodeKind,
) -> Vec<u8> {
let nibble_count = rstd::cmp::min(trie_constants::NIBBLE_SIZE_BOUND, nibble_count);
let mut output = Vec::with_capacity(3 + (nibble_count / nibble_ops::NIBBLE_PER_BYTE));
match node_kind {
NodeKind::Leaf => NodeHeader::Leaf(nibble_count).encode_to(&mut output),
NodeKind::BranchWithValue => NodeHeader::Branch(true, nibble_count).encode_to(&mut output),
NodeKind::BranchNoValue => NodeHeader::Branch(false, nibble_count).encode_to(&mut output),
};
output.extend(partial);
output
}
/// Encode and allocate node type header (type and size), and partial value.
/// Same as `partial_from_iterator_encode` but uses non encoded `Partial` as input.
fn partial_encode(partial: Partial, node_kind: NodeKind) -> Vec<u8> {
let number_nibble_encoded = (partial.0).0 as usize;
let nibble_count = partial.1.len() * nibble_ops::NIBBLE_PER_BYTE + number_nibble_encoded;
let nibble_count = rstd::cmp::min(trie_constants::NIBBLE_SIZE_BOUND, nibble_count);
let mut output = Vec::with_capacity(3 + partial.1.len());
match node_kind {
NodeKind::Leaf => NodeHeader::Leaf(nibble_count).encode_to(&mut output),
NodeKind::BranchWithValue => NodeHeader::Branch(true, nibble_count).encode_to(&mut output),
NodeKind::BranchNoValue => NodeHeader::Branch(false, nibble_count).encode_to(&mut output),
};
if number_nibble_encoded > 0 {
output.push(nibble_ops::pad_right((partial.0).1));
}
output.extend_from_slice(&partial.1[..]);
output
}
const BITMAP_LENGTH: usize = 2;
/// Radix 16 trie, bitmap encoding implementation,
/// it contains children mapping information for a branch
/// (children presence only), it encodes into
/// a compact bitmap encoding representation.
pub(crate) struct Bitmap(u16);
impl Bitmap {
pub fn decode(data: &[u8]) -> Result<Self, Error> {
u16::decode(&mut &data[..])
.ok_or(Error::BadFormat)
.map(|v|Bitmap(v))
}
pub fn value_at(&self, i: usize) -> bool {
self.0 & (1u16 << i) != 0
}
pub fn encode<I: Iterator<Item = bool>>(has_children: I , dest: &mut [u8]) {
let mut bitmap: u16 = 0;
let mut cursor: u16 = 1;
for v in has_children {
if v { bitmap |= cursor }
cursor <<= 1;
}
dest[0] = (bitmap % 256) as u8;
dest[1] = (bitmap / 256) as u8;
}
}
+85 -42
View File
@@ -16,62 +16,105 @@
//! The node header.
use crate::trie_constants;
use codec::{Encode, Decode, Input, Output};
use super::{EMPTY_TRIE, LEAF_NODE_OFFSET, LEAF_NODE_BIG, EXTENSION_NODE_OFFSET,
EXTENSION_NODE_BIG, BRANCH_NODE_NO_VALUE, BRANCH_NODE_WITH_VALUE, LEAF_NODE_THRESHOLD,
EXTENSION_NODE_THRESHOLD, LEAF_NODE_SMALL_MAX, EXTENSION_NODE_SMALL_MAX};
use rstd::iter::once;
/// A node header.
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub enum NodeHeader {
/// A node header
#[derive(Copy, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "std", derive(Debug))]
pub(crate) enum NodeHeader {
Null,
Branch(bool),
Extension(usize),
Branch(bool, usize),
Leaf(usize),
}
/// NodeHeader without content
pub(crate) enum NodeKind {
Leaf,
BranchNoValue,
BranchWithValue,
}
impl Encode for NodeHeader {
fn encode_to<T: Output>(&self, output: &mut T) {
match self {
NodeHeader::Null => output.push_byte(EMPTY_TRIE),
NodeHeader::Branch(true) => output.push_byte(BRANCH_NODE_WITH_VALUE),
NodeHeader::Branch(false) => output.push_byte(BRANCH_NODE_NO_VALUE),
NodeHeader::Leaf(nibble_count) if *nibble_count < LEAF_NODE_THRESHOLD as usize =>
output.push_byte(LEAF_NODE_OFFSET + *nibble_count as u8),
NodeHeader::Leaf(nibble_count) => {
output.push_byte(LEAF_NODE_BIG);
output.push_byte((*nibble_count - LEAF_NODE_THRESHOLD as usize) as u8);
}
NodeHeader::Extension(nibble_count) if *nibble_count < EXTENSION_NODE_THRESHOLD as usize =>
output.push_byte(EXTENSION_NODE_OFFSET + *nibble_count as u8),
NodeHeader::Extension(nibble_count) => {
output.push_byte(EXTENSION_NODE_BIG);
output.push_byte((*nibble_count - EXTENSION_NODE_THRESHOLD as usize) as u8);
}
NodeHeader::Null => output.push_byte(trie_constants::EMPTY_TRIE),
NodeHeader::Branch(true, nibble_count) =>
encode_size_and_prefix(*nibble_count, trie_constants::BRANCH_WITH_MASK, output),
NodeHeader::Branch(false, nibble_count) =>
encode_size_and_prefix(*nibble_count, trie_constants::BRANCH_WITHOUT_MASK, output),
NodeHeader::Leaf(nibble_count) =>
encode_size_and_prefix(*nibble_count, trie_constants::LEAF_PREFIX_MASK, output),
}
}
}
impl Decode for NodeHeader {
fn decode<I: Input>(input: &mut I) -> Option<Self> {
Some(match input.read_byte()? {
EMPTY_TRIE => NodeHeader::Null, // 0
i @ LEAF_NODE_OFFSET ..= LEAF_NODE_SMALL_MAX => // 1 ... (127 - 1)
NodeHeader::Leaf((i - LEAF_NODE_OFFSET) as usize),
LEAF_NODE_BIG => // 127
NodeHeader::Leaf(input.read_byte()? as usize + LEAF_NODE_THRESHOLD as usize),
i @ EXTENSION_NODE_OFFSET ..= EXTENSION_NODE_SMALL_MAX =>// 128 ... (253 - 1)
NodeHeader::Extension((i - EXTENSION_NODE_OFFSET) as usize),
EXTENSION_NODE_BIG => // 253
NodeHeader::Extension(input.read_byte()? as usize + EXTENSION_NODE_THRESHOLD as usize),
BRANCH_NODE_NO_VALUE => NodeHeader::Branch(false), // 254
BRANCH_NODE_WITH_VALUE => NodeHeader::Branch(true), // 255
})
let i = input.read_byte()?;
if i == trie_constants::EMPTY_TRIE {
return Some(NodeHeader::Null);
}
match i & (0b11 << 6) {
trie_constants::LEAF_PREFIX_MASK => Some(NodeHeader::Leaf(decode_size(i, input)?)),
trie_constants::BRANCH_WITHOUT_MASK => Some(NodeHeader::Branch(false, decode_size(i, input)?)),
trie_constants::BRANCH_WITH_MASK => Some(NodeHeader::Branch(true, decode_size(i, input)?)),
// do not allow any special encoding
_ => None,
}
}
}
/// Returns an iterator over encoded bytes for node header and size.
/// Size encoding allows unlimited, length unefficient, representation, but
/// is bounded to 16 bit maximum value to avoid possible DOS.
pub(crate) fn size_and_prefix_iterator(size: usize, prefix: u8) -> impl Iterator<Item = u8> {
let size = rstd::cmp::min(trie_constants::NIBBLE_SIZE_BOUND, size);
let l1 = rstd::cmp::min(62, size);
let (first_byte, mut rem) = if size == l1 {
(once(prefix + l1 as u8), 0)
} else {
(once(prefix + 63), size - l1)
};
let next_bytes = move || {
if rem > 0 {
if rem < 256 {
let result = rem - 1;
rem = 0;
Some(result as u8)
} else {
rem = rem.saturating_sub(255);
Some(255)
}
} else {
None
}
};
first_byte.chain(rstd::iter::from_fn(next_bytes))
}
/// Encodes size and prefix to a stream output.
fn encode_size_and_prefix(size: usize, prefix: u8, out: &mut impl Output) {
for b in size_and_prefix_iterator(size, prefix) {
out.push_byte(b)
}
}
/// Decode size only from stream input and header byte.
fn decode_size(first: u8, input: &mut impl Input) -> Option<usize> {
let mut result = (first & 255u8 >> 2) as usize;
if result < 63 {
return Some(result);
}
result -= 1;
while result <= trie_constants::NIBBLE_SIZE_BOUND {
let n = input.read_byte()? as usize;
if n < 255 {
return Some(result + n + 1);
}
result += 255;
}
Some(trie_constants::NIBBLE_SIZE_BOUND)
}
+80 -37
View File
@@ -16,16 +16,19 @@
//! `TrieStream` implementation for Substrate's trie format.
use rstd::iter::once;
use hash_db::Hasher;
use trie_root;
use codec::Encode;
use rstd::vec::Vec;
use crate::trie_constants;
use crate::node_header::{NodeKind, size_and_prefix_iterator};
use crate::node_codec::Bitmap;
use super::{EMPTY_TRIE, LEAF_NODE_OFFSET, LEAF_NODE_BIG, EXTENSION_NODE_OFFSET,
EXTENSION_NODE_BIG, branch_node};
const BRANCH_NODE_NO_VALUE: u8 = 254;
const BRANCH_NODE_WITH_VALUE: u8 = 255;
/// Codec-flavored TrieStream
#[derive(Default, Clone)]
/// Codec-flavored TrieStream.
pub struct TrieStream {
buffer: Vec<u8>,
}
@@ -35,62 +38,102 @@ impl TrieStream {
pub fn as_raw(&self) -> &[u8] { &self.buffer }
}
/// Create a leaf/extension node, encoding a number of nibbles. Note that this
/// cannot handle a number of nibbles that is zero or greater than 127 and if
/// you attempt to do so *IT WILL PANIC*.
fn fuse_nibbles_node<'a>(nibbles: &'a [u8], leaf: bool) -> impl Iterator<Item = u8> + 'a {
debug_assert!(nibbles.len() < 255 + 126, "nibbles length too long. what kind of size of key are you trying to include in the trie!?!");
// We use two ranges of possible values; one for leafs and the other for extensions.
// Each range encodes zero following nibbles up to some maximum. If the maximum is
// reached, then it is considered "big" and a second byte follows it in order to
// encode a further offset to the number of nibbles of up to 255. Beyond that, we
// cannot encode. This shouldn't be a problem though since that allows for keys of
// up to 380 nibbles (190 bytes) and we expect key sizes to be generally 128-bit (16
// bytes) or, at a push, 384-bit (48 bytes).
fn branch_node_bit_mask(has_children: impl Iterator<Item = bool>) -> (u8, u8) {
let mut bitmap: u16 = 0;
let mut cursor: u16 = 1;
for v in has_children {
if v { bitmap |= cursor }
cursor <<= 1;
}
((bitmap % 256 ) as u8, (bitmap / 256 ) as u8)
}
let (first_byte_small, big_threshold) = if leaf {
(LEAF_NODE_OFFSET, (LEAF_NODE_BIG - LEAF_NODE_OFFSET) as usize)
} else {
(EXTENSION_NODE_OFFSET, (EXTENSION_NODE_BIG - EXTENSION_NODE_OFFSET) as usize)
/// Create a leaf/branch node, encoding a number of nibbles.
fn fuse_nibbles_node<'a>(nibbles: &'a [u8], kind: NodeKind) -> impl Iterator<Item = u8> + 'a {
let size = rstd::cmp::min(trie_constants::NIBBLE_SIZE_BOUND, nibbles.len());
let iter_start = match kind {
NodeKind::Leaf => size_and_prefix_iterator(size, trie_constants::LEAF_PREFIX_MASK),
NodeKind::BranchNoValue => size_and_prefix_iterator(size, trie_constants::BRANCH_WITHOUT_MASK),
NodeKind::BranchWithValue => size_and_prefix_iterator(size, trie_constants::BRANCH_WITH_MASK),
};
let first_byte = first_byte_small + nibbles.len().min(big_threshold) as u8;
once(first_byte)
.chain(if nibbles.len() >= big_threshold { Some((nibbles.len() - big_threshold) as u8) } else { None })
iter_start
.chain(if nibbles.len() % 2 == 1 { Some(nibbles[0]) } else { None })
.chain(nibbles[nibbles.len() % 2..].chunks(2).map(|ch| ch[0] << 4 | ch[1]))
}
impl trie_root::TrieStream for TrieStream {
fn new() -> Self { Self {buffer: Vec::new() } }
fn new() -> Self {
TrieStream {
buffer: Vec::new()
}
}
fn append_empty_data(&mut self) {
self.buffer.push(EMPTY_TRIE);
self.buffer.push(trie_constants::EMPTY_TRIE);
}
fn append_leaf(&mut self, key: &[u8], value: &[u8]) {
self.buffer.extend(fuse_nibbles_node(key, true));
self.buffer.extend(fuse_nibbles_node(key, NodeKind::Leaf));
value.encode_to(&mut self.buffer);
}
fn begin_branch(&mut self, maybe_value: Option<&[u8]>, has_children: impl Iterator<Item = bool>) {
self.buffer.extend(&branch_node(maybe_value.is_some(), has_children));
// Push the value if one exists.
fn begin_branch(
&mut self,
maybe_partial: Option<&[u8]>,
maybe_value: Option<&[u8]>,
has_children: impl Iterator<Item = bool>,
) {
if let Some(partial) = maybe_partial {
if maybe_value.is_some() {
self.buffer.extend(fuse_nibbles_node(partial, NodeKind::BranchWithValue));
} else {
self.buffer.extend(fuse_nibbles_node(partial, NodeKind::BranchNoValue));
}
let bm = branch_node_bit_mask(has_children);
self.buffer.extend([bm.0,bm.1].iter());
} else {
debug_assert!(false, "trie stream codec only for no extension trie");
self.buffer.extend(&branch_node(maybe_value.is_some(), has_children));
}
if let Some(value) = maybe_value {
value.encode_to(&mut self.buffer);
}
}
fn append_extension(&mut self, key: &[u8]) {
self.buffer.extend(fuse_nibbles_node(key, false));
fn append_extension(&mut self, _key: &[u8]) {
debug_assert!(false, "trie stream codec only for no extension trie");
}
fn append_substream<H: Hasher>(&mut self, other: Self) {
let data = other.out();
match data.len() {
0..=31 => {
data.encode_to(&mut self.buffer)
},
_ => {
H::hash(&data).as_ref().encode_to(&mut self.buffer)
}
0..=31 => data.encode_to(&mut self.buffer),
_ => H::hash(&data).as_ref().encode_to(&mut self.buffer),
}
}
fn out(self) -> Vec<u8> { self.buffer }
}
fn branch_node(has_value: bool, has_children: impl Iterator<Item = bool>) -> [u8; 3] {
let mut result = [0, 0, 0];
branch_node_buffered(has_value, has_children, &mut result[..]);
result
}
fn branch_node_buffered<I>(has_value: bool, has_children: I, output: &mut[u8])
where
I: Iterator<Item = bool>,
{
let first = if has_value {
BRANCH_NODE_WITH_VALUE
} else {
BRANCH_NODE_NO_VALUE
};
output[0] = first;
Bitmap::encode(has_children, &mut output[1..]);
}
+1 -1
View File
@@ -18,7 +18,7 @@ tokio = "0.1"
exit-future = "0.1"
parking_lot = "0.8.0"
parity-codec = "4.1.1"
trie-root = "0.14.0"
trie-root = "0.15.0"
sr-io = { path = "../core/sr-io" }
substrate-cli = { path = "../core/cli" }
primitives = { package = "substrate-primitives", path = "../core/primitives" }
+1 -1
View File
@@ -6,7 +6,7 @@ description = "Substrate node implementation in Rust."
edition = "2018"
[dependencies]
trie-root = "0.14.0"
trie-root = "0.15.0"
parity-codec = "4.1.1"
runtime_io = { package = "sr-io", path = "../../core/sr-io" }
state_machine = { package = "substrate-state-machine", path = "../../core/state-machine" }
+2 -2
View File
@@ -403,13 +403,13 @@ mod tests {
parent_hash: Hash,
extrinsics: Vec<CheckedExtrinsic>,
) -> (Vec<u8>, Hash) {
use trie::ordered_trie_root;
use trie::{TrieConfiguration, trie_types::Layout};
// sign extrinsics.
let extrinsics = extrinsics.into_iter().map(sign).collect::<Vec<_>>();
// calculate the header fields that we can.
let extrinsics_root = ordered_trie_root::<Blake2Hasher, _, _>(
let extrinsics_root = Layout::<Blake2Hasher>::ordered_trie_root(
extrinsics.iter().map(Encode::encode)
).to_fixed_bytes()
.into();
+2 -2
View File
@@ -79,8 +79,8 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
// and set impl_version to equal spec_version. If only runtime
// implementation changes and behavior does not, then leave spec_version as
// is and increment impl_version.
spec_version: 126,
impl_version: 126,
spec_version: 127,
impl_version: 127,
apis: RUNTIME_API_VERSIONS,
};
+1 -1
View File
@@ -500,7 +500,7 @@ mod tests {
header: Header {
parent_hash: [69u8; 32].into(),
number: 1,
state_root: hex!("ba811447b8ae3bf798a07a18f5355ea59926917c8a9cc7527ede20b261aacfdf").into(),
state_root: hex!("3e51b47b6cc8449eece93eee4b01f03b00a0ca7981c0b6c0447b6e0d50ca886d").into(),
extrinsics_root: hex!("03170a2e7597b7b7e3d84c05391d139a62b157e78786d8c082f29dcf4c111314").into(),
digest: Digest { logs: vec![], },
},
+3 -3
View File
@@ -33,8 +33,8 @@ use srml_support::{
StorageValue, StorageMap, decl_module, decl_storage,
};
use srml_support::{Parameter, print};
use substrate_trie::{MemoryDB, Trie, TrieMut, TrieDBMut, TrieDB, Recorder};
use substrate_trie::{MemoryDB, Trie, TrieMut, Recorder, EMPTY_PREFIX};
use substrate_trie::trie_types::{TrieDBMut, TrieDB};
use super::{SessionIndex, Module as SessionModule};
/// Trait necessary for the historical module.
@@ -219,7 +219,7 @@ impl<T: Trait> ProvingTrie<T> {
let mut memory_db = MemoryDB::default();
for node in nodes {
HashDBT::insert(&mut memory_db, &[], &node[..]);
HashDBT::insert(&mut memory_db, EMPTY_PREFIX, &node[..]);
}
ProvingTrie {