commit 987a8312b91aaa5209a08c6f5dca5cf387cd8ada
parent ebb42a45515784cff6b5ce4683b57aabd00bff26
Author: Joris Hartog <jorishartog@hotmail.com>
Date: Mon, 10 Aug 2026 00:00:54 +0200
Release v0.2.39
Diffstat:
4 files changed, 33 insertions(+), 28 deletions(-)
diff --git a/Cargo.lock b/Cargo.lock
@@ -537,7 +537,7 @@ checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682"
[[package]]
name = "iuna"
-version = "0.2.38"
+version = "0.2.39"
dependencies = [
"anyhow",
"axum",
diff --git a/Cargo.toml b/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "iuna"
-version = "0.2.38"
+version = "0.2.39"
edition = "2024"
license = "Apache-2.0"
diff --git a/src/adapters/http.rs b/src/adapters/http.rs
@@ -3370,6 +3370,8 @@ const INDEX_HTML: &str = r#"<!doctype html>
.mining-event-title { color: #eef6f8; font-weight: 850; overflow-wrap: anywhere; }
.mining-event-detail { margin-top: 3px; color: #9fa8ad; font-size: 12px; line-height: 1.35; overflow-wrap: anywhere; }
.mining-event-time { color: #7f888e; font-size: 11px; font-weight: 800; white-space: nowrap; }
+ .mining-event-empty { height: 42px; border: 1px solid #30383d; border-radius: 8px; background: #111316; }
+ .mining-event-empty .skeleton-line { width: 100%; height: 100%; border-radius: 8px; opacity: .55; }
.panel-separator { border-top: 1px solid #2f363c; margin: 14px 0 12px; }
.stratum-config { display: grid; gap: 10px; }
.stratum-note { max-width: 760px; color: #9eb3bc; font-size: 12px; line-height: 1.45; }
@@ -3795,24 +3797,7 @@ const INDEX_HTML: &str = r#"<!doctype html>
<div class="mining-event-log" aria-label="Mining event log">
<div class="mining-event-log-head"><span>Event log</span><span x-text="`${miningEventLog().length} lines`"></span></div>
<template x-if="miningEventLog().length === 0">
- <div class="mining-event skeleton-card" aria-hidden="true">
- <span class="mining-event-dot"></span>
- <div>
- <div class="skeleton-line medium"></div>
- <div class="skeleton-line long"></div>
- </div>
- <div class="skeleton-line short"></div>
- </div>
- </template>
- <template x-if="miningEventLog().length === 0">
- <div class="mining-event skeleton-card" aria-hidden="true">
- <span class="mining-event-dot"></span>
- <div>
- <div class="skeleton-line short"></div>
- <div class="skeleton-line medium"></div>
- </div>
- <div class="skeleton-line short"></div>
- </div>
+ <div class="mining-event-empty skeleton-card" aria-hidden="true"><div class="skeleton-line"></div></div>
</template>
<template x-for="event in miningEventLog()" :key="event.key">
<div class="mining-event" :class="event.kind">
@@ -6272,6 +6257,7 @@ mod tests {
assert!(app_js.contains("slice(0, this.miningEventLimit)"));
assert!(super::INDEX_HTML.contains("aria-label=\"Mining event log\""));
assert!(super::INDEX_HTML.contains("miningEventLog().length === 0"));
+ assert!(super::INDEX_HTML.contains("mining-event-empty"));
assert!(app_js.contains("Resource budget:"));
assert!(app_js.contains("isPowMineSuccessStatus"));
assert!(app_js.contains("You mined a PoW action"));
diff --git a/src/domain.rs b/src/domain.rs
@@ -28,6 +28,7 @@ pub const MAX_VDF_ROUNDS: u64 = i64::MAX as u64;
pub const MINE_DIFFICULTY_BITS: u32 = 12;
pub const MINE_ACTIONS_PER_ANCHOR_LIMIT: usize = 2;
pub const MINE_ACTIONS_PER_ANCHOR_LIMIT_ACTIVATION_HEIGHT: u64 = 200;
+pub const FALLBACK_VDF_RETARGET_ACTIVATION_HEIGHT: u64 = 380;
pub const MAX_BLINDED_TRANSACTION_EXPIRY_HEIGHTS: u64 = 20;
pub const REVEAL_COMMITTEE_SIZE: usize = 3;
pub const MAX_REVEAL_BUNDLE_BYTES: usize = 10_000;
@@ -5862,7 +5863,10 @@ fn clamped_vdf_retarget_observed_block_ms(observed_block_ms: u64) -> u64 {
}
fn vdf_retarget_observed_block_ms(parent: &Block, child: &Block) -> Option<u64> {
- if child.finalizer_mode != FinalizerMode::Ticket || child.finalizer_rank != 0 {
+ if child.finalizer_mode != FinalizerMode::Ticket {
+ return None;
+ }
+ if child.finalizer_rank != 0 && child.height < FALLBACK_VDF_RETARGET_ACTIVATION_HEIGHT {
return None;
}
@@ -6650,14 +6654,16 @@ mod tests {
}
#[test]
- fn vdf_retarget_observed_block_time_ignores_ticket_fallback_ranks() {
+ fn vdf_retarget_observed_block_time_includes_ticket_fallback_ranks_after_activation() {
let parent = vdf_retarget_sample_block(0, FinalizerMode::Ticket, 0);
let primary_child =
vdf_retarget_sample_block(VDF_TARGET_BLOCK_MS, FinalizerMode::Ticket, 0);
- let rank_one_child =
- vdf_retarget_sample_block(VDF_TARGET_BLOCK_MS, FinalizerMode::Ticket, 1);
- let rank_two_child =
- vdf_retarget_sample_block(VDF_TARGET_BLOCK_MS * 2, FinalizerMode::Ticket, 2);
+ let mut rank_one_child =
+ vdf_retarget_sample_block(VDF_TARGET_BLOCK_MS * 2, FinalizerMode::Ticket, 1);
+ rank_one_child.height = FALLBACK_VDF_RETARGET_ACTIVATION_HEIGHT;
+ let mut rank_two_child =
+ vdf_retarget_sample_block(VDF_TARGET_BLOCK_MS * 4, FinalizerMode::Ticket, 2);
+ rank_two_child.height = FALLBACK_VDF_RETARGET_ACTIVATION_HEIGHT + 1;
assert_eq!(
vdf_retarget_observed_block_ms(&parent, &primary_child),
@@ -6665,10 +6671,23 @@ mod tests {
);
assert_eq!(
vdf_retarget_observed_block_ms(&parent, &rank_one_child),
- None
+ Some(VDF_TARGET_BLOCK_MS * 2)
);
assert_eq!(
vdf_retarget_observed_block_ms(&parent, &rank_two_child),
+ Some(VDF_TARGET_BLOCK_MS * 4)
+ );
+ }
+
+ #[test]
+ fn vdf_retarget_observed_block_time_ignores_ticket_fallback_ranks_before_activation() {
+ let parent = vdf_retarget_sample_block(0, FinalizerMode::Ticket, 0);
+ let mut fallback_child =
+ vdf_retarget_sample_block(VDF_TARGET_BLOCK_MS * 2, FinalizerMode::Ticket, 1);
+ fallback_child.height = FALLBACK_VDF_RETARGET_ACTIVATION_HEIGHT - 1;
+
+ assert_eq!(
+ vdf_retarget_observed_block_ms(&parent, &fallback_child),
None
);
}
@@ -6743,7 +6762,7 @@ mod tests {
}
#[test]
- fn fallback_block_is_excluded_from_vdf_retarget_observations() {
+ fn fallback_block_before_activation_is_excluded_from_vdf_retarget_observations() {
let alice = Wallet::from_seed("fallback-retarget-alice");
let bob = Wallet::from_seed("fallback-retarget-bob");
let wallets = [&alice, &bob];