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.
751"""Test behavior of update, lookup, extends, and diff."""752#pylint: disable=too-many-locals,too-many-nested-blocks753# Iterate over the number of leaves the random test ASMap objects have.754for leaves in range(1, 20):755# Iterate over the number of bits in the AS numbers used.756for asnbits in range(0, 10):757# Iterate over the probability that leaves are unassigned.758for pct in range(0, 101):759# Construct a random ASMap object according to the above parameters.760asmap = ASMap.from_random(num_leaves=leaves, max_asn=1 + (1 << asnbits),761unassigned_prob=0.01 * pct)762# Make a copy of that asmap object to which patches will be applied.763# It starts off being equal to asmap.764patched = copy.copy(asmap)765# Keep a list of patches performed.766patches: list[ASNEntry] = []767# Initially there cannot be any difference.768self.assertEqual(asmap.diff(patched), [])769# Make 5 patches, each building on top of the previous ones.770for _ in range(0, 5):771# Construct a random path and new ASN to assign it to, apply it to patched,772# and remember it in patches.773pathlen = random.randrange(5)774path = [random.getrandbits(1) != 0 for _ in range(pathlen)]775newasn = random.randrange(1 + (1 << asnbits))776patched.update(path, newasn)777patches = [(path, newasn)] + patches779# Compute the diff, and whether asmap extends patched, and the other way780# around.781diff = asmap.diff(patched)782self.assertEqual(asmap == patched, len(diff) == 0)783extends = asmap.extends(patched)784back_extends = patched.extends(asmap)785# Determine whether those extends results are consistent with the diff786# result.787self.assertEqual(extends, all(d[2] == 0 for d in diff))788self.assertEqual(back_extends, all(d[1] == 0 for d in diff))789# For every diff found:790for path, old_asn, new_asn in diff:791# Verify asmap and patched actually differ there.792self.assertTrue(old_asn != new_asn)793self.assertEqual(asmap.lookup(path), old_asn)794self.assertEqual(patched.lookup(path), new_asn)795for _ in range(2):796# Extend the path far enough that it's smaller than any mapped797# range, and check the lookup holds there too.798spec_path = list(path)799while len(spec_path) < 32:800spec_path.append(random.getrandbits(1) != 0)801self.assertEqual(asmap.lookup(spec_path), old_asn)802self.assertEqual(patched.lookup(spec_path), new_asn)803# Search through the list of performed patches to find the last one804# applying to the extended path (note that patches is in reverse805# order, so the first match should work).806found = False807for patch_path, patch_asn in patches:808if spec_path[:len(patch_path)] == patch_path:809# When found, it must match whatever the result was patched810# to.811self.assertEqual(new_asn, patch_asn)812found = True813break814# And such a patch must exist.815self.assertTrue(found)817if __name__ == '__main__':818unittest.main()
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.