Store admin keys atomically and reject invalid transfer context
This commit is contained in:
1 parent
e65ceeafdc
commit
76527de44f
2 files changed
+62
-14
No files matched your search
@@ -953,18 +953,51 @@ int topo_node_sqlite_channel_get_privs(sqlite3* db, const char* channel_id,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Импорт пары: savepoint охватывает UPDATE и его завершение, внешний commit остаётся вызывающему. */
|
||||
int topo_node_sqlite_channel_set_privs(sqlite3* db, const char* channel_id,
|
||||
const uint8_t* x25519_priv, const uint8_t* ed25519_priv) {
|
||||
if (!db || !channel_id || !x25519_priv || !ed25519_priv) return -1;
|
||||
if (!db || !channel_id || !channel_id[0] || !x25519_priv || !ed25519_priv) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_BGP, "channel private keys: invalid arguments"); return -1;
|
||||
}
|
||||
int own = sqlite3_get_autocommit(db);
|
||||
int rc = sqlite3_exec(db, "SAVEPOINT channel_private_keys", NULL, NULL, NULL);
|
||||
if (rc != SQLITE_OK) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_BGP, "channel private keys: channel=%s stage=savepoint rc=%d: %s",
|
||||
channel_id, rc, sqlite3_errmsg(db)); return -1;
|
||||
}
|
||||
sqlite3_stmt* stmt = NULL;
|
||||
if (sqlite3_prepare_v2(db,
|
||||
"UPDATE channels SET x25519_privkey=?, ed25519_privkey=? WHERE channel_id=?", -1, &stmt, NULL) != SQLITE_OK) return -1;
|
||||
sqlite3_bind_blob(stmt, 1, x25519_priv, 32, SQLITE_STATIC);
|
||||
sqlite3_bind_blob(stmt, 2, ed25519_priv, 32, SQLITE_STATIC);
|
||||
sqlite3_bind_text(stmt, 3, channel_id, -1, SQLITE_STATIC);
|
||||
int rc = sqlite3_step(stmt) == SQLITE_DONE ? 0 : -1;
|
||||
sqlite3_finalize(stmt);
|
||||
return rc;
|
||||
const char* stage = "prepare";
|
||||
rc = sqlite3_prepare_v2(db, "UPDATE channels SET x25519_privkey=?, ed25519_privkey=? WHERE channel_id=?", -1, &stmt, NULL);
|
||||
if (rc != SQLITE_OK) goto fail;
|
||||
stage = "bind x25519"; rc = sqlite3_bind_blob(stmt, 1, x25519_priv, 32, SQLITE_STATIC);
|
||||
if (rc != SQLITE_OK) goto fail;
|
||||
stage = "bind ed25519"; rc = sqlite3_bind_blob(stmt, 2, ed25519_priv, 32, SQLITE_STATIC);
|
||||
if (rc != SQLITE_OK) goto fail;
|
||||
stage = "bind channel"; rc = sqlite3_bind_text(stmt, 3, channel_id, -1, SQLITE_STATIC);
|
||||
if (rc != SQLITE_OK) goto fail;
|
||||
stage = "update"; rc = sqlite3_step(stmt);
|
||||
if (rc != SQLITE_DONE) goto fail;
|
||||
int changed = sqlite3_changes(db);
|
||||
stage = "finalize"; rc = sqlite3_finalize(stmt); stmt = NULL;
|
||||
if (rc != SQLITE_OK) goto fail;
|
||||
if (changed != 1) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_BGP, "channel private keys: channel=%s changed=%d expected=1", channel_id, changed);
|
||||
stage = "row count"; rc = SQLITE_NOTFOUND; goto fail;
|
||||
}
|
||||
stage = "release"; rc = sqlite3_exec(db, "RELEASE channel_private_keys", NULL, NULL, NULL);
|
||||
if (rc != SQLITE_OK) goto fail;
|
||||
DEBUG_DEBUG(DEBUG_CATEGORY_BGP, "channel private keys stored: channel=%s committed=%d", channel_id, own);
|
||||
return 0;
|
||||
fail:
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_BGP, "channel private keys: channel=%s stage=%s rc=%d: %s",
|
||||
channel_id, stage, rc, sqlite3_errmsg(db));
|
||||
int final_rc = sqlite3_finalize(stmt);
|
||||
if (final_rc != SQLITE_OK) DEBUG_ERROR(DEBUG_CATEGORY_BGP,
|
||||
"channel private keys: cleanup finalize channel=%s rc=%d: %s", channel_id, final_rc, sqlite3_errmsg(db));
|
||||
if (!sqlite3_get_autocommit(db) &&
|
||||
sqlite3_exec(db, "ROLLBACK TO channel_private_keys; RELEASE channel_private_keys", NULL, NULL, NULL) != SQLITE_OK)
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_BGP, "channel private keys: rollback failed channel=%s: %s", channel_id, sqlite3_errmsg(db));
|
||||
return -1;
|
||||
}
|
||||
|
||||
int topo_node_sqlite_node_set_online(sqlite3* db, uint64_t node_id, int online) {
|
||||
|
||||
Reference in new issue
Block a user