good morning!!!!

Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • github/maticnetwork/bor
  • open/bor
2 results
Show changes
......@@ -20,7 +20,9 @@ import (
"fmt"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/rlp"
)
// SecureTrie wraps a trie with key hashing. In a secure trie, all
......@@ -85,6 +87,21 @@ func (t *SecureTrie) TryGetNode(path []byte) ([]byte, int, error) {
return t.trie.TryGetNode(path)
}
// TryUpdate account will abstract the write of an account to the
// secure trie.
func (t *SecureTrie) TryUpdateAccount(key []byte, acc *types.StateAccount) error {
hk := t.hashKey(key)
data, err := rlp.EncodeToBytes(acc)
if err != nil {
return err
}
if err := t.trie.TryUpdate(hk, data); err != nil {
return err
}
t.getSecKeyCache()[string(hk)] = common.CopyBytes(key)
return nil
}
// Update associates key with value in the trie. Subsequent calls to
// Get will return value. If value has length zero, any existing value
// is deleted from the trie and calls to Get will return nil.
......@@ -144,7 +161,7 @@ func (t *SecureTrie) GetKey(shaKey []byte) []byte {
//
// Committing flushes nodes from memory. Subsequent Get calls will load nodes
// from the database.
func (t *SecureTrie) Commit(onleaf LeafCallback) (root common.Hash, err error) {
func (t *SecureTrie) Commit(onleaf LeafCallback) (common.Hash, int, error) {
// Write all the pre-images to the actual disk database
if len(t.getSecKeyCache()) > 0 {
if t.trie.db.preimages != nil { // Ugly direct check but avoids the below write lock
......
// Copyright 2021 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package trie
import (
......
......@@ -24,8 +24,10 @@ import (
"sync"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/rlp"
)
var (
......@@ -174,6 +176,10 @@ func (t *Trie) TryGetNode(path []byte) ([]byte, int, error) {
}
func (t *Trie) tryGetNode(origNode node, path []byte, pos int) (item []byte, newnode node, resolved int, err error) {
// If non-existent path requested, abort
if origNode == nil {
return nil, nil, 0, nil
}
// If we reached the requested path, return the current node
if pos >= len(path) {
// Although we most probably have the original node expanded, encoding
......@@ -193,10 +199,6 @@ func (t *Trie) tryGetNode(origNode node, path []byte, pos int) (item []byte, new
}
// Path still needs to be traversed, descend into children
switch n := (origNode).(type) {
case nil:
// Non-existent path requested, abort
return nil, nil, 0, nil
case valueNode:
// Path prematurely ended, abort
return nil, nil, 0, nil
......@@ -246,6 +248,14 @@ func (t *Trie) Update(key, value []byte) {
}
}
func (t *Trie) TryUpdateAccount(key []byte, acc *types.StateAccount) error {
data, err := rlp.EncodeToBytes(acc)
if err != nil {
return fmt.Errorf("can't encode object at %x: %w", key[:], err)
}
return t.TryUpdate(key, data)
}
// TryUpdate associates key with value in the trie. Subsequent calls to
// Get will return value. If value has length zero, any existing value
// is deleted from the trie and calls to Get will return nil.
......@@ -514,12 +524,12 @@ func (t *Trie) Hash() common.Hash {
// Commit writes all nodes to the trie's memory database, tracking the internal
// and external (for account tries) references.
func (t *Trie) Commit(onleaf LeafCallback) (root common.Hash, err error) {
func (t *Trie) Commit(onleaf LeafCallback) (common.Hash, int, error) {
if t.db == nil {
panic("commit called on trie with nil database")
}
if t.root == nil {
return emptyRoot, nil
return emptyRoot, 0, nil
}
// Derive the hash for all dirty nodes first. We hold the assumption
// in the following procedure that all nodes are hashed.
......@@ -531,7 +541,7 @@ func (t *Trie) Commit(onleaf LeafCallback) (root common.Hash, err error) {
// up goroutines. This can happen e.g. if we load a trie for reading storage
// values, but don't write to it.
if _, dirty := t.root.cache(); !dirty {
return rootHash, nil
return rootHash, 0, nil
}
var wg sync.WaitGroup
if onleaf != nil {
......@@ -543,8 +553,7 @@ func (t *Trie) Commit(onleaf LeafCallback) (root common.Hash, err error) {
h.commitLoop(t.db)
}()
}
var newRoot hashNode
newRoot, err = h.Commit(t.root, t.db)
newRoot, committed, err := h.Commit(t.root, t.db)
if onleaf != nil {
// The leafch is created in newCommitter if there was an onleaf callback
// provided. The commitLoop only _reads_ from it, and the commit
......@@ -554,10 +563,10 @@ func (t *Trie) Commit(onleaf LeafCallback) (root common.Hash, err error) {
wg.Wait()
}
if err != nil {
return common.Hash{}, err
return common.Hash{}, 0, err
}
t.root = newRoot
return rootHash, nil
return rootHash, committed, nil
}
// hashRoot calculates the root hash of the given trie
......
......@@ -32,6 +32,7 @@ import (
"github.com/davecgh/go-spew/spew"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/ethdb/leveldb"
......@@ -90,7 +91,7 @@ func testMissingNode(t *testing.T, memonly bool) {
trie, _ := New(common.Hash{}, triedb)
updateString(trie, "120000", "qwerqwerqwerqwerqwerqwerqwerqwer")
updateString(trie, "123456", "asdfasdfasdfasdfasdfasdfasdfasdf")
root, _ := trie.Commit(nil)
root, _, _ := trie.Commit(nil)
if !memonly {
triedb.Commit(root, true, nil)
}
......@@ -172,7 +173,7 @@ func TestInsert(t *testing.T) {
updateString(trie, "A", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")
exp = common.HexToHash("d23786fb4a010da3ce639d66d5e904a11dbc02746d1ce25029e53290cabf28ab")
root, err := trie.Commit(nil)
root, _, err := trie.Commit(nil)
if err != nil {
t.Fatalf("commit error: %v", err)
}
......@@ -270,7 +271,7 @@ func TestReplication(t *testing.T) {
for _, val := range vals {
updateString(trie, val.k, val.v)
}
exp, err := trie.Commit(nil)
exp, _, err := trie.Commit(nil)
if err != nil {
t.Fatalf("commit error: %v", err)
}
......@@ -285,7 +286,7 @@ func TestReplication(t *testing.T) {
t.Errorf("trie2 doesn't have %q => %q", kv.k, kv.v)
}
}
hash, err := trie2.Commit(nil)
hash, _, err := trie2.Commit(nil)
if err != nil {
t.Fatalf("commit error: %v", err)
}
......@@ -429,11 +430,11 @@ func runRandTest(rt randTest) bool {
rt[i].err = fmt.Errorf("mismatch for key 0x%x, got 0x%x want 0x%x", step.key, v, want)
}
case opCommit:
_, rt[i].err = tr.Commit(nil)
_, _, rt[i].err = tr.Commit(nil)
case opHash:
tr.Hash()
case opReset:
hash, err := tr.Commit(nil)
hash, _, err := tr.Commit(nil)
if err != nil {
rt[i].err = err
return false
......@@ -553,13 +554,6 @@ func BenchmarkHash(b *testing.B) {
trie.Hash()
}
type account struct {
Nonce uint64
Balance *big.Int
Root common.Hash
Code []byte
}
// Benchmarks the trie Commit following a Hash. Since the trie caches the result of any operation,
// we cannot use b.N as the number of hashing rouns, since all rounds apart from
// the first one will be NOOP. As such, we'll use b.N as the number of account to
......@@ -568,7 +562,7 @@ func BenchmarkCommitAfterHash(b *testing.B) {
b.Run("no-onleaf", func(b *testing.B) {
benchmarkCommitAfterHash(b, nil)
})
var a account
var a types.StateAccount
onleaf := func(paths [][]byte, hexpath []byte, leaf []byte, parent common.Hash) error {
rlp.DecodeBytes(leaf, &a)
return nil
......@@ -633,7 +627,7 @@ func TestCommitAfterHash(t *testing.T) {
if exp != root {
t.Errorf("got %x, exp %x", root, exp)
}
root, _ = trie.Commit(nil)
root, _, _ = trie.Commit(nil)
if exp != root {
t.Errorf("got %x, exp %x", root, exp)
}
......@@ -664,7 +658,7 @@ func makeAccounts(size int) (addresses [][20]byte, accounts [][]byte) {
balanceBytes := make([]byte, numBytes)
random.Read(balanceBytes)
balance := new(big.Int).SetBytes(balanceBytes)
data, _ := rlp.EncodeToBytes(&account{nonce, balance, root, code})
data, _ := rlp.EncodeToBytes(&types.StateAccount{Nonce: nonce, Balance: balance, Root: root, CodeHash: code})
accounts[i] = data
}
return addresses, accounts
......@@ -740,7 +734,7 @@ func TestCommitSequence(t *testing.T) {
trie.Update(crypto.Keccak256(addresses[i][:]), accounts[i])
}
// Flush trie -> database
root, _ := trie.Commit(nil)
root, _, _ := trie.Commit(nil)
// Flush memdb -> disk (sponge)
db.Commit(root, false, func(c common.Hash) {
// And spongify the callback-order
......@@ -792,7 +786,7 @@ func TestCommitSequenceRandomBlobs(t *testing.T) {
trie.Update(key, val)
}
// Flush trie -> database
root, _ := trie.Commit(nil)
root, _, _ := trie.Commit(nil)
// Flush memdb -> disk (sponge)
db.Commit(root, false, func(c common.Hash) {
// And spongify the callback-order
......@@ -834,7 +828,7 @@ func TestCommitSequenceStackTrie(t *testing.T) {
stTrie.TryUpdate(key, val)
}
// Flush trie -> database
root, _ := trie.Commit(nil)
root, _, _ := trie.Commit(nil)
// Flush memdb -> disk (sponge)
db.Commit(root, false, nil)
// And flush stacktrie -> disk
......@@ -879,7 +873,7 @@ func TestCommitSequenceSmallRoot(t *testing.T) {
trie.TryUpdate(key, []byte{0x1})
stTrie.TryUpdate(key, []byte{0x1})
// Flush trie -> database
root, _ := trie.Commit(nil)
root, _, _ := trie.Commit(nil)
// Flush memdb -> disk (sponge)
db.Commit(root, false, nil)
// And flush stacktrie -> disk
......