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

KIP-111 Use ExtHash in trie database #1859

Merged
merged 15 commits into from
Jul 17, 2023
Merged

Conversation

blukat29
Copy link
Contributor

@blukat29 blukat29 commented Jun 9, 2023

Proposed changes

Use ExtHash type throught the trie-handling code. This is a step towards implmementing the KIP-111 State Pruning. This PR must not change any behavior of the Klaytn node.

Methodology

Identify trie node hashes in the codebase. Convert the variable type, function argument type, and return types (collectively "hash types") to ExtHash if needed. Trie node hashes can be categorized into three.

  1. State root - Root of a world state trie associated to a block, i.e. block.Root().
  2. Storage root - Root of a contract storage trie dedicated to each contract account, i.e. account.StorageRoot().
  3. Child node - Child nodes in the both tries.

If a value always conveys State roots, then keep the hash type common.Hash.
If a value can potentially carry Storage roots or Child nodes, then make the hash type to common.ExtHash.

For example StateDB.IntermediateRoot() common.Hash kept its type because it is the State root.
In contrast, DBManager.ReadTrieNode(common.ExtHash) changed its type because it receives all kinds of node hashes.

CodeHash (contract bytecode) is unrelated to trie nodes, so it stays common.Hash.

Use hash.ExtendLegacy() and exthash.Unextend() to convert between the two types.
After this PR, any ExtHash value flowing in the codebase must be extended with Legacy Nonce.

Notable changes

  • DiskDB - DBManager: All TrieNode accessors uses ExtHash. Code accessors are Hash.
    Trie node keyed by ExtHashLegacy (i.e. hash.ExtendLegacy()) are stored with 32-byte key (i.e. db.Put(exthash.Unextend(), node))

    • Modified interfaces ProofDBReader and StateTrieReadDB accordingly.
    • Removed struct stateTrieMigrationDB in favor of DBManager.
  • Node encoding: Trie nodes may contain ExtHash references to other trie nodes. Encoding and Decoding mechanisms are updated.

    • decodeNode() can decode both Hash and ExtHash references.
    • hasher.hashRoot() injects either Hash or ExtHash when encoding the nodes.
    • See node_test.go and hasher_test.go for details.
  • TrieDB - Database: Most internal fields and methods carry ExtHash. Below are the exceptional cases.

    • Reference(H,H) is diversified into
      • Reference(EH,EH) for linking state trie leaf (EH) and storage trie root (EH)
      • ReferenceRoot(H) for referencing the State root (H)
    • Dereference(H) is left untouched because it's exclusively used with State root (H)
    • Commit(H) is left untouched because it's exclusively used with State root (H)
  • TrieDB - Trie: trie node references are internally stored in hashNode == []byte, so not much type changes.
    However, some functions are diversified into two variants.

    • NewTrie(H) and NewSecureTrie(H) open State tries. They are left untouched because it's only for State root.
    • NewStorageTrie(EH) and NewSecureStorageTrie(EH) open account storage tries. They accept ExtHash as root hash.
    • Hash() and Commit() returns the
  • Contract Account: A contract account (CA), contains a reference to its Storage root. Therefore its encoding format must change.

    • The field SmartContractAccount.StorageRoot is now ExtHash.
    • Methods GetStorageRoot() and SetStorageRoot handles ExtHash.
    • Contracts accounts are RLP-encoded before stored in database. In its encoding, the Storage root may be represented in Hash or ExtHash.
      • AccountSerializer can decode both formats.
      • AccountSerializer can choose to encode into one of the two formats.

Full list of changes are available in the table in Further Comments section.

Types of changes

  • Bugfix
  • New feature or enhancement
  • Others

Checklist

  • I have read the CONTRIBUTING GUIDELINES doc
  • I have signed the CLA
  • Lint and unit tests pass locally with my changes ($ make test)
  • I have added tests that prove my fix is effective or that my feature works
  • I have added necessary documentation (if appropriate)
  • Any dependent changes have been merged and published in downstream modules

Related issues

Further comments

Comprehensive list of hash type changes. = means interface unchanged, ~ means changed, + means newly added.

Scope Before After Commits
DiskDB TrieNodeKey (H)
ReadTrieNode (H)
HasTrieNode (H)
WriteTrieNode (H)
PutTrieNodeToBatch (H)
DeleteTrieNode (H)
interface ProofDBReader {H}
interface StateTrieReadDB {H}
~ TrieNodeKey (EH)
~ ReadTrieNode (EH)
~ HasTrieNode (EH)
~ WriteTrieNode (EH)
~ PutTrieNodeToBatch (EH)
~ DeleteTrieNode (EH)
~ interface ProofDBReader {EH}
~ interface StateTrieReadDB {EH}
9b6cfa9
node
encoding
decodeNode (H)
hasher.hash ()->H
~ decodeNode (EH)
~ hasher.hash ()->EH
603e9b8
61b175b
TrieDB node (H)
Node (H)
NodeFromOld (H)
DoesExistCachedNode (H)
DoesExistNodeInPersistent (H)
Nodes ()->[]H
NodeChildren (H)->[]H
CollectChildrenStats (H)
insert (H)
Reference (H,H)
-
Dereference (H)
Commit (H)
~ node (EH)
~ Node (EH)
~ NodeFromOld (EH)
~ DoesExistCachedNode (EH)
~ DoesExistNodeInPersistent (EH)
~ Nodes ()->[]EH
~ NodeChildren (EH)->[]EH
~ CollectChildrenStats (EH)
~ insert (EH)
~ Reference (EH,EH)
+ ReferenceRoot (H)
= Dereference (H)
= Commit(H)
15f0b58
29d069f
2968339
Trie NewTrie (H)
-
NewSecureTrie (H)
-
OpenTrie (H)
OpenStorageTrie (H)
Hash ()->H
-
Commit ()->H
-
LeafCallback (H)
= NewTrie (H)
+ NewStorageTrie (EH)
= NewSecureTrie (H)
+ NewSecureStorageTrie (EH)
= OpenTrie (H)
+ OpenStorageTrie (EH)
= Hash ()->H
+ HashExt ()->EH
= Commit ()->H
+ CommitExt ()->EH
~ LeafCallback (EH)
bc40be2
Proof VerifyProof (H)
VerifyRangeProof (H)
= VerifyProof (H)
= VerifyRangeProof (H)
TrieSync request {H}
SyncResult {H}
AddSubTrie (H)
AddCodeEntry (parent H)
Missing ()->(nodes []H)
= request {H}
= SyncResult {H}
= AddSubTrie (H)
= AddCodeEntry (parent H)
= Missing ()->(nodes []H)
Iterator statedb.nodeIterator.Hash ()->H
statedb.nodeIterator.Parent ()->H
state.NodeIterator.Hash: H
state.NodeIterator.Parent: H
= statedb.nodeIterator.Hash ()->H
= statedb.nodeIterator.Parent ()->H
= state.NodeIterator.Hash: H
= state.NodeIterator.Parent: H
StateDB IntermediateRoot ()->H
Commit ()->H
Reset (H)
GetContractStorageRoot ()->H
openStorageTrie (H)
= IntermediateRoot ()->H
= Commit ()->H
= Reset (H)
~ GetContractStorageRoot ()->EH
~ openStorageTrie (EH)
e62143f
3e408ff
Contract
Account
SmartContractAccount {H}
GetStorageRoot ()->H
SetStorageRoot (H)
~ SmartContractAccount {EH}
~ GetStorageRoot ()->EH
~ SetStorageRoot (EH)
eff7caf
860507d

@blukat29 blukat29 force-pushed the trie-use-exthash branch 3 times, most recently from f9068b9 to e30137f Compare June 14, 2023 10:40
@blukat29 blukat29 mentioned this pull request Jun 19, 2023
9 tasks
@blukat29 blukat29 force-pushed the trie-use-exthash branch 3 times, most recently from 786488d to cb437cb Compare June 20, 2023 10:09
@blukat29 blukat29 marked this pull request as ready for review June 26, 2023 06:34
@blukat29 blukat29 changed the title Use ExtHash in trie database KIP-111 Use ExtHash in trie database Jun 26, 2023
storage/statedb/trie.go Show resolved Hide resolved
blockchain/types/account/account_serializer.go Outdated Show resolved Hide resolved
blockchain/types/account/account_serializer.go Outdated Show resolved Hide resolved
@blukat29 blukat29 mentioned this pull request Jun 30, 2023
9 tasks
@aidan-kwon aidan-kwon merged commit 1941d9c into klaytn:dev Jul 17, 2023
11 checks passed
@blukat29 blukat29 deleted the trie-use-exthash branch July 17, 2023 01:45
@JayChoi1736 JayChoi1736 mentioned this pull request Jul 24, 2023
20 tasks
@aidan-kwon aidan-kwon mentioned this pull request Jul 30, 2023
9 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants