Browse Source

db_sync: fix bad_sig infinite loop — delete+rechain, advance synced_pos past dup/bad_sig, accept on covered tail

topo_upd
Evgeny 2 months ago
parent
commit
e9fce43be5
  1. 26
      src/db_sync.c

26
src/db_sync.c

@ -429,7 +429,18 @@ static int db_record_insert(struct DB_SYNC_INSTANCE* si,
int rc;
// Verify author signature (mandatory)
if (db_verify_author_sig(si, ts, author_node_id, json, jlen, author_sig) != 0) return -2;
if (db_verify_author_sig(si, ts, author_node_id, json, jlen, author_sig) != 0) {
sqlite3_stmt* del;
if (si_prep(si, &del, "DELETE FROM \"%s\" WHERE timestamp=? AND author_signature=?") == SQLITE_OK) {
sqlite3_bind_int64(del, 1, (sqlite3_int64)ts);
sqlite3_bind_blob(del, 2, author_sig, DB_SIG_SIZE, SQLITE_STATIC);
sqlite3_step(del);
int chg = sqlite3_changes(SI_DB(si));
sqlite3_finalize(del);
if (chg > 0) db_cascade_from(si, si_find_pos(si, ts, author_sig));
}
return -2;
}
rc = sqlite3_exec(db, "BEGIN IMMEDIATE", NULL, NULL, NULL);
if (rc != SQLITE_OK) { DEBUG_ERROR(DEBUG_CATEGORY_DB_SYNC, "insert BEGIN: %s", sqlite3_errmsg(db)); return -1; }
@ -905,10 +916,12 @@ static void db_handle_send_data(struct DB_SYNC_INSTANCE* si, uint64_t src, const
if (ret == 0 && si->on_insert) si->on_insert(si, rts, (const char*)rdata, rdlen, src, si->on_insert_arg);
}
if (received > 0) {
uint16_t total_processed = received + duplicates + bad_sigs;
if (total_processed > 0) {
uint32_t rst = (from < old_synced_pos) ? from : old_synced_pos;
db_cascade_range(si, rst, from + received);
if (sp) sp->synced_pos = from + received - 1;
if (sp) sp->synced_pos = from + total_processed - 1;
for (int j = 0; j < si->peer_count; j++) {
if (si->peers[j].synced_pos >= rst && &si->peers[j] != sp)
si->peers[j].synced_pos = rst > 0 ? rst - 1 : 0;
@ -1051,6 +1064,13 @@ static void db_handle_sync_done(struct DB_SYNC_INSTANCE* si, uint64_t src, const
}
if (mc < pc) {
if (sp && sp->synced_pos + 1 >= pc) {
if (sp) { sp->synced_pos = pc - 1; sp->sync_state = 2; }
DEBUG_INFO(DEBUG_CATEGORY_DB_SYNC,
"sync [%s:%04llX] ← SYNC_DONE: count diff my=%u peer=%u but synced=%u covers tail — accept",
SI_SHRT(si), (unsigned long long)(src >> 16), mc, pc, sp ? sp->synced_pos : 0);
return;
}
DEBUG_INFO(DEBUG_CATEGORY_DB_SYNC,
"sync [%s:%04llX] ← SYNC_DONE: count diff my=%u peer=%u — requesting tail from=%u",
SI_SHRT(si), (unsigned long long)(src >> 16), mc, pc, mc);

Loading…
Cancel
Save