Browse Source

merkle_sync: fix _get_level_hashes — range query instead of exact mismatch (prefix encoding bug)

topo_upd
Evgeny 2 months ago
parent
commit
5983acd988
  1. 30
      tools/chatgui/transport/merkle_sync.c

30
tools/chatgui/transport/merkle_sync.c

@ -165,15 +165,31 @@ static int _get_level_hashes(struct merkle_sync* ms, const char* ns,
memset(hashes, 0, sizeof(uint8_t) * MT_BUCKETS * MT_HASH_SIZE); memset(hashes, 0, sizeof(uint8_t) * MT_BUCKETS * MT_HASH_SIZE);
*bitmap = 0; *bitmap = 0;
if (level >= MT_MAX_LEVEL) return 0; if (level >= MT_MAX_LEVEL) return 0;
int next_shift = 63 - ((int)level + 1) * 5;
for (int i = 0; i < MT_BUCKETS; i++) { sqlite3* db = _db(ms->inst); if (!db) return -1;
uint64_t child_prefix = prefix | ((uint64_t)i << (next_shift > 0 ? next_shift : 0)); int parent_shift = 63 - (int)level * 5; if (parent_shift < 0) parent_shift = 0;
const uint8_t* h = merkle_sync_get_hash(ms->inst, ns, (uint8_t)(level + 1), child_prefix); int next_shift = 63 - ((int)level + 1) * 5; if (next_shift < 0) next_shift = 0;
int empty = 1; uint64_t range_end = prefix | ((1ULL << parent_shift) - 1);
for (int j = 0; j < MT_HASH_SIZE; j++) { if (h[j] != 0) { empty = 0; break; } }
if (!empty) { *bitmap |= (1u << i); memcpy(hashes[i], h, MT_HASH_SIZE); } sqlite3_stmt* stmt = NULL;
if (sqlite3_prepare_v2(db,
"SELECT prefix64, hash FROM merkle_tree_hash"
" WHERE namespace=? AND level=? AND prefix64>=? AND prefix64<=?"
" ORDER BY prefix64", -1, &stmt, NULL) != SQLITE_OK || !stmt)
return -1;
sqlite3_bind_text(stmt, 1, ns, -1, SQLITE_STATIC);
sqlite3_bind_int(stmt, 2, (int)(level + 1));
sqlite3_bind_int64(stmt, 3, (sqlite3_int64)prefix);
sqlite3_bind_int64(stmt, 4, (sqlite3_int64)range_end);
while (sqlite3_step(stmt) == SQLITE_ROW) {
sqlite3_int64 row_pfx = sqlite3_column_int64(stmt, 0);
const void* h = sqlite3_column_blob(stmt, 1);
if (!h || sqlite3_column_bytes(stmt, 1) < MT_HASH_SIZE) continue;
int bucket = (int)(((uint64_t)row_pfx >> next_shift) & 0x1F);
*bitmap |= (1u << bucket);
memcpy(hashes[bucket], h, MT_HASH_SIZE);
} }
sqlite3_finalize(stmt);
return 0; return 0;
} }

Loading…
Cancel
Save