Propagate all member block binding and finalization failures before index publication
This commit is contained in:
1 parent
1ce58cbeac
commit
60942e542b
2 files changed
+38
-19
No files matched your search
@@ -726,7 +726,9 @@ int topo_node_sqlite_member_block_put(sqlite3* db, const char* channel_id, uint6
|
||||
const uint8_t* x25519_pubkey, const uint8_t* ed25519_pubkey,
|
||||
const char* userinfo, const uint8_t* creator_sig,
|
||||
uint64_t signed_by, const uint8_t* signature) {
|
||||
if (!db || !channel_id || !x25519_pubkey || !ed25519_pubkey) return -1;
|
||||
if (!db || !channel_id || !x25519_pubkey || !ed25519_pubkey) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_MEMBER_SYNC, "member block: invalid database/channel/key arguments"); return -1;
|
||||
}
|
||||
char peers_tbl[80]; peers_table_name(channel_id, peers_tbl, sizeof(peers_tbl));
|
||||
char sql[768];
|
||||
snprintf(sql, sizeof(sql),
|
||||
@@ -746,24 +748,40 @@ int topo_node_sqlite_member_block_put(sqlite3* db, const char* channel_id, uint6
|
||||
" signature=excluded.signature,"
|
||||
" source=0", 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);
|
||||
sqlite3_bind_int64(stmt, 10, (sqlite3_int64)signed_by);
|
||||
if (signature) sqlite3_bind_blob(stmt, 11, signature, 64, SQLITE_STATIC);
|
||||
else sqlite3_bind_null(stmt, 11);
|
||||
int rc = sqlite3_step(stmt); sqlite3_finalize(stmt);
|
||||
return rc == SQLITE_DONE ? 0 : -1;
|
||||
const char* stage = "prepare";
|
||||
int rc = sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);
|
||||
if (rc == SQLITE_OK) { stage = "bind node"; rc = sqlite3_bind_int64(stmt, 1, (sqlite3_int64)node_id); }
|
||||
if (rc == SQLITE_OK) { stage = "bind X25519"; rc = sqlite3_bind_blob(stmt, 2, x25519_pubkey, 32, SQLITE_STATIC); }
|
||||
if (rc == SQLITE_OK) { stage = "bind Ed25519"; rc = sqlite3_bind_blob(stmt, 3, ed25519_pubkey, 32, SQLITE_STATIC); }
|
||||
if (rc == SQLITE_OK) {
|
||||
static const uint8_t zero_signature[PEERS_JOIN_SIG_SIZE] = {0}; stage = "bind JOIN signature";
|
||||
rc = sqlite3_bind_blob(stmt, 4, join_sig ? join_sig : zero_signature, PEERS_JOIN_SIG_SIZE, SQLITE_STATIC);
|
||||
}
|
||||
if (rc == SQLITE_OK) { stage = "bind JOIN timestamp"; rc = sqlite3_bind_int64(stmt, 5, (sqlite3_int64)join_ts); }
|
||||
if (rc == SQLITE_OK) {
|
||||
stage = "bind profile signature";
|
||||
rc = update_sig ? sqlite3_bind_blob(stmt, 6, update_sig, PEERS_UPDATE_SIG_SIZE, SQLITE_STATIC) : sqlite3_bind_null(stmt, 6);
|
||||
}
|
||||
if (rc == SQLITE_OK) { stage = "bind profile timestamp"; rc = sqlite3_bind_int64(stmt, 7, (sqlite3_int64)update_ts); }
|
||||
if (rc == SQLITE_OK) { stage = "bind profile"; rc = sqlite3_bind_text(stmt, 8, userinfo ? userinfo : "", -1, SQLITE_STATIC); }
|
||||
if (rc == SQLITE_OK) {
|
||||
stage = "bind creator signature";
|
||||
rc = creator_sig ? sqlite3_bind_blob(stmt, 9, creator_sig, PEERS_JOIN_SIG_SIZE, SQLITE_STATIC) : sqlite3_bind_null(stmt, 9);
|
||||
}
|
||||
if (rc == SQLITE_OK) { stage = "bind inviter"; rc = sqlite3_bind_int64(stmt, 10, (sqlite3_int64)signed_by); }
|
||||
if (rc == SQLITE_OK) {
|
||||
stage = "bind invitation signature";
|
||||
rc = signature ? sqlite3_bind_blob(stmt, 11, signature, 64, SQLITE_STATIC) : sqlite3_bind_null(stmt, 11);
|
||||
}
|
||||
if (rc == SQLITE_OK) { stage = "write"; rc = sqlite3_step(stmt); }
|
||||
int changed = rc == SQLITE_DONE ? sqlite3_changes(db) : 0;
|
||||
if (rc != SQLITE_DONE || changed != 1) DEBUG_ERROR(DEBUG_CATEGORY_MEMBER_SYNC,
|
||||
"member block: channel=%s node=%016llx stage=%s rc=%d (%s) changed=%d db=%s",
|
||||
channel_id, (unsigned long long)node_id, stage, rc, sqlite3_errstr(rc), changed, sqlite3_errmsg(db));
|
||||
int final = sqlite3_finalize(stmt);
|
||||
if (final != SQLITE_OK) DEBUG_ERROR(DEBUG_CATEGORY_MEMBER_SYNC, "member block: finalize channel=%s node=%016llx rc=%d",
|
||||
channel_id, (unsigned long long)node_id, final);
|
||||
return rc == SQLITE_DONE && changed == 1 && final == SQLITE_OK ? 0 : -1;
|
||||
}
|
||||
|
||||
/* Обновляет только блок владельца (adm_tags/adm_tags_sig/storage),
|
||||
|
||||
@@ -79,6 +79,7 @@ int topo_node_sqlite_member_placeholder_put(sqlite3* db, const char* channel_id,
|
||||
* signed_by/signature — дерево приглашений: кто подписал pubkey узла (0 = корень, ключом группы).
|
||||
* 0/-1; подписи по 64, ключи по 32 байта. NULL join_sig даёт нулевую подпись, userinfo=NULL даёт ''.
|
||||
* Сбрасывает source=0; свежесть/подписи проверяет вызывающий, owner/local-поля сохраняются. */
|
||||
/* Проверяет все bind,step,changes1 и finalize;при отказе caller откатывает свою транзакцию записи/индекса. */
|
||||
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,
|
||||
|
||||
Reference in new issue
Block a user