sparse-tools/src/bs_send_merkle.c

161 lines
4.0 KiB
C

// Created by haraldwolff on 07.08.22.
//
#include <blksync.h>
#include <hash.h>
#include <time.h>
/*
int sync_merkle(bsync_engine_t *engine, merkle_t* merkle, merkle_t *remote, int d, int n);
int bs_send_merkle(bsync_engine_t *engine){
int s;
int blocks = (engine->filesize + engine->blocksize - 1) / engine->blocksize;
uint64_t hash;
merkle_t *merkle, *remote_merkle;
if (merkle_create(&remote_merkle, 2, blocks)<0)
return -ENOMEM;
s = bs_merkle_build(engine, &merkle);
if (s < 0){
fprintf(stderr, "failed to build merkle tree.\n");
}
fprintf(stdout, "synchronize merkle trees...\n");
fflush(stdout);
if (bs_recv(engine->remote, &hash, sizeof(uint64_t)) < 0)
return -EIO;
merkle_set(remote_merkle, 0, 0, hash);
fprintf(stdout, "remote top: 0x%016lx\n", hash);
fflush(stdout);
if (engine->tool_flags & BS_DEBUG){
merkle_dump( merkle );
}
if (sync_merkle(engine, merkle, remote_merkle, 0, 0)<0)
{
fprintf(stderr, "could not sync merkle trees.\n");
return -1;
}
s = -1;
if (
(bs_send(engine->remote, &s, sizeof(int)) < 0) ||
(bs_send(engine->remote, &s, sizeof(int)) < 0)
){
fprintf(stderr, "failed to send end-of-sync mark\n");
return -EIO;
}
if (engine->tool_flags & BS_DEBUG){
merkle_dump( remote_merkle );
}
uint64_t *myrow, *yourrow;
char *block = malloc(engine->blocksize);
if (!block) {
fprintf(stderr, "out of memory allocating block buffer\n");
return -ENOMEM;
}
merkle_get_row(merkle, merkle->parameters.depth, &myrow, NULL);
merkle_get_row(remote_merkle, remote_merkle->parameters.depth, &yourrow, NULL);
int count_changed = 0;
int count_sent = 0;
for (int nblock = 0; nblock < blocks; nblock++) {
if (yourrow[nblock] && (yourrow[nblock] != myrow[nblock]))
count_changed++;
}
for (int nblock = 0; nblock < blocks; nblock++){
if (yourrow[nblock] && (yourrow[nblock] != myrow[nblock])){
long offset = ((long)engine->blocksize) * nblock;
int size = (nblock == (blocks - 1)) ? engine->filesize - offset : engine->blocksize;
if (read_block(engine, offset, block, size)<0)
return -EIO;
if (engine->tool_flags & BS_VERBOSE) {
fprintf(stdout, "\tsending block 0x%016lx (%d bytes)\n", offset, size);
fflush(stdout);
}
if (
(bs_send(engine->remote, &offset, sizeof(offset)) < 0) ||
(bs_send(engine->remote, block, size) < 0)
){
fprintf(stderr, "could not send block at 0x%016lx\n", offset);
return -EIO;
}
count_sent++;
time_t now = time(NULL);
if (engine->t_last_update != now){
bs_time_t bst;
engine->t_last_update = now;
bs_time_set( &bst, (now - engine->t_start) * (count_changed-count_sent) / count_sent);
fprintf(stdout, "\r%d / %d [ %d%% ] => %02d:%02d:%02d", count_sent, count_changed, 100 * count_sent / count_changed, bst.hours, bst.minutes, bst.seconds);
fflush(stdout);
}
}
}
free(block);
hash = -1;
bs_send(engine->remote, &hash, sizeof(hash));
merkle_free(merkle);
merkle_free(remote_merkle);
return 0;
}
int sync_merkle(bsync_engine_t *engine, merkle_t* merkle, merkle_t *remote, int d, int n)
{
uint64_t mine, yours;
uint64_t *nextrow;
merkle_get(merkle, d, n, &mine);
merkle_get(remote, d, n, &yours);
if (engine->tool_flags & BS_DEBUG) {
fprintf(stdout, "%d / %d : 0x%016lx 0x%016lx\n", d, n, mine, yours);
fflush(stdout);
}
if (mine != yours){
if (
(bs_send(engine->remote, &d, sizeof(int)) < 0) ||
(bs_send(engine->remote, &n, sizeof(int)) < 0)
){
fprintf(stderr, "failed to request tree hashes for d=%d n=%d\n", d, n);
return -EIO;
}
merkle_get_row(remote, d+1, &nextrow, NULL);
if (bs_recv(engine->remote, &nextrow[n * (remote->parameters.n)], remote->parameters.n * sizeof(uint64_t)) < 0)
{
fprintf(stderr, "failed to receive tree hashes for d=%d n=%d\n", d, n);
return -EIO;
}
if (d < (remote->parameters.depth-1)) {
for (int i = 0; i < remote->parameters.n; i++) {
int s = sync_merkle(engine, merkle, remote, d+1, (n*merkle->parameters.n) + i);
if (s < 0)
return s;
}
}
}
return 0;
}
*/