Skip to content

Commit

Permalink
Merge pull request #1403 from evoskuil/master
Browse files Browse the repository at this point in the history
Add checkpoint::is_at and fix is_conflict, add tests.
  • Loading branch information
evoskuil committed Feb 20, 2024
2 parents 82d2daa + 883f0f3 commit de8da03
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 4 deletions.
2 changes: 1 addition & 1 deletion include/bitcoin/system/chain/checkpoint.hpp
Expand Up @@ -21,7 +21,6 @@

#include <iostream>
#include <memory>
#include <string>
#include <vector>
#include <bitcoin/system/data/data.hpp>
#include <bitcoin/system/define.hpp>
Expand All @@ -39,6 +38,7 @@ class BC_API checkpoint

DEFAULT_COPY_MOVE_DESTRUCT(checkpoint);

static bool is_at(const list& checkpoints, size_t height) NOEXCEPT;
static bool is_under(const list& checkpoints, size_t height) NOEXCEPT;
static bool is_conflict(const list& checkpoints, const hash_digest& hash,
size_t height) NOEXCEPT;
Expand Down
15 changes: 12 additions & 3 deletions src/chain/checkpoint.cpp
Expand Up @@ -20,7 +20,6 @@

#include <algorithm>
#include <iostream>
#include <string>
#include <utility>
#include <bitcoin/system/data/data.hpp>
#include <bitcoin/system/hash/hash.hpp>
Expand All @@ -32,9 +31,18 @@ namespace libbitcoin {
namespace system {
namespace chain {

bool checkpoint::is_at(const list& checkpoints, size_t height) NOEXCEPT
{
return std::any_of(checkpoints.begin(), checkpoints.end(),
[&](const auto& item) NOEXCEPT
{
return height == item.height();
});
}

bool checkpoint::is_under(const list& checkpoints, size_t height) NOEXCEPT
{
// False if empty, optimial if checkpoints sorted by increasing height.
// False if empty, optimal if checkpoints sorted by increasing height.
return std::any_of(checkpoints.rbegin(), checkpoints.rend(),
[&](const auto& item) NOEXCEPT
{
Expand All @@ -45,13 +53,14 @@ bool checkpoint::is_under(const list& checkpoints, size_t height) NOEXCEPT
bool checkpoint::is_conflict(const list& checkpoints, const hash_digest& hash,
size_t height) NOEXCEPT
{
// Conflict if height matches and hash does not.
const auto it = std::find_if(checkpoints.begin(), checkpoints.end(),
[&](const auto& item) NOEXCEPT
{
return height == item.height();
});

return it != checkpoints.end() && it->hash() == hash;
return it != checkpoints.end() && it->hash() != hash;
}

// Constructors.
Expand Down
73 changes: 73 additions & 0 deletions test/chain/checkpoint.cpp
Expand Up @@ -166,6 +166,79 @@ BOOST_AUTO_TEST_CASE(checkpoint__equality__different__expected)
BOOST_REQUIRE(!(instance1 == instance2));
}

BOOST_AUTO_TEST_CASE(checkpoint__is_at__empty__false)
{
const checkpoints points{};
BOOST_REQUIRE(!checkpoint::is_at(points, 0));
BOOST_REQUIRE(!checkpoint::is_at(points, 42));
}

BOOST_AUTO_TEST_CASE(checkpoint__is_at__non_empty__expected)
{
const checkpoints points
{
{ "0000000000000000000000000000000000000000000000000000000000000000", 17 },
{ "0102030405060708090a0102030405060708090a0102030405060708090a0b0c", 42 },
{ "1111111111111111111111111111111111111111111111111111111111111111", 1000 }
};

BOOST_REQUIRE(!checkpoint::is_at(points, 0));
BOOST_REQUIRE(!checkpoint::is_at(points, 1));
BOOST_REQUIRE(checkpoint::is_at(points, 17));
BOOST_REQUIRE(checkpoint::is_at(points, 42));
BOOST_REQUIRE(checkpoint::is_at(points, 1000));
BOOST_REQUIRE(!checkpoint::is_at(points, 1001));
}

BOOST_AUTO_TEST_CASE(checkpoint__is_under__empty__false)
{
const checkpoints points{};
BOOST_REQUIRE(!checkpoint::is_under(points, 0));
BOOST_REQUIRE(!checkpoint::is_under(points, 42));
}

BOOST_AUTO_TEST_CASE(checkpoint__is_under__non_empty__expected)
{
const checkpoints points
{
{ "0000000000000000000000000000000000000000000000000000000000000000", 17 },
{ "0102030405060708090a0102030405060708090a0102030405060708090a0b0c", 42 },
{ "1111111111111111111111111111111111111111111111111111111111111111", 1000 }
};

BOOST_REQUIRE(checkpoint::is_under(points, 0));
BOOST_REQUIRE(checkpoint::is_under(points, 1));
BOOST_REQUIRE(checkpoint::is_under(points, 17));
BOOST_REQUIRE(checkpoint::is_under(points, 42));
BOOST_REQUIRE(checkpoint::is_under(points, 1000));
BOOST_REQUIRE(!checkpoint::is_under(points, 1001));
}

BOOST_AUTO_TEST_CASE(checkpoint__is_conflict__empty__false)
{
const checkpoints points{};
const checkpoint point("0102030405060708090a0102030405060708090a0102030405060708090a0b0c", 42);
BOOST_REQUIRE(!checkpoint::is_conflict(points, point.hash(), 0));
BOOST_REQUIRE(!checkpoint::is_conflict(points, point.hash(), point.height()));
}

BOOST_AUTO_TEST_CASE(checkpoint__is_conflict__non_empty__expected)
{
const checkpoints points
{
{ "0000000000000000000000000000000000000000000000000000000000000000", 17 },
{ "0102030405060708090a0102030405060708090a0102030405060708090a0b0c", 42 },
{ "1111111111111111111111111111111111111111111111111111111111111111", 1000 }
};
const auto hash = base16_hash("0102030405060708090a0102030405060708090a0102030405060708090a0b0c");

BOOST_REQUIRE(!checkpoint::is_conflict(points, hash, 0));
BOOST_REQUIRE(checkpoint::is_conflict(points, hash, 17));
BOOST_REQUIRE(!checkpoint::is_conflict(points, hash, 42));
BOOST_REQUIRE(checkpoint::is_conflict(points, hash, 1000));
BOOST_REQUIRE(!checkpoint::is_conflict(points, hash, 1001));
}

// json
// ----------------------------------------------------------------------------

Expand Down

0 comments on commit de8da03

Please sign in to comment.