Let's take a closer look at how an MMR is structured. As we mentioned in another article, an MMR is a collection of balanced binary trees, but that collection has an important property - it is a sequence of trees ordered descending by their height. Notice that this inequality is strict, which implies that there are no two trees with the same height. (Height is the number of edges between the root node and leaves.)
Since every tree in an MMR is a balanced binary tree, it has leaves, where is the height of that tree. To calculate the number of all nodes, we have to notice that on every layer (set of nodes which have the same distance to the root) there are exactly nodes where is the layer's height. So when we sum the number of nodes in each layer we get .
Because the number of leaves in every tree is a power of and every tree size appears at most once in an MMR, we can represent the number of leaves as a sum of powers of :In that representation, is if and only if a tree of height is present in an MMR. Therefore, MMR size () can be calculated using the following formula:After some simplifications, we get:Notice that is just counting ones in the binary representation of number , so we can simplify even further:
Here are implementations in some languages
function count_ones(n: number) {
let sum = 0;
while (n) {
sum++;
n &= n - 1;
}
return sum;
}
function leaf_count_to_mmr_size(leaf_count: number) {
return 2 * leaf_count - count_ones(leaf_count);
}