1
0
forked from cheng/wallet

cleaned up svg code

Realized that generalizing a Merkle-patricia tree to represent an arbitrary Merkle dag was just too messy.

Led to complicated data structures forming complicated trees navigated in complicated ways.

Treating each type of Merkle vertex as its own thing, and a Merkle-patricia vertex as a common and useful special case of a Merkle vetex leads to simpler data structures that more directly represent concepts.

learning how to do paths without inkscape

M point c point point point s point point s point point ...
If you have more than one c triplet, you will have kinks

Or m point, q point point t point t point ...

M point q point will often suffice.  You should never need many s or t values, and never have more than one c or q values.

cleaned up consensus, made a start on cleaning up blockdags
This commit is contained in:
reaction.la 2022-03-06 20:14:19 +10:00
parent 01d20a8260
commit ad5c97e7dc
No known key found for this signature in database
GPG Key ID: 99914792148C8388
2 changed files with 169 additions and 100 deletions

View File

@ -69,10 +69,10 @@ there is for a prong of a fork.
### Sampling the peers
So we have to sample the peers, or rather have each peer form the same
representative sample. And then we implement something similar to Paxos
and Raft within that small sample. And sometimes peers will disagree about
which sample, resulting in a fork, which has to be resolved.
So we have to sample the peers, or rather have each peer draw consensus
from the same representative sample. And then we implement something
similar to Paxos and Raft within that small sample. And sometimes peers
will disagree about which sample, resulting in a fork, which has to be resolved.
For each peer that could be on the network, including those that have been
sleeping in a cold wallet for years, each peer keeps a running cumulative
@ -105,13 +105,19 @@ there will be multiple next blocks, and entire sequences of blocks. In
which case each peer has to rank them and weight them and choose the
highest ranked and weighted block, or the highest weighted sequence of blocks.
A peer cannot tell the difference between network bisection and a whole lot
of peers being offline.
We have to keep producing a result when a whole lot of peers are offline,
rather than just stop working as Practical Byzantine Fault Resistant
Consensus and its raft equivalent does. Which means that in a long lasting
network bisection, there is going to be fork which will have to be resolved
when the network recovers.
[running average]:./running_average.html
"how to calculate the running average\
dogs"
"how to calculate the running average"
{target="_blank"}
The rank of a block is rank of the lowest rank peer of the group forming the block, or one plus the [running average] of previous blocks rounded up to the nearest integer, whichever is less.
The weight of a block is $m*2^R$, where $m$ is the size of the group
@ -157,6 +163,14 @@ one group fail, another group will succeed.
Correctly behaving peers will wait longer the lower their rank before attempting to participate in block formation, will wait longer before participating in an attempt to form a low weighted block, and will not attempt to form a new block if a block of which they already have a copy would be higher rank or weight. (Because they would abandon it immediately in favour of a block already formed.)
To ensure that forks and network bisections are resolved, the timeout before attempting to forming a new block increases exponentially with the difference between the proposed block and the running average, and inverse linearly with the running average.
High ranking peers try to form a new block first, and in the event of
network bisection, the smaller part of the bisection will on average have
fewer peers, therefore the highest ranking peers available will on average
be lower rank, so the smaller portion of the bisection will form new blocks
more slowly on average.
In the course of attempting to form a group, peers will find out what other high ranking peers are online, so, if the Hedera assumption (that everyone
always gets through eventually and that everyone knows who is online) is
true, or true enough, there will only be one block formed, and it will be
@ -189,14 +203,19 @@ one or both prongs of the fork?
Then we calculate the weight of the prong:
$$\displaystyle\sum\limits_{i}2^{R_i}$$
$$\displaystyle\sum\limits_{i}{\large 2^{R_i}}$$
Where $i$ is the peer, and R_i$ is the rank of the last block on that prong of
the fork that he has participated in forming.
Where $i$ is a peer that has formed blocks on that prong, and R_i$ is the
rank of the last block on that prong of the fork that he has participated in forming.
If two prongs have the same weight, hash all the public keys of the signatories, their ranks, and the block height of the root of the fork and take the prong with the largest hash.
Which, in the event of a fork, will on average reflect the total stake of
peers on that fork.
This value, the weight of a prong of the fork, will over time for large deep
If two prongs have the same weight, take the prong with the most transactions. If they have the same weight and the same number of transactions, hash all the public keys of the signatories that formed the
blocks, their ranks, and the block height of the root of the fork and take
the prong with the largest hash.
This value, the weight of a prong of the fork will, over time for large deep
forks, approximate the stake of the peers online on that prong, without the
painful cost taking a poll of all peers online, and without the considerable
risk that that poll will be jammed by hostile parties.

