diff --git a/src/routing_layer/topo_node_sqlite.c b/src/routing_layer/topo_node_sqlite.c index c8aa02b7..d4e2629e 100644 --- a/src/routing_layer/topo_node_sqlite.c +++ b/src/routing_layer/topo_node_sqlite.c @@ -274,6 +274,68 @@ int topo_node_sqlite_member_put(sqlite3* db, const char* channel_id, uint64_t no return 0; } +/* Обновляет только блок мембера (keys/join/update_sig/update_ts/userinfo), + * НЕ трогая adm_tags/adm_tags_sig/storage (блок владельца) и локальные поля. */ +int topo_node_sqlite_member_block_put(sqlite3* db, const char* channel_id, uint64_t node_id, + const uint8_t* join_sig, uint64_t join_ts, + const uint8_t* update_sig, uint64_t update_ts, + const uint8_t* x25519_pubkey, const uint8_t* ed25519_pubkey, + const char* userinfo, const uint8_t* creator_sig) { + if (!db || !channel_id || !x25519_pubkey || !ed25519_pubkey) return -1; + char peers_tbl[80]; peers_table_name(channel_id, peers_tbl, sizeof(peers_tbl)); + char sql[512]; + snprintf(sql, sizeof(sql), + "INSERT INTO \"%s\"(node_id, x25519_pubkey, ed25519_pubkey," + " join_sig, join_ts, update_sig, update_ts, userinfo, creator_sig)" + " VALUES(?,?,?,?,?,?,?,?,?)" + " ON CONFLICT(node_id) DO UPDATE SET" + " x25519_pubkey=excluded.x25519_pubkey," + " ed25519_pubkey=excluded.ed25519_pubkey," + " join_sig=excluded.join_sig," + " join_ts=excluded.join_ts," + " update_sig=excluded.update_sig," + " update_ts=excluded.update_ts," + " userinfo=excluded.userinfo," + " creator_sig=excluded.creator_sig", 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); + sqlite3_bind_blob(stmt, 2, x25519_pubkey, 32, SQLITE_STATIC); + sqlite3_bind_blob(stmt, 3, ed25519_pubkey, 32, SQLITE_STATIC); + 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); + int rc = sqlite3_step(stmt); sqlite3_finalize(stmt); + return rc == SQLITE_DONE ? 0 : -1; +} + +/* Обновляет только блок владельца (adm_tags/adm_tags_sig/storage), + * НЕ трогая блок мембера. */ +int topo_node_sqlite_member_owner_put(sqlite3* db, const char* channel_id, uint64_t node_id, + const char* adm_tags, const uint8_t* adm_tags_sig, int storage) { + if (!db || !channel_id) return -1; + char peers_tbl[80]; peers_table_name(channel_id, peers_tbl, sizeof(peers_tbl)); + char sql[256]; + snprintf(sql, sizeof(sql), + "UPDATE \"%s\" SET adm_tags=?, adm_tags_sig=?, storage=? WHERE node_id=?", peers_tbl); + sqlite3_stmt* u = NULL; + if (sqlite3_prepare_v2(db, sql, -1, &u, NULL) != SQLITE_OK) return -1; + if (adm_tags && adm_tags[0]) sqlite3_bind_text(u, 1, adm_tags, -1, SQLITE_STATIC); + else sqlite3_bind_null(u, 1); + if (adm_tags_sig) sqlite3_bind_blob(u, 2, adm_tags_sig, 64, SQLITE_STATIC); + else sqlite3_bind_null(u, 2); + sqlite3_bind_int(u, 3, storage); + sqlite3_bind_int64(u, 4, (sqlite3_int64)node_id); + sqlite3_step(u); sqlite3_finalize(u); + return 0; +} + 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, time_t created_at) { if (!db || !x25519 || !ed25519) return -1; diff --git a/src/routing_layer/topo_node_sqlite.h b/src/routing_layer/topo_node_sqlite.h index 89907892..e407ac97 100644 --- a/src/routing_layer/topo_node_sqlite.h +++ b/src/routing_layer/topo_node_sqlite.h @@ -31,6 +31,17 @@ int topo_node_sqlite_member_put(sqlite3* db, const char* channel_id, uint64_t no const uint8_t* creator_sig, const char* adm_tags, const uint8_t* adm_tags_sig, int storage); +/* Обновляет только блок мембера (keys/join/update_sig/update_ts/userinfo), не трогая блок владельца. */ +int topo_node_sqlite_member_block_put(sqlite3* db, const char* channel_id, uint64_t node_id, + const uint8_t* join_sig, uint64_t join_ts, + const uint8_t* update_sig, uint64_t update_ts, + const uint8_t* x25519_pubkey, const uint8_t* ed25519_pubkey, const char* userinfo, + const uint8_t* creator_sig); + +/* Обновляет только блок владельца (adm_tags/adm_tags_sig/storage). */ +int topo_node_sqlite_member_owner_put(sqlite3* db, const char* channel_id, uint64_t node_id, + const char* adm_tags, const uint8_t* adm_tags_sig, int storage); + int topo_node_sqlite_member_get_join(sqlite3* db, const char* channel_id, uint64_t node_id, uint8_t* join_sig_out, uint64_t* join_ts_out);