0.3.18 (app only): the clock sample asks igneum_getExecStatus first and takes no block from a follower without a record (ledger N7)
A node before 0.3.18's exec RPC fix dies on eth_getBlockByNumber when its exec follower holds no record (rpc.rs indexes records[0] on an empty vector; the panic hook exits the process), and this sample ran every 9 s once blocks arrived, so a fresh install's IBD and PC 1's restart crash-looped. The sample now waits for executedTipHash. No node change; the pin stays at 5899f603. Version 0.3.18 on the 0.3.17 app tree. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
parent
a7a9e5c231
commit
0f6b4650b6
7 changed files with 46 additions and 10 deletions
2
app/igneum-app/Cargo.lock
generated
2
app/igneum-app/Cargo.lock
generated
|
|
@ -219,7 +219,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "igneum-app"
|
||||
version = "0.3.17"
|
||||
version = "0.3.18"
|
||||
dependencies = [
|
||||
"ed25519-dalek",
|
||||
"getrandom",
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "igneum-app"
|
||||
version = "0.3.17"
|
||||
version = "0.3.18"
|
||||
edition = "2021"
|
||||
description = "Igneum Miner engine: supervises the node, the miner and the GPU workers, and serves the dashboard on 127.0.0.1"
|
||||
license = "MIT"
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@
|
|||
1 ICON "igneum.ico"
|
||||
|
||||
1 VERSIONINFO
|
||||
FILEVERSION 0,3,17,0
|
||||
PRODUCTVERSION 0,3,17,0
|
||||
FILEVERSION 0,3,18,0
|
||||
PRODUCTVERSION 0,3,18,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
FILEFLAGS 0x0L
|
||||
FILEOS VOS_NT_WINDOWS32
|
||||
|
|
@ -20,12 +20,12 @@ BEGIN
|
|||
BEGIN
|
||||
VALUE "CompanyName", "Igneum"
|
||||
VALUE "FileDescription", "Igneum Miner engine"
|
||||
VALUE "FileVersion", "0.3.17"
|
||||
VALUE "FileVersion", "0.3.18"
|
||||
VALUE "InternalName", "igneum-app"
|
||||
VALUE "LegalCopyright", "Igneum contributors"
|
||||
VALUE "OriginalFilename", "igneum-app.exe"
|
||||
VALUE "ProductName", "Igneum Miner"
|
||||
VALUE "ProductVersion", "0.3.17"
|
||||
VALUE "ProductVersion", "0.3.18"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
|
|
|||
|
|
@ -40,9 +40,36 @@ fn days_from_civil(y: i64, m: i64, d: i64) -> i64 {
|
|||
era * 146_097 + doe - 719_468
|
||||
}
|
||||
|
||||
/// True once the node's exec follower holds a record (igneum_getExecStatus's executedTipHash is set). Any error or an
|
||||
/// unreachable node reads false: the block sample waits rather than asks.
|
||||
fn exec_has_record(evm_port: u16) -> bool {
|
||||
let body = "{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"igneum_getExecStatus\",\"params\":[]}";
|
||||
let out = crate::detect::run_timeout(
|
||||
Command::new(crate::platform::tool("curl")).args(["-s", "--max-time", "5", "-X", "POST", &format!("http://127.0.0.1:{evm_port}"), "-H", "Content-Type: application/json", "-d", body]),
|
||||
None,
|
||||
Duration::from_secs(7),
|
||||
);
|
||||
out.as_deref().map(exec_status_has_record).unwrap_or(false)
|
||||
}
|
||||
|
||||
/// The reading of an igneum_getExecStatus reply: a record is held when executedTipHash is a non-null string.
|
||||
pub fn exec_status_has_record(reply: &str) -> bool {
|
||||
serde_json::from_str::<serde_json::Value>(reply)
|
||||
.ok()
|
||||
.and_then(|v| v.get("result")?.get("executedTipHash")?.as_str().map(|h| !h.is_empty()))
|
||||
.unwrap_or(false)
|
||||
}
|
||||
|
||||
/// The latest block's timestamp (unix seconds) from the node's Ethereum JSON-RPC (the execution layer mirrors the
|
||||
/// consensus block times). The first clock source: local time against what the peers produced.
|
||||
pub fn latest_block_time(evm_port: u16) -> Option<f64> {
|
||||
// 0.3.18 (ledger N7, 7 October 2026): a node whose exec follower holds no record yet dies on eth_getBlockByNumber
|
||||
// (rpc.rs indexes records[0] on an empty vector and the panic hook exits the process). The nodes before 0.3.18's
|
||||
// fix are live on every machine, and this sample runs every 9 s once blocks arrive, so it asks igneum_getExecStatus
|
||||
// first (it indexes nothing) and takes no block until the follower reports an executed tip.
|
||||
if !exec_has_record(evm_port) {
|
||||
return None;
|
||||
}
|
||||
let body = "{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"eth_getBlockByNumber\",\"params\":[\"latest\",false]}";
|
||||
let out = crate::detect::run_timeout(
|
||||
Command::new(crate::platform::tool("curl")).args(["-s", "--max-time", "5", "-X", "POST", &format!("http://127.0.0.1:{evm_port}"), "-H", "Content-Type: application/json", "-d", body]),
|
||||
|
|
@ -56,6 +83,15 @@ pub fn latest_block_time(evm_port: u16) -> Option<f64> {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
/// Ledger N7: the clock sample must not ask eth_getBlockByNumber of a follower with no record
|
||||
#[test]
|
||||
fn exec_status_gate() {
|
||||
assert!(super::exec_status_has_record(r#"{"jsonrpc":"2.0","id":1,"result":{"executedTip":"0x38a5","executedTipHash":"0xa3ae37ec31b9227c3855a1b25ba50ee9f6815bf00b0befcc8836b430baf04343"}}"#));
|
||||
assert!(!super::exec_status_has_record(r#"{"jsonrpc":"2.0","id":1,"result":{"executedTip":"0x0","executedTipHash":null}}"#));
|
||||
assert!(!super::exec_status_has_record(r#"{"jsonrpc":"2.0","id":1,"error":{"code":-32601,"message":"method not found"}}"#));
|
||||
assert!(!super::exec_status_has_record(""));
|
||||
assert!(!super::exec_status_has_record("not json"));
|
||||
}
|
||||
#[test]
|
||||
fn http_date() {
|
||||
assert_eq!(super::parse_http_date("Sun, 04 Oct 2026 11:17:47 GMT"), Some(1_791_112_667.0));
|
||||
|
|
|
|||
|
|
@ -3,6 +3,6 @@
|
|||
// packaging/windows/Igneum-Miner.iss when the app version moves. Include guards, not #pragma once: rc.exe reads it too.
|
||||
#ifndef IGNEUM_HOST_VERSION_H
|
||||
#define IGNEUM_HOST_VERSION_H
|
||||
#define IGNEUM_HOST_VERSION_STR "0.3.17"
|
||||
#define IGNEUM_HOST_VERSION_RC 0,3,17,0
|
||||
#define IGNEUM_HOST_VERSION_STR "0.3.18"
|
||||
#define IGNEUM_HOST_VERSION_RC 0,3,18,0
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
<key>CFBundleVersion</key>
|
||||
<string>VERSION_STAMP</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>0.3.17</string>
|
||||
<string>0.3.18</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
#define ArtDir "..\..\brand\icons"
|
||||
#endif
|
||||
#ifndef AppVersion
|
||||
#define AppVersion "0.3.17"
|
||||
#define AppVersion "0.3.18"
|
||||
#endif
|
||||
#define AppName "Igneum Miner"
|
||||
#define Publisher "Igneum"
|
||||
|
|
|
|||
Loading…
Reference in a new issue