Separate missing member verification keys from SQLite failures

This commit is contained in:
evgeny committed 2026-10-26 14:42:59 +01:00
1 parent fe7bcb334c
commit 1f3f1d9a34
2 files changed
+48 -20

No files matched your search

+39 -18
View File
@@ -876,18 +876,26 @@ int topo_node_sqlite_member_del(sqlite3* db, const char* channel_id, uint64_t no
int topo_node_sqlite_channel_get(sqlite3* db, const char* channel_id,
char* name_out, int name_sz, uint64_t* owner_node_id,
uint8_t* x25519_pub, uint8_t* ed25519_pub, uint8_t* signature) {
if (!db || !channel_id) return -1;
if (!db || !channel_id) {
DEBUG_ERROR(DEBUG_CATEGORY_BGP, "channel lookup: invalid arguments"); return TOPO_SQLITE_LOOKUP_ERROR;
}
sqlite3_stmt* stmt = NULL;
if (sqlite3_prepare_v2(db,
int rc = sqlite3_prepare_v2(db,
"SELECT name, owner_node_id, x25519_pubkey, ed25519_pubkey, signature"
" FROM channels WHERE channel_id=?", -1, &stmt, NULL) != SQLITE_OK) return -1;
sqlite3_bind_text(stmt, 1, channel_id, -1, SQLITE_STATIC);
if (sqlite3_step(stmt) != SQLITE_ROW) { sqlite3_finalize(stmt); return -1; }
if ((x25519_pub && sqlite3_column_bytes(stmt, 2) != 32) ||
(ed25519_pub && sqlite3_column_bytes(stmt, 3) != 32) || (signature && sqlite3_column_bytes(stmt, 4) != 64)) {
DEBUG_ERROR(DEBUG_CATEGORY_BGP, "invalid stored channel keys/signature channel=%s sizes=%d/%d/%d", channel_id,
sqlite3_column_bytes(stmt, 2), sqlite3_column_bytes(stmt, 3), sqlite3_column_bytes(stmt, 4));
sqlite3_finalize(stmt); return -1;
" FROM channels WHERE channel_id=?", -1, &stmt, NULL);
if (rc == SQLITE_OK) rc = sqlite3_bind_text(stmt, 1, channel_id, -1, SQLITE_STATIC);
if (rc == SQLITE_OK) rc = sqlite3_step(stmt);
int result = TOPO_SQLITE_LOOKUP_ERROR;
if (rc == SQLITE_DONE) { result = TOPO_SQLITE_LOOKUP_MISSING; goto done; }
if (rc != SQLITE_ROW) goto done;
for (int col = 2; col <= 4; col++) {
if (!(col == 2 ? x25519_pub != NULL : col == 3 ? ed25519_pub != NULL : signature != NULL)) continue;
int size = sqlite3_column_bytes(stmt, col), expected = col == 4 ? 64 : 32;
if (size == expected) continue;
if (size == 0 && sqlite3_errcode(db) != SQLITE_NOMEM) result = TOPO_SQLITE_LOOKUP_MISSING;
else DEBUG_ERROR(DEBUG_CATEGORY_BGP, "channel lookup: invalid field channel=%s column=%d bytes=%d expected=%d",
channel_id, col, size, expected);
goto done;
}
if (name_out && name_sz > 0) {
const unsigned char* txt = sqlite3_column_text(stmt, 0);
@@ -897,8 +905,18 @@ int topo_node_sqlite_channel_get(sqlite3* db, const char* channel_id,
if (x25519_pub) memcpy(x25519_pub, sqlite3_column_blob(stmt, 2), 32);
if (ed25519_pub) memcpy(ed25519_pub, sqlite3_column_blob(stmt, 3), 32);
if (signature) memcpy(signature, sqlite3_column_blob(stmt, 4), 64);
sqlite3_finalize(stmt);
return 0;
result = 0;
done:
{
int final_rc = sqlite3_finalize(stmt);
if (final_rc != SQLITE_OK) result = TOPO_SQLITE_LOOKUP_ERROR;
if (result == TOPO_SQLITE_LOOKUP_ERROR)
DEBUG_ERROR(DEBUG_CATEGORY_BGP, "channel lookup failed channel=%s rc=%d finalize=%d: %s",
channel_id, rc, final_rc, sqlite3_errmsg(db));
else if (result == TOPO_SQLITE_LOOKUP_MISSING)
DEBUG_DEBUG(DEBUG_CATEGORY_BGP, "channel lookup: dependency unavailable channel=%s", channel_id);
}
return result;
}
int topo_node_sqlite_channel_get_priv(sqlite3* db, const char* channel_id,
@@ -977,23 +995,26 @@ int topo_node_sqlite_get_ed25519_pubkey(sqlite3* db, uint64_t node_id, uint8_t p
{
if (!db || !pubkey_out) {
DEBUG_ERROR(DEBUG_CATEGORY_ROUTING, "get_ed25519_pubkey: invalid arguments node=%016llx", (unsigned long long)node_id);
return -1;
return TOPO_SQLITE_LOOKUP_ERROR;
}
sqlite3_stmt* stmt = NULL;
int sql_rc = sqlite3_prepare_v2(db, "SELECT ed25519_pubkey FROM nodes WHERE node_id=?", -1, &stmt, NULL);
if (sql_rc == SQLITE_OK) sql_rc = sqlite3_bind_int64(stmt, 1, (sqlite3_int64)node_id);
if (sql_rc == SQLITE_OK) sql_rc = sqlite3_step(stmt);
int rc = -1;
int rc = sql_rc == SQLITE_DONE ? TOPO_SQLITE_LOOKUP_MISSING : TOPO_SQLITE_LOOKUP_ERROR;
uint8_t key[32];
if (sql_rc == SQLITE_ROW) {
const void* b = sqlite3_column_blob(stmt, 0);
int bytes = sqlite3_column_bytes(stmt, 0);
if (b && bytes == 32) { memcpy(pubkey_out, b, 32); rc = 0; }
if (b && bytes == 32) { memcpy(key, b, 32); rc = 0; }
else if (bytes == 0 && sqlite3_errcode(db) != SQLITE_NOMEM) rc = TOPO_SQLITE_LOOKUP_MISSING;
}
int final_rc = sqlite3_finalize(stmt);
if (final_rc != SQLITE_OK) rc = -1;
if (rc && sql_rc == SQLITE_DONE && final_rc == SQLITE_OK)
if (final_rc != SQLITE_OK) rc = TOPO_SQLITE_LOOKUP_ERROR;
if (rc == 0) memcpy(pubkey_out, key, 32);
if (rc == TOPO_SQLITE_LOOKUP_MISSING)
DEBUG_DEBUG(DEBUG_CATEGORY_ROUTING, "get_ed25519_pubkey: unknown node=%016llx", (unsigned long long)node_id);
else if (rc) DEBUG_WARN(DEBUG_CATEGORY_ROUTING, "get_ed25519_pubkey: unavailable node=%016llx sql=%d finalize=%d: %s",
else if (rc) DEBUG_ERROR(DEBUG_CATEGORY_ROUTING, "get_ed25519_pubkey: unavailable node=%016llx sql=%d finalize=%d: %s",
(unsigned long long)node_id, sql_rc, final_rc, sqlite3_errmsg(db));
return rc;
}
+9 -2
View File
@@ -17,6 +17,10 @@
#define PEERS_JOIN_TS_SIZE 8
#define PEERS_UPDATE_SIG_SIZE 64
/* Результаты channel_get/get_ed25519_pubkey: отсутствие зависимости и отказ чтения различаются. */
#define TOPO_SQLITE_LOOKUP_MISSING (-1)
#define TOPO_SQLITE_LOOKUP_ERROR (-2)
/* flags byte in wire format */
#define PEERS_FLAG_HAS_JOIN 0x01
@@ -104,7 +108,9 @@ int topo_node_sqlite_member_del(sqlite3* db, const char* channel_id, uint64_t no
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);
/* Метаданные канала; 0/-1. Все выходы необязательны; name_sz включает NUL, ключи по 32, подпись 64 байта. */
/* Метаданные канала: 0 — успех, LOOKUP_MISSING — нет строки/запрошенного ключа,
* LOOKUP_ERROR — аргументы/SQL/повреждённый размер. Выходы действительны только при 0.
* Все выходы необязательны; name_sz включает NUL, ключи по 32, подпись 64 байта. */
int topo_node_sqlite_channel_get(sqlite3* db, const char* channel_id,
char* name_out, int name_sz, uint64_t* owner_node_id,
uint8_t* x25519_pub, uint8_t* ed25519_pub, uint8_t* signature);
@@ -126,7 +132,8 @@ int topo_node_sqlite_channel_set_privs(sqlite3* db, const char* channel_id,
int topo_node_sqlite_node_set_online(sqlite3* db, uint64_t node_id, int online);
/* online из nodes; 0, если записи нет или запрос не выполнен. */
int topo_node_sqlite_node_get_online(sqlite3* db, uint64_t node_id);
/* Скопировать ровно 32 байта Ed25519 из nodes: 0 — найден, -1 — отсутствует/другая длина/ошибка SQLite.
/* Скопировать ровно 32 байта Ed25519 из nodes: 0 — найден, LOOKUP_MISSING — нет строки/ключа,
* LOOKUP_ERROR — аргументы/SQL/повреждённый размер. При отказе выход не меняется.
* Значение байтов не определяет наличие ключа; криптографическую пригодность проверяет операция verify. */
int topo_node_sqlite_get_ed25519_pubkey(sqlite3* db, uint64_t node_id, uint8_t pubkey_out[32]);