mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-20 10:52:25 +00:00
Restacktrie with pruning (#13)
* revert snaphash to processing all accounts * use ReStackTrie in generateTrie * Save memory by hashing a branch if no more insert will occur
This commit is contained in:
parent
6dc45cf878
commit
62d322a1a7
3 changed files with 41 additions and 18 deletions
|
|
@ -18,7 +18,6 @@ package main
|
|||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/ethereum/go-ethereum/core/state/snapshot"
|
||||
"os"
|
||||
|
|
@ -617,18 +616,14 @@ func snapToHash(ctx *cli.Context) error {
|
|||
if err != nil {
|
||||
return fmt.Errorf("Could not create iterator for root %x: %v", root, err)
|
||||
}
|
||||
ollKorrekt := snapshot.CrosscheckTriehasher(it, 0, 10000)
|
||||
//generatedRoot := snapshot.GenerateTrieRoot(it)
|
||||
//if err := it.Error(); err != nil {
|
||||
// fmt.Printf("Iterator error: %v\n", it.Error())
|
||||
//}
|
||||
//if root != generatedRoot {
|
||||
// return fmt.Errorf("Wrong hash generated, expected %x, got %x", root, generatedRoot[:])
|
||||
//}
|
||||
if !ollKorrekt {
|
||||
return errors.New("Computer says No, @gballet\n...come on man, fix me already!")
|
||||
generatedRoot := snapshot.GenerateTrieRoot(it)
|
||||
if err := it.Error(); err != nil {
|
||||
fmt.Printf("Iterator error: %v\n", it.Error())
|
||||
}
|
||||
//log.Info("Generation done", "root", generatedRoot)
|
||||
if root != generatedRoot {
|
||||
return fmt.Errorf("Wrong hash generated, expected %x, got %x", root, generatedRoot[:])
|
||||
}
|
||||
log.Info("Generation done", "root", generatedRoot)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ type trieGeneratorFn func(in chan (leaf), out chan (common.Hash))
|
|||
// GenerateTrieRoot takes an account iterator and reproduces the root hash.
|
||||
func GenerateTrieRoot(it AccountIterator) common.Hash {
|
||||
//return generateTrieRoot(it, StackGenerate)
|
||||
return generateTrieRoot(it, StdGenerate)
|
||||
return generateTrieRoot(it, ReStackGenerate)
|
||||
}
|
||||
|
||||
func CrosscheckTriehasher(it AccountIterator, begin, end int) bool {
|
||||
|
|
|
|||
|
|
@ -287,6 +287,7 @@ const (
|
|||
extNode
|
||||
leafNode
|
||||
emptyNode
|
||||
hashedNode
|
||||
)
|
||||
|
||||
func (st *ReStackTrie) TryUpdate(key, value []byte) error {
|
||||
|
|
@ -318,6 +319,18 @@ func (st *ReStackTrie) insert(key, value []byte) {
|
|||
st.children[idx] = NewReStackTrie()
|
||||
st.children[idx].keyOffset = st.keyOffset + 1
|
||||
}
|
||||
for i := idx - 1; i >= 0; i-- {
|
||||
if st.children[i] != nil {
|
||||
if st.children[i].nodeType != hashedNode {
|
||||
st.children[i].val = st.children[i].Hash().Bytes()
|
||||
st.children[i].key = nil
|
||||
st.children[i].nodeType = hashedNode
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
|
||||
}
|
||||
st.children[idx].insert(key, value)
|
||||
case extNode: /* Ext */
|
||||
// Compare both key chunks and see where they differ
|
||||
|
|
@ -415,6 +428,8 @@ func (st *ReStackTrie) insert(key, value []byte) {
|
|||
|
||||
// Create the two child leaves: the one containing the
|
||||
// original value and the one containing the new value
|
||||
// The child leave will be hashed directly in order to
|
||||
// free up some memory.
|
||||
origIdx := st.key[diffidx]
|
||||
p.children[origIdx] = NewReStackTrie()
|
||||
p.children[origIdx].nodeType = leafNode
|
||||
|
|
@ -422,6 +437,10 @@ func (st *ReStackTrie) insert(key, value []byte) {
|
|||
p.children[origIdx].val = st.val
|
||||
p.children[origIdx].keyOffset = p.keyOffset + 1
|
||||
|
||||
p.children[origIdx].val = p.children[origIdx].Hash().Bytes()
|
||||
p.children[origIdx].nodeType = hashedNode
|
||||
p.children[origIdx].key = nil
|
||||
|
||||
newIdx := key[diffidx+st.keyOffset]
|
||||
p.children[newIdx] = NewReStackTrie()
|
||||
p.children[newIdx].nodeType = leafNode
|
||||
|
|
@ -434,6 +453,8 @@ func (st *ReStackTrie) insert(key, value []byte) {
|
|||
st.nodeType = leafNode
|
||||
st.key = key[st.keyOffset:]
|
||||
st.val = value
|
||||
case hashedNode:
|
||||
panic("trying to insert into hash")
|
||||
default:
|
||||
panic("invalid type")
|
||||
}
|
||||
|
|
@ -539,18 +560,24 @@ func writeHPRLP(writer io.Writer, key, val []byte, leaf bool) {
|
|||
}
|
||||
|
||||
func (st *ReStackTrie) Hash() (h common.Hash) {
|
||||
/* Shortcut if node is already hashed */
|
||||
if st.nodeType == hashedNode {
|
||||
return common.BytesToHash(st.val)
|
||||
}
|
||||
|
||||
d := sha3.NewLegacyKeccak256()
|
||||
switch st.nodeType {
|
||||
case 0:
|
||||
case branchNode:
|
||||
payload := [544]byte{}
|
||||
pos := 3 // maximum header length given what we know
|
||||
for _, v := range st.children {
|
||||
for i, v := range st.children {
|
||||
if v != nil {
|
||||
// Write a 32 byte list to the sponge
|
||||
payload[pos] = 0xa0
|
||||
pos++
|
||||
copy(payload[pos:pos+32], v.Hash().Bytes())
|
||||
pos += 32
|
||||
st.children[i] = nil // Reclaim mem from subtree
|
||||
} else {
|
||||
// Write an empty list to the sponge
|
||||
payload[pos] = 0x80
|
||||
|
|
@ -579,12 +606,13 @@ func (st *ReStackTrie) Hash() (h common.Hash) {
|
|||
start = 0
|
||||
}
|
||||
d.Write(payload[start:pos])
|
||||
case 1:
|
||||
case extNode:
|
||||
ch := st.children[0].Hash().Bytes()
|
||||
writeHPRLP(d, st.key, ch, false)
|
||||
case 2:
|
||||
st.children[0] = nil // Reclaim mem from subtree
|
||||
case leafNode:
|
||||
writeHPRLP(d, st.key, st.val, true)
|
||||
case 3:
|
||||
case emptyNode:
|
||||
default:
|
||||
panic("Invalid node type")
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue