|
|
|
|
@ -309,7 +309,7 @@ static void test_tree_empty_ns(void) {
|
|
|
|
|
inst.ua = uasync_create(); |
|
|
|
|
if (merkle_sync_init(&inst, 0x72, &g_test_ops, &ctx) != 0) abort(); |
|
|
|
|
|
|
|
|
|
merkle_sync_recompute_path(&inst, MT_DATA_MEMBERS, MT_DATA_MEMBERS, MT_DATA_MEMBERS, MT_DATA_MEMBERS, MT_DATA_MEMBERS, MT_DATA_MEMBERS, MT_DATA_MEMBERS, MT_DATA_MEMBERS, MT_DATA_MEMBERS, MS_NS_TEST, 0x1234ULL); |
|
|
|
|
merkle_sync_recompute_path(&inst, MT_DATA_MEMBERS, MS_NS_TEST, 0x1234ULL); |
|
|
|
|
if (_db_count_rows(db, MS_NS_TEST) == 0) PASS(); else FAIL("got %d rows", _db_count_rows(db, MS_NS_TEST)); |
|
|
|
|
|
|
|
|
|
merkle_sync_destroy(&inst); uasync_destroy(inst.ua, 0); sqlite3_close(db); |
|
|
|
|
@ -330,7 +330,7 @@ static void test_tree_single_item(void) {
|
|
|
|
|
inst.ua = uasync_create(); |
|
|
|
|
if (merkle_sync_init(&inst, 0x72, &g_test_ops, &ctx) != 0) abort(); |
|
|
|
|
|
|
|
|
|
merkle_sync_recompute_path(&inst, MS_NS_TEST, key); |
|
|
|
|
merkle_sync_recompute_path(&inst, MT_DATA_MEMBERS, MS_NS_TEST, key); |
|
|
|
|
int rows = _db_count_rows(db, MS_NS_TEST); |
|
|
|
|
if (rows != 6) { FAIL("expected 6 rows got %d", rows); merkle_sync_destroy(&inst); uasync_destroy(inst.ua, 0); sqlite3_close(db); return; } |
|
|
|
|
|
|
|
|
|
@ -365,8 +365,8 @@ static void test_tree_multi_item_same_bucket(void) {
|
|
|
|
|
if (merkle_sync_init(&inst, 0x72, &g_test_ops, &ctx) != 0) abort(); |
|
|
|
|
|
|
|
|
|
/* recompute for both */ |
|
|
|
|
merkle_sync_recompute_path(&inst, MS_NS_TEST, k1); |
|
|
|
|
merkle_sync_recompute_path(&inst, MS_NS_TEST, k2); |
|
|
|
|
merkle_sync_recompute_path(&inst, MT_DATA_MEMBERS, MS_NS_TEST, k1); |
|
|
|
|
merkle_sync_recompute_path(&inst, MT_DATA_MEMBERS, MS_NS_TEST, k2); |
|
|
|
|
|
|
|
|
|
uint64_t pf1 = merkle_sync_level_prefix(k1, 1); |
|
|
|
|
uint64_t pf2 = merkle_sync_level_prefix(k2, 1); |
|
|
|
|
@ -397,8 +397,8 @@ static void test_tree_different_buckets(void) {
|
|
|
|
|
inst.ua = uasync_create(); |
|
|
|
|
if (merkle_sync_init(&inst, 0x72, &g_test_ops, &ctx) != 0) abort(); |
|
|
|
|
|
|
|
|
|
merkle_sync_recompute_path(&inst, "ns", kA); |
|
|
|
|
merkle_sync_recompute_path(&inst, "ns", kB); |
|
|
|
|
merkle_sync_recompute_path(&inst, MT_DATA_MEMBERS, "ns", kA); |
|
|
|
|
merkle_sync_recompute_path(&inst, MT_DATA_MEMBERS, "ns", kB); |
|
|
|
|
|
|
|
|
|
uint64_t pfA = merkle_sync_level_prefix(kA, 1); |
|
|
|
|
uint64_t pfB = merkle_sync_level_prefix(kB, 1); |
|
|
|
|
@ -427,12 +427,12 @@ static void test_tree_delete_empty_bucket(void) {
|
|
|
|
|
inst.ua = uasync_create(); |
|
|
|
|
if (merkle_sync_init(&inst, 0x72, &g_test_ops, &ctx) != 0) abort(); |
|
|
|
|
|
|
|
|
|
merkle_sync_recompute_path(&inst, MS_NS_TEST, k); |
|
|
|
|
merkle_sync_recompute_path(&inst, MT_DATA_MEMBERS, MS_NS_TEST, k); |
|
|
|
|
if (_db_count_rows(db, MS_NS_TEST) != 6) { FAIL("expected 6 rows"); merkle_sync_destroy(&inst); uasync_destroy(inst.ua, 0); sqlite3_close(db); return; } |
|
|
|
|
|
|
|
|
|
/* remove item and recompute */ |
|
|
|
|
data.count = 0; |
|
|
|
|
merkle_sync_recompute_path(&inst, MS_NS_TEST, k); |
|
|
|
|
merkle_sync_recompute_path(&inst, MT_DATA_MEMBERS, MS_NS_TEST, k); |
|
|
|
|
if (_db_count_rows(db, MS_NS_TEST) != 0) { FAIL("expected 0 rows got %d", _db_count_rows(db, MS_NS_TEST)); merkle_sync_destroy(&inst); uasync_destroy(inst.ua, 0); sqlite3_close(db); return; } |
|
|
|
|
|
|
|
|
|
uint64_t pf = merkle_sync_level_prefix(k, 3); |
|
|
|
|
@ -466,7 +466,7 @@ static void test_tree_consistency(void) {
|
|
|
|
|
if (merkle_sync_init(&inst, 0x72, &g_test_ops, &ctx) != 0) abort(); |
|
|
|
|
|
|
|
|
|
for (int i = 0; i < data.count; i++) |
|
|
|
|
merkle_sync_recompute_path(&inst, "ns", data.items[i].key); |
|
|
|
|
merkle_sync_recompute_path(&inst, MT_DATA_MEMBERS, "ns", data.items[i].key); |
|
|
|
|
|
|
|
|
|
/* verify: recompute each bucket, compare with stored hash */ |
|
|
|
|
sqlite3_stmt* st = NULL; |
|
|
|
|
@ -711,7 +711,7 @@ static void test_peer_empty(void) {
|
|
|
|
|
if (_intg_init_two() != 0) { FAIL("setup failed"); return; } |
|
|
|
|
_intg_ins_many(&data_b, i_b, 0, 5); |
|
|
|
|
done_sync = 0; |
|
|
|
|
merkle_sync_start(i_a, MT_DATA_MEMBERS, MT_DATA_MEMBERS, MT_DATA_MEMBERS, MT_DATA_MEMBERS, MT_DATA_MEMBERS, MT_DATA_MEMBERS, MT_DATA_MEMBERS, MT_DATA_MEMBERS, i_b->node_id, MS_NS_TEST, _on_sync_done, NULL); |
|
|
|
|
merkle_sync_start(i_a, MT_DATA_MEMBERS, i_b->node_id, MS_NS_TEST, _on_sync_done, NULL); |
|
|
|
|
if (!_wait_for("sync done", _cond_done, PHASE_TIMEOUT_TB)) |
|
|
|
|
{ FAIL("sync timeout"); _intg_cleanup(); return; } |
|
|
|
|
printf(" A data=%d B data=%d, A tree=%d B tree=%d\n", |
|
|
|
|
@ -730,7 +730,7 @@ static void test_hash_match(void) {
|
|
|
|
|
_intg_ins_many(&data_a, i_a, 0, 5); |
|
|
|
|
_intg_ins_many(&data_b, i_b, 0, 5); |
|
|
|
|
done_sync = 0; |
|
|
|
|
merkle_sync_start(i_a, i_b->node_id, MS_NS_TEST, _on_sync_done, NULL); |
|
|
|
|
merkle_sync_start(i_a, MT_DATA_MEMBERS, i_b->node_id, MS_NS_TEST, _on_sync_done, NULL); |
|
|
|
|
for (int i = 0; i < 200 && !done_sync && i_phase == 0; i++) uasync_poll(i_ua, 1); |
|
|
|
|
if (!done_sync) { FAIL("sync did not complete quickly"); _intg_cleanup(); return; } |
|
|
|
|
if (_intg_verify_all(i_a, i_b, &data_a, &data_b, MS_NS_TEST) != 0) |
|
|
|
|
@ -745,7 +745,7 @@ static void test_divergence_merge(void) {
|
|
|
|
|
_intg_ins_many(&data_a, i_a, 0, 3); |
|
|
|
|
_intg_ins_many(&data_b, i_b, 10, 2); |
|
|
|
|
done_sync = 0; |
|
|
|
|
merkle_sync_start(i_a, i_b->node_id, MS_NS_TEST, _on_sync_done, NULL); |
|
|
|
|
merkle_sync_start(i_a, MT_DATA_MEMBERS, i_b->node_id, MS_NS_TEST, _on_sync_done, NULL); |
|
|
|
|
if (!_wait_for("sync done", _cond_done, PHASE_TIMEOUT_TB)) |
|
|
|
|
{ FAIL("sync timeout"); _intg_cleanup(); return; } |
|
|
|
|
if (_intg_verify_all(i_a, i_b, &data_a, &data_b, MS_NS_TEST) != 0) |
|
|
|
|
@ -781,11 +781,11 @@ static void test_randomized_two(void) {
|
|
|
|
|
_data_insert(&data_b, k, (uint32_t)rand()); |
|
|
|
|
} |
|
|
|
|
_data_sort(&data_a); _data_sort(&data_b); |
|
|
|
|
for (int i = 0; i < data_a.count; i++) merkle_sync_recompute_path(i_a, MT_DATA_MEMBERS, MT_DATA_MEMBERS, MS_NS_RND, data_a.items[i].key); |
|
|
|
|
for (int i = 0; i < data_b.count; i++) merkle_sync_recompute_path(i_b, MT_DATA_MEMBERS, MT_DATA_MEMBERS, MT_DATA_MEMBERS, MT_DATA_MEMBERS, MS_NS_RND, data_b.items[i].key); |
|
|
|
|
for (int i = 0; i < data_a.count; i++) merkle_sync_recompute_path(i_a, MT_DATA_MEMBERS, MS_NS_RND, data_a.items[i].key); |
|
|
|
|
for (int i = 0; i < data_b.count; i++) merkle_sync_recompute_path(i_b, MT_DATA_MEMBERS, MS_NS_RND, data_b.items[i].key); |
|
|
|
|
|
|
|
|
|
done_sync = 0; |
|
|
|
|
merkle_sync_start(i_a, i_b->node_id, MS_NS_RND, _on_sync_done, NULL); |
|
|
|
|
merkle_sync_start(i_a, MT_DATA_MEMBERS, i_b->node_id, MS_NS_RND, _on_sync_done, NULL); |
|
|
|
|
if (!_wait_for("sync", _cond_done, PHASE_TIMEOUT_TB)) { FAIL("timeout iter %d", iter); _intg_cleanup(); break; } |
|
|
|
|
if (_intg_verify_all(i_a, i_b, &data_a, &data_b, MS_NS_RND) != 0) { |
|
|
|
|
printf(" A data=%d B data=%d A tree=%d B tree=%d\n", |
|
|
|
|
@ -878,8 +878,8 @@ static void test_randomized_three(void) {
|
|
|
|
|
for (int i = 0; i < na; i++) { uint64_t k = ((uint64_t)rand()<<32)|(uint64_t)rand(); _data_insert(&data_a, k, (uint32_t)rand()); } |
|
|
|
|
for (int i = 0; i < nb; i++) { uint64_t k = ((uint64_t)rand()<<32)|(uint64_t)rand(); _data_insert(&data_b, k, (uint32_t)rand()); } |
|
|
|
|
for (int i = 0; i < nc; i++) { uint64_t k = ((uint64_t)rand()<<32)|(uint64_t)rand(); _data_insert(&data_c, k, (uint32_t)rand()); } |
|
|
|
|
_data_sort(&data_a); for (int i = 0; i < data_a.count; i++) merkle_sync_recompute_path(i_a, MS_NS_RND, data_a.items[i].key); |
|
|
|
|
_data_sort(&data_b); for (int i = 0; i < data_b.count; i++) merkle_sync_recompute_path(i_b, MS_NS_RND, data_b.items[i].key); |
|
|
|
|
_data_sort(&data_a); for (int i = 0; i < data_a.count; i++) merkle_sync_recompute_path(i_a, MT_DATA_MEMBERS, MS_NS_RND, data_a.items[i].key); |
|
|
|
|
_data_sort(&data_b); for (int i = 0; i < data_b.count; i++) merkle_sync_recompute_path(i_b, MT_DATA_MEMBERS, MS_NS_RND, data_b.items[i].key); |
|
|
|
|
_data_sort(&data_c); for (int i = 0; i < data_c.count; i++) merkle_sync_recompute_path(i_c, MT_DATA_MEMBERS, MS_NS_RND, data_c.items[i].key); |
|
|
|
|
|
|
|
|
|
done_sync = 0; i_phase = 0; |
|
|
|
|
@ -911,7 +911,7 @@ static void test_cancel(void) {
|
|
|
|
|
if (_intg_init_two() != 0) { FAIL("setup failed"); return; } |
|
|
|
|
_intg_ins_many(&data_b, i_b, 0, 5); |
|
|
|
|
done_sync = 0; |
|
|
|
|
merkle_sync_start(i_a, i_b->node_id, MS_NS_TEST, _on_sync_done, NULL); |
|
|
|
|
merkle_sync_start(i_a, MT_DATA_MEMBERS, i_b->node_id, MS_NS_TEST, _on_sync_done, NULL); |
|
|
|
|
merkle_sync_cancel(i_a, MT_DATA_MEMBERS, i_b->node_id, MS_NS_TEST); |
|
|
|
|
for (int i = 0; i < 100 && i_phase == 0; i++) uasync_poll(i_ua, 10); |
|
|
|
|
if (!done_sync) PASS(); else FAIL("done_cb was called"); |
|
|
|
|
@ -927,8 +927,8 @@ static void test_start_overwrite(void) {
|
|
|
|
|
if (_intg_init_two() != 0) { FAIL("setup failed"); return; } |
|
|
|
|
_intg_ins_many(&data_b, i_b, 0, 3); |
|
|
|
|
sw_cb1_called = sw_cb2_called = 0; |
|
|
|
|
merkle_sync_start(i_a, i_b->node_id, MS_NS_TEST, _sw_done1, NULL); |
|
|
|
|
merkle_sync_start(i_a, i_b->node_id, MS_NS_TEST, _sw_done2, NULL); |
|
|
|
|
merkle_sync_start(i_a, MT_DATA_MEMBERS, i_b->node_id, MS_NS_TEST, _sw_done1, NULL); |
|
|
|
|
merkle_sync_start(i_a, MT_DATA_MEMBERS, i_b->node_id, MS_NS_TEST, _sw_done2, NULL); |
|
|
|
|
for (int i = 0; i < 500 && !sw_cb2_called && i_phase == 0; i++) uasync_poll(i_ua, 10); |
|
|
|
|
if (sw_cb1_called && sw_cb2_called) PASS(); else FAIL("cb1=%d cb2=%d", sw_cb1_called, sw_cb2_called); |
|
|
|
|
_intg_cleanup(); |
|
|
|
|
@ -1018,7 +1018,7 @@ static void _str_spam_cb(void* arg) {
|
|
|
|
|
uint64_t key = ((uint64_t)idx) << 60; |
|
|
|
|
_data_insert(&gs->data[idx], key, (uint32_t)(gs->data[idx].count + 1)); |
|
|
|
|
merkle_sync_recompute_path(gs->inst[idx], MT_DATA_MEMBERS, MS_NS_STRESS, key); |
|
|
|
|
merkle_sync_start(gs->inst[idx], MT_DATA_MEMBERS, MT_DATA_MEMBERS, gs->inst[STRESS_HUB]->node_id, MS_NS_STRESS, NULL, NULL); |
|
|
|
|
merkle_sync_start(gs->inst[idx], MT_DATA_MEMBERS, gs->inst[STRESS_HUB]->node_id, MS_NS_STRESS, NULL, NULL); |
|
|
|
|
|
|
|
|
|
_str_spam_schedule(gs, idx); |
|
|
|
|
} |
|
|
|
|
@ -1027,7 +1027,7 @@ static void _str_obs_spam_cb(void* arg) {
|
|
|
|
|
if (!gs || !gs->spam_active) return; |
|
|
|
|
int idx = (int)(intptr_t)arg; |
|
|
|
|
|
|
|
|
|
merkle_sync_start(gs->inst[idx], gs->inst[STRESS_HUB]->node_id, MS_NS_STRESS, NULL, NULL); |
|
|
|
|
merkle_sync_start(gs->inst[idx], MT_DATA_MEMBERS, gs->inst[STRESS_HUB]->node_id, MS_NS_STRESS, NULL, NULL); |
|
|
|
|
|
|
|
|
|
int delay_tb = ((rand() % 10) + 1) * 10; /* 1-10ms */ |
|
|
|
|
uasync_set_timeout(gs->ua, (uint32_t)delay_tb, arg, _str_obs_spam_cb, "obs_spam"); |
|
|
|
|
@ -1150,7 +1150,7 @@ static int _str_init(void) {
|
|
|
|
|
/* initial sync: each spoke → hub */ |
|
|
|
|
s->sync_pending = STRESS_N - 1; |
|
|
|
|
for (int i = 1; i < STRESS_N; i++) |
|
|
|
|
merkle_sync_start(s->inst[i], MT_DATA_MEMBERS, MT_DATA_MEMBERS, s->inst[STRESS_HUB]->node_id, MS_NS_STRESS, _str_sync_done, s); |
|
|
|
|
merkle_sync_start(s->inst[i], MT_DATA_MEMBERS, s->inst[STRESS_HUB]->node_id, MS_NS_STRESS, _str_sync_done, s); |
|
|
|
|
_str_wait_for("initial sync", _str_cond_sync_done, STRESS_SYNC_TB); |
|
|
|
|
|
|
|
|
|
/* observers: sync with hub too */ |
|
|
|
|
@ -1211,7 +1211,7 @@ static void _str_start_final_round(void) {
|
|
|
|
|
s->final_pending = STRESS_N - 1; |
|
|
|
|
printf(" final round %d: syncing %d spokes -> hub\n", s->final_round, s->final_pending); |
|
|
|
|
for (int i = 1; i < STRESS_N; i++) |
|
|
|
|
merkle_sync_start(s->inst[i], s->inst[STRESS_HUB]->node_id, MS_NS_STRESS, _str_final_done, NULL); |
|
|
|
|
merkle_sync_start(s->inst[i], MT_DATA_MEMBERS, s->inst[STRESS_HUB]->node_id, MS_NS_STRESS, _str_final_done, NULL); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void _str_final_done(uint64_t peer, const char* ns, int result, void* arg) { |
|
|
|
|
@ -1352,14 +1352,14 @@ static void test_large_leaf_and_automatic_update(void) {
|
|
|
|
|
if (_intg_init_two() != 0) { FAIL("setup failed"); return; } |
|
|
|
|
for (uint64_t i = 0; i < 6000; i++) _data_insert(&data_b, i, (uint32_t)i); |
|
|
|
|
_data_sort(&data_b); |
|
|
|
|
if (merkle_sync_recompute_path(i_b, MS_NS_TEST, 0) < 0) { FAIL("recompute failed"); _intg_cleanup(); return; } |
|
|
|
|
if (merkle_sync_recompute_path(i_b, MT_DATA_MEMBERS, MS_NS_TEST, 0) < 0) { FAIL("recompute failed"); _intg_cleanup(); return; } |
|
|
|
|
done_sync = 0; |
|
|
|
|
merkle_sync_start(i_a, i_b->node_id, MS_NS_TEST, _on_sync_done, NULL); |
|
|
|
|
merkle_sync_start(i_a, MT_DATA_MEMBERS, i_b->node_id, MS_NS_TEST, _on_sync_done, NULL); |
|
|
|
|
if (!_wait_for("large leaf", _cond_done, PHASE_TIMEOUT_TB) || !_cond_pair_equal()) { |
|
|
|
|
FAIL("large leaf did not converge"); _intg_cleanup(); return; |
|
|
|
|
} |
|
|
|
|
data_b.items[0].val = 9999; |
|
|
|
|
merkle_sync_recompute_path(i_b, MS_NS_TEST, 0); |
|
|
|
|
merkle_sync_recompute_path(i_b, MT_DATA_MEMBERS, MS_NS_TEST, 0); |
|
|
|
|
if (!_wait_for("automatic change", _cond_pair_equal, PHASE_TIMEOUT_TB)) { |
|
|
|
|
FAIL("automatic change did not propagate"); _intg_cleanup(); return; |
|
|
|
|
} |
|
|
|
|
|