forked from cheng/wallet
work in progress backed up
This commit is contained in:
parent
b75fbbc80a
commit
62065333e1
@ -1,5 +1,5 @@
|
||||
---
|
||||
lang: 'en-US'
|
||||
# notmine
|
||||
title: How could regulators successfully introduce Bitcoin censorship and other dystopias
|
||||
---
|
||||
[Original document](https://juraj.bednar.io/en/blog-en/2020/11/12/how-could-regulators-successfully-introduce-bitcoin-censorship-and-other-dystopias/) by [Juraj Bednar](https://juraj.bednar.io/en/juraj-bednar-2/)
|
||||
|
@ -91,11 +91,21 @@ his stake is very low, he gets to be high rank every now and then.
|
||||
A small group of the highest ranking peers get to decide on the next block,
|
||||
and the likelihood of being a high ranking peer depends on stake.
|
||||
|
||||
They produce the next block by unanimous agreement and joint signature.
|
||||
The group is small enough that this is likely to succeed, and if they do not,
|
||||
some other group will. The other group possibly being the first group with
|
||||
some members who had poor connectivity thrown out.
|
||||
|
||||
And then, if more than one such group produces a putative next block,
|
||||
possibly several small and unrepresentative groups of not very high rank
|
||||
then the consensus process that we will describe kicks in.
|
||||
|
||||
Each peer is going to use a consensus created by those few peers that are
|
||||
high ranking at this block height of the blockchain, and since there are few
|
||||
such peers, there will usually only be one such consensus.
|
||||
|
||||
Each peer gets to be rank $R+1$ half as often as he gets to be rank $N$, and he gets to be a rank higher than $R$ as often as he gets to be rank $N$.
|
||||
Each peer gets to be rank $R+1$ half as often as he gets to be rank $N$,
|
||||
and he gets to be a rank higher than $R$ as often as he gets to be rank $R$.
|
||||
|
||||
The algorithm for producing the next block ensures that if the Hedera assumptions are true, (that everyone of high rank knows what high ranking
|
||||
peers are online, and everyone always gets through) a single next block
|
||||
@ -110,7 +120,7 @@ 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
|
||||
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.
|
||||
|
||||
@ -206,7 +216,17 @@ Then we calculate the weight of the prong:
|
||||
$$\displaystyle\sum\limits_{i}{\large 2^{R_i}}$$
|
||||
|
||||
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.
|
||||
rank of the his signature with the highest sequence number on either prong.
|
||||
|
||||
If he has signed a block in one prong, and a block in the other prong, only
|
||||
the signature with highest sequence number counts. If two signatures have
|
||||
equal sequence number , or if the difference in sequence numbers is out of
|
||||
range, or if a signature has an out of order sequence number within a chain
|
||||
of blocks following the fork,neither signature counts. A correctly behaving
|
||||
peer should assign sequence numbers sequentially, but nothing enforces
|
||||
this, and the system needs to be able to produce a sensible result even if
|
||||
some peers maliciously or through failure do not generate sequential
|
||||
signature sequence numbers.
|
||||
|
||||
Which, in the event of a fork, will on average reflect the total stake of
|
||||
peers on that fork.
|
||||
|
@ -2,6 +2,66 @@
|
||||
title: Libraries
|
||||
---
|
||||
|
||||
# Wireguard, Tailwind, and identity
|
||||
|
||||
Wireguard is a secure vpn.
|
||||
|
||||
Tailwind is peer to peer built on Oauth2 and Wireguard. Lacks peering
|
||||
through NAT facilities, though this is probably not hard to fix or add. The
|
||||
Tailwind server just tells both peers to start pinging each other
|
||||
simultaneously, and tells each peer when the other peer has acked a
|
||||
meeting time. With most nats, the first ping to arrive after a ping has been
|
||||
sent will get through. Wireguard has a provision to keep on pinging.
|
||||
|
||||
If a peer has a stable IP and port accessible from the internet, it does not
|
||||
ping. The other guy has to ping. If he does not ping for a while, the
|
||||
connection may stop working. If the peer with the stable IP and port finds
|
||||
it cannot get through, discards the connection information, but if it never
|
||||
attempts to use that information, it may hang around for a very long time.
|
||||
|
||||
Oauth is a generic interface to identity protocols. Anyone can implement
|
||||
Oauth in any way.
|
||||
|
||||
The Zooko identity model is that each party has his own mapping between
|
||||
non unique Zooko human readable, typeable, and memorable names, and
|
||||
globally unique non human memorable, non human typeable, public keys.
|
||||
|
||||
We put on top of that a consensus mapping, which is mutable. The end
|
||||
user sees his local name for an identity, that identity's name for itself, and
|
||||
a recent consensus human readable human typeable name for that identity.
|
||||
|
||||
For major and important widely known identities these should all be the
|
||||
same, and the end user should see a single short human readable name. If
|
||||
the end user sees two or three different human readable names for a
|
||||
counterparty, there is likely to be an issue. If he sees three different
|
||||
human readable names, plus the public key, definitely an issue.
|
||||
|
||||
The end user's mapping from local petnames to global keys is locally unique, and mutable at the end user's discretion.
|
||||
|
||||
The consensus mapping is mutable by consensus.
|
||||
|
||||
For friends who are well known to himself, but not well known to others,
|
||||
the global consensus name may merely be a distraction, and he may turn it
|
||||
off. If someone is on his buddy list, people whitelisted the global
|
||||
consensus name is turned off, unless it is the same, in which case it is
|
||||
turned on, and if the consensus changes, the end user sees that change.
|
||||
|
||||
# Consensus
|
||||
|
||||
I have no end of smart ideas about how a blockchain should work, but no
|
||||
actual blockchain. Smart ideas are worth two cents a bale, but only if
|
||||
already baled. Need to port in someone else's blockchain code, with a
|
||||
bridge to their blockchain.
|
||||
|
||||
Then I can make a start on implementing my bright ideas as part of
|
||||
working code.
|
||||
|
||||
[Near]:https://near.org/papers/the-official-near-white-paper/#introduction
|
||||
{target="_blank"}
|
||||
|
||||
[Near] is actually implementing no end of things that I have been thinking
|
||||
about, so seems like a good fit.
|
||||
|
||||
# Git submodules
|
||||
|
||||
Libraries are best dealt with as [Git submodules].
|
||||
@ -331,6 +391,123 @@ certificate a CA certificate, in which case the connection looks to the
|
||||
server like any other, except for the cookie which enables it to send
|
||||
messages, typically a payment request, to the wallet.
|
||||
|
||||
# zk-snarks
|
||||
|
||||
[Aurora]:https://eprint.iacr.org/2018/828.pdf
|
||||
{target="_blank"}
|
||||
|
||||
Supposedly there is a language, R1CS, such that you can express a
|
||||
program that gives a true false answer, such that [Aurora] can execute
|
||||
the program and generate a prover and a verifier.
|
||||
|
||||
[starkware]:https://iacr.org/submit/files/slides/2021/rwc/rwc2021/1005/slides.pdf
|
||||
{target="_blank"}
|
||||
|
||||
According to [starkware], they have the fastest proving time, but their
|
||||
proofs are rather large, 138KiB, Groth16 Snarks have the most compact
|
||||
proofs.
|
||||
|
||||
Not actually seeing it as a useful library yet that I could actually use, but
|
||||
more like a proof of principle that someone could build such a library.
|
||||
|
||||
To be actually useful, a zk-snark system needs to be a compiler, that
|
||||
compiles a program written in what Starkware calls R1CS, and other
|
||||
people are calling script, and generates two programs, a prover and a\
|
||||
verifier.
|
||||
|
||||
The prover operates on two blobs, the public blob and private blob, and
|
||||
produces a boolean result, true or false, pass or fail, and a proof that it\
|
||||
did so.
|
||||
|
||||
The proof is approximately constant size, regardless of how much
|
||||
computation is required and regardless of how large the private blob was,
|
||||
but takes a very long time.
|
||||
|
||||
The verifier operates on the public blob and the proof, takes a short and
|
||||
approximately constant time to do so, regardless of how big the
|
||||
computation was, and regardless of how big the private data was and
|
||||
determines, with 2^(126) likelihood of error, what result the prover got.
|
||||
|
||||
But at present I get the impression that neither script nor R1CS have any
|
||||
real existence, though I have seen a script language that operates on a
|
||||
stack, and, though it has no variables, can dupe any item on the stack to
|
||||
the top of the stack. It seems to have only been ever used to generate one
|
||||
prover and one verifier, because actually creating the prover and verifier
|
||||
still required some coding by hand. Also lacked certain control structures.
|
||||
|
||||
At present, people seem to be writing the prover and the verifier by hand, a
|
||||
very difficult operation with a very high likelihood of bugs. The prover and
|
||||
the verifier do very simple tasks like proving the encoded inputs to a
|
||||
transaction are greater than or equal to the encoded outputs and that no
|
||||
numeric underflow or overflow occurred.
|
||||
|
||||
Another problem is that we would really like the public data to be the root
|
||||
hash of a merkle tree, and no one seems to have a script language that
|
||||
contains a useful hash function Stackware is built out of hash functions,
|
||||
but last time I looked, you could not call a hash function from R1CS.
|
||||
|
||||
We need a script language that can not merely add and subtract, but can also
|
||||
do hashes and elliptic point operations. zk-stark systems are built out of
|
||||
hashes and elliptic point operations, but it seems to be uphill trying to
|
||||
generate proofs that prove something about the results of hashes and
|
||||
elliptic point operations, making very difficult to produce a proof that a
|
||||
pile of proofs in the pre-image of a merkle tree have been verified. I
|
||||
suspect that a prover might take a very very long time to produce such a
|
||||
proof.
|
||||
|
||||
The proofs are succinct, in that you can prove something about a gigantic
|
||||
pile of data and the size of the proof and the time taken to verify scarcely
|
||||
grows - about 128 KiB, for the smallest that anyone would care about, to
|
||||
utterly gigantic proofs. But proof generation is not all that fast, and grows
|
||||
with the matter to be proven, so to be useful for utterly gigantic proofs,
|
||||
you would need to be able to distribute proof generation over an enormous
|
||||
multitude of untrusting shards. Which you can obviously do by proving a
|
||||
verification. Not sure how long it takes to produce a proof that a large
|
||||
number of proofs were verified.
|
||||
|
||||
What you want is to be able to prove that a final hash is the root of of an
|
||||
enormous merkle tree, some generalization of a merkle-patricia tree,
|
||||
representing an immutable append only data structure consisting of a
|
||||
sequence of piles of transactions, and the state generated by these
|
||||
transactions, represents a valid branch of a chain of signatures, that the
|
||||
final state is correctly derived by applying the batch of transactions to
|
||||
the previous state.
|
||||
|
||||
And then you want to do this for states so enormous, and piles of
|
||||
transactions so enormous, that no one person has all of them.
|
||||
|
||||
And then you still have the problem of resolving forks.
|
||||
|
||||
You would like to have a blockchain of blockchains of blockchains, such
|
||||
that your state, and your transactions, are divided into a product of
|
||||
substates, with consensus on each substate advancing a bit ahead of the
|
||||
consensus on the combination of several substates, so that transactions
|
||||
within a substate finalize fast, but transactions between substates take
|
||||
longer. (because the number of forks of the product state is the product of
|
||||
the number of forks of each substate)
|
||||
|
||||
Each of the substates very quickly comes up with a proof that a transaction
|
||||
within a substate is valid and quickly comes up with consensus as to
|
||||
which fork everyone is on, but the proof for a transaction between
|
||||
substates is finalized quickly in the paying substate, and quickly affects
|
||||
the paying substate, but the transaction does not get included in the state
|
||||
that is a product of the receiving and paying substate for a while, does not
|
||||
get proven valid in the product substate for a while, and does not get
|
||||
included in the receiving substate till a bit after than it is included in the
|
||||
product substate, whereupon it is in due course quickly proven to be
|
||||
a valid addition of value to the receiving substate. So that the consensus
|
||||
problem remains manageable, we need insulation and delay between the
|
||||
states, so that the product state has its own pile of state, representing the
|
||||
delay between a transaction affecting a the payer factor state, and the
|
||||
transaction affecting the payee factor state. A transaction has no immediate
|
||||
affect. The payer mutable substate changes in a way reflecting the
|
||||
transaction block at the next block boundary. And that change then has
|
||||
effect on product mutable state at a subsequent product state block boundary, changing the stake possessed by the substate.
|
||||
|
||||
Which then has effect on the payee mutable substate at its next
|
||||
block boundary when the payee substate links back to the previous
|
||||
product state.
|
||||
|
||||
# Safe maths
|
||||
|
||||
[Safeint]:https://github.com/dcleblanc/SafeInt
|
||||
|
@ -12,6 +12,33 @@ numbers.
|
||||
|
||||
Secondly, to represent integers within a patricia merkle tree representing a database index, we want all values to be left field aligned, rather than right field aligned.
|
||||
|
||||
## Merkle patricia dag
|
||||
|
||||
We intend to have a vast Merkle dag, and a vast collection of immutable
|
||||
append only data structures. Each new block in the append only data
|
||||
structure is represented by a hash, whose preimage is a Merkle vertex. A
|
||||
path through the Merkle dag is represented by sequence of integers, which
|
||||
are zero terminated if the path is intended to end at that preimage. The
|
||||
same path in different versions should lead to an object that is in some
|
||||
sense equivalent to the entity that that path led to in a previous version of
|
||||
that merkle vertex. Equivalence and relationship of objects between
|
||||
different merkle vertices in the same immutable append only sequence is
|
||||
represented by constant paths leading to different objects.
|
||||
|
||||
If the sequence corresponds to valid unicode characters that are non control, non whitespace, and not #, @, (), or {}, it is so represented to the user. If one of the integers in the sequence is not, then the user will generally see a # followed by a sequence of base 58 characters representing a sequence of integers, until there is an integer corresponding to a non control, non whitespace, non numeric, non ascii alpha, and not #, @, (), or {}, at which point the human representation switches back to unicode.
|
||||
|
||||
If an ascii blank, character 32, occurs within a sequence being represented
|
||||
to the human as unicode, it is displayed as a blank and all subsequent
|
||||
values are displayed as dot separated decimal numbers, the displayed
|
||||
decimal number being the underlying number minus one. If the underlying
|
||||
value is zero, this terminates the sequence and is therefore never displayed.
|
||||
|
||||
A space introduces a sequence of version numbers intended to be
|
||||
intelligible to both humans and computers as a version number. The
|
||||
intended usage is package authentication and source control - the package
|
||||
manager will know this is an updated package, rather than an unrelated
|
||||
package.
|
||||
|
||||
## Compression algorithm preserving sort order
|
||||
|
||||
We want to represent integers by byte strings whose lexicographic order reflects their order as integers, which is to say, when sorted as a left aligned field, sort like integers represented as a right aligned field. (Because a Merkle patricia tree has a hard time with right aligned fields)
|
||||
@ -40,7 +67,35 @@ Similarly the bits 111 0111 indicate a fifteen byte value representing 113 bit i
|
||||
|
||||
To represent signed integers so that signed integers sort correctly with each other (but not with unsigned integers) the leading bit indicates the sign, a one bit for positive signed integers, and a zero bit for negative integers, and the if the signed integer is negative, we invert the bits of the byte count. Thus signed integers in the range $-2^6\le n \lt 2^6$ are represented by the corresponding eight bit value with its leading bit inverted.
|
||||
|
||||
This is perhaps a little too much cleverness except for the uncommon case where we actually need a representation that sorts correctly.
|
||||
This is perhaps a little too much cleverness except for the uncommon case
|
||||
where we actually need a representation of signed integers that sorts
|
||||
correctly.
|
||||
|
||||
## base 58 representation of a sequence of unsigned integers
|
||||
|
||||
Values $n$ in the range $0\le n \lt 58/2$ are represented by a single base 58 character.
|
||||
|
||||
Values $n$ in the range $58/2\le n \lt \lfloor 58*2^{-2}\rfloor*58 +58/2$ are represented by two base 58 characters starting with a base 58 character $c$ in the range $58/2\le c\lt 58/2+\lfloor 58*2^{-2}\rfloor$
|
||||
|
||||
Values $n$ in the range:
|
||||
|
||||
$$\lfloor 58*2^{-2}\rfloor*58 +58/2\le n \lt \lfloor 58*2^{-3}\rfloor*58^2 +\lfloor 58*2^{-2}\rfloor*58 +58/2$$
|
||||
|
||||
are similarly represented by three base 58 characters starting with a base 58 character $c$ in the range $58/2+\lfloor 58*2^{-2}\rfloor\le c \lt 58/2+\lfloor 58*2^{-2}\rfloor58+\lfloor 58*2^{-3}\rfloor$ .
|
||||
|
||||
Values $n$ in the range:
|
||||
|
||||
$$\lfloor 58*2^{-3}\rfloor*58^2 +\lfloor 58*2^{-2}\rfloor*58 +58/2\le n \lt \lfloor 58*2^{-4}\rfloor*58^3 +\lfloor 58*2^{-3}\rfloor*58^2 +\lfloor 58*2^{-2}\rfloor*58 +58/2$$
|
||||
|
||||
are similarly represented by four base 58 characters.
|
||||
|
||||
And so on, for arbitrarily large values. A truly enormous number is going to start with `zzzz....`, `z` being the representation of $58-1$ in base 58.
|
||||
|
||||
This amounts to shifting the underlying value to the appropriate range, then displaying it as the shifted base 58 value.
|
||||
|
||||
We display a value in the range $0\le n \lt 58/2$ as itself,
|
||||
|
||||
a value $n$ in the range $58/2\le n \lt \lfloor 58*2^{-2}\rfloor*58 +58/2$ as the base 58 representation of $n+58*(58/2-1)$
|
||||
|
||||
## Use case
|
||||
|
||||
@ -89,6 +144,10 @@ be very large, and can be increased without breaking compatibility, and
|
||||
without all implementations needing to changing their limit in the same
|
||||
way at the same time.
|
||||
|
||||
The problem with this representation is that the sort order as a bitstring
|
||||
differs from the sort order of the underlying integers, which is going to
|
||||
result in problems if these are used to define paths in a Merkle-patricia dag.
|
||||
|
||||
## Prefix Free Number Encoding
|
||||
|
||||
In this class of solutions, numbers are embedded as variable sized groups of bits within a bitstream, in a way that makes it possible to find the boundary between one number and the next. It is used in data compression, but seldom used in compressed data transmission, because far too slow.
|
||||
|
@ -2,6 +2,62 @@
|
||||
title: Scaling, trust and clients
|
||||
---
|
||||
|
||||
# Scaling
|
||||
|
||||
The Bitcoin blockchain has become inconveniently large, and evaluating it from beginning to end to
|
||||
determine the current mutable state is apt to fail half way through. Your computer takes a very long
|
||||
time and is apt to fail to make it all the way.
|
||||
|
||||
And, to take over the world, needs to become one hundred times larger. Instead of five hundred
|
||||
gigabytes of blockchain, fifty terabytes. And if you have eight eight terabyte drives attached to your
|
||||
computer, it is big expensive computer, and drives keep failing from time to time. And they are not
|
||||
the only thing that fails from time to time.
|
||||
|
||||
It is doable, but the only people that would be full peers on the blockchain would be a bunch of
|
||||
corporations and quite wealthy individuals. You would have a small data centre, rather than a computer
|
||||
Which is likely to have bad consequences.
|
||||
|
||||
## Merkle Patricia tree of signatures
|
||||
|
||||
Suppose that every block of the root primary blockchain contains hash of Merkle-patricia keys of signatures of blobs.
|
||||
|
||||
Each blob represents the current state, current commitment of anyone who wants to be able to prove that he is committing to a single state, a single append only chain of states, to anyone who wants to know,
|
||||
telling the same story to Bob as to Carol. This can be used to prevent Byzantine defection, but does
|
||||
not in itself prevent it. The peers on the blockchain do not know who is committing to what, or
|
||||
whether their sequence of commitments is internally consistent.
|
||||
|
||||
Among the Byzantine defections it can prevent is forking a chain of signatures, but there are no end
|
||||
of algorithms where we want to exclude Byzantine defection. Such algorithms are often complex, and
|
||||
have results that are hard to explain and hard to make use of. It is a powerful tool, but not obvious
|
||||
how to take advantage of it such that everyone gets his due.
|
||||
|
||||
Suppose this is hash the state sequence of Bob. Then everyone sharing this preimage can know that all the other people participating in this state sequence are seeing the same preimage. Which is a good start on preventing bad things from happening, but does not in itself prevent bad things from happening.
|
||||
|
||||
We all know the company with good reputation, that gets into financial difficulties, sells its good name to new management, which cashes in the long accrued reputation for a quick buck, then the phones
|
||||
stop being answered, the website gradually ceases to work, and large amounts of spam mail arrives.
|
||||
|
||||
## sharding, many blockchains.
|
||||
|
||||
Coins in a shard are shares in [sovereign cipher corporations] whose
|
||||
primary asset is a coin on the primary blockchain that vests power over
|
||||
their name and assets in a frequently changing public key. Every time
|
||||
money moves from the main chain to a sidechain, or from one sidechain to
|
||||
another, the old coin is spent, and a new coin is created. The public key on
|
||||
the mainchain coin corresponds to [a frequently changing secret that is distributed]
|
||||
between the peers on the sidechain in proportion to their stake.
|
||||
|
||||
The mainchain transaction is a big transaction between many sidechains,
|
||||
that contains a single output or input from each side chain, with each
|
||||
single input or output from each sidechain representing many single
|
||||
transactions between sidechains, and each single transaction between
|
||||
sidechains representing many single transactions between many clients of
|
||||
each sidechain.
|
||||
|
||||
The single big mainchain transaction merkle chains to the total history of
|
||||
each sidechain, and each client of a sidechain can verify any state
|
||||
information about his sidechain against the most recent sidechain
|
||||
transaction on the mainchain, and routinely does.
|
||||
|
||||
# Client trust
|
||||
|
||||
When there are billions of people using the blockchain, it will inevitably
|
||||
@ -49,28 +105,6 @@ client unpredictably verifies a small number of transactions, the net effect
|
||||
is going to be that most transactions are going to be unpredictably verified
|
||||
by several clients.
|
||||
|
||||
## sharding, many blockchains
|
||||
|
||||
Coins in a shard are shares in [sovereign cipher corporations] whose
|
||||
primary asset is a coin on the primary blockchain that vests power over
|
||||
their name and assets in a frequently changing public key. Every time
|
||||
money moves from the main chain to a sidechain, or from one sidechain to
|
||||
another, the old coin is spent, and a new coin is created. The public key on
|
||||
the mainchain coin corresponds to [a frequently changing secret that is distributed]
|
||||
between the peers on the sidechain in proportion to their stake.
|
||||
|
||||
The mainchain transaction is a big transaction between many sidechains,
|
||||
that contains a single output or input from each side chain, with each
|
||||
single input or output from each sidechain representing many single
|
||||
transactions between sidechains, and each single transaction between
|
||||
sidechains representing many single transactions between many clients of
|
||||
each sidechain.
|
||||
|
||||
The single big mainchain transaction merkle chains to the total history of
|
||||
each sidechain, and each client of a sidechain can verify any state
|
||||
information about his sidechain against the most recent sidechain
|
||||
transaction on the mainchain, and routinely does.
|
||||
|
||||
## lightning layer
|
||||
|
||||
The [lightning layer] is the correct place for privacy and contracts – because
|
||||
|
Loading…
Reference in New Issue
Block a user