ntp: use NTP-corrected time everywhere instead of unixepoch()/gettimeofday

- db_sync_next_timestamp(): ntp_time_get_us() via si->db_sync->inst
- topo_node_sqlite_node_put: +time_t now_sec param, replace unixepoch()
- topo_node_sqlite_node_update_verified: +time_t created_at param
- topo_node_sqlite_member_put: joined_at = join_ts (already NTP-corrected)
- All INSERTs (nodes, local_identity, accounts, peers):
  replace DEFAULT(unixepoch()) with explicit ntp_time_get_seconds()
- ON CONFLICT DO UPDATE: created_at = COALESCE(nodes.created_at, excluded.created_at)
- Updated callers: topo_group.c, chat_sync.c, chat_conn_mgr.c, chat_core.c
This commit is contained in:
Evgeny committed 2026-07-22 11:39:10 +03:00
1 parent fab1c77cfb
commit df809f251c
7 files changed
+64 -39

No files matched your search

+9 -3
View File
@@ -1587,9 +1587,15 @@ uint64_t db_sync_get_last_timestamp(struct DB_SYNC_INSTANCE* si)
uint64_t db_sync_next_timestamp(struct DB_SYNC_INSTANCE* si)
{
if (!si) return 0;
struct timeval tv;
utun_gettimeofday(&tv, NULL);
uint64_t nu = (uint64_t)tv.tv_sec * 1000ULL + (uint64_t)tv.tv_usec / 1000ULL;
int64_t now_us;
if (si->db_sync && si->db_sync->inst && si->db_sync->inst->ntp.synced)
now_us = ntp_time_get_us(si->db_sync->inst);
else {
struct timeval tv;
utun_gettimeofday(&tv, NULL);
now_us = (int64_t)tv.tv_sec * 1000000LL + tv.tv_usec;
}
uint64_t nu = (uint64_t)(now_us / 1000LL);
if (nu <= si->last_timestamp_ms) nu = si->last_timestamp_ms + 1;
si->last_timestamp_ms = nu;
return nu;
+1 -1
View File
@@ -581,7 +581,7 @@ int topo_group_process_nodeinfo(struct TOPO_GROUP* group, struct ETCP_CONN* from
if (node_id != group->instance->node_id) {
sqlite3* sdb = group->instance->topo_sqlite_db;
if (sdb) {
topo_node_sqlite_node_put(sdb, nodeinfo1);
topo_node_sqlite_node_put(sdb, nodeinfo1, ntp_time_get_seconds(group->instance));
if (group->group_type == TOPO_GROUP_TYPE_CHAT && group->channel_id[0]) {
topo_node_sqlite_member_put(sdb, group->channel_id, node_id, NULL, 0, NULL, 0, NULL, NULL, NULL, NULL);
DEBUG_DEBUG(DEBUG_CATEGORY_DEBUG, "SQLite member_put: ch=%s node=%016llx", group->channel_id, (unsigned long long)node_id);
+20 -15
View File
@@ -118,7 +118,7 @@ static uint8_t collect_socket_ids(struct TOPO_NODE* ni, uint8_t* sock_ids) {
return count;
}
int topo_node_sqlite_node_put(sqlite3* db, struct TOPO_NODEQ* nq) {
int topo_node_sqlite_node_put(sqlite3* db, struct TOPO_NODEQ* nq, time_t now_sec) {
if (!db || !nq || !nq->node) return -1;
struct TOPO_NODE* ni = nq->node;
@@ -127,15 +127,17 @@ int topo_node_sqlite_node_put(sqlite3* db, struct TOPO_NODEQ* nq) {
sqlite3_stmt* stmt = NULL;
if (sqlite3_prepare_v2(db,
"INSERT INTO nodes(node_id, name, x25519_pubkey, ed25519_pubkey, last_seen_at)"
" VALUES(?,?,?,?,unixepoch())"
" VALUES(?,?,?,?,?)"
" ON CONFLICT(node_id) DO UPDATE SET"
" name=excluded.name, x25519_pubkey=excluded.x25519_pubkey,"
" ed25519_pubkey=excluded.ed25519_pubkey, last_seen_at=excluded.last_seen_at",
" ed25519_pubkey=excluded.ed25519_pubkey, last_seen_at=excluded.last_seen_at,\n"
" created_at=COALESCE(nodes.created_at, excluded.created_at)",
-1, &stmt, NULL) == SQLITE_OK) {
sqlite3_bind_int64(stmt, 1, (sqlite3_int64)ni->node_id);
sqlite3_bind_text(stmt, 2, ni->node_name ? ni->node_name : "", -1, SQLITE_STATIC);
sqlite3_bind_blob(stmt, 3, ni->public_key, 32, SQLITE_STATIC);
sqlite3_bind_blob(stmt, 4, ni->ed25519_public_key, 32, SQLITE_STATIC);
sqlite3_bind_int64(stmt, 5, (sqlite3_int64)now_sec);
sqlite3_step(stmt); sqlite3_finalize(stmt);
}
@@ -317,8 +319,8 @@ int topo_node_sqlite_member_put(sqlite3* db, const char* channel_id, uint64_t no
char sql[256];
snprintf(sql, sizeof(sql),
"INSERT OR REPLACE INTO \"%s\"(node_id, x25519_pubkey, ed25519_pubkey,"
" join_sig, join_ts, update_sig, update_ts, userinfo, creator_sig)"
" VALUES(?,?,?,?,?,?,?,?,?)", peers_tbl);
" join_sig, join_ts, joined_at, update_sig, update_ts, userinfo, creator_sig)"
" VALUES(?,?,?,?,?,?,?,?,?,?)", peers_tbl);
sqlite3_stmt* stmt = NULL;
if (sqlite3_prepare_v2(db, sql, -1, &stmt, NULL) != SQLITE_OK) return -1;
sqlite3_bind_int64(stmt, 1, (sqlite3_int64)node_id);
@@ -327,28 +329,30 @@ int topo_node_sqlite_member_put(sqlite3* db, const char* channel_id, uint64_t no
if (join_sig) sqlite3_bind_blob(stmt, 4, join_sig, PEERS_JOIN_SIG_SIZE, SQLITE_STATIC);
else { static const unsigned char zsig[PEERS_JOIN_SIG_SIZE] = {0}; sqlite3_bind_blob(stmt, 4, zsig, PEERS_JOIN_SIG_SIZE, SQLITE_STATIC); }
sqlite3_bind_int64(stmt, 5, (sqlite3_int64)join_ts);
if (update_sig) sqlite3_bind_blob(stmt, 6, update_sig, PEERS_UPDATE_SIG_SIZE, SQLITE_STATIC);
else sqlite3_bind_null(stmt, 6);
sqlite3_bind_int64(stmt, 7, (sqlite3_int64)update_ts);
sqlite3_bind_text(stmt, 8, userinfo ? userinfo : "", -1, SQLITE_STATIC);
if (creator_sig) sqlite3_bind_blob(stmt, 9, creator_sig, PEERS_JOIN_SIG_SIZE, SQLITE_STATIC);
else sqlite3_bind_null(stmt, 9);
sqlite3_bind_int64(stmt, 6, (sqlite3_int64)join_ts);
if (update_sig) sqlite3_bind_blob(stmt, 7, update_sig, PEERS_UPDATE_SIG_SIZE, SQLITE_STATIC);
else sqlite3_bind_null(stmt, 7);
sqlite3_bind_int64(stmt, 8, (sqlite3_int64)update_ts);
sqlite3_bind_text(stmt, 9, userinfo ? userinfo : "", -1, SQLITE_STATIC);
if (creator_sig) sqlite3_bind_blob(stmt, 10, creator_sig, PEERS_JOIN_SIG_SIZE, SQLITE_STATIC);
else sqlite3_bind_null(stmt, 10);
int rc = sqlite3_step(stmt); sqlite3_finalize(stmt);
return rc == SQLITE_DONE ? 0 : -1;
}
int topo_node_sqlite_node_update_verified(sqlite3* db, uint64_t node_id,
const char* name, const uint8_t* x25519, const uint8_t* ed25519, uint64_t update_ts) {
const char* name, const uint8_t* x25519, const uint8_t* ed25519, uint64_t update_ts, time_t created_at) {
if (!db || !x25519 || !ed25519) return -1;
sqlite3_stmt* stmt = NULL;
if (sqlite3_prepare_v2(db,
"INSERT INTO nodes(node_id, name, x25519_pubkey, ed25519_pubkey, update_ts)"
" VALUES(?,?,?,?,?)"
"INSERT INTO nodes(node_id, name, x25519_pubkey, ed25519_pubkey, created_at, update_ts)"
" VALUES(?,?,?,?,?,?)"
" ON CONFLICT(node_id) DO UPDATE SET"
" name=CASE WHEN excluded.name IS NOT NULL AND excluded.name != ''"
" THEN excluded.name ELSE nodes.name END,"
" x25519_pubkey=excluded.x25519_pubkey,"
" ed25519_pubkey=excluded.ed25519_pubkey,"
" created_at=COALESCE(nodes.created_at, excluded.created_at),"
" update_ts=CASE WHEN nodes.update_ts IS NULL OR excluded.update_ts > nodes.update_ts"
" THEN excluded.update_ts ELSE nodes.update_ts END",
-1, &stmt, NULL) != SQLITE_OK) return -1;
@@ -356,7 +360,8 @@ int topo_node_sqlite_node_update_verified(sqlite3* db, uint64_t node_id,
sqlite3_bind_text(stmt, 2, name && name[0] ? name : "", -1, SQLITE_STATIC);
sqlite3_bind_blob(stmt, 3, x25519, 32, SQLITE_STATIC);
sqlite3_bind_blob(stmt, 4, ed25519, 32, SQLITE_STATIC);
sqlite3_bind_int64(stmt, 5, (sqlite3_int64)update_ts);
sqlite3_bind_int64(stmt, 5, (sqlite3_int64)created_at);
sqlite3_bind_int64(stmt, 6, (sqlite3_int64)update_ts);
sqlite3_step(stmt);
sqlite3_finalize(stmt);
return 0;
+3 -2
View File
@@ -4,6 +4,7 @@
#include <sqlite3.h>
#include <stdint.h>
#include <stddef.h>
#include <time.h>
struct TOPO_NODEQ;
@@ -16,7 +17,7 @@ struct TOPO_NODEQ;
int topo_node_sqlite_init(sqlite3* db);
int topo_node_sqlite_node_put(sqlite3* db, struct TOPO_NODEQ* nq);
int topo_node_sqlite_node_put(sqlite3* db, struct TOPO_NODEQ* nq, time_t now_sec);
int topo_node_sqlite_channel_put(sqlite3* db, const char* channel_id,
const char* name, uint64_t owner_node_id,
@@ -36,7 +37,7 @@ int topo_node_sqlite_member_get_join(sqlite3* db, const char* channel_id, uint64
int topo_node_sqlite_member_del(sqlite3* db, const char* channel_id, uint64_t node_id);
int topo_node_sqlite_node_update_verified(sqlite3* db, uint64_t node_id,
const char* name, const uint8_t* x25519, const uint8_t* ed25519, uint64_t update_ts);
const char* name, const uint8_t* x25519, const uint8_t* ed25519, uint64_t update_ts, time_t created_at);
int topo_node_sqlite_channel_get(sqlite3* db, const char* channel_id,
char* name_out, int name_sz, uint64_t* owner_node_id,