Version signed node snapshots with persistent timestamps
This commit is contained in:
1 parent
7374d1648c
commit
ec51b2d61f
10 files changed
+440
-95
No files matched your search
@@ -253,6 +253,8 @@ int topo_node_sqlite_init(sqlite3* db) {
|
||||
if (!db) return -1;
|
||||
|
||||
const char* sql =
|
||||
"CREATE TABLE IF NOT EXISTS node_snapshots ("
|
||||
"node_id INTEGER PRIMARY KEY, timestamp INTEGER NOT NULL, record BLOB NOT NULL);"
|
||||
"CREATE TABLE IF NOT EXISTS nodes ("
|
||||
" node_id INTEGER PRIMARY KEY,"
|
||||
" name TEXT,"
|
||||
@@ -903,8 +905,68 @@ void topo_node_sqlite_update_rtt(sqlite3* db, uint64_t node_id, uint16_t rtt) {
|
||||
(unsigned long long)node_id, (unsigned)rtt);
|
||||
}
|
||||
|
||||
uint64_t topo_node_sqlite_snapshot_timestamp(sqlite3* db, uint64_t node_id) {
|
||||
sqlite3_stmt* stmt = NULL;
|
||||
uint64_t timestamp = 0;
|
||||
if (sqlite3_prepare_v2(db, "SELECT timestamp FROM node_snapshots WHERE node_id=?", -1, &stmt, NULL) != SQLITE_OK) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_BGP, "snapshot timestamp: %s", sqlite3_errmsg(db)); return 0;
|
||||
}
|
||||
sqlite3_bind_int64(stmt, 1, (sqlite3_int64)node_id);
|
||||
int rc = sqlite3_step(stmt);
|
||||
if (rc == SQLITE_ROW) timestamp = (uint64_t)sqlite3_column_int64(stmt, 0);
|
||||
else if (rc != SQLITE_DONE) DEBUG_ERROR(DEBUG_CATEGORY_BGP, "snapshot timestamp read: %s", sqlite3_errmsg(db));
|
||||
sqlite3_finalize(stmt);
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
int topo_node_sqlite_snapshot_put(sqlite3* db, struct TOPO_NODE* ni) {
|
||||
if (!db || topo_node_verify(ni) < 0) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "invalid node snapshot"); return -1; }
|
||||
uint8_t record[4096];
|
||||
struct TOPO_GROUP_NODE nq = {0};
|
||||
int len = topo_node_serialize(ni, &nq, 0, 0, record, sizeof(record), 0);
|
||||
if (len < 0) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "snapshot serialization failed"); return -1; }
|
||||
sqlite3_stmt* stmt = NULL;
|
||||
const char* sql = "INSERT INTO node_snapshots(node_id,timestamp,record) VALUES(?,?,?) "
|
||||
"ON CONFLICT(node_id) DO UPDATE SET timestamp=excluded.timestamp,record=excluded.record "
|
||||
"WHERE excluded.timestamp > node_snapshots.timestamp";
|
||||
int rc = sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);
|
||||
if (rc == SQLITE_OK) {
|
||||
sqlite3_bind_int64(stmt, 1, (sqlite3_int64)ni->node_id);
|
||||
sqlite3_bind_int64(stmt, 2, (sqlite3_int64)ni->timestamp);
|
||||
sqlite3_bind_blob(stmt, 3, record, len, SQLITE_STATIC);
|
||||
rc = sqlite3_step(stmt);
|
||||
}
|
||||
if (rc != SQLITE_DONE) DEBUG_ERROR(DEBUG_CATEGORY_BGP, "snapshot write: %s", sqlite3_errmsg(db));
|
||||
sqlite3_finalize(stmt);
|
||||
return rc == SQLITE_DONE ? 0 : -1;
|
||||
}
|
||||
|
||||
struct TOPO_NODE* topo_node_sqlite_snapshot_load(sqlite3* db, struct TOPO_GROUPS* groups, uint64_t node_id) {
|
||||
sqlite3_stmt* stmt = NULL;
|
||||
struct TOPO_NODE* ni = NULL;
|
||||
if (sqlite3_prepare_v2(db, "SELECT record FROM node_snapshots WHERE node_id=?", -1, &stmt, NULL) != SQLITE_OK) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_BGP, "snapshot load: %s", sqlite3_errmsg(db)); return NULL;
|
||||
}
|
||||
sqlite3_bind_int64(stmt, 1, (sqlite3_int64)node_id);
|
||||
int rc = sqlite3_step(stmt);
|
||||
if (rc == SQLITE_ROW) {
|
||||
struct TOPO_GROUP group = { .instance = groups->instance };
|
||||
const uint8_t* data = sqlite3_column_blob(stmt, 0);
|
||||
int len = sqlite3_column_bytes(stmt, 0);
|
||||
if (topo_node_deserialize(&group, data, (size_t)len, &ni, NULL, NULL, NULL, NULL) < 0 ||
|
||||
!ni || ni->node_id != node_id || topo_node_verify(ni) < 0) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_BGP, "invalid persisted snapshot node=%016llx", (unsigned long long)node_id);
|
||||
topo_node_destroy(groups, ni); ni = NULL;
|
||||
}
|
||||
} else if (rc != SQLITE_DONE) DEBUG_ERROR(DEBUG_CATEGORY_BGP, "snapshot read: %s", sqlite3_errmsg(db));
|
||||
sqlite3_finalize(stmt);
|
||||
return ni;
|
||||
}
|
||||
|
||||
struct TOPO_NODE* topo_node_sqlite_node_load(sqlite3* db, struct TOPO_GROUPS* groups, uint64_t node_id) {
|
||||
if (!db || !groups) return NULL;
|
||||
struct TOPO_NODE* snapshot = topo_node_sqlite_snapshot_load(db, groups, node_id);
|
||||
if (snapshot) return snapshot;
|
||||
|
||||
uint8_t pubkey[32] = {0}, ed_pubkey[32] = {0};
|
||||
char* name = NULL;
|
||||
|
||||
Reference in new issue
Block a user