From 8659d15b9a2ac7916f54ff03cad977d83ba5a3f9 Mon Sep 17 00:00:00 2001 From: Intel Date: Mon, 12 May 2014 09:26:19 -0400 Subject: [PATCH] Fixed Merkle Tree Hashing --- src/server/poolserver/Stratum/Client.cpp | 12 +++---- src/server/shared/Bitcoin/Block.cpp | 41 ++++++++++-------------- src/server/shared/Bitcoin/Block.h | 2 +- 3 files changed, 24 insertions(+), 31 deletions(-) diff --git a/src/server/poolserver/Stratum/Client.cpp b/src/server/poolserver/Stratum/Client.cpp index 589df7f..e37d766 100644 --- a/src/server/poolserver/Stratum/Client.cpp +++ b/src/server/poolserver/Stratum/Client.cpp @@ -49,12 +49,12 @@ namespace Stratum // Build merkle branch array JSON merkle_branch(JSON_ARRAY); - uint64 branches = job.block->merkleBranches; - uint64 index = 0; - while (branches > 1) { - merkle_branch.Add(Util::BinToASCII(job.block->merkleTree[index+1])); - index += branches; - branches /= 2; + + uint32 j = 0; + for (uint32 size = job.block->tx.size(); size > 1; size = (size+1)/2) + { + merkle_branch.Add(Util::BinToASCII(job.block->merkleTree[j+1])); + j += size; } // Reverse prev block hash every 4 bytes... Makes a lot of sense... diff --git a/src/server/shared/Bitcoin/Block.cpp b/src/server/shared/Bitcoin/Block.cpp index 1f0c482..6f24892 100644 --- a/src/server/shared/Bitcoin/Block.cpp +++ b/src/server/shared/Bitcoin/Block.cpp @@ -1,4 +1,5 @@ #include "Block.h" +#include "Log.h" namespace Bitcoin { @@ -6,28 +7,20 @@ namespace Bitcoin { merkleTree.clear(); - uint64 branches = 1; - uint32 levels = 0; - while (branches < tx.size()) { - branches *= 2; - ++levels; - } - - // Used when sending merkle branches - merkleBranches = branches; - // Add transactions - for (uint64 i = 0; i < branches; ++i) - merkleTree.push_back(tx[std::min(i, tx.size()-1)].GetHash()); + for (uint64 i = 0; i < tx.size(); ++i) + merkleTree.push_back(tx[i].GetHash()); - uint32 merkleIndex = 0; - for (uint32 level = levels; level > 0; --level) + uint32 j = 0; + for (uint32 size = tx.size(); size > 1; size = (size+1)/2) { - // Decrease before calculating because bottom level is transactions - branches /= 2; + for (uint32 i = 0; i < size; i += 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) - merkleTree.push_back(Crypto::SHA256D(Util::Join(merkleTree[merkleIndex++], merkleTree[merkleIndex++]))); + j += size; } // Last hash is merkle root @@ -39,12 +32,12 @@ namespace Bitcoin // Set coinbase tx hash merkleTree[0] = tx[0].GetHash(); - uint64 branches = merkleBranches; - uint64 index = 0; - while (branches > 1) { - merkleTree[index+branches] = Crypto::SHA256D(Util::Join(merkleTree[index], merkleTree[index+1])); - index += branches; - branches /= 2; + // Only rebuild left side of the tree + uint32 j = 0; + for (uint32 size = tx.size(); size > 1; size = (size+1)/2) + { + merkleTree[size] = Crypto::SHA256D(Util::Join(merkleTree[j], merkleTree[j+1])); + j += size; } // Last hash is merkle root diff --git a/src/server/shared/Bitcoin/Block.h b/src/server/shared/Bitcoin/Block.h index 084c181..16235f2 100644 --- a/src/server/shared/Bitcoin/Block.h +++ b/src/server/shared/Bitcoin/Block.h @@ -18,6 +18,7 @@ namespace Bitcoin uint32 time; uint32 bits; uint32 nonce; + BinaryData signature; }; class Block : public BlockHeader @@ -28,7 +29,6 @@ namespace Bitcoin // Other data std::vector merkleTree; - uint64 merkleBranches; void BuildMerkleTree(); // Rebuilds only left side of merkle tree