Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add skip-list-like header structure for the light client #2631

Closed
maxzaver opened this issue May 12, 2020 · 2 comments
Closed

Add skip-list-like header structure for the light client #2631

maxzaver opened this issue May 12, 2020 · 2 comments
Assignees
Labels
A-chain Area: Chain, client & related P-critical Priority: critical

Comments

@maxzaver
Copy link
Contributor

As discussed with @k06a , @abacabadabacaba , @SkidanovAlex , @bowenwang1996 we won't be able to submit every LightClientBlockView into Near2EthClient, because there are too many of them. Instead, we will be submitting it once every epoch. However, this means that if one wants to verify a proof towards certain transaction outcome they would need to submit a proof that chains through all blocks until the submitted block. Such chain would be too long to process, since we have ~43k blocks in epoch. Instead we will build a skip-list-like structure proposed by @abacabadabacaba that will allow us to make log n hops from the block we want to prove to the block that was submitted to the light client. @bowenwang1996 kindly agreed to implement it with the help of @abacabadabacaba .

Here is the copy-past of the design proposal:

Skip-list-like structure to access previous blocks

Preliminaries:
Every block has an index i. Indexes are consecutive integers starting with 0.
Every block has an ID, which is a hash of the block's contents (including links to previous blocks). Hash of the block at index i is denoted block_hash[i].

We introduce some additional hashes:
dnode_hash[i, j]: defined if j-i = 2**k for some k, and both i and j are divisible by 2**k.
dnode_hash[i, i+1] = block_hash[i].
dnode_hash[i, i+2**k] = hash(dnode_hash[i, i+2**(k-1)] + dnode_hash[i+2**(k-1), i+2**k]) for any k > 0 such that i is divisible by 2**k.
Essentially, dnode_hash'es define a Merkle tree of all block_id's.

anode_hash[i]: defined if i > 0.
anode_hash[2**k] = dnode_hash[0, 2**k].
anode_hash[i] = hash(anode_hash[i-2**k] + dnode_hash[i-2**k, i]), where i is not a power of 2 and 2**k is the largest power of 2 that divides i.
These hashes define something similar to Merkle tree. In particular, it is possible to reach block_hash[j] from anode_hash[i] (where i > j) in at most 2*log(n) steps.

In blocks, replace prev_hash with anode_hash[i]. It is possible to reach block_hash[i-1] from anode_hash[i] in at most log(n) steps, so having both anode_hash and prev_hash is redundant.

Proof structure: similar to proofs in Merkle trees.

Example: suppose that we have block_hash[5], and want to prove block_hash[3].
block_hash[5] = hash(anode_hash[5] + block_inner_hash[5])
anode_hash[5] = hash(anode_hash[4] + dnode_hash[4, 5])
anode_hash[4] = dnode_hash[0, 4]
dnode_hash[0, 4] = hash(dnode_hash[0, 2] + dnode_hash[2, 4])
dnode_hash[2, 4] = hash(dnode_hash[2, 3] + dnode_hash[3, 4])
dnode_hash[3, 4] = block_hash[3]

A proof would include 4 hashes: block_inner_hash[5], dnode_hash[4, 5], dnode_hash[0, 2], and dnode_hash[2, 3].

Verifier would compute:
dnode_hash[3, 4] = block_hash[3]
dnode_hash[2, 4] = hash(dnode_hash[2, 3] + dnode_hash[3, 4])
dnode_hash[0, 4] = hash(dnode_hash[0, 2] + dnode_hash[2, 4])
anode_hash[4] = dnode_hash[0, 4]
anode_hash[5] = hash(anode_hash[4] + dnode_hash[4, 5])
block_hash[5] = hash(anode_hash[5] + block_inner_hash[5])
Then, verifier will check that the computed block_hash[5] matches the known value.
@maxzaver maxzaver added the P-critical Priority: critical label May 12, 2020
@maxzaver maxzaver added the A-chain Area: Chain, client & related label May 12, 2020
@maxzaver
Copy link
Contributor Author

Setting estimate to 13 (~2 weeks) which is how @bowenwang1996 estimated the work. Also setting priority to P0 since this is blocking the rest of our work on the bridge, like making sure the Near2EthProver works correctly, and also our bridge work is P0.

@maxzaver
Copy link
Contributor Author

Superseded by #2632

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-chain Area: Chain, client & related P-critical Priority: critical
Projects
None yet
Development

No branches or pull requests

2 participants