Inside Bitcoin
Opening the selected file…
Inside Bitcoin
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#ifndef _MINISKETCH_H_2#define _MINISKETCH_H_ 14#include <stdint.h>5#include <stdlib.h>7#ifdef _MSC_VER8# include <BaseTsd.h>9typedef SSIZE_T ssize_t;10#else11# include <unistd.h>12#endif14#ifndef MINISKETCH_API15# if defined(_WIN32)16# ifdef MINISKETCH_BUILD17# define MINISKETCH_API __declspec(dllexport)18# else19# define MINISKETCH_API20# endif21# elif defined(__GNUC__) && (__GNUC__ >= 4) && defined(MINISKETCH_BUILD)22# define MINISKETCH_API __attribute__ ((visibility ("default")))23# else24# define MINISKETCH_API25# endif26#endif28#ifdef __cplusplus29# if __cplusplus >= 201103L30# include <memory>31# include <vector>32# include <cassert>33# if __cplusplus >= 201703L34# include <optional>35# endif // __cplusplus >= 201703L36# endif // __cplusplus >= 201103L37extern "C" {38#endif // __cplusplus40/** Opaque type for decoded sketches. */41typedef struct minisketch minisketch;43/** Determine whether support for elements of `bits` bits was compiled in. */44MINISKETCH_API int minisketch_bits_supported(uint32_t bits);46/** Determine the maximum number of implementations available.47*48* Multiple implementations may be available for a given element size, with49* different performance characteristics on different hardware.50*51* Each implementation is identified by a number from 0 to the output of this52* function call, inclusive. Note that not every combination of implementation53* and element size may exist (see further).54*/55MINISKETCH_API uint32_t minisketch_implementation_max(void);57/** Determine if the a combination of bits and implementation number is available.58*59* Returns 1 if it is, 0 otherwise.60*/61MINISKETCH_API int minisketch_implementation_supported(uint32_t bits, uint32_t implementation);63/** Construct a sketch for a given element size, implementation and capacity.64*65* If the combination of `bits` and `implementation` is unavailable, or when66* OOM occurs, NULL is returned. If minisketch_implementation_supported67* returns 1 for the specified bits and implementation, this will always succeed68* (except when allocation fails).69*70* If the result is not NULL, it must be destroyed using minisketch_destroy.71*/72MINISKETCH_API minisketch* minisketch_create(uint32_t bits, uint32_t implementation, size_t capacity);74/** Get the element size of a sketch in bits. */75MINISKETCH_API uint32_t minisketch_bits(const minisketch* sketch);77/** Get the capacity of a sketch. */78MINISKETCH_API size_t minisketch_capacity(const minisketch* sketch);80/** Get the implementation of a sketch. */81MINISKETCH_API uint32_t minisketch_implementation(const minisketch* sketch);83/** Set the seed for randomizing algorithm choices to a fixed value.84*85* By default, sketches are initialized with a random seed. This is important86* to avoid scenarios where an attacker could force worst-case behavior.87*88* This function initializes the seed to a user-provided value (any 64-bit89* integer is acceptable, regardless of field size).90*91* When seed is -1, a fixed internal value with predictable behavior is92* used. It is only intended for testing.93*/94MINISKETCH_API void minisketch_set_seed(minisketch* sketch, uint64_t seed);96/** Clone a sketch.97*98* The result must be destroyed using minisketch_destroy.99*/100MINISKETCH_API minisketch* minisketch_clone(const minisketch* sketch);102/** Destroy a sketch.103*104* The pointer that was passed in may not be used anymore afterwards.105*/106MINISKETCH_API void minisketch_destroy(minisketch* sketch);108/** Compute the size in bytes for serializing a given sketch. */109MINISKETCH_API size_t minisketch_serialized_size(const minisketch* sketch);111/** Serialize a sketch to bytes. */112MINISKETCH_API void minisketch_serialize(const minisketch* sketch, unsigned char* output);114/** Deserialize a sketch from bytes. */115MINISKETCH_API void minisketch_deserialize(minisketch* sketch, const unsigned char* input);117/** Add an element to a sketch.118*119* If the element to be added is too large for the sketch, the most significant120* bits of the element are dropped. More precisely, if the element size of121* `sketch` is b bits, then this function adds the unsigned integer represented122* by the b least significant bits of `element` to `sketch`.123*124* If the element to be added is 0 (after potentially dropping the most significant125* bits), then this function is a no-op. Sketches cannot contain an element with126* the value 0.127*128* Note that adding the same element a second time removes it again.129*/130MINISKETCH_API void minisketch_add_uint64(minisketch* sketch, uint64_t element);132/** Merge the elements of another sketch into this sketch.133*134* After merging, `sketch` will contain every element that existed in one but not135* both of the input sketches. It can be seen as an exclusive or operation on136* the set elements. If the capacity of `other_sketch` is lower than `sketch`'s,137* merging reduces the capacity of `sketch` to that of `other_sketch`.138*139* This function returns the capacity of `sketch` after merging has been performed140* (where this capacity is at least 1), or 0 to indicate that merging has failed because141* the two input sketches differ in their element size or implementation. If 0 is142* returned, `sketch` (and its capacity) have not been modified.143*144* It is also possible to perform this operation directly on the serializations145* of two sketches with the same element size and capacity by performing a bitwise XOR146* of the serializations.147*/148MINISKETCH_API size_t minisketch_merge(minisketch* sketch, const minisketch* other_sketch);150/** Decode a sketch.151*152* `output` is a pointer to an array of `max_element` uint64_t's, which will be153* filled with the elements in this sketch.154*155* The return value is the number of decoded elements, or -1 if decoding failed.156*/157MINISKETCH_API ssize_t minisketch_decode(const minisketch* sketch, size_t max_elements, uint64_t* output);159/** Compute the capacity needed to achieve a certain rate of false positives.160*161* A sketch with capacity c and no more than c elements can always be decoded162* correctly. However, if it has more than c elements, or contains just random163* bytes, it is possible that it will still decode, but the result will be164* nonsense. This can be counteracted by increasing the capacity slightly.165*166* Given a field size bits, an intended number of elements that can be decoded167* max_elements, and a false positive probability of 1 in 2**fpbits, this168* function computes the necessary capacity. It is only guaranteed to be169* accurate up to fpbits=256.170*/171MINISKETCH_API size_t minisketch_compute_capacity(uint32_t bits, size_t max_elements, uint32_t fpbits);173/** Compute what max_elements can be decoded for a certain rate of false positives.174*175* This is the inverse operation of minisketch_compute_capacity. It determines,176* given a field size bits, a capacity of a sketch, and an acceptable false177* positive probability of 1 in 2**fpbits, what the maximum allowed178* max_elements value is. If no value of max_elements would give the desired179* false positive probability, 0 is returned.180*181* Note that this is not an exact inverse of minisketch_compute_capacity. For182* example, with bits=32, fpbits=16, and max_elements=8,183* minisketch_compute_capacity will return 9, as capacity 8 would only have a184* false positive chance of 1 in 2^15.3. Increasing the capacity to 9 however185* decreases the fp chance to 1 in 2^47.3, enough for max_elements=9 (with fp186* chance of 1 in 2^18.5). Therefore, minisketch_compute_max_elements with187* capacity=9 will return 9.188*/189MINISKETCH_API size_t minisketch_compute_max_elements(uint32_t bits, size_t capacity, uint32_t fpbits);191#ifdef __cplusplus192}194#if __cplusplus >= 201103L195/** Simple RAII C++11 wrapper around the minisketch API. */196class Minisketch197{198struct Deleter199{200void operator()(minisketch* ptr) const201{202minisketch_destroy(ptr);203}204};206std::unique_ptr<minisketch, Deleter> m_minisketch;208public:209/** Check whether the library supports fields of the given size. */210static bool BitsSupported(uint32_t bits) noexcept { return minisketch_bits_supported(bits); }212/** Get the highest supported implementation number. */213static uint32_t MaxImplementation() noexcept { return minisketch_implementation_max(); }215/** Check whether the library supports fields with a given size and implementation number.216* If a particular field size `bits` is supported, implementation 0 is always supported for it.217* Higher implementation numbers may or may not be available as well, up to MaxImplementation().218*/219static bool ImplementationSupported(uint32_t bits, uint32_t implementation) noexcept { return minisketch_implementation_supported(bits, implementation); }221/** Given field size and a maximum number of decodable elements n, compute what capacity c to222* use so that sketches with more elements than n have a chance no higher than 2^-fpbits of223* being decoded incorrectly (and will instead fail when decoding for up to n elements).224*225* See minisketch_compute_capacity for more details. */226static size_t ComputeCapacity(uint32_t bits, size_t max_elements, uint32_t fpbits) noexcept { return minisketch_compute_capacity(bits, max_elements, fpbits); }228/** Reverse operation of ComputeCapacity. See minisketch_compute_max_elements. */229static size_t ComputeMaxElements(uint32_t bits, size_t capacity, uint32_t fpbits) noexcept { return minisketch_compute_max_elements(bits, capacity, fpbits); }231/** Construct a clone of the specified sketch. */232Minisketch(const Minisketch& sketch) noexcept233{234if (sketch.m_minisketch) {235m_minisketch = std::unique_ptr<minisketch, Deleter>(minisketch_clone(sketch.m_minisketch.get()));236}237}239/** Make this Minisketch a clone of the specified one. */240Minisketch& operator=(const Minisketch& sketch) noexcept241{242if (this != &sketch && sketch.m_minisketch) {243m_minisketch = std::unique_ptr<minisketch, Deleter>(minisketch_clone(sketch.m_minisketch.get()));244}245return *this;246}248/** Check whether this Minisketch object is valid. */249explicit operator bool() const noexcept { return bool{m_minisketch}; }
Independent explanations by MyBitcoinExplorer. Not affiliated with or endorsed by Bitcoin Core. Guides are educational and do not replace the source or its tests.
Bitcoin Core source © its contributors, distributed under the MIT license. Original notices and bundled third-party licenses are retained in the source tree.