Please check the build logs for more information.
See Builds for ideas on how to fix a failed build, or Metadata for how to configure docs.rs builds.
If you believe this is docs.rs' fault, open an issue.
bitcoin-asmap
High‑fidelity Rust implementation of Bitcoin Core's ASMAP interpreter, decoder, and structural validator.
This crate provides a bit‑exact reimplementation of the Autonomous System (AS) mapping logic used by Bitcoin Core to probabilistically infer the AS number (ASN) associated with a peer's IP address. It is designed for:
- Node operators and infrastructure providers who need deterministic ASMAP behavior in Rust services.
- Researchers performing network topology or AS‑level analysis of the Bitcoin network.
- Library authors integrating Bitcoin‑style AS‑based peer selection or routing policies into Rust applications.
Conceptual overview
ASMAP and ASN inference
An ASMAP file encodes a decision tree over IP address bits that maps each address to an Autonomous System Number (ASN). In Bitcoin Core, this mapping is used to diversify peer selection by AS to reduce the risk that many peers are controlled by the same routing domain.
Key ideas:
- The ASMAP is a compact, prefix‑based program over bits of an IP address.
- An IP address is represented as a boolean slice
[bool; 128](for IPv6) or appropriately padded for IPv4‑in‑IPv6. - The ASMAP is represented as a boolean program
asmap: &[bool]which is interpreted to yield a final ASN.
This crate mirrors the C++ reference implementation used by Bitcoin Core, including its variable‑length integer coding, instruction set, and comprehensive structural sanity checks.
Core data model
Instruction set
``
The instruction stream is encoded as bits and decoded via `decode_type`, which internally uses `decode_bits` and a compact opcode encoding.
- **RETURN**: Decode and return an ASN; terminates the program if structurally valid.
- **JUMP**: Conditionally jump forward in the instruction stream based on the next IP bit.
- **MATCH**: Match a short bit pattern against the next IP bits; either continue or fall back to the current default ASN.
- **DEFAULT**: Update the current default ASN used when a `MATCH` fails.
These instructions, combined with a stack of jump targets, implement a structured decision tree with compact representation.
---
## Public API
### Reading and validating an ASMAP file
```rust
use decode_asmap;
let asmap_bits = decode_asmap;
if asmap_bits.is_empty
decode_asmap<P: AsRef<Path>>(path: P) -> Vec<bool>:
- Reads the raw ASMAP file from disk (little‑endian, LSB‑first, identical to C++).
- Converts bytes into a
Vec<bool>bit stream (bit 0 is the LSB of each byte). - Runs a full structural sanity check via
sanity_check_as_map. - Returns the validated bit vector, or an empty vector on failure.
This is the entry point you usually want when consuming an ASMAP file shipped with Bitcoin Core or derived tools.
Interpreting an ASMAP for a given IP
use ;
let asmap = decode_asmap;
if asmap.is_empty
// Example: represent an IPv4 address as 128 bits (IPv4‑mapped)
let ip_bits = ipv4_to_bits;
let asn = interpret;
if asn == 0
interpret(asmap: &[bool], ip: &[bool]) -> u32:
- Executes the ASMAP program over
ip's bits. - Returns the mapped ASN on success.
- Returns
0on structural failure (e.g., invalid jumps, truncated encodings), even ifsanity_check_as_mapshould normally prevent such cases in production.
Important: This crate expects the same IP bit ordering and normalization that Bitcoin Core uses. If you want behavior identical to Core, ensure you pass in
ipbits constructed according to its reference logic (e.g., IPv4 mapped into IPv6).
Structural sanity checking
use ;
let asmap = decode_asmap;
if asmap.is_empty
let ok = sanity_check_as_map;
assert!;
sanity_check_as_map(asmap: &[bool], bits: i32) -> bool:
- Performs exhaustive structural validation of the ASMAP program.
- Mirrors Bitcoin Core's rules:
- No jumps into the middle of another instruction.
- No intersecting jumps.
- No consuming IP bits past the declared input width.
- No consecutive
DEFAULTs. - No
RETURNimmediately afterDEFAULT. - No unmatched trailing code after
RETURN. - Correct use of padding and zero padding bits.
- Constraints on sequences of short
MATCHinstructions.
- Returns
trueiff the structure is valid.
This is useful if you:
- Load ASMAPs from untrusted sources.
- Mutate or generate ASMAPs programmatically.
- Want defensive validation independent of
decode_asmap.
Bit‑level primitives
These are low‑level helpers that directly mirror the C++ implementation and are usually not needed by typical users but are valuable for experimentation or custom tooling.
decodeasn
Decodes an ASN value from asmap starting at *pos using a variable‑length integer scheme defined by ASN_BIT_SIZES.
posis updated in‑place.- Returns the ASN, or an
INVALIDsentinel value (internal constant) on failure.
decode_jump
Decodes a jump offset using JUMP_BIT_SIZES. The returned value is a forward offset from the current pos.
decode_match
Decodes a match pattern plus a sentinel bit using MATCH_BIT_SIZES. The number of data bits in the pattern is count_bits(m) - 1, where m is the decoded value.
decode_bits
This is the core variable‑length integer decoder, parameterized by:
minval: base value added to the final decoded integer.bit_sizes: an increasing sequence of mantissa widths.
The decoding logic is exponential‑Golomb‑like:
- For each
bitsizeexcept the last, it reads an exponent bit. - If the exponent bit is
1, it incrementsvalby1 << bitsizeand continues to the nextbitsize. - If the exponent bit is
0, it consumesbitsizemantissa bits intovaland returns. - For the last
bitsize, no exponent bit is read; instead, the path falls through if all previous exponent bits were1.
On early EOF, returns INVALID and leaves an error trace.
decode_type
Decodes an instruction opcode using TYPE_BIT_SIZES and returns the corresponding Instruction variant.
count_bits
Helper that wraps u32::count_ones for internal clarity.
Logging and diagnostics
The implementation uses structured logging macros such as trace!, debug!, info!, and error! (typically from the tracing crate). These log at every decision point:
- Early returns during decoding.
- Invalid opcodes or truncated integers.
- Sanity check violations including exact reason and offset.
To benefit from these diagnostics, configure a compatible subscriber in your application, for example:
use FmtSubscriber;
Error handling and invariants
decode_asmapreturns an emptyVec<bool>on any I/O error or failed sanity check. Empty means "do not use".interpretreturns0on structural failure;0is not a valid ASN by design.- Internally, decoding uses an
INVALIDsentinel (not exposed) to signal truncated encodings. sanity_check_as_mapshould be run on any externally provided ASMAP before usinginterpretin production.
If you require stronger typing (e.g., non‑zero ASN newtypes) or richer error types, you can wrap this crate in a thin adapter layer.
Performance considerations
- Bit representation uses
Vec<bool>, which is compact but may have non‑trivial overhead for heavy random access. This mirrors the reference C++ behavior but not necessarily the most optimal Rust representation. - The interpreter is single‑pass and operates in
O(|asmap| + |ip|)time. - Sanity checking is more expensive (
O(|asmap|)with additional structural invariants) and should be performed once per ASMAP file, not per lookup.
For workloads performing a large number of interpret calls against a static ASMAP, the typical pattern is:
- Load and validate the ASMAP once via
decode_asmap(or manually reading the file and usingsanity_check_as_map). - Reuse the resulting
Vec<bool>for all subsequent IP lookups.
Intended use cases
- Bitcoin node infrastructure: Implement AS‑aware peer selection or connection policies in Rust node software.
- Research and analysis: Offline analysis of Bitcoin network AS distribution using the same mapping logic as Bitcoin Core.
- Monitoring and policy engines: Integrate ASMAP‑based classification into monitoring agents or traffic policy components written in Rust.
Repository, license, and edition
- Crate name:
bitcoin-asmap - Version:
0.1.19 - Repository: https://github.com/klebs6/bitcoin-rs
- License: MIT
- Rust edition: 2021
Caveats and compatibility
- Behavior is designed to be bit‑for‑bit compatible with the original Bitcoin Core C++ implementation. Nevertheless, you should validate against known test vectors when integrating into a critical system.
- Ensure that the IP bit ordering and normalization (IPv4 vs IPv6) match Bitcoin Core if you seek identical outcomes.
- This crate does not fetch or update ASMAP data itself; you must supply a valid ASMAP file.