mirror of
https://github.com/MarekZegare4/MeshCore-Solo.git
synced 2026-09-14 23:26:38 +00:00
fix(rtc): bootstrap from contacts is a floor, never a rollback
BaseChatMesh::bootstrapRTCfromContacts() called setCurrentTime(latest+1) unconditionally. The newest contact's lastmod proves the clock must be at *least* that late -- it says nothing about it being any earlier -- so on any node that already has a better time source (a board with a real RTC, or the Emscripten sim whose SimRTCClock is backed by the host's wall clock) this dragged a correct clock backwards to whatever timestamp happened to be persisted alongside the contact list. Measured in the sim: ~9s behind real time after every reboot, growing with how long the previous session ran. Also adds sim_test_sync_time(epoch_secs) next to the other SIM_PLATFORM/__EMSCRIPTEN__ test hooks, so a host page can re-anchor the RTC on every (re)boot. The clock is live state the real mesh writes to at runtime -- a peer whose own clock runs ahead pushes ours forward, which is right on a node with no better source and, with meshcore-solo-site's cross-visitor relay, means one skewed visitor can drag everyone. On a demo running on someone's computer, "reset the device" should also mean "the clock is correct again". Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018iubftDmKNWmkNnhJRz8UH
This commit is contained in:
@@ -498,6 +498,25 @@ extern "C" EMSCRIPTEN_KEEPALIVE int sim_test_disable_screen_timeout() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Re-anchors this instance's RTC to the host's real wall clock. SimRTCClock
|
||||
// (variants/sim/SimRTCClock.h) already starts out reading time(NULL), so a
|
||||
// freshly booted instance needs no help -- but the clock is a shared, live
|
||||
// thing the real mesh code legitimately writes to at runtime: a received
|
||||
// packet or a contact-list bootstrap carrying a timestamp ahead of ours
|
||||
// pushes it forward (BaseChatMesh::bootstrapRTCfromContacts(),
|
||||
// MyMesh's own timestamp handling), which is correct behaviour on a real
|
||||
// node with no better time source, and means one peer with a badly skewed
|
||||
// clock can drag every node that hears it. Calling this on every (re)boot
|
||||
// makes "reset the device" mean "the demo's clock matches the visitor's own
|
||||
// computer again", the same guarantee the timezone hook above gives.
|
||||
// Seconds since the Unix epoch, as a double because a JS Date.now()/1000
|
||||
// value has no exact int32 representation to pass through ccall.
|
||||
extern "C" EMSCRIPTEN_KEEPALIVE int sim_test_sync_time(double epoch_secs) {
|
||||
if (epoch_secs < 1000000000.0) return 0; // obvious nonsense (pre-2001) -- leave the clock alone
|
||||
rtc_clock.setCurrentTime((uint32_t)epoch_secs);
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifdef DISPLAY_CLASS
|
||||
// Jumps the on-device UI straight to the DM thread with the first known
|
||||
// ADV_TYPE_CHAT contact (UITask::openContactDM() -- the exact same real
|
||||
|
||||
Reference in New Issue
Block a user