mirror of
https://github.com/monero-project/monero.git
synced 2025-08-23 20:55:15 -04:00
New add_aux_pow RPC to support merge mining
This commit is contained in:
parent
cb70ae9450
commit
19b228393f
14 changed files with 720 additions and 1 deletions
|
@ -104,3 +104,154 @@ void tree_hash(const char (*hashes)[HASH_SIZE], size_t count, char *root_hash) {
|
|||
free(ints);
|
||||
}
|
||||
}
|
||||
|
||||
bool tree_path(size_t count, size_t idx, uint32_t *path)
|
||||
{
|
||||
if (count == 0)
|
||||
return false;
|
||||
|
||||
if (count == 1) {
|
||||
*path = 0;
|
||||
} else if (count == 2) {
|
||||
*path = idx == 0 ? 0 : 1;
|
||||
} else {
|
||||
size_t i, j;
|
||||
|
||||
*path = 0;
|
||||
size_t cnt = tree_hash_cnt( count );
|
||||
|
||||
for (i = 2 * cnt - count, j = 2 * cnt - count; j < cnt; i += 2, ++j) {
|
||||
if (idx == i || idx == i+1)
|
||||
{
|
||||
*path = (*path << 1) | (idx == i ? 0 : 1);
|
||||
idx = j;
|
||||
}
|
||||
}
|
||||
assert(i == count);
|
||||
|
||||
while (cnt > 2) {
|
||||
cnt >>= 1;
|
||||
for (i = 0, j = 0; j < cnt; i += 2, ++j) {
|
||||
if (idx == i || idx == i + 1)
|
||||
{
|
||||
*path = (*path << 1) | (idx == i ? 0 : 1);
|
||||
idx = j;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (idx == 0 || idx == 1)
|
||||
{
|
||||
*path = (*path << 1) | (idx == 0 ? 0 : 1);
|
||||
idx = 0;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool tree_branch(const char (*hashes)[HASH_SIZE], size_t count, const char *hash, char (*branch)[HASH_SIZE], size_t *depth, uint32_t *path)
|
||||
{
|
||||
size_t idx;
|
||||
|
||||
if (count == 0)
|
||||
return false;
|
||||
|
||||
for (idx = 0; idx < count; ++idx)
|
||||
if (!memcmp(hash, hashes[idx], HASH_SIZE))
|
||||
break;
|
||||
if (idx == count)
|
||||
return false;
|
||||
|
||||
assert(count > 0);
|
||||
if (count == 1) {
|
||||
*depth = 0;
|
||||
*path = 0;
|
||||
} else if (count == 2) {
|
||||
*depth = 1;
|
||||
*path = idx == 0 ? 0 : 1;
|
||||
memcpy(branch[0], hashes[idx ^ 1], HASH_SIZE);
|
||||
} else {
|
||||
size_t i, j;
|
||||
|
||||
*depth = 0;
|
||||
*path = 0;
|
||||
size_t cnt = tree_hash_cnt( count );
|
||||
|
||||
char *ints = calloc(cnt, HASH_SIZE); // zero out as extra protection for using uninitialized mem
|
||||
assert(ints);
|
||||
|
||||
memcpy(ints, hashes, (2 * cnt - count) * HASH_SIZE);
|
||||
|
||||
for (i = 2 * cnt - count, j = 2 * cnt - count; j < cnt; i += 2, ++j) {
|
||||
if (idx == i || idx == i+1)
|
||||
{
|
||||
memcpy(branch[*depth], hashes[idx == i ? i + 1 : i], HASH_SIZE);
|
||||
++*depth;
|
||||
*path = (*path << 1) | (idx == i ? 0 : 1);
|
||||
idx = j;
|
||||
}
|
||||
cn_fast_hash(hashes[i], 64, ints + j * HASH_SIZE);
|
||||
}
|
||||
assert(i == count);
|
||||
|
||||
while (cnt > 2) {
|
||||
cnt >>= 1;
|
||||
for (i = 0, j = 0; j < cnt; i += 2, ++j) {
|
||||
if (idx == i || idx == i + 1)
|
||||
{
|
||||
memcpy(branch[*depth], ints + (idx == i ? i + 1 : i) * HASH_SIZE, HASH_SIZE);
|
||||
++*depth;
|
||||
*path = (*path << 1) | (idx == i ? 0 : 1);
|
||||
idx = j;
|
||||
}
|
||||
cn_fast_hash(ints + i * HASH_SIZE, 64, ints + j * HASH_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
if (idx == 0 || idx == 1)
|
||||
{
|
||||
memcpy(branch[*depth], ints + (idx == 0 ? 1 : 0) * HASH_SIZE, HASH_SIZE);
|
||||
++*depth;
|
||||
*path = (*path << 1) | (idx == 0 ? 0 : 1);
|
||||
idx = 0;
|
||||
}
|
||||
|
||||
free(ints);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool tree_branch_hash(const char hash[HASH_SIZE], const char (*branch)[HASH_SIZE], size_t depth, uint32_t path, char root[HASH_SIZE])
|
||||
{
|
||||
size_t d;
|
||||
char partial[HASH_SIZE];
|
||||
|
||||
memcpy(partial, hash, HASH_SIZE);
|
||||
|
||||
for (d = 0; d < depth; ++d)
|
||||
{
|
||||
char buffer[2 * HASH_SIZE];
|
||||
if ((path >> (depth - d - 1)) & 1)
|
||||
{
|
||||
memcpy(buffer, branch[d], HASH_SIZE);
|
||||
memcpy(buffer + HASH_SIZE, partial, HASH_SIZE);
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(buffer, partial, HASH_SIZE);
|
||||
memcpy(buffer + HASH_SIZE, branch[d], HASH_SIZE);
|
||||
}
|
||||
cn_fast_hash(buffer, 2 * HASH_SIZE, partial);
|
||||
}
|
||||
|
||||
memcpy(root, partial, HASH_SIZE);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool is_branch_in_tree(const char hash[HASH_SIZE], const char root[HASH_SIZE], const char (*branch)[HASH_SIZE], size_t depth, uint32_t path)
|
||||
{
|
||||
char res[HASH_SIZE];
|
||||
if (!tree_branch_hash(hash, branch, depth, path, res))
|
||||
return false;
|
||||
return memcmp(res, root, HASH_SIZE) == 0;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue