-
Notifications
You must be signed in to change notification settings - Fork 4.4k
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
Purge accounts with lamports=0 on rooted forks #6315
Merged
sakridge
merged 1 commit into
solana-labs:master
from
sakridge:cleanup-zero-lamport-accounts
Oct 23, 2019
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
# Snapshot Verification | ||
|
||
## Problem | ||
|
||
When a validator boots up from a snapshot, it needs a way to verify the account set matches what the rest of the network sees quickly. A potential | ||
attacker could give the validator an incorrect state, and then try to convince it to accept a transaction that would otherwise be rejected. | ||
|
||
## Solution | ||
|
||
Currently the bank hash is derived from hashing the delta state of the accounts in a slot which is then combined with the previous bank hash value. | ||
The problem with this is that the list of hashes will grow on the order of the number of slots processed by the chain and become a burden to both | ||
transmit and verify successfully. | ||
|
||
Another naive method could be to create a merkle tree of the account state. This has the downside that with each account update, the merkle tree | ||
would have to be recomputed from the entire account state of all live accounts in the system. | ||
|
||
To verify the snapshot, we do the following: | ||
|
||
On account store of non-zero lamport accounts, we hash the following data: | ||
|
||
* Account owner | ||
* Account data | ||
* Account pubkey | ||
* Account lamports balance | ||
* Fork the account is stored on | ||
|
||
Use this resulting hash value as input to an expansion function which expands the hash value into an image value. | ||
The function will create a 440 byte block of data where the first 32 bytes are the hash value, and the next 440 - 32 bytes are | ||
generated from a Chacha RNG with the hash as the seed. | ||
|
||
The account images are then combined with xor. The previous account value will be xored into the state and the new account value also xored into the state. | ||
|
||
Voting and sysvar hash values occur with the hash of the resulting full image value. | ||
|
||
On validator boot, when it loads from a snapshot, it would verify the hash value with the accounts set. It would then | ||
use SPV to display the percentage of the network that voted for the hash value given. | ||
|
||
The resulting value can be verified by a validator to be the result of xoring all current account states together. | ||
|
||
A snapshot must be purged of zero lamport accounts before creation and during verify since the zero lamport accounts do not affect the hash value but may cause | ||
a validator bank to read that an account is not present when it really should be. | ||
|
||
An attack on the xor state could be made to influence its value: | ||
|
||
Thus the 440 byte image size comes from this paper, avoiding xor collision with 0 \(or thus any other given bit pattern\): \[[https://link.springer.com/content/pdf/10.1007%2F3-540-45708-9\_19.pdf](https://link.springer.com/content/pdf/10.1007%2F3-540-45708-9_19.pdf)\] | ||
|
||
The math provides 128 bit security in this case: | ||
|
||
```text | ||
O(k * 2^(n/(1+lg(k))) | ||
k=2^40 accounts | ||
n=440 | ||
2^(40) * 2^(448 * 8 / 41) ~= O(2^(128)) | ||
``` | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this one's interesting, how come?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because if we purge, we would not maintain the correct bank hash value.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah!