Merge pull request #93 from nuttycom/shardtree/root_at_checkpoint_id
shardtree: Add `root_at_checkpoint_id` methods.
This commit is contained in:
commit
302c91aa96
|
@ -1,2 +1 @@
|
|||
target
|
||||
Cargo.lock
|
||||
|
|
|
@ -0,0 +1,476 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "assert_matches"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b34d609dfbaf33d6889b2b7106d3ca345eacad44200913df5ba02bfd31d2ba9"
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||
|
||||
[[package]]
|
||||
name = "bit-set"
|
||||
version = "0.5.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1"
|
||||
dependencies = [
|
||||
"bit-vec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bit-vec"
|
||||
version = "0.6.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "2.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07"
|
||||
|
||||
[[package]]
|
||||
name = "bridgetree"
|
||||
version = "0.4.0"
|
||||
dependencies = [
|
||||
"incrementalmerkletree",
|
||||
"proptest",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07"
|
||||
|
||||
[[package]]
|
||||
name = "errno"
|
||||
version = "0.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac3e13f66a2f95e32a39eaa81f6b95d42878ca0e1db0c7543723dfe12557e860"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fastrand"
|
||||
version = "1.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be"
|
||||
dependencies = [
|
||||
"instant",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fnv"
|
||||
version = "1.0.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.2.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"wasi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7"
|
||||
|
||||
[[package]]
|
||||
name = "incrementalmerkletree"
|
||||
version = "0.5.0"
|
||||
dependencies = [
|
||||
"either",
|
||||
"proptest",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "instant"
|
||||
version = "0.1.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "io-lifetimes"
|
||||
version = "1.0.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2"
|
||||
dependencies = [
|
||||
"hermit-abi",
|
||||
"libc",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.149"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b"
|
||||
|
||||
[[package]]
|
||||
name = "libm"
|
||||
version = "0.2.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058"
|
||||
|
||||
[[package]]
|
||||
name = "linux-raw-sys"
|
||||
version = "0.3.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519"
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"libm",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.18.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d"
|
||||
|
||||
[[package]]
|
||||
name = "pin-project-lite"
|
||||
version = "0.2.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58"
|
||||
|
||||
[[package]]
|
||||
name = "ppv-lite86"
|
||||
version = "0.2.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.69"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proptest"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4e35c06b98bf36aba164cc17cb25f7e232f5c4aeea73baa14b8a9f0d92dbfa65"
|
||||
dependencies = [
|
||||
"bit-set",
|
||||
"bitflags 1.3.2",
|
||||
"byteorder",
|
||||
"lazy_static",
|
||||
"num-traits",
|
||||
"rand",
|
||||
"rand_chacha",
|
||||
"rand_xorshift",
|
||||
"regex-syntax",
|
||||
"rusty-fork",
|
||||
"tempfile",
|
||||
"unarray",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quick-error"
|
||||
version = "1.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.33"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"rand_chacha",
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_chacha"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
|
||||
dependencies = [
|
||||
"ppv-lite86",
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_xorshift"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d25bf25ec5ae4a3f1b92f929810509a2f53d7dca2f50b794ff57e3face536c8f"
|
||||
dependencies = [
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.6.29"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1"
|
||||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "0.37.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fea8ca367a3a01fe35e6943c400addf443c0f57670e6ec51196f71a4b8762dd2"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"errno",
|
||||
"io-lifetimes",
|
||||
"libc",
|
||||
"linux-raw-sys",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rusty-fork"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cb3dcc6e454c328bb824492db107ab7c0ae8fcffe4ad210136ef014458c1bc4f"
|
||||
dependencies = [
|
||||
"fnv",
|
||||
"quick-error",
|
||||
"tempfile",
|
||||
"wait-timeout",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "shardtree"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"assert_matches",
|
||||
"bitflags 2.4.1",
|
||||
"either",
|
||||
"incrementalmerkletree",
|
||||
"proptest",
|
||||
"tempfile",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.38"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tempfile"
|
||||
version = "3.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "31c0432476357e58790aaa47a8efb0c5138f137343f3b5f23bd36a27e3b0a6d6"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"cfg-if",
|
||||
"fastrand",
|
||||
"redox_syscall",
|
||||
"rustix",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing"
|
||||
version = "0.1.40"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef"
|
||||
dependencies = [
|
||||
"pin-project-lite",
|
||||
"tracing-attributes",
|
||||
"tracing-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-attributes"
|
||||
version = "0.1.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-core"
|
||||
version = "0.1.32"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unarray"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
|
||||
|
||||
[[package]]
|
||||
name = "wait-timeout"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.11.0+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
|
||||
dependencies = [
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm",
|
||||
"windows_aarch64_msvc",
|
||||
"windows_i686_gnu",
|
||||
"windows_i686_msvc",
|
||||
"windows_x86_64_gnu",
|
||||
"windows_x86_64_gnullvm",
|
||||
"windows_x86_64_msvc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
|
|
@ -7,6 +7,18 @@ and this project adheres to Rust's notion of
|
|||
|
||||
## Unreleased
|
||||
|
||||
## Added
|
||||
* `Shardtree::{root_at_checkpoint_id, root_at_checkpoint_id_caching}`
|
||||
* `Shardtree::{witness_at_checkpoint_id, witness_at_checkpoint_id_caching}`
|
||||
|
||||
## Changed
|
||||
* `Shardtree::root_at_checkpoint` and `Shardtree::root_at_checkpoint_caching` have
|
||||
been renamed to `root_at_checkpoint_depth` and `root_at_checkpoint_depth_caching`,
|
||||
respectively.
|
||||
* `Shardtree::witness` and `Shardtree::witness_caching` have
|
||||
been renamed to `witness_at_checkpoint_depth` and `witness_at_checkpoint_depth_caching`,
|
||||
respectively.
|
||||
|
||||
## [0.1.0] - 2023-09-08
|
||||
|
||||
Initial release!
|
||||
|
|
|
@ -533,8 +533,8 @@ mod tests {
|
|||
assert_eq!(lhs.max_leaf_position(0), Ok(Some(Position::from(i as u64))));
|
||||
assert_eq!(rhs.max_leaf_position(0), Ok(Some(Position::from(i as u64))));
|
||||
|
||||
assert_eq!(lhs.root_at_checkpoint(0).unwrap(), expected_root);
|
||||
assert_eq!(rhs.root_at_checkpoint(0).unwrap(), expected_root);
|
||||
assert_eq!(lhs.root_at_checkpoint_depth(0).unwrap(), expected_root);
|
||||
assert_eq!(rhs.root_at_checkpoint_depth(0).unwrap(), expected_root);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -554,7 +554,7 @@ mod proptests {
|
|||
let (left, right) = build_insert_tree_and_batch_insert(leaves);
|
||||
|
||||
// Check that the resulting trees are equal.
|
||||
assert_eq!(left.root_at_checkpoint(0), right.root_at_checkpoint(0));
|
||||
assert_eq!(left.root_at_checkpoint_depth(0), right.root_at_checkpoint_depth(0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -641,7 +641,7 @@ impl<
|
|||
/// given position, and parents of such nodes, will be replaced by the empty root for the
|
||||
/// associated level.
|
||||
///
|
||||
/// Use [`Self::root_at_checkpoint`] to obtain the root of the overall tree.
|
||||
/// Use [`Self::root_at_checkpoint_depth`] to obtain the root of the overall tree.
|
||||
pub fn root(
|
||||
&self,
|
||||
address: Address,
|
||||
|
@ -970,12 +970,47 @@ impl<
|
|||
})
|
||||
}
|
||||
|
||||
/// Computes the root of the tree as of the checkpointed position having the specified
|
||||
/// checkpoint id.
|
||||
pub fn root_at_checkpoint_id(&self, checkpoint: &C) -> Result<H, ShardTreeError<S::Error>> {
|
||||
let position = self
|
||||
.store
|
||||
.get_checkpoint(checkpoint)
|
||||
.map_err(ShardTreeError::Storage)?
|
||||
.map(|c| c.position())
|
||||
.ok_or(QueryError::CheckpointPruned)?;
|
||||
|
||||
position.map_or_else(
|
||||
|| Ok(H::empty_root(Self::root_addr().level())),
|
||||
|pos| self.root(Self::root_addr(), pos + 1),
|
||||
)
|
||||
}
|
||||
|
||||
/// Computes the root of the tree as of the checkpointed position having the specified
|
||||
/// checkpoint id, caching intermediate values produced while computing the root.
|
||||
pub fn root_at_checkpoint_id_caching(
|
||||
&mut self,
|
||||
checkpoint: &C,
|
||||
) -> Result<H, ShardTreeError<S::Error>> {
|
||||
let position = self
|
||||
.store
|
||||
.get_checkpoint(checkpoint)
|
||||
.map_err(ShardTreeError::Storage)?
|
||||
.map(|c| c.position())
|
||||
.ok_or(QueryError::CheckpointPruned)?;
|
||||
|
||||
position.map_or_else(
|
||||
|| Ok(H::empty_root(Self::root_addr().level())),
|
||||
|pos| self.root_caching(Self::root_addr(), pos + 1),
|
||||
)
|
||||
}
|
||||
|
||||
/// Computes the root of the tree as of the checkpointed position at the specified depth.
|
||||
///
|
||||
/// Returns the root as of the most recently appended leaf if `checkpoint_depth == 0`. Note
|
||||
/// that if the most recently appended leaf is also a checkpoint, this will return the same
|
||||
/// result as `checkpoint_depth == 1`.
|
||||
pub fn root_at_checkpoint(
|
||||
pub fn root_at_checkpoint_depth(
|
||||
&self,
|
||||
checkpoint_depth: usize,
|
||||
) -> Result<H, ShardTreeError<S::Error>> {
|
||||
|
@ -985,7 +1020,9 @@ impl<
|
|||
)
|
||||
}
|
||||
|
||||
pub fn root_at_checkpoint_caching(
|
||||
/// Computes the root of the tree as of the checkpointed position at the specified depth,
|
||||
/// caching intermediate values produced while computing the root.
|
||||
pub fn root_at_checkpoint_depth_caching(
|
||||
&mut self,
|
||||
checkpoint_depth: usize,
|
||||
) -> Result<H, ShardTreeError<S::Error>> {
|
||||
|
@ -995,94 +1032,148 @@ impl<
|
|||
)
|
||||
}
|
||||
|
||||
/// Computes the witness for the leaf at the specified position.
|
||||
fn witness_helper<Ctx>(
|
||||
mut ctx: Ctx,
|
||||
position: Position,
|
||||
as_of: Position,
|
||||
get_shard: impl Fn(&Ctx, Address) -> Result<Option<LocatedPrunableTree<H>>, S::Error>,
|
||||
mut root: impl FnMut(&mut Ctx, Address, Position) -> Result<H, ShardTreeError<S::Error>>,
|
||||
) -> Result<MerklePath<H, DEPTH>, ShardTreeError<S::Error>> {
|
||||
let subtree_addr = Self::subtree_addr(position);
|
||||
|
||||
// compute the witness for the specified position up to the subtree root
|
||||
let mut witness = get_shard(&ctx, subtree_addr)
|
||||
.map_err(ShardTreeError::Storage)?
|
||||
.map_or_else(
|
||||
|| Err(QueryError::TreeIncomplete(vec![subtree_addr])),
|
||||
|subtree| subtree.witness(position, as_of + 1),
|
||||
)?;
|
||||
|
||||
// compute the remaining parts of the witness up to the root
|
||||
let root_addr = Self::root_addr();
|
||||
let mut cur_addr = subtree_addr;
|
||||
while cur_addr != root_addr {
|
||||
witness.push(root(&mut ctx, cur_addr.sibling(), as_of + 1)?);
|
||||
cur_addr = cur_addr.parent();
|
||||
}
|
||||
|
||||
Ok(MerklePath::from_parts(witness, position).unwrap())
|
||||
}
|
||||
|
||||
fn witness_internal(
|
||||
&self,
|
||||
position: Position,
|
||||
as_of: Position,
|
||||
) -> Result<MerklePath<H, DEPTH>, ShardTreeError<S::Error>> {
|
||||
Self::witness_helper(
|
||||
self,
|
||||
position,
|
||||
as_of,
|
||||
|ctx, shard_root| ctx.store.get_shard(shard_root),
|
||||
|ctx, address, truncate_at| ctx.root(address, truncate_at),
|
||||
)
|
||||
}
|
||||
|
||||
fn witness_internal_caching(
|
||||
&mut self,
|
||||
position: Position,
|
||||
as_of: Position,
|
||||
) -> Result<MerklePath<H, DEPTH>, ShardTreeError<S::Error>> {
|
||||
Self::witness_helper(
|
||||
self,
|
||||
position,
|
||||
as_of,
|
||||
|ctx, shard_root| ctx.store.get_shard(shard_root),
|
||||
|ctx, address, truncate_at| ctx.root_caching(address, truncate_at),
|
||||
)
|
||||
}
|
||||
|
||||
/// Computes the witness for the leaf at the specified position, as of the given checkpoint
|
||||
/// depth.
|
||||
///
|
||||
/// Returns the witness as of the most recently appended leaf if `checkpoint_depth == 0`. Note
|
||||
/// that if the most recently appended leaf is also a checkpoint, this will return the same
|
||||
/// result as `checkpoint_depth == 1`.
|
||||
pub fn witness(
|
||||
pub fn witness_at_checkpoint_depth(
|
||||
&self,
|
||||
position: Position,
|
||||
checkpoint_depth: usize,
|
||||
) -> Result<MerklePath<H, DEPTH>, ShardTreeError<S::Error>> {
|
||||
let max_leaf_position = self.max_leaf_position(checkpoint_depth).and_then(|v| {
|
||||
let as_of = self.max_leaf_position(checkpoint_depth).and_then(|v| {
|
||||
v.ok_or_else(|| QueryError::TreeIncomplete(vec![Self::root_addr()]).into())
|
||||
})?;
|
||||
|
||||
if position > max_leaf_position {
|
||||
if position > as_of {
|
||||
Err(
|
||||
QueryError::NotContained(Address::from_parts(Level::from(0), position.into()))
|
||||
.into(),
|
||||
)
|
||||
} else {
|
||||
let subtree_addr = Self::subtree_addr(position);
|
||||
|
||||
// compute the witness for the specified position up to the subtree root
|
||||
let mut witness = self
|
||||
.store
|
||||
.get_shard(subtree_addr)
|
||||
.map_err(ShardTreeError::Storage)?
|
||||
.map_or_else(
|
||||
|| Err(QueryError::TreeIncomplete(vec![subtree_addr])),
|
||||
|subtree| subtree.witness(position, max_leaf_position + 1),
|
||||
)?;
|
||||
|
||||
// compute the remaining parts of the witness up to the root
|
||||
let root_addr = Self::root_addr();
|
||||
let mut cur_addr = subtree_addr;
|
||||
while cur_addr != root_addr {
|
||||
witness.push(self.root(cur_addr.sibling(), max_leaf_position + 1)?);
|
||||
cur_addr = cur_addr.parent();
|
||||
}
|
||||
|
||||
Ok(MerklePath::from_parts(witness, position).unwrap())
|
||||
self.witness_internal(position, as_of)
|
||||
}
|
||||
}
|
||||
|
||||
/// Computes the witness for the leaf at the specified position.
|
||||
/// Computes the witness for the leaf at the specified position, as of the given checkpoint
|
||||
/// depth.
|
||||
///
|
||||
/// This implementation will mutate the tree to cache intermediate root (ommer) values that are
|
||||
/// computed in the process of constructing the witness, so as to avoid the need to recompute
|
||||
/// those values from potentially large numbers of subtree roots in the future.
|
||||
pub fn witness_caching(
|
||||
pub fn witness_at_checkpoint_depth_caching(
|
||||
&mut self,
|
||||
position: Position,
|
||||
checkpoint_depth: usize,
|
||||
) -> Result<MerklePath<H, DEPTH>, ShardTreeError<S::Error>> {
|
||||
let max_leaf_position = self.max_leaf_position(checkpoint_depth).and_then(|v| {
|
||||
let as_of = self.max_leaf_position(checkpoint_depth).and_then(|v| {
|
||||
v.ok_or_else(|| QueryError::TreeIncomplete(vec![Self::root_addr()]).into())
|
||||
})?;
|
||||
|
||||
if position > max_leaf_position {
|
||||
if position > as_of {
|
||||
Err(
|
||||
QueryError::NotContained(Address::from_parts(Level::from(0), position.into()))
|
||||
.into(),
|
||||
)
|
||||
} else {
|
||||
let subtree_addr = Address::above_position(Self::subtree_level(), position);
|
||||
|
||||
// compute the witness for the specified position up to the subtree root
|
||||
let mut witness = self
|
||||
.store
|
||||
.get_shard(subtree_addr)
|
||||
.map_err(ShardTreeError::Storage)?
|
||||
.map_or_else(
|
||||
|| Err(QueryError::TreeIncomplete(vec![subtree_addr])),
|
||||
|subtree| subtree.witness(position, max_leaf_position + 1),
|
||||
)?;
|
||||
|
||||
// compute the remaining parts of the witness up to the root
|
||||
let root_addr = Self::root_addr();
|
||||
let mut cur_addr = subtree_addr;
|
||||
while cur_addr != root_addr {
|
||||
witness.push(self.root_caching(cur_addr.sibling(), max_leaf_position + 1)?);
|
||||
cur_addr = cur_addr.parent();
|
||||
}
|
||||
|
||||
Ok(MerklePath::from_parts(witness, position).unwrap())
|
||||
self.witness_internal_caching(position, as_of)
|
||||
}
|
||||
}
|
||||
|
||||
/// Computes the witness for the leaf at the specified position, as of the given checkpoint.
|
||||
pub fn witness_at_checkpoint_id(
|
||||
&self,
|
||||
position: Position,
|
||||
checkpoint_id: &C,
|
||||
) -> Result<MerklePath<H, DEPTH>, ShardTreeError<S::Error>> {
|
||||
let as_of = self
|
||||
.store
|
||||
.get_checkpoint(checkpoint_id)
|
||||
.map_err(ShardTreeError::Storage)?
|
||||
.and_then(|c| c.position())
|
||||
.ok_or(QueryError::CheckpointPruned)?;
|
||||
|
||||
self.witness_internal(position, as_of)
|
||||
}
|
||||
|
||||
/// Computes the witness for the leaf at the specified position, as of the given checkpoint.
|
||||
///
|
||||
/// This implementation will mutate the tree to cache intermediate root (ommer) values that are
|
||||
/// computed in the process of constructing the witness, so as to avoid the need to recompute
|
||||
/// those values from potentially large numbers of subtree roots in the future.
|
||||
pub fn witness_at_checkpoint_id_caching(
|
||||
&mut self,
|
||||
position: Position,
|
||||
checkpoint_id: &C,
|
||||
) -> Result<MerklePath<H, DEPTH>, ShardTreeError<S::Error>> {
|
||||
let as_of = self
|
||||
.store
|
||||
.get_checkpoint(checkpoint_id)
|
||||
.map_err(ShardTreeError::Storage)?
|
||||
.and_then(|c| c.position())
|
||||
.ok_or(QueryError::CheckpointPruned)?;
|
||||
|
||||
self.witness_internal_caching(position, as_of)
|
||||
}
|
||||
|
||||
/// Make a marked leaf at a position eligible to be pruned.
|
||||
///
|
||||
/// If the checkpoint associated with the specified identifier does not exist because the
|
||||
|
@ -1341,8 +1432,8 @@ mod tests {
|
|||
assert_eq!(root, caching_root);
|
||||
|
||||
for pos in marked_positions {
|
||||
let witness = tree.witness(pos, 0);
|
||||
let caching_witness = tree.witness_caching(pos, 0);
|
||||
let witness = tree.witness_at_checkpoint_depth(pos, 0);
|
||||
let caching_witness = tree.witness_at_checkpoint_depth_caching(pos, 0);
|
||||
assert_matches!(witness, Ok(_));
|
||||
assert_eq!(witness, caching_witness);
|
||||
}
|
||||
|
|
|
@ -96,9 +96,9 @@ pub trait ShardStore {
|
|||
/// Returns the number of checkpoints maintained by the data store
|
||||
fn checkpoint_count(&self) -> Result<usize, Self::Error>;
|
||||
|
||||
/// Returns the position of the checkpoint, if any, along with the number of subsequent
|
||||
/// checkpoints at the same position. Returns `None` if `checkpoint_depth == 0` or if
|
||||
/// insufficient checkpoints exist to seek back to the requested depth.
|
||||
/// Returns the id and position of the checkpoint, if any. Returns `None` if
|
||||
/// `checkpoint_depth == 0` or if insufficient checkpoints exist to seek back
|
||||
/// to the requested depth.
|
||||
fn get_checkpoint_at_depth(
|
||||
&self,
|
||||
checkpoint_depth: usize,
|
||||
|
|
|
@ -185,14 +185,14 @@ impl<
|
|||
}
|
||||
|
||||
fn root(&self, checkpoint_depth: usize) -> Option<H> {
|
||||
match ShardTree::root_at_checkpoint(self, checkpoint_depth) {
|
||||
match ShardTree::root_at_checkpoint_depth(self, checkpoint_depth) {
|
||||
Ok(v) => Some(v),
|
||||
Err(err) => panic!("root computation failed: {:?}", err),
|
||||
}
|
||||
}
|
||||
|
||||
fn witness(&self, position: Position, checkpoint_depth: usize) -> Option<Vec<H>> {
|
||||
match ShardTree::witness(self, position, checkpoint_depth) {
|
||||
match ShardTree::witness_at_checkpoint_depth(self, position, checkpoint_depth) {
|
||||
Ok(p) => Some(p.path_elems().to_vec()),
|
||||
Err(ShardTreeError::Query(
|
||||
QueryError::NotContained(_)
|
||||
|
@ -254,7 +254,7 @@ pub fn check_shardtree_insertion<
|
|||
);
|
||||
|
||||
assert_matches!(
|
||||
tree.root_at_checkpoint(1),
|
||||
tree.root_at_checkpoint_depth(1),
|
||||
Err(ShardTreeError::Query(QueryError::TreeIncomplete(v))) if v == vec![Address::from_parts(Level::from(0), 0)]
|
||||
);
|
||||
|
||||
|
@ -271,12 +271,12 @@ pub fn check_shardtree_insertion<
|
|||
);
|
||||
|
||||
assert_matches!(
|
||||
tree.root_at_checkpoint(0),
|
||||
tree.root_at_checkpoint_depth(0),
|
||||
Ok(h) if h == *"abcd____________"
|
||||
);
|
||||
|
||||
assert_matches!(
|
||||
tree.root_at_checkpoint(1),
|
||||
tree.root_at_checkpoint_depth(1),
|
||||
Ok(h) if h == *"ab______________"
|
||||
);
|
||||
|
||||
|
@ -308,7 +308,7 @@ pub fn check_shardtree_insertion<
|
|||
);
|
||||
|
||||
assert_matches!(
|
||||
tree.root_at_checkpoint(0),
|
||||
tree.root_at_checkpoint_depth(0),
|
||||
// The (0, 13) and (1, 7) incomplete subtrees are
|
||||
// not considered incomplete here because they appear
|
||||
// at the tip of the tree.
|
||||
|
@ -331,12 +331,12 @@ pub fn check_shardtree_insertion<
|
|||
);
|
||||
|
||||
assert_matches!(
|
||||
tree.root_at_checkpoint(0),
|
||||
tree.root_at_checkpoint_depth(0),
|
||||
Ok(h) if h == *"abcdefghijkl____"
|
||||
);
|
||||
|
||||
assert_matches!(
|
||||
tree.root_at_checkpoint(1),
|
||||
tree.root_at_checkpoint_depth(1),
|
||||
Ok(h) if h == *"ab______________"
|
||||
);
|
||||
}
|
||||
|
@ -396,7 +396,9 @@ pub fn check_witness_with_pruned_subtrees<
|
|||
.unwrap();
|
||||
|
||||
// construct a witness for the note
|
||||
let witness = tree.witness(Position::from(26), 0).unwrap();
|
||||
let witness = tree
|
||||
.witness_at_checkpoint_depth(Position::from(26), 0)
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
witness.path_elems(),
|
||||
&[
|
||||
|
|
Loading…
Reference in New Issue