mirror of
https://github.com/logos-blockchain/logos-blockchain.git
synced 2026-05-18 15:29:30 +00:00
chore: enforce dependency declaration structure (#2667)
This commit is contained in:
parent
5a352d2222
commit
3b54edf586
9
.github/workflows/code-check.yml
vendored
9
.github/workflows/code-check.yml
vendored
@ -57,6 +57,15 @@ jobs:
|
||||
- name: Run cargo-deny
|
||||
run: cargo-deny --locked --all-features check --hide-inclusion-graph -c .cargo-deny.toml --show-stats -D warnings
|
||||
|
||||
workspace-deps:
|
||||
name: Check for correctly declared dependencies in the workspace
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@85e6279cec87321a52edac9c87bce653a07cf6c2 # Version 4.2.2
|
||||
- name: Run workspace dependency policies check
|
||||
run: scripts/check-workspace-dependency-policies.sh
|
||||
|
||||
unused-deps:
|
||||
name: Check for unused dependencies
|
||||
strategy:
|
||||
|
||||
15
Cargo.lock
generated
15
Cargo.lock
generated
@ -4491,7 +4491,7 @@ dependencies = [
|
||||
"logos-blockchain-core",
|
||||
"logos-blockchain-demo-sequencer",
|
||||
"owo-colors",
|
||||
"redb 3.1.3",
|
||||
"redb",
|
||||
"reqwest",
|
||||
"serde",
|
||||
"serde_json",
|
||||
@ -4514,7 +4514,7 @@ dependencies = [
|
||||
"logos-blockchain-key-management-system-service",
|
||||
"owo-colors",
|
||||
"rand 0.8.6",
|
||||
"redb 2.6.3",
|
||||
"redb",
|
||||
"reqwest",
|
||||
"serde",
|
||||
"serde_json",
|
||||
@ -5144,7 +5144,7 @@ dependencies = [
|
||||
"num-bigint",
|
||||
"quickcheck",
|
||||
"quickcheck_macros",
|
||||
"rand 0.9.4",
|
||||
"rand 0.8.6",
|
||||
"rpds",
|
||||
"serde",
|
||||
"thiserror 2.0.18",
|
||||
@ -6945,15 +6945,6 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redb"
|
||||
version = "3.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4ba239c1c1693315d3cc0e601db3b3965543afbf48c41730fdca2f069f510f4a"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.5.18"
|
||||
|
||||
329
scripts/check-workspace-dependency-policies.sh
Executable file
329
scripts/check-workspace-dependency-policies.sh
Executable file
@ -0,0 +1,329 @@
|
||||
#!/usr/bin/env sh
|
||||
set -eu
|
||||
|
||||
# Enforces workspace dependency policy across Cargo manifests.
|
||||
#
|
||||
# Checks:
|
||||
# - Workspace members must declare dependencies using `workspace = true` only
|
||||
# (no direct version/path/git dependency declarations).
|
||||
# - Workspace members must not override `default-features` on workspace deps.
|
||||
# - Root `[workspace.dependencies]` entries must set `default-features = false`.
|
||||
# - Root `[workspace.dependencies]` entries must not set `features`.
|
||||
#
|
||||
# Exit codes:
|
||||
# - 0: all checks passed.
|
||||
# - 1: one or more policy violations were found.
|
||||
# - 255: internal/tooling error while running the checker.
|
||||
|
||||
repo_root="$(cd "$(dirname "$0")/.." && pwd)"
|
||||
root_manifest="$repo_root/Cargo.toml"
|
||||
|
||||
FAILURE_DETECTED_EXIT_CODE=1
|
||||
INTERNAL_ERROR_EXIT_CODE=255
|
||||
|
||||
if [ ! -f "$root_manifest" ]; then
|
||||
echo "error: could not find workspace root Cargo.toml at $root_manifest" >&2
|
||||
exit $INTERNAL_ERROR_EXIT_CODE
|
||||
fi
|
||||
|
||||
if ! command -v cargo >/dev/null 2>&1; then
|
||||
echo "error: cargo is required" >&2
|
||||
exit $INTERNAL_ERROR_EXIT_CODE
|
||||
fi
|
||||
|
||||
manifest_list_file="$(mktemp "$repo_root/.tmp-workspace-manifests.XXXXXX")"
|
||||
awk_script_file="$(mktemp "$repo_root/.tmp-check-workspace-deps.XXXXXX.awk")"
|
||||
|
||||
cleanup() {
|
||||
rm -f "$manifest_list_file" "$awk_script_file"
|
||||
}
|
||||
trap cleanup 0 HUP INT TERM
|
||||
|
||||
if ! (
|
||||
cd "$repo_root" && cargo metadata --no-deps --format-version 1
|
||||
) | grep -o '"manifest_path":"[^"]*"' \
|
||||
| sed -E 's/^"manifest_path":"(.*)"$/\1/' \
|
||||
| sed 's#\\/#/#g' \
|
||||
| sort -u >"$manifest_list_file"; then
|
||||
echo "error: failed to read workspace manifests via cargo metadata" >&2
|
||||
exit $INTERNAL_ERROR_EXIT_CODE
|
||||
fi
|
||||
|
||||
if [ ! -s "$manifest_list_file" ]; then
|
||||
echo "error: could not extract package manifests from cargo metadata" >&2
|
||||
exit $INTERNAL_ERROR_EXIT_CODE
|
||||
fi
|
||||
|
||||
root_present=0
|
||||
while IFS= read -r manifest; do
|
||||
if [ "$manifest" = "$root_manifest" ]; then
|
||||
root_present=1
|
||||
break
|
||||
fi
|
||||
done <"$manifest_list_file"
|
||||
if [ "$root_present" -eq 0 ]; then
|
||||
printf '%s\n' "$root_manifest" >>"$manifest_list_file"
|
||||
fi
|
||||
|
||||
cat <<'AWK' >"$awk_script_file"
|
||||
function trim(s) {
|
||||
sub(/^[[:space:]]+/, "", s)
|
||||
sub(/[[:space:]]+$/, "", s)
|
||||
return s
|
||||
}
|
||||
|
||||
function normalize_dep_name(name) {
|
||||
name = trim(name)
|
||||
gsub(/^"|"$/, "", name)
|
||||
gsub(/^'|'$/, "", name)
|
||||
return name
|
||||
}
|
||||
|
||||
function record_violation(rule, dep, line_no, details) {
|
||||
violations += 1
|
||||
printf("- [%s] %s:%d dependency=%s %s\n", rule, manifest_path, line_no, dep, details)
|
||||
}
|
||||
|
||||
function braces_delta(s, opens, closes, copy) {
|
||||
copy = s
|
||||
opens = gsub(/\{/, "{", copy)
|
||||
copy = s
|
||||
closes = gsub(/\}/, "}", copy)
|
||||
return opens - closes
|
||||
}
|
||||
|
||||
function has_key(text, key) {
|
||||
return text ~ ("(^|[,{[:space:]])" key "[[:space:]]*=")
|
||||
}
|
||||
|
||||
function has_workspace_true(text) {
|
||||
return text ~ /workspace[[:space:]]*=[[:space:]]*true/
|
||||
}
|
||||
|
||||
function has_default_features_false(text) {
|
||||
return text ~ /default-features[[:space:]]*=[[:space:]]*false/
|
||||
}
|
||||
|
||||
function in_member_dependency_table(section_name) {
|
||||
return section_name ~ /(^|\.)dependencies$/ ||
|
||||
section_name ~ /(^|\.)dev-dependencies$/ ||
|
||||
section_name ~ /(^|\.)build-dependencies$/
|
||||
}
|
||||
|
||||
function in_member_dependency_item_table(section_name) {
|
||||
return section_name ~ /(^|\.)dependencies\.[^\.]+$/ ||
|
||||
section_name ~ /(^|\.)dev-dependencies\.[^\.]+$/ ||
|
||||
section_name ~ /(^|\.)build-dependencies\.[^\.]+$/
|
||||
}
|
||||
|
||||
function is_workspace_dependencies_table(section_name) {
|
||||
return section_name == "workspace.dependencies"
|
||||
}
|
||||
|
||||
function is_workspace_dependency_item_table(section_name) {
|
||||
return section_name ~ /^workspace\.dependencies\.[^\.]+$/
|
||||
}
|
||||
|
||||
function reset_specific_state() {
|
||||
specific_active = 0
|
||||
specific_kind = ""
|
||||
specific_dep = ""
|
||||
specific_dep_line = 0
|
||||
specific_workspace_true = 0
|
||||
specific_default_features_seen = 0
|
||||
specific_default_features_false = 0
|
||||
specific_features_seen = 0
|
||||
}
|
||||
|
||||
function finalize_specific_state() {
|
||||
if (!specific_active) {
|
||||
return
|
||||
}
|
||||
|
||||
if (specific_kind == "member") {
|
||||
if (!specific_workspace_true) {
|
||||
record_violation("workspace-only", specific_dep, specific_dep_line, "must set workspace = true")
|
||||
}
|
||||
if (specific_workspace_true && specific_default_features_seen) {
|
||||
record_violation("no-default-features-override", specific_dep, specific_dep_line, "must not set default-features when using workspace dependency")
|
||||
}
|
||||
} else if (specific_kind == "workspace-root") {
|
||||
if (!specific_default_features_seen || !specific_default_features_false) {
|
||||
record_violation("workspace-default-features-false", specific_dep, specific_dep_line, "must set default-features = false")
|
||||
}
|
||||
if (specific_features_seen) {
|
||||
record_violation("no-features", specific_dep, specific_dep_line, "must not set features")
|
||||
}
|
||||
}
|
||||
|
||||
reset_specific_state()
|
||||
}
|
||||
|
||||
function analyze_dependency_assignment(dep, value_text, line_no) {
|
||||
dep = normalize_dep_name(dep)
|
||||
|
||||
if (current_section == "workspace.dependencies" && is_root_manifest) {
|
||||
if (!has_default_features_false(value_text)) {
|
||||
record_violation("workspace-default-features-false", dep, line_no, "must set default-features = false")
|
||||
}
|
||||
if (has_key(value_text, "features")) {
|
||||
record_violation("no-features", dep, line_no, "must not set features")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if (!is_root_manifest && in_member_dependency_table(current_section)) {
|
||||
workspace_true = has_workspace_true(value_text)
|
||||
default_features_set = has_key(value_text, "default-features")
|
||||
|
||||
if (!workspace_true) {
|
||||
record_violation("workspace-only", dep, line_no, "must use workspace = true (no direct dependency declarations)")
|
||||
}
|
||||
if (workspace_true && default_features_set) {
|
||||
record_violation("no-default-features-override", dep, line_no, "must not set default-features when using workspace dependency")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BEGIN {
|
||||
violations = 0
|
||||
current_section = ""
|
||||
reset_specific_state()
|
||||
}
|
||||
|
||||
{
|
||||
original_line = $0
|
||||
line = $0
|
||||
sub(/[[:space:]]*#.*$/, "", line)
|
||||
|
||||
if (line ~ /^[[:space:]]*\[\[[^]]+\]\][[:space:]]*$/) {
|
||||
finalize_specific_state()
|
||||
section_value = line
|
||||
sub(/^[[:space:]]*\[\[/, "", section_value)
|
||||
sub(/\]\][[:space:]]*$/, "", section_value)
|
||||
current_section = trim(section_value)
|
||||
next
|
||||
}
|
||||
|
||||
if (line ~ /^[[:space:]]*\[[^]]+\][[:space:]]*$/) {
|
||||
finalize_specific_state()
|
||||
section_value = line
|
||||
sub(/^[[:space:]]*\[/, "", section_value)
|
||||
sub(/\][[:space:]]*$/, "", section_value)
|
||||
current_section = trim(section_value)
|
||||
|
||||
if (!is_root_manifest && in_member_dependency_item_table(current_section)) {
|
||||
specific_active = 1
|
||||
specific_kind = "member"
|
||||
specific_dep = normalize_dep_name(current_section)
|
||||
sub(/^.*\./, "", specific_dep)
|
||||
specific_dep = normalize_dep_name(specific_dep)
|
||||
specific_dep_line = NR
|
||||
next
|
||||
}
|
||||
|
||||
if (is_root_manifest && is_workspace_dependency_item_table(current_section)) {
|
||||
specific_active = 1
|
||||
specific_kind = "workspace-root"
|
||||
specific_dep = normalize_dep_name(current_section)
|
||||
sub(/^.*\./, "", specific_dep)
|
||||
specific_dep = normalize_dep_name(specific_dep)
|
||||
specific_dep_line = NR
|
||||
next
|
||||
}
|
||||
|
||||
next
|
||||
}
|
||||
|
||||
if (specific_active) {
|
||||
eq_pos = index(line, "=")
|
||||
if (eq_pos > 0) {
|
||||
key = trim(substr(line, 1, eq_pos - 1))
|
||||
value = trim(substr(line, eq_pos + 1))
|
||||
|
||||
if (key == "workspace" && value ~ /^true([[:space:]]|$)/) {
|
||||
specific_workspace_true = 1
|
||||
}
|
||||
if (key == "default-features") {
|
||||
specific_default_features_seen = 1
|
||||
if (value ~ /^false([[:space:]]|$)/) {
|
||||
specific_default_features_false = 1
|
||||
}
|
||||
}
|
||||
if (key == "features") {
|
||||
specific_features_seen = 1
|
||||
}
|
||||
}
|
||||
next
|
||||
}
|
||||
|
||||
if ((is_root_manifest && current_section == "workspace.dependencies") ||
|
||||
(!is_root_manifest && in_member_dependency_table(current_section))) {
|
||||
eq_pos = index(line, "=")
|
||||
if (eq_pos == 0) {
|
||||
next
|
||||
}
|
||||
|
||||
dep = trim(substr(line, 1, eq_pos - 1))
|
||||
value = trim(substr(line, eq_pos + 1))
|
||||
start_line = NR
|
||||
|
||||
if (value ~ /^\{/) {
|
||||
buffer = value
|
||||
delta = braces_delta(value)
|
||||
while (delta > 0 && getline next_line) {
|
||||
NR += 0
|
||||
temp = next_line
|
||||
sub(/[[:space:]]*#.*$/, "", temp)
|
||||
buffer = buffer " " trim(temp)
|
||||
delta += braces_delta(temp)
|
||||
}
|
||||
analyze_dependency_assignment(dep, buffer, start_line)
|
||||
} else {
|
||||
analyze_dependency_assignment(dep, value, start_line)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
END {
|
||||
finalize_specific_state()
|
||||
if (violations > 0) {
|
||||
exit 2
|
||||
}
|
||||
}
|
||||
AWK
|
||||
|
||||
had_violations=0
|
||||
had_internal_error=0
|
||||
|
||||
while IFS= read -r manifest; do
|
||||
is_root=0
|
||||
if [ "$manifest" = "$root_manifest" ]; then
|
||||
is_root=1
|
||||
fi
|
||||
|
||||
if output="$(awk -v manifest_path="$manifest" -v is_root_manifest="$is_root" -f "$awk_script_file" "$manifest")"; then
|
||||
:
|
||||
else
|
||||
status=$?
|
||||
if [ "$status" -eq 2 ]; then
|
||||
had_violations=1
|
||||
if [ -n "$output" ]; then
|
||||
printf '%s\n' "$output"
|
||||
fi
|
||||
else
|
||||
had_internal_error=1
|
||||
echo "error: failed while checking $manifest" >&2
|
||||
fi
|
||||
fi
|
||||
done <"$manifest_list_file"
|
||||
|
||||
if [ "$had_internal_error" -eq 1 ]; then
|
||||
exit $INTERNAL_ERROR_EXIT_CODE
|
||||
fi
|
||||
|
||||
if [ "$had_violations" -eq 1 ]; then
|
||||
exit $FAILURE_DETECTED_EXIT_CODE
|
||||
fi
|
||||
|
||||
echo "workspace dependency policy check passed"
|
||||
@ -23,14 +23,13 @@ lb-common-http-client = { workspace = true }
|
||||
lb-core = { workspace = true }
|
||||
lb-demo-sequencer = { workspace = true }
|
||||
owo-colors = { workspace = true }
|
||||
# TODO: Replace with unified workspace dependency
|
||||
redb = { default-features = false, version = "3.1.0" }
|
||||
reqwest = { features = ["json", "rustls-tls"], workspace = true }
|
||||
serde = { workspace = true }
|
||||
serde_json = { workspace = true }
|
||||
thiserror = { workspace = true }
|
||||
tokio = { workspace = true }
|
||||
tokio-stream = { workspace = true }
|
||||
tokio-util = { workspace = true }
|
||||
tower-http = { features = ["cors"], workspace = true }
|
||||
url = { workspace = true }
|
||||
redb = { workspace = true }
|
||||
reqwest = { features = ["json", "rustls-tls"], workspace = true }
|
||||
serde = { workspace = true }
|
||||
serde_json = { workspace = true }
|
||||
thiserror = { workspace = true }
|
||||
tokio = { workspace = true }
|
||||
tokio-stream = { workspace = true }
|
||||
tokio-util = { workspace = true }
|
||||
tower-http = { features = ["cors"], workspace = true }
|
||||
url = { workspace = true }
|
||||
|
||||
@ -2,8 +2,8 @@ use std::sync::Arc;
|
||||
|
||||
use lb_core::codec::{DeserializeOp as _, SerializeOp as _};
|
||||
use redb::{
|
||||
CommitError, Database, DatabaseError, ReadableDatabase as _, ReadableTable as _, StorageError,
|
||||
TableDefinition, TableError, TransactionError,
|
||||
CommitError, Database, DatabaseError, ReadableTable as _, StorageError, TableDefinition,
|
||||
TableError, TransactionError,
|
||||
};
|
||||
use thiserror::Error;
|
||||
use tokio::sync::RwLock;
|
||||
|
||||
@ -21,8 +21,7 @@ thiserror = { workspace = true }
|
||||
[dev-dependencies]
|
||||
quickcheck = { workspace = true }
|
||||
quickcheck_macros = { workspace = true }
|
||||
# TODO: Replace with unified workspace dependency
|
||||
rand = { default-features = false, features = ["thread_rng"], version = "0.9" }
|
||||
rand = { workspace = true }
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
||||
@ -231,7 +231,7 @@ mod serde {
|
||||
mod tests {
|
||||
use quickcheck::{Arbitrary, Gen};
|
||||
use quickcheck_macros::quickcheck;
|
||||
use rand::rng;
|
||||
use rand::thread_rng;
|
||||
|
||||
use super::*;
|
||||
use crate::test_fr::TestFr;
|
||||
@ -246,7 +246,7 @@ mod tests {
|
||||
#[test]
|
||||
fn test_single_insert() {
|
||||
let tree: UtxoTree<TestFr, TestFr, TestHash> = UtxoTree::new();
|
||||
let item = TestFr::from_rng(&mut rng());
|
||||
let item = TestFr::from_rng(&mut thread_rng());
|
||||
let key = item;
|
||||
let (tree_with_item, _pos) = tree.insert(key, item);
|
||||
|
||||
@ -260,9 +260,9 @@ mod tests {
|
||||
let tree: UtxoTree<TestFr, TestFr, TestHash> = UtxoTree::new();
|
||||
|
||||
let items = [
|
||||
TestFr::from_rng(&mut rng()),
|
||||
TestFr::from_rng(&mut rng()),
|
||||
TestFr::from_rng(&mut rng()),
|
||||
TestFr::from_rng(&mut thread_rng()),
|
||||
TestFr::from_rng(&mut thread_rng()),
|
||||
TestFr::from_rng(&mut thread_rng()),
|
||||
];
|
||||
let mut current_tree = tree;
|
||||
|
||||
@ -281,7 +281,7 @@ mod tests {
|
||||
fn test_remove_existing_item() {
|
||||
let tree: UtxoTree<TestFr, TestFr, TestHash> = UtxoTree::new();
|
||||
|
||||
let item = TestFr::from_rng(&mut rng());
|
||||
let item = TestFr::from_rng(&mut thread_rng());
|
||||
let key = item;
|
||||
let (tree_with_item, _) = tree.insert(key, item);
|
||||
|
||||
@ -297,11 +297,11 @@ mod tests {
|
||||
fn test_remove_non_existing_item() {
|
||||
let tree: UtxoTree<TestFr, TestFr, TestHash> = UtxoTree::new();
|
||||
|
||||
let item = TestFr::from_rng(&mut rng());
|
||||
let item = TestFr::from_rng(&mut thread_rng());
|
||||
let key = item;
|
||||
let (tree_with_item, _) = tree.insert(key, item);
|
||||
|
||||
let non_existing_key = TestFr::from_rng(&mut rng());
|
||||
let non_existing_key = TestFr::from_rng(&mut thread_rng());
|
||||
let result = tree_with_item.remove(&non_existing_key);
|
||||
assert!(matches!(result, Err(Error::NotFound)));
|
||||
}
|
||||
@ -310,7 +310,7 @@ mod tests {
|
||||
fn test_remove_from_empty_tree() {
|
||||
let tree: UtxoTree<TestFr, TestFr, TestHash> = UtxoTree::new();
|
||||
|
||||
let key = TestFr::from_rng(&mut rng());
|
||||
let key = TestFr::from_rng(&mut thread_rng());
|
||||
let result = tree.remove(&key);
|
||||
assert!(matches!(result, Err(Error::NotFound)));
|
||||
}
|
||||
@ -319,8 +319,8 @@ mod tests {
|
||||
fn test_structural_sharing() {
|
||||
let tree: UtxoTree<TestFr, TestFr, TestHash> = UtxoTree::new();
|
||||
|
||||
let item1 = TestFr::from_rng(&mut rng());
|
||||
let item2 = TestFr::from_rng(&mut rng());
|
||||
let item1 = TestFr::from_rng(&mut thread_rng());
|
||||
let item2 = TestFr::from_rng(&mut thread_rng());
|
||||
let key1 = item1;
|
||||
let key2 = item2;
|
||||
|
||||
@ -338,7 +338,7 @@ mod tests {
|
||||
|
||||
let empty_root = tree.root();
|
||||
|
||||
let item = TestFr::from_rng(&mut rng());
|
||||
let item = TestFr::from_rng(&mut thread_rng());
|
||||
let key = item;
|
||||
let (tree_with_item, _) = tree.insert(key, item);
|
||||
let root_with_item = tree_with_item.root();
|
||||
@ -357,9 +357,9 @@ mod tests {
|
||||
let tree2: UtxoTree<TestFr, TestFr, TestHash> = UtxoTree::new();
|
||||
|
||||
let items = vec![
|
||||
TestFr::from_rng(&mut rng()),
|
||||
TestFr::from_rng(&mut rng()),
|
||||
TestFr::from_rng(&mut rng()),
|
||||
TestFr::from_rng(&mut thread_rng()),
|
||||
TestFr::from_rng(&mut thread_rng()),
|
||||
TestFr::from_rng(&mut thread_rng()),
|
||||
];
|
||||
|
||||
let mut current_tree1 = tree1;
|
||||
@ -382,10 +382,10 @@ mod tests {
|
||||
|
||||
let mut current_tree = tree;
|
||||
let items = vec![
|
||||
TestFr::from_rng(&mut rng()),
|
||||
TestFr::from_rng(&mut rng()),
|
||||
TestFr::from_rng(&mut rng()),
|
||||
TestFr::from_rng(&mut rng()),
|
||||
TestFr::from_rng(&mut thread_rng()),
|
||||
TestFr::from_rng(&mut thread_rng()),
|
||||
TestFr::from_rng(&mut thread_rng()),
|
||||
TestFr::from_rng(&mut thread_rng()),
|
||||
];
|
||||
|
||||
for item in &items {
|
||||
@ -401,7 +401,7 @@ mod tests {
|
||||
let (tree_after_removal2, _) = tree_after_removal.remove(&items[3]).unwrap();
|
||||
assert_eq!(tree_after_removal2.size(), 2);
|
||||
|
||||
let new_item = TestFr::from_rng(&mut rng());
|
||||
let new_item = TestFr::from_rng(&mut thread_rng());
|
||||
let new_key = new_item;
|
||||
let (final_tree, _) = tree_after_removal2.insert(new_key, new_item);
|
||||
assert_eq!(final_tree.size(), 3);
|
||||
@ -420,9 +420,9 @@ mod tests {
|
||||
let tree: UtxoTree<TestFr, TestFr, TestHash> = UtxoTree::new();
|
||||
|
||||
let items = vec![
|
||||
TestFr::from_rng(&mut rng()),
|
||||
TestFr::from_rng(&mut rng()),
|
||||
TestFr::from_rng(&mut rng()),
|
||||
TestFr::from_rng(&mut thread_rng()),
|
||||
TestFr::from_rng(&mut thread_rng()),
|
||||
TestFr::from_rng(&mut thread_rng()),
|
||||
];
|
||||
let mut current_tree = tree;
|
||||
let mut positions = Vec::new();
|
||||
|
||||
@ -490,7 +490,7 @@ mod tests {
|
||||
#[test]
|
||||
fn test_hole_management() {
|
||||
let tree: DynamicMerkleTree<TestFr, TestHash> = DynamicMerkleTree::new();
|
||||
let mut rng = rand::rng();
|
||||
let mut rng = rand::thread_rng();
|
||||
let a = TestFr::from_rng(&mut rng);
|
||||
let b = TestFr::from_rng(&mut rng);
|
||||
let c = TestFr::from_rng(&mut rng);
|
||||
@ -510,7 +510,7 @@ mod tests {
|
||||
#[test]
|
||||
fn test_root_consistency() {
|
||||
let tree: DynamicMerkleTree<TestFr, TestHash> = DynamicMerkleTree::new();
|
||||
let mut rng = rand::rng();
|
||||
let mut rng = rand::thread_rng();
|
||||
let a = TestFr::from_rng(&mut rng);
|
||||
let b = TestFr::from_rng(&mut rng);
|
||||
let (tree1, _) = tree.insert(a);
|
||||
@ -527,7 +527,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_deterministic_root() {
|
||||
let mut rng = rand::rng();
|
||||
let mut rng = rand::thread_rng();
|
||||
let a = TestFr::from_rng(&mut rng);
|
||||
let b = TestFr::from_rng(&mut rng);
|
||||
let tree1: DynamicMerkleTree<TestFr, TestHash> = DynamicMerkleTree::new();
|
||||
@ -545,14 +545,14 @@ mod tests {
|
||||
#[should_panic(expected = "Index out of bounds")]
|
||||
fn test_remove_out_of_bounds() {
|
||||
let tree: DynamicMerkleTree<TestFr, TestHash> = DynamicMerkleTree::new();
|
||||
let (tree, _) = tree.insert(TestFr::from_rng(&mut rand::rng()));
|
||||
let (tree, _) = tree.insert(TestFr::from_rng(&mut rand::thread_rng()));
|
||||
tree.remove(1 << 32);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_single_insert() {
|
||||
let tree: DynamicMerkleTree<TestFr, TestHash> = DynamicMerkleTree::new();
|
||||
let item = TestFr::from_rng(&mut rand::rng());
|
||||
let item = TestFr::from_rng(&mut rand::thread_rng());
|
||||
let (tree_with_item, index) = tree.insert(item);
|
||||
|
||||
assert_eq!(tree_with_item.size(), 1);
|
||||
@ -565,9 +565,9 @@ mod tests {
|
||||
fn test_multiple_inserts() {
|
||||
let mut tree: DynamicMerkleTree<TestFr, TestHash> = DynamicMerkleTree::new();
|
||||
let items = [
|
||||
TestFr::from_rng(&mut rand::rng()),
|
||||
TestFr::from_rng(&mut rand::rng()),
|
||||
TestFr::from_rng(&mut rand::rng()),
|
||||
TestFr::from_rng(&mut rand::thread_rng()),
|
||||
TestFr::from_rng(&mut rand::thread_rng()),
|
||||
TestFr::from_rng(&mut rand::thread_rng()),
|
||||
];
|
||||
|
||||
for (i, item) in items.iter().enumerate() {
|
||||
@ -583,7 +583,7 @@ mod tests {
|
||||
#[test]
|
||||
fn test_remove_single_item() {
|
||||
let tree: DynamicMerkleTree<TestFr, TestHash> = DynamicMerkleTree::new();
|
||||
let item = TestFr::from_rng(&mut rand::rng());
|
||||
let item = TestFr::from_rng(&mut rand::thread_rng());
|
||||
let (tree_with_item, _) = tree.insert(item);
|
||||
|
||||
let tree_after_removal = tree_with_item.remove(0);
|
||||
@ -595,9 +595,9 @@ mod tests {
|
||||
fn test_remove_and_reinsert() {
|
||||
let mut tree: DynamicMerkleTree<TestFr, TestHash> = DynamicMerkleTree::new();
|
||||
let items = vec![
|
||||
TestFr::from_rng(&mut rand::rng()),
|
||||
TestFr::from_rng(&mut rand::rng()),
|
||||
TestFr::from_rng(&mut rand::rng()),
|
||||
TestFr::from_rng(&mut rand::thread_rng()),
|
||||
TestFr::from_rng(&mut rand::thread_rng()),
|
||||
TestFr::from_rng(&mut rand::thread_rng()),
|
||||
];
|
||||
|
||||
for item in &items {
|
||||
@ -609,7 +609,7 @@ mod tests {
|
||||
assert_eq!(tree_after_removal.size(), 2);
|
||||
|
||||
let (tree_after_reinsert, index) =
|
||||
tree_after_removal.insert(TestFr::from_rng(&mut rand::rng()));
|
||||
tree_after_removal.insert(TestFr::from_rng(&mut rand::thread_rng()));
|
||||
assert_eq!(tree_after_reinsert.size(), 3);
|
||||
assert_eq!(index, 1);
|
||||
}
|
||||
@ -617,8 +617,8 @@ mod tests {
|
||||
#[test]
|
||||
fn test_structural_sharing() {
|
||||
let tree1: DynamicMerkleTree<TestFr, TestHash> = DynamicMerkleTree::new();
|
||||
let (tree2, _) = tree1.insert(TestFr::from_rng(&mut rand::rng()));
|
||||
let (tree3, _) = tree2.insert(TestFr::from_rng(&mut rand::rng()));
|
||||
let (tree2, _) = tree1.insert(TestFr::from_rng(&mut rand::thread_rng()));
|
||||
let (tree3, _) = tree2.insert(TestFr::from_rng(&mut rand::thread_rng()));
|
||||
|
||||
assert_eq!(tree1.size(), 0);
|
||||
assert_eq!(tree2.size(), 1);
|
||||
@ -634,11 +634,11 @@ mod tests {
|
||||
let tree: DynamicMerkleTree<TestFr, TestHash> = DynamicMerkleTree::new();
|
||||
|
||||
// Insert items at positions 0, 1, 2, 3, 4
|
||||
let (tree, _) = tree.insert(TestFr::from_rng(&mut rand::rng()));
|
||||
let (tree, _) = tree.insert(TestFr::from_rng(&mut rand::rng()));
|
||||
let (tree, _) = tree.insert(TestFr::from_rng(&mut rand::rng()));
|
||||
let (tree, _) = tree.insert(TestFr::from_rng(&mut rand::rng()));
|
||||
let (tree, _) = tree.insert(TestFr::from_rng(&mut rand::rng()));
|
||||
let (tree, _) = tree.insert(TestFr::from_rng(&mut rand::thread_rng()));
|
||||
let (tree, _) = tree.insert(TestFr::from_rng(&mut rand::thread_rng()));
|
||||
let (tree, _) = tree.insert(TestFr::from_rng(&mut rand::thread_rng()));
|
||||
let (tree, _) = tree.insert(TestFr::from_rng(&mut rand::thread_rng()));
|
||||
let (tree, _) = tree.insert(TestFr::from_rng(&mut rand::thread_rng()));
|
||||
|
||||
// Remove items at positions 3, 1, 4 (creating holes in that order)
|
||||
let tree = tree.remove(3);
|
||||
@ -647,15 +647,15 @@ mod tests {
|
||||
|
||||
// Now we have holes at positions 1, 3, 4
|
||||
// The smallest hole should be selected first (position 1)
|
||||
let (tree, index1) = tree.insert(TestFr::from_rng(&mut rand::rng()));
|
||||
let (tree, index1) = tree.insert(TestFr::from_rng(&mut rand::thread_rng()));
|
||||
assert_eq!(index1, 1, "Should select smallest hole first");
|
||||
|
||||
// Next insertion should use the next smallest hole (position 3)
|
||||
let (tree, index2) = tree.insert(TestFr::from_rng(&mut rand::rng()));
|
||||
let (tree, index2) = tree.insert(TestFr::from_rng(&mut rand::thread_rng()));
|
||||
assert_eq!(index2, 3, "Should select next smallest hole");
|
||||
|
||||
// Final insertion should use the last hole (position 4)
|
||||
let (_, index3) = tree.insert(TestFr::from_rng(&mut rand::rng()));
|
||||
let (_, index3) = tree.insert(TestFr::from_rng(&mut rand::thread_rng()));
|
||||
assert_eq!(index3, 4, "Should select remaining hole");
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user