View File

@ -856,100 +856,150 @@ solve the problem of the number of items not being a power of two?
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="29em" height="17em"
viewBox="0 209 360 102"
viewBox="0 202 230 102"
style="background-color:ivory" stroke-width=".6" stroke-linecap="round" >
<g font-family="'Times New Roman'" font-size="6" font-weight="400" fill-rule="evenodd" fill="black" >
<g id="height_3_tree" fill="none" >
<path stroke="#b00000"
d="
M71.36 234.686s2.145-.873 3.102 0c1.426 1.303 14.645 21.829 16.933 23.136 1.302.745 4.496.45 5-2.3
M145.916 220c0-.93.124-.992.992-1.364.869-.373 2.42-.373 3.04.558.62.93-2.852-4.94 18.607 38.394.715 1.443 2.348 1.186 4-2
M147.218 218.5c1.303-.124 1.675.062 2.11.93.434.868.558 3.846.558 3.846-.25 2.496.31 3.597-1.365 19.166-1.675 15.568-1.54 21.825-.744 24.872.744 3.853 3.0 2.853 5.2 .295
M71.36 234.686c2.42-.434 2.916-.93 6.079-.186 3.163.745 4.466 1.551 12.715 5.52 8.25 3.97 37.774 3.66 41.31 2.606C134.999 241.57 136 240 137 239
M71.36 234.686s1.551-.558 2.171.186c.62.745 2.481 4.528 1.8 10.545-.683 6.016-2.854 20.719-2.854 22.577 0 2.171 1.116 2.482 2.543 1.8C76.447 269.11 76 268 77 264"/>
<path stroke="#80e080"
d="
M10 253c-3.536 5.335-4.29 7.765-4.466 12.095-.139 3.405.677 6 3.3 2.094
M18 245c1.799-1.55 20.903-7.319 35.603-10.855 14.7-3.535 18.918-7.69 52.35-8.621 33.432-.93 36.037-.869 38-3
M21 248c2.17-.372 6.744-1.343 10.792-1.736 5.858-.57 18.925-2.228 29-4.094 3.36-.728 7.673-1.492 7.618-2.812
M16.963 253.232c-.0 0 3 4 5.2 4.2 1.7 .7 4.093 .6 7-2.3"/>
<path stroke="#000000"
d="
M70.077 236c-.162-6.288 74.008-3.04 76-12
m-7.417 12c.161-6.127 9.306-6.425 8.5-12"/>
<g id="height_2_tree">
<path stroke="#b00000"
d="
M31.3 250.83c1.054-.372 2.046-.744 2.357.31.31 1.055-.571 11.044.682 15.569C36.013 272.766 38 269.675 39 266"/>
<path stroke="#000000"
d="
M29.767 252c1.774-4 38.858-5.904 39.18-12
M60 252c0-4.875 10.41-6.871 11.205-12"/>
<g id="height_1_tree">
<path
style="stroke:#B00000"
d="m 10,264.1 c 1,-2.2 3.2,-2 3.85,-0.4 C 15,267 20,273 21,266"
id="prev_leaf_link"/>
<path stroke="#000"
d="M10.09 264c0-4 18.868-.062 19.174-8.062M21.866 264c0-3.008 8.893-1.544 9.513-8"/>
<g id="leaf_vertex" >
<g style="stroke:#000000;">
<path
d="M 11.7,265 8,271
M 11.7,265 9.5,271
M 11.7,265 11,271"
id="path1024" />
</g>
<rect id="merkle_vertex" width="4" height="4" x="8" y="264" fill="#00f"/>
</g>
<use width="100%" height="100%" transform="translate(12)" xlink:href="#leaf_vertex"/>
<use width="100%" height="100%" transform="translate(20 -12)" xlink:href="#merkle_vertex"/>
</g>
<use width="100%" height="100%" transform="translate(30)" xlink:href="#height_1_tree"/>
<use width="100%" height="100%" transform="translate(60 -28)" xlink:href="#merkle_vertex"/>
</g>
<g width="100%" height="100%" >
<use transform="translate(68)" xlink:href="#height_2_tree"/>
<use transform="translate(136 -44)" xlink:href="#merkle_vertex"/>
<use transform="translate(144)" xlink:href="#height_1_tree"/>
</g>
</g>
<!--viewBox="-12 209 360 102" -->
<!--viewBox="130 209 180 50" -->
<g font-family="'Times New Roman'" font-size="10" font-weight="400" fill-rule="evenodd" fill="black" >
<path stroke="#80e080" fill="none"
d="
M10 253c-3.536 5.335-4.29 7.765-4.466 12.095-.139 3.405.677 6 3.3 2.094
M18 245c1.799-1.55 20.903-7.319 35.603-10.855 14.7-3.535 18.918-7.69 52.35-8.621 33.432-.93 36.037-.869 38-3
M21 248c2.17-.372 6.744-1.343 10.792-1.736 5.858-.57 18.925-2.228 29-4.094 3.36-.728 7.673-1.492 7.618-2.812
M16.963 253.232c-.0 0 3 4 5.2 4.2 1.7 .7 4.093 .6 7-2.3
"/>
<g id="blockchain_id" >
<ellipse cx="14" cy="249" fill="#80e080" rx="8" ry="5"/>
<text>
<tspan x="11.08" y="251.265">id</tspan>
<ellipse cx="14" cy="249" fill="#80e080" rx="8" ry="5"/>
<text fill="black">
<tspan x="11.08" y="251.265">id</tspan>
</text>
</g>
<rect width="168" height=".4" x="8" y="276" fill="#000"/>
<text y="278">
<tspan dy="8" x="6" >Immutable append only file as a Merkle chain</tspan>
</text>
<g id="balanced merkle tree" fill="none">
<g id="height_4_tree" >
<path stroke="#F00000"
d="
M146,220 q2,-3 4,-2 t26,14 t34,9 t2,-1
M147,218.5 q2,-2 2,4 t-1,22 t1,22 t4,0
M146,220 c0,-1 0,-1 1,-1 c1,0 3,0 3,1 s3,0 12,26 s 14,-1 14,9
"/>
<path stroke="#000000"
d="
M146, 220 c4,-20 151,2 151.5,-12
m-7,12 c0,-6 9,-6 8.5,-12"
/>
<g id="height_3_tree">
<path stroke="#F00000"
d="
M71,234.686 s2,-1 3,0 t10,15 t15,2
M71.36 234.686s1.551-.558 2.171.186c.62.745 2.481 4.528 1.8 10.545-.683 6.016-2.854 20.719-2.854 22.577 0 2.171 1.116 2.482 2.543 1.8C76.447 269.11 76 268 77 264
"/>
<path stroke="#000000"
d="
M70,236 c0,-6 74,-3 76,-12
m-7,12 c0,-6 9,-6 8,-12"
/>
<g id="height_2_tree">
<path stroke="#F00000"
d="
M31.3 250.83c1.054-.372 2.046-.744 2.357.31.31 1.055-.571 11.044.682 15.569C36.013 272.766 38 269.675 39 266"/>
<path stroke="#000000"
d="
m29.767 252c1.774-4 38.858-5.904 39.18-12
"/>
<path id="uplink_1-2" stroke="#000000"
d="
M60 252c0-4.875 10.41-6.871 11.205-12
"/>
<g id="height_1_tree">
<path
style="stroke:#F00000"
d="M10,264 q3,-4 6,2 t4.5,2"
id="prev_leaf_link"/>
<path stroke="#000"
d="M10.09,264 q2,-4 11,-4 t9,-5
M22,264 c0,-3 9,-1.5 9,-8"/>
<g id="leaf_vertex" >
<g style="stroke:#000000;">
<path id="path1024"
d="
M 11.7,265 8,271
M 11.7,265 9.5,271
M 11.7,265 11,271
">
</g>
<rect id="merkle_vertex" width="4" height="4" x="8" y="264" fill="#00F"/>
</g><!-- end id="leaf vertex" -->
<use width="100%" height="100%" transform="translate(12)" xlink:href="#leaf_vertex"/>
<use width="100%" height="100%" transform="translate(20 -12)" xlink:href="#merkle_vertex"/>
</g><!-- end id="height_1_tree" -->
<use width="100%" height="100%" transform="translate(30)" xlink:href="#height_1_tree"/>
<use width="100%" height="100%" transform="translate(60 -28)" xlink:href="#merkle_vertex"/>
</g><!-- end id="height_2_tree" -->
<g width="100%" height="100%" >
<use transform="translate(68)" xlink:href="#height_2_tree"/>
<use transform="translate(136 -44)" xlink:href="#merkle_vertex"/>
</g>
</g><!-- end id="height_3_tree" -->
<use transform="translate(144)" xlink:href="#height_3_tree"/>
<use transform="translate(288 -60)" xlink:href="#merkle_vertex"/>
</g><!-- end id="height_4_tree" -->
</g> <!-- end id="balanced merkle tree" -->
<text y="188">
<tspan dy="12" x="6" >Immutable append only file as a collection of</tspan>
<tspan dy="12" x="6" >balanced binary Merkle trees</tspan>
<tspan dy="12" x="6" >in postfix order</tspan>
</text>
<g id="merkle_chain">
<use transform="translate(0,50)" xlink:href="#blockchain_id"/>
<path
<path
style="fill:none;stroke:#80e080;"
d="m 18,297 c 4,-6 4,-6 5.6,3 C 25,305 28,304 28.5,300"/>
<g id="4_leaf_links">
<g id="2_leaf_links">
<g id="leaf_link">
<path
style="fill:none;stroke:#000000;"
d="m 29,299 c 4,-6 4,-6 5.6,3 C 35,305 38,304 38.5,300"/>
<use transform="translate(20,33)" xlink:href="#leaf_vertex"/>
</g>
<use transform="translate(10,0)" xlink:href="#leaf_link"/>
</g>
<use transform="translate(20,0)" xlink:href="#2_leaf_links"/>
</g>
<use transform="translate(40,0)" xlink:href="#4_leaf_links"/>
<use transform="translate(80,0)" xlink:href="#4_leaf_links"/>
<use transform="translate(140,33)" xlink:href="#leaf_vertex"/>
<text y="208">
<tspan dy="8" x="6" >Immutable append only file as a collection of</tspan>
<tspan dy="8" x="6" >balanced binary Merkle trees</tspan>
<tspan dy="8" x="6" >in postfix order</tspan>
</text>
</g>
</svg>
<g id="16_leaf_links">
<g id="8_leaf_links">
<g id="4_leaf_links">
<g id="2_leaf_links">
<g id="leaf_link">
<path
style="fill:none;stroke:#000000;"
d="m 29,299 c 4,-6 4,-6 5.6,3 C 35,305 38,304 38.5,300"/>
<use transform="translate(20,33)" xlink:href="#leaf_vertex"/>
</g><!-- end id="leaf link" -->
<use transform="translate(10,0)"
xlink:href="#leaf_link"
/>
</g> <!-- end id="2 leaf links" -->
<use transform="translate(20,0)"
xlink:href="#2_leaf_links"
/>
</g> <!-- end id="4 leaf links" -->
<use transform="translate(40,0)"
xlink:href="#4_leaf_links"
/>
</g> <!-- end id="8 leaf links" -->
<use transform="translate(80,0)"
xlink:href="#8_leaf_links"
/>
</g> <!-- end id="16 leaf links" -->
<use transform="translate(160,0)"
xlink:href="#16_leaf_links"
/>
</g> <!-- end id="merkle chain" -->
<rect width="210" height=".4" x="8" y="276" fill="#000"/>
<text y="280">
<tspan dy="8" x="6" >Immutable append only file as a Merkle chain</tspan>
</text>
</g>
</svg>
This is a Merkle binary dag, not a Merkle-patricia tree. I found that
generalizing Merkle patricia trees to handle the case of immutable append
only files led to more complicated data structures and more complicated
descriptions. It has a great deal in common with a Merkle-patricia tree, but
a Merkle vertex is its own type, even though it convenient for it to have
much in common with a Merkle patricia vertex. Putting it into the patricia
straightjacket generated a lot of mess. A Merkle patricia vertex is best
handled as a special case of a Merkle vertex, and a Merkle patricia tree as
special vertices within a Merkle dag.
The superstructure of balanced binary Merkle trees allows us to verify any
part of it with only $O(log)$ hashes, and thus to verify that one version of