during computeCommitment exits with RootHash when there are no updates to apply (#366)

This commit is contained in:
Artem Tsebrovskiy 2022-03-15 20:01:51 +03:00 committed by GitHub
parent 77eb94b53e
commit 6687e6b4d6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 73 additions and 2 deletions

View File

@ -2326,6 +2326,11 @@ func (w *Writer) computeCommitment(trace bool) ([]byte, error) {
j++ j++
return true return true
}) })
if len(updates) == 0 {
return w.a.hph.RootHash()
}
w.a.hph.Reset() w.a.hph.Reset()
w.a.hph.ResetFns(w.branchFn, w.accountFn, w.storageFn, w.lockFn, w.unlockFn) w.a.hph.ResetFns(w.branchFn, w.accountFn, w.storageFn, w.lockFn, w.unlockFn)
w.a.hph.SetTrace(trace) w.a.hph.SetTrace(trace)
@ -2376,6 +2381,7 @@ func (w *Writer) computeCommitment(trace bool) ([]byte, error) {
} }
} }
} }
var rootHash []byte var rootHash []byte
if rootHash, err = w.a.hph.RootHash(); err != nil { if rootHash, err = w.a.hph.RootHash(); err != nil {
return nil, err return nil, err

View File

@ -27,9 +27,10 @@ import (
"strings" "strings"
"github.com/holiman/uint256" "github.com/holiman/uint256"
"golang.org/x/crypto/sha3"
"github.com/ledgerwatch/erigon-lib/common/length" "github.com/ledgerwatch/erigon-lib/common/length"
"github.com/ledgerwatch/erigon-lib/rlp" "github.com/ledgerwatch/erigon-lib/rlp"
"golang.org/x/crypto/sha3"
) )
// keccakState wraps sha3.state. In addition to the usual hash methods, it also supports // keccakState wraps sha3.state. In addition to the usual hash methods, it also supports

View File

@ -17,6 +17,7 @@
package commitment package commitment
import ( import (
"bytes"
"encoding/binary" "encoding/binary"
"encoding/hex" "encoding/hex"
"fmt" "fmt"
@ -24,8 +25,9 @@ import (
"testing" "testing"
"github.com/holiman/uint256" "github.com/holiman/uint256"
"github.com/ledgerwatch/erigon-lib/common"
"golang.org/x/crypto/sha3" "golang.org/x/crypto/sha3"
"github.com/ledgerwatch/erigon-lib/common"
) )
// In memory commitment and state to use with the tests // In memory commitment and state to use with the tests
@ -481,3 +483,65 @@ func TestEmptyState(t *testing.T) {
fmt.Printf("%x => %s\n", CompactToHex([]byte(key)), branchToString(branchNodeUpdate)) fmt.Printf("%x => %s\n", CompactToHex([]byte(key)), branchToString(branchNodeUpdate))
} }
} }
func TestEmptyUpdateState(t *testing.T) {
ms := NewMockState(t)
hph := NewHexPatriciaHashed(1, ms.branchFn, ms.accountFn, ms.storageFn, ms.lockFn, ms.unlockFn)
hph.SetTrace(false)
plainKeys, hashedKeys, updates := NewUpdateBuilder().
Balance("00", 4).
Balance("01", 5).
Build()
if err := ms.applyPlainUpdates(plainKeys, updates); err != nil {
t.Fatal(err)
}
branchNodeUpdates, err := hph.ProcessUpdates(plainKeys, hashedKeys, updates)
if err != nil {
t.Fatal(err)
}
rh, err := hph.RootHash()
if err != nil {
t.Fatal(err)
}
fmt.Printf("root %v\n", hex.EncodeToString(rh))
ms.applyBranchNodeUpdates(branchNodeUpdates)
fmt.Println("1. Updates applied")
var keys []string
for key := range branchNodeUpdates {
keys = append(keys, key)
}
sort.Strings(keys)
for _, key := range keys {
branchNodeUpdate := branchNodeUpdates[key]
fmt.Printf("%x => %s\n", CompactToHex([]byte(key)), branchToString(branchNodeUpdate))
}
// generate empty updates and do NOT reset tree
//hph.Reset()
hph.SetTrace(true)
plainKeys, hashedKeys, updates = NewUpdateBuilder().Build()
if err := ms.applyPlainUpdates(plainKeys, updates); err != nil {
t.Fatal(err)
}
branchNodeUpdates, err = hph.ProcessUpdates(plainKeys, hashedKeys, updates)
if err != nil {
t.Fatal(err)
}
ms.applyBranchNodeUpdates(branchNodeUpdates)
fmt.Println("2. empty updates applied without state reset")
firstRH := rh
rh, err = hph.RootHash()
if err != nil {
t.Fatal(err)
}
if !bytes.Equal(firstRH, rh) {
t.Fatalf("expected root hash [%v] after update but got [%v]", hex.EncodeToString(firstRH), hex.EncodeToString(rh))
}
fmt.Printf("root %v\n", hex.EncodeToString(rh))
}