22 std::vector<FeeFrac> diagram;
23 diagram.reserve(chunks.
size() + 1);
25 diagram.emplace_back(0, 0);
26 for (
auto& chunk : chunks) {
27 diagram.emplace_back(diagram.back() + chunk);
40 unsigned not_above = 0;
41 unsigned not_below = diagram.
size() - 1;
43 if (size < diagram[not_above].size)
return {diagram[not_above].fee, 1};
44 if (size > diagram[not_below].size)
return {diagram[not_below].fee, 1};
46 while (not_below > not_above + 1) {
47 unsigned mid = (not_below + not_above) / 2;
48 if (diagram[mid].size <= size) not_above = mid;
49 if (diagram[mid].size >= size) not_below = mid;
52 if (not_below == not_above)
return {diagram[not_below].fee, 1};
54 auto dir_coef = diagram[not_below] - diagram[not_above];
57 const auto& point_a = diagram[not_above];
62 assert(size >= point_a.size);
63 return {point_a.fee * dir_coef.size + dir_coef.fee * (size - point_a.size), dir_coef.size};
68 return FeeRateCompare(
FeeFrac{ff.
fee, 1}, EvaluateDiagram(ff.
size, diagram));
75 for (
const auto p1 : dia1) {
76 auto cmp = CompareFeeFracWithDiagram(p1, dia2);
77 if (std::is_lt(cmp)) all_ge =
false;
78 if (std::is_gt(cmp)) all_le =
false;
80 for (
const auto p2 : dia2) {
81 auto cmp = CompareFeeFracWithDiagram(p2, dia1);
82 if (std::is_lt(cmp)) all_le =
false;
83 if (std::is_gt(cmp)) all_ge =
false;
85 if (all_ge && all_le)
return std::partial_ordering::equivalent;
86 if (all_ge && !all_le)
return std::partial_ordering::greater;
87 if (!all_ge && all_le)
return std::partial_ordering::less;
88 return std::partial_ordering::unordered;
91void PopulateChunks(
FuzzedDataProvider& fuzzed_data_provider, std::vector<FeeFrac>& chunks)
108 std::vector<FeeFrac> chunks1, chunks2;
111 PopulateChunks(fuzzed_data_provider, chunks1);
112 PopulateChunks(fuzzed_data_provider, chunks2);
114 std::vector<FeeFrac> diagram1{BuildDiagramFromChunks(chunks1)};
115 std::vector<FeeFrac> diagram2{BuildDiagramFromChunks(chunks2)};
117 assert(diagram1.front() == empty);
118 assert(diagram2.front() == empty);
121 auto sim = CompareDiagrams(diagram1, diagram2);
127 auto eval1 = EvaluateDiagram(size, diagram1);
128 auto eval2 = EvaluateDiagram(size, diagram2);
129 auto cmp = FeeRateCompare(eval1, eval2);
130 if (std::is_lt(cmp))
assert(!std::is_gt(real));
131 if (std::is_gt(cmp))
assert(!std::is_lt(real));
T ConsumeIntegralInRange(T min, T max)
A Span is an object that can refer to a contiguous sequence of objects.
constexpr std::size_t size() const noexcept
FUZZ_TARGET(build_and_compare_feerate_diagram)
#define LIMITED_WHILE(condition, limit)
Can be used to limit a theoretically unbounded loop.
Data structure storing a fee and size, ordered by increasing fee/size.
std::partial_ordering CompareChunks(Span< const FeeFrac > chunks0, Span< const FeeFrac > chunks1)
Compare the feerate diagrams implied by the provided sorted chunks data.