Inside Bitcoin
Opening the selected file…
Opening the selected file…
The code behind the network, with room to understand it.
Release published 2026-10-28 · Snapshot fetched 2026-11-01. Latest stable release at fetch time; development branches and Git history are excluded. Only the selected code window and visible folders load here.
1// Copyright (c) The Bitcoin Core developers2// Distributed under the MIT software license, see the accompanying3// file COPYING or http://www.opensource.org/licenses/mit-license.php.5#include <util/feefrac.h>7#include <util/check.h>9#include <array>10#include <cstddef>12std::partial_ordering CompareChunks(std::span<const FeeFrac> chunks0, std::span<const FeeFrac> chunks1)13{14/** Array to allow indexed access to input diagrams. */15const std::array<std::span<const FeeFrac>, 2> chunk = {chunks0, chunks1};16/** How many elements we have processed in each input. */17size_t next_index[2] = {0, 0};18/** Accumulated fee/sizes in diagrams, up to next_index[i] - 1. */19FeeFrac accum[2];20/** Whether the corresponding input is strictly better than the other at least in one place. */21bool better_somewhere[2] = {false, false};22/** Get the first unprocessed point in diagram number dia. */23const auto next_point = [&](int dia) { return chunk[dia][next_index[dia]] + accum[dia]; };24/** Get the last processed point in diagram number dia. */25const auto prev_point = [&](int dia) { return accum[dia]; };26/** Move to the next point in diagram number dia. */27const auto advance = [&](int dia) { accum[dia] += chunk[dia][next_index[dia]++]; };29do {30bool done_0 = next_index[0] == chunk[0].size();31bool done_1 = next_index[1] == chunk[1].size();32if (done_0 && done_1) break;34// Determine which diagram has the first unprocessed point. If a single side is finished, use the35// other one. Only up to one can be done due to check above.36const int unproc_side = (done_0 || done_1) ? done_0 : next_point(0).size > next_point(1).size;38// Let `P` be the next point on diagram unproc_side, and `A` and `B` the previous and next points39// on the other diagram. We want to know if P lies above or below the line AB. To determine this, we40// compute the slopes of line AB and of line AP, and compare them. These slopes are fee per size,41// and can thus be expressed as FeeFracs.42const FeeFrac& point_p = next_point(unproc_side);43const FeeFrac& point_a = prev_point(!unproc_side);45const auto slope_ap = point_p - point_a;46Assume(slope_ap.size > 0);47auto cmp = std::strong_ordering::equivalent;48if (done_0 || done_1) {49// If a single side has no points left, act as if AB has slope tail_feerate(of 0).50Assume(!(done_0 && done_1));51cmp = ByRatio{slope_ap} <=> ByRatio{FeeFrac(0, 1)};52} else {53// If both sides have points left, compute B, and the slope of AB explicitly.54const FeeFrac& point_b = next_point(!unproc_side);55const auto slope_ab = point_b - point_a;56Assume(slope_ab.size >= slope_ap.size);57cmp = ByRatio{slope_ap} <=> ByRatio{slope_ab};59// If B and P have the same size, B can be marked as processed (in addition to P, see60// below), as we've already performed a comparison at this size.61if (point_b.size == point_p.size) advance(!unproc_side);62}63// If P lies above AB, unproc_side is better in P. If P lies below AB, then !unproc_side is64// better in P.65if (std::is_gt(cmp)) better_somewhere[unproc_side] = true;66if (std::is_lt(cmp)) better_somewhere[!unproc_side] = true;67advance(unproc_side);69// If both diagrams are better somewhere, they are incomparable.70if (better_somewhere[0] && better_somewhere[1]) return std::partial_ordering::unordered;71} while(true);73// Otherwise compare the better_somewhere values.74return better_somewhere[0] <=> better_somewhere[1];75}