merged merkle torrent creation fix from RC_0_16

This commit is contained in:
Arvid Norberg 2013-01-21 07:33:48 +00:00
parent a50c6c9121
commit b3ef6011aa
6 changed files with 86 additions and 9 deletions

View File

@ -10,6 +10,7 @@
* fix uTP edge case where udp socket buffer fills up
* fix nagle implementation in uTP
* fixed merkle tree torrent creation bug
* fixed crash with empty url-lists in torrent files
* added missing max_connections() function to python bindings

View File

@ -255,8 +255,14 @@ int main(int argc, char* argv[])
if (!merklefile.empty())
{
output = fopen(merklefile.c_str(), "wb+");
if (output == NULL)
{
fprintf(stderr, "failed to open file \"%s\": (%d) %s\n"
, merklefile.c_str(), errno, strerror(errno));
return 1;
}
int ret = fwrite(&t.merkle_tree()[0], 20, t.merkle_tree().size(), output);
if (ret != t.merkle_tree().size() * 20)
if (ret != t.merkle_tree().size())
{
fprintf(stderr, "failed to write %s: (%d) %s\n"
, merklefile.c_str(), errno, strerror(errno));

View File

@ -74,6 +74,11 @@ namespace libtorrent
, tracker_retry_delay_max = 60 * 60
};
TORRENT_EXTRA_EXPORT int merkle_num_leafs(int);
TORRENT_EXTRA_EXPORT int merkle_num_nodes(int);
TORRENT_EXTRA_EXPORT int merkle_get_parent(int);
TORRENT_EXTRA_EXPORT int merkle_get_sibling(int);
struct TORRENT_EXPORT announce_entry
{
announce_entry(std::string const& u);

View File

@ -34,6 +34,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/file_pool.hpp"
#include "libtorrent/storage.hpp"
#include "libtorrent/escape_string.hpp"
#include "libtorrent/torrent_info.hpp" // for merkle_*()
#include <boost/bind.hpp>
#include <boost/next_prior.hpp>
@ -45,11 +46,6 @@ POSSIBILITY OF SUCH DAMAGE.
namespace libtorrent
{
// defined in torrent_info.cpp
int merkle_num_leafs(int);
int merkle_num_nodes(int);
int merkle_get_parent(int);
int merkle_get_sibling(int);
namespace detail
{

View File

@ -421,10 +421,11 @@ namespace libtorrent
int merkle_num_leafs(int pieces)
{
TORRENT_ASSERT(pieces > 0);
// round up to nearest 2 exponent
int i;
for (i = 0; pieces > 0; pieces >>= 1, ++i);
return 1 << i;
int ret = 1;
while (pieces > ret) ret <<= 1;
return ret;
}
int load_file(std::string const& filename, std::vector<char>& v, error_code& ec, int limit)

View File

@ -1913,6 +1913,74 @@ int test_main()
test1.resize(100, true);
TEST_CHECK(test1.all_set() == true);
// test merkle_*() functions
// this is the structure:
// 0
// 1 2
// 3 4 5 6
// 7 8 9 10 11 12 13 14
// num_leafs = 8
TEST_EQUAL(merkle_num_leafs(1), 1);
TEST_EQUAL(merkle_num_leafs(2), 2);
TEST_EQUAL(merkle_num_leafs(3), 4);
TEST_EQUAL(merkle_num_leafs(4), 4);
TEST_EQUAL(merkle_num_leafs(5), 8);
TEST_EQUAL(merkle_num_leafs(6), 8);
TEST_EQUAL(merkle_num_leafs(7), 8);
TEST_EQUAL(merkle_num_leafs(8), 8);
TEST_EQUAL(merkle_num_leafs(9), 16);
TEST_EQUAL(merkle_num_leafs(10), 16);
TEST_EQUAL(merkle_num_leafs(11), 16);
TEST_EQUAL(merkle_num_leafs(12), 16);
TEST_EQUAL(merkle_num_leafs(13), 16);
TEST_EQUAL(merkle_num_leafs(14), 16);
TEST_EQUAL(merkle_num_leafs(15), 16);
TEST_EQUAL(merkle_num_leafs(16), 16);
TEST_EQUAL(merkle_num_leafs(17), 32);
TEST_EQUAL(merkle_num_leafs(18), 32);
// parents
TEST_EQUAL(merkle_get_parent(1), 0);
TEST_EQUAL(merkle_get_parent(2), 0);
TEST_EQUAL(merkle_get_parent(3), 1);
TEST_EQUAL(merkle_get_parent(4), 1);
TEST_EQUAL(merkle_get_parent(5), 2);
TEST_EQUAL(merkle_get_parent(6), 2);
TEST_EQUAL(merkle_get_parent(7), 3);
TEST_EQUAL(merkle_get_parent(8), 3);
TEST_EQUAL(merkle_get_parent(9), 4);
TEST_EQUAL(merkle_get_parent(10), 4);
TEST_EQUAL(merkle_get_parent(11), 5);
TEST_EQUAL(merkle_get_parent(12), 5);
TEST_EQUAL(merkle_get_parent(13), 6);
TEST_EQUAL(merkle_get_parent(14), 6);
// siblings
TEST_EQUAL(merkle_get_sibling(1), 2);
TEST_EQUAL(merkle_get_sibling(2), 1);
TEST_EQUAL(merkle_get_sibling(3), 4);
TEST_EQUAL(merkle_get_sibling(4), 3);
TEST_EQUAL(merkle_get_sibling(5), 6);
TEST_EQUAL(merkle_get_sibling(6), 5);
TEST_EQUAL(merkle_get_sibling(7), 8);
TEST_EQUAL(merkle_get_sibling(8), 7);
TEST_EQUAL(merkle_get_sibling(9), 10);
TEST_EQUAL(merkle_get_sibling(10), 9);
TEST_EQUAL(merkle_get_sibling(11), 12);
TEST_EQUAL(merkle_get_sibling(12), 11);
TEST_EQUAL(merkle_get_sibling(13), 14);
TEST_EQUAL(merkle_get_sibling(14), 13);
// total number of nodes given the number of leafs
TEST_EQUAL(merkle_num_nodes(1), 1);
TEST_EQUAL(merkle_num_nodes(2), 3);
TEST_EQUAL(merkle_num_nodes(4), 7);
TEST_EQUAL(merkle_num_nodes(8), 15);
TEST_EQUAL(merkle_num_nodes(16), 31);
return 0;
}