Browse Source

Fixed Merkle Tree Hashing

master
Intel 10 years ago
parent
commit
8659d15b9a
  1. 12
      src/server/poolserver/Stratum/Client.cpp
  2. 41
      src/server/shared/Bitcoin/Block.cpp
  3. 2
      src/server/shared/Bitcoin/Block.h

12
src/server/poolserver/Stratum/Client.cpp

@ -49,12 +49,12 @@ namespace Stratum
// Build merkle branch array // Build merkle branch array
JSON merkle_branch(JSON_ARRAY); JSON merkle_branch(JSON_ARRAY);
uint64 branches = job.block->merkleBranches;
uint64 index = 0; uint32 j = 0;
while (branches > 1) { for (uint32 size = job.block->tx.size(); size > 1; size = (size+1)/2)
merkle_branch.Add(Util::BinToASCII(job.block->merkleTree[index+1])); {
index += branches; merkle_branch.Add(Util::BinToASCII(job.block->merkleTree[j+1]));
branches /= 2; j += size;
} }
// Reverse prev block hash every 4 bytes... Makes a lot of sense... // Reverse prev block hash every 4 bytes... Makes a lot of sense...

41
src/server/shared/Bitcoin/Block.cpp

@ -1,4 +1,5 @@
#include "Block.h" #include "Block.h"
#include "Log.h"
namespace Bitcoin namespace Bitcoin
{ {
@ -6,28 +7,20 @@ namespace Bitcoin
{ {
merkleTree.clear(); merkleTree.clear();
uint64 branches = 1;
uint32 levels = 0;
while (branches < tx.size()) {
branches *= 2;
++levels;
}
// Used when sending merkle branches
merkleBranches = branches;
// Add transactions // Add transactions
for (uint64 i = 0; i < branches; ++i) for (uint64 i = 0; i < tx.size(); ++i)
merkleTree.push_back(tx[std::min(i, tx.size()-1)].GetHash()); merkleTree.push_back(tx[i].GetHash());
uint32 merkleIndex = 0; uint32 j = 0;
for (uint32 level = levels; level > 0; --level) for (uint32 size = tx.size(); size > 1; size = (size+1)/2)
{ {
// Decrease before calculating because bottom level is transactions for (uint32 i = 0; i < size; i += 2)
branches /= 2; {
uint32 i2 = std::min(i+1, size-1);
merkleTree.push_back(Crypto::SHA256D(Util::Join(merkleTree[j+i], merkleTree[j+i2])));
}
for (uint32 branch = 0; branch < branches; ++branch) j += size;
merkleTree.push_back(Crypto::SHA256D(Util::Join(merkleTree[merkleIndex++], merkleTree[merkleIndex++])));
} }
// Last hash is merkle root // Last hash is merkle root
@ -39,12 +32,12 @@ namespace Bitcoin
// Set coinbase tx hash // Set coinbase tx hash
merkleTree[0] = tx[0].GetHash(); merkleTree[0] = tx[0].GetHash();
uint64 branches = merkleBranches; // Only rebuild left side of the tree
uint64 index = 0; uint32 j = 0;
while (branches > 1) { for (uint32 size = tx.size(); size > 1; size = (size+1)/2)
merkleTree[index+branches] = Crypto::SHA256D(Util::Join(merkleTree[index], merkleTree[index+1])); {
index += branches; merkleTree[size] = Crypto::SHA256D(Util::Join(merkleTree[j], merkleTree[j+1]));
branches /= 2; j += size;
} }
// Last hash is merkle root // Last hash is merkle root

2
src/server/shared/Bitcoin/Block.h

@ -18,6 +18,7 @@ namespace Bitcoin
uint32 time; uint32 time;
uint32 bits; uint32 bits;
uint32 nonce; uint32 nonce;
BinaryData signature;
}; };
class Block : public BlockHeader class Block : public BlockHeader
@ -28,7 +29,6 @@ namespace Bitcoin
// Other data // Other data
std::vector<BinaryData> merkleTree; std::vector<BinaryData> merkleTree;
uint64 merkleBranches;
void BuildMerkleTree(); void BuildMerkleTree();
// Rebuilds only left side of merkle tree // Rebuilds only left side of merkle tree

Loading…
Cancel
Save