Something goes horribly wrong for me in the mining kernel. Running this on arm64 with 32gb ram and the same amount of swap.
2025-05-22T12:36:38.306762Z INFO poke{src="timer"}:do_poke:slam:interpret: slogger: candidate block timestamp updated: 0x8000000d36cd27d6
2025-05-22T12:36:38.306762Z DEBUG next_effect: nockapp::nockapp::driver: Waiting for recv on next effect
2025-05-22T12:36:38.306814Z DEBUG next_effect: nockapp::nockapp::driver: Waiting for recv on next effect
thread 'serf' panicked at crates/nockvm/rust/nockvm/src/mem.rs:301:23:
Box<dyn Any>
thread 'tokio-runtime-worker' panicked at crates/nockchain/src/mining.rs:175:14:
Could not load mining kernel: OneshotChannelError(RecvError(()))
2025-05-22T12:36:38.309510Z WARN nockchain::mining: Error during mining attempt: JoinError::Panic(Id(2932), "Could not load mining kernel: OneshotChannelError(RecvError(()))", ...)
It’s related to this code in mem.rs
:
/** Initialization:
* The initial frame is a west frame. When the stack is initialized, a number of slots is given.
* We add three extra slots to store the “previous” frame, stack, and allocation pointer. For the
* initial frame, the previous allocation pointer is set to the beginning (low boundary) of the
* arena, the previous frame pointer is set to NULL, and the previous stack pointer is set to NULL
* size is in 64-bit (i.e. 8-byte) words.
* top_slots is how many slots to allocate to the top stack frame.
*/
pub fn new(size: usize, top_slots: usize) -> NockStack {
let result = Self::new_(size, top_slots);
match result {
Ok((stack, _)) => stack,
Err(e) => std::panic::panic_any(e),
}
}
pub fn new_(size: usize, top_slots: usize) -> Result<(NockStack, usize), NewStackError> {
if top_slots + RESERVED > size {
return Err(NewStackError::StackTooSmall);
}
let free = size - (top_slots + RESERVED);
#[cfg(feature = "mmap")]
let mut memory = Memory::allocate(AllocType::Mmap, size)?;
#[cfg(feature = "malloc")]
let mut memory = Memory::allocate(AllocType::Malloc, size)?;
let start = memory.as_mut_ptr() as *mut u64;
// Here, frame_offset < alloc_offset, so the initial frame is West
let frame_offset = RESERVED + top_slots;
let stack_offset = frame_offset;
// FIXME: This was alloc_offset = size; why?
let alloc_offset = size;
unsafe {
// Store previous frame/stack/alloc info in reserved slots
let prev_frame_slot = frame_offset - (FRAME + 1);
let prev_stack_slot = frame_offset - (STACK + 1);
let prev_alloc_slot = frame_offset - (ALLOC + 1);
*(start.add(prev_frame_slot)) = ptr::null::<u64>() as u64; // "frame pointer" from "previous" frame
*(start.add(prev_stack_slot)) = ptr::null::<u64>() as u64; // "stack pointer" from "previous" frame
*(start.add(prev_alloc_slot)) = start as u64; // "alloc pointer" from "previous" frame
};
assert_eq!(alloc_offset - stack_offset, free);
Ok((
NockStack {
start: start as *const u64,
size,
frame_offset,
stack_offset,
alloc_offset,
memory,
pc: false,
},
free,
))
}
I’d love to learn more about why this happens and how to avoid it. It’s not sporadic, this happens every time I try to start PoW.
logs/min2-1747915616.log:2025-05-22T12:40:27.525940Z INFO poke{src="libp2p"}:do_poke:slam:interpret: slogger: [%mining-on 14.013.155.469.355.287.694 17.658.163.466.538.601.719 16.139.960.547.538.818.049 13.146.085.519.865.444.801 3.604.770.390.141.248.621]
logs/min2-1747915616.log:thread 'tokio-runtime-worker' panicked at crates/nockchain/src/mining.rs:175:14:
logs/min2-1747915616.log:Could not load mining kernel: OneshotChannelError(RecvError(()))
logs/min2-1747915616.log:2025-05-22T12:40:27.692917Z WARN nockchain::mining: Error during mining attempt: JoinError::Panic(Id(3138), "Could not load mining kernel: OneshotChannelError(RecvError(()))", ...)