diff --git a/src/chat/chat_sync.c b/src/chat/chat_sync.c index 8dc062ce..2d4c5f0f 100644 --- a/src/chat/chat_sync.c +++ b/src/chat/chat_sync.c @@ -1247,12 +1247,20 @@ static void cs_handle_join_info_resp(struct chat_sync* cs, uint64_t peer, chat_core_ensure_channel_ready(cs->inst, ch_id); /* добавить connection-узел в мемберы (дерево приглашений из INFO_RESP) */ - sqlite3* vdb = cs->inst->topo_sqlite_db; - topo_node_sqlite_member_block_put(vdb, ch_id, c_node_id, c_join_sig, c_join_ts, - c_update_sig, c_update_ts, c_x25519, c_ed, - c_userinfo, NULL, c_signed_by, c_signature); - { char cn_name[128]; json_flat_get(c_userinfo, "name", cn_name, sizeof(cn_name)); - topo_node_sqlite_node_update_verified(vdb, c_node_id, cn_name, c_x25519, c_ed, c_join_ts, ntp_time_get_seconds(cs->inst)); } + struct ms_member_rec connection_member = { + .node_id = c_node_id, .x25519 = c_x25519, .ed25519 = c_ed, + .join_sig = c_join_sig, .join_ts = c_join_ts, .update_sig = c_update_sig, .update_ts = c_update_ts, + .userinfo = c_userinfo, .signed_by = c_signed_by, .signature = c_signature + }; + /* Запись модели и Merkle-индекс меняются в одной транзакции member_sync. */ + int mrc = member_sync_apply_record(cs->inst, ch_id, peer, &connection_member); + if (mrc < 0) { + DEBUG_ERROR(DEBUG_CATEGORY_MEMBER_SYNC, "%s: JOIN_INFO_RESP member rejected ch=%s node=%016llx rc=%d", + CS_ID, ch_id, (unsigned long long)c_node_id, mrc); + return; + } + DEBUG_DEBUG(DEBUG_CATEGORY_MEMBER_SYNC, "%s: JOIN_INFO_RESP member indexed ch=%s node=%016llx rc=%d", + CS_ID, ch_id, (unsigned long long)c_node_id, mrc); /* построить собственный join_sig */ uint64_t myid = cs->inst->node_id; diff --git a/src/chat/db_sync.c b/src/chat/db_sync.c index 34d09322..be09cb7d 100644 --- a/src/chat/db_sync.c +++ b/src/chat/db_sync.c @@ -765,7 +765,7 @@ static void db_handle_request_sync(struct DB_SYNC_INSTANCE* si, uint64_t src, co { (void)p; (void)len; struct SI_PEER* sp = si_peer_add(si, src); - if (sp && is_master(si->db_sync->inst->node_id, src)) { + if (sp && sp->sync_state != 1 && is_master(si->db_sync->inst->node_id, src)) { db_sync_initiate_sync(si, src); } } @@ -1123,8 +1123,8 @@ static void db_handle_sync_done(struct DB_SYNC_INSTANCE* si, uint64_t src, const // mc > pc: send tail if (sp) sp->last_peer_count = pc; uint32_t scnt = mc - pc; if (scnt > DB_SEND_DATA_MAX) scnt = DB_SEND_DATA_MAX; - si_send_data_batch(si, src, pc, scnt, pc > 0 ? pc - 1 : (uint32_t)-1, DB_WANT_FROM_NONE); - if (sp) sp->sync_state = 1; + if (si_send_data_batch(si, src, pc, scnt, pc > 0 ? pc - 1 : (uint32_t)-1, DB_WANT_FROM_NONE) < 0) return; + if (sp) { sp->sync_state = 1; sp->sync_start_tb = get_time_tb(); } DEBUG_INFO(DEBUG_CATEGORY_CHAT_SYNC, "sync [%s:%04llX] ← SYNC_DONE: mc=%u > pc=%u → send tail from=%u", SI_SHRT(si), (unsigned long long)(src >> 16), mc, pc, pc); } else {