Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
G
Geth-Modification
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
张蕾
Geth-Modification
Commits
216e5848
Unverified
Commit
216e5848
authored
Jan 15, 2018
by
Péter Szilágyi
Committed by
GitHub
Jan 15, 2018
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Revert "trie: make fullnode children hash calculation concurrently (#15131)" (#15889)
This reverts commit
0f7fbb85
.
parent
18a7d313
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
32 additions
and
88 deletions
+32
-88
hasher.go
trie/hasher.go
+27
-84
secure_trie.go
trie/secure_trie.go
+4
-4
trie.go
trie/trie.go
+1
-0
No files found.
trie/hasher.go
View file @
216e5848
...
...
@@ -26,46 +26,27 @@ import (
"github.com/ethereum/go-ethereum/rlp"
)
// calculator is a utility used by the hasher to calculate the hash value of the tree node.
type
calculator
struct
{
sha
hash
.
Hash
buffer
*
bytes
.
Buffer
type
hasher
struct
{
tmp
*
bytes
.
Buffer
sha
hash
.
Hash
cachegen
,
cachelimit
uint16
}
//
calculatorPool is a set of temporary calculators that may be individually saved and retrieved
.
var
calculato
rPool
=
sync
.
Pool
{
//
hashers live in a global pool
.
var
hashe
rPool
=
sync
.
Pool
{
New
:
func
()
interface
{}
{
return
&
calculator
{
buffer
:
new
(
bytes
.
Buffer
),
sha
:
sha3
.
NewKeccak256
()}
return
&
hasher
{
tmp
:
new
(
bytes
.
Buffer
),
sha
:
sha3
.
NewKeccak256
()}
},
}
// hasher hasher is used to calculate the hash value of the whole tree.
type
hasher
struct
{
cachegen
uint16
cachelimit
uint16
threaded
bool
mu
sync
.
Mutex
}
func
newHasher
(
cachegen
,
cachelimit
uint16
)
*
hasher
{
h
:=
&
hasher
{
cachegen
:
cachegen
,
cachelimit
:
cachelimit
,
}
h
:=
hasherPool
.
Get
()
.
(
*
hasher
)
h
.
cachegen
,
h
.
cachelimit
=
cachegen
,
cachelimit
return
h
}
// newCalculator retrieves a cleaned calculator from calculator pool.
func
(
h
*
hasher
)
newCalculator
()
*
calculator
{
calculator
:=
calculatorPool
.
Get
()
.
(
*
calculator
)
calculator
.
buffer
.
Reset
()
calculator
.
sha
.
Reset
()
return
calculator
}
// returnCalculator returns a no longer used calculator to the pool.
func
(
h
*
hasher
)
returnCalculator
(
calculator
*
calculator
)
{
calculatorPool
.
Put
(
calculator
)
func
returnHasherToPool
(
h
*
hasher
)
{
hasherPool
.
Put
(
h
)
}
// hash collapses a node down into a hash node, also returning a copy of the
...
...
@@ -142,49 +123,16 @@ func (h *hasher) hashChildren(original node, db DatabaseWriter) (node, node, err
// Hash the full node's children, caching the newly hashed subtrees
collapsed
,
cached
:=
n
.
copy
(),
n
.
copy
()
// hashChild is a helper to hash a single child, which is called either on the
// same thread as the caller or in a goroutine for the toplevel branching.
hashChild
:=
func
(
index
int
,
wg
*
sync
.
WaitGroup
)
{
if
wg
!=
nil
{
defer
wg
.
Done
()
}
// Ensure that nil children are encoded as empty strings.
if
collapsed
.
Children
[
index
]
==
nil
{
collapsed
.
Children
[
index
]
=
valueNode
(
nil
)
return
}
// Hash all other children properly
var
herr
error
collapsed
.
Children
[
index
],
cached
.
Children
[
index
],
herr
=
h
.
hash
(
n
.
Children
[
index
],
db
,
false
)
if
herr
!=
nil
{
h
.
mu
.
Lock
()
// rarely if ever locked, no congenstion
err
=
herr
h
.
mu
.
Unlock
()
for
i
:=
0
;
i
<
16
;
i
++
{
if
n
.
Children
[
i
]
!=
nil
{
collapsed
.
Children
[
i
],
cached
.
Children
[
i
],
err
=
h
.
hash
(
n
.
Children
[
i
],
db
,
false
)
if
err
!=
nil
{
return
original
,
original
,
err
}
}
else
{
collapsed
.
Children
[
i
]
=
valueNode
(
nil
)
// Ensure that nil children are encoded as empty strings.
}
}
// If we're not running in threaded mode yet, span a goroutine for each child
if
!
h
.
threaded
{
// Disable further threading
h
.
threaded
=
true
// Hash all the children concurrently
var
wg
sync
.
WaitGroup
for
i
:=
0
;
i
<
16
;
i
++
{
wg
.
Add
(
1
)
go
hashChild
(
i
,
&
wg
)
}
wg
.
Wait
()
// Reenable threading for subsequent hash calls
h
.
threaded
=
false
}
else
{
for
i
:=
0
;
i
<
16
;
i
++
{
hashChild
(
i
,
nil
)
}
}
if
err
!=
nil
{
return
original
,
original
,
err
}
cached
.
Children
[
16
]
=
n
.
Children
[
16
]
if
collapsed
.
Children
[
16
]
==
nil
{
collapsed
.
Children
[
16
]
=
valueNode
(
nil
)
...
...
@@ -202,29 +150,24 @@ func (h *hasher) store(n node, db DatabaseWriter, force bool) (node, error) {
if
_
,
isHash
:=
n
.
(
hashNode
);
n
==
nil
||
isHash
{
return
n
,
nil
}
calculator
:=
h
.
newCalculator
()
defer
h
.
returnCalculator
(
calculator
)
// Generate the RLP encoding of the node
if
err
:=
rlp
.
Encode
(
calculator
.
buffer
,
n
);
err
!=
nil
{
h
.
tmp
.
Reset
()
if
err
:=
rlp
.
Encode
(
h
.
tmp
,
n
);
err
!=
nil
{
panic
(
"encode error: "
+
err
.
Error
())
}
if
calculator
.
buffer
.
Len
()
<
32
&&
!
force
{
if
h
.
tmp
.
Len
()
<
32
&&
!
force
{
return
n
,
nil
// Nodes smaller than 32 bytes are stored inside their parent
}
// Larger nodes are replaced by their hash and stored in the database.
hash
,
_
:=
n
.
cache
()
if
hash
==
nil
{
calculator
.
sha
.
Write
(
calculator
.
buffer
.
Bytes
())
hash
=
hashNode
(
calculator
.
sha
.
Sum
(
nil
))
h
.
sha
.
Reset
()
h
.
sha
.
Write
(
h
.
tmp
.
Bytes
())
hash
=
hashNode
(
h
.
sha
.
Sum
(
nil
))
}
if
db
!=
nil
{
// db might be a leveldb batch, which is not safe for concurrent writes
h
.
mu
.
Lock
()
err
:=
db
.
Put
(
hash
,
calculator
.
buffer
.
Bytes
())
h
.
mu
.
Unlock
()
return
hash
,
err
return
hash
,
db
.
Put
(
hash
,
h
.
tmp
.
Bytes
())
}
return
hash
,
nil
}
trie/secure_trie.go
View file @
216e5848
...
...
@@ -199,10 +199,10 @@ func (t *SecureTrie) secKey(key []byte) []byte {
// invalid on the next call to hashKey or secKey.
func
(
t
*
SecureTrie
)
hashKey
(
key
[]
byte
)
[]
byte
{
h
:=
newHasher
(
0
,
0
)
calculator
:=
h
.
newCalculator
()
calculator
.
sha
.
Write
(
key
)
buf
:=
calculator
.
sha
.
Sum
(
t
.
hashKeyBuf
[
:
0
])
h
.
returnCalculator
(
calculator
)
h
.
sha
.
Reset
()
h
.
sha
.
Write
(
key
)
buf
:=
h
.
sha
.
Sum
(
t
.
hashKeyBuf
[
:
0
])
returnHasherToPool
(
h
)
return
buf
}
...
...
trie/trie.go
View file @
216e5848
...
...
@@ -501,5 +501,6 @@ func (t *Trie) hashRoot(db DatabaseWriter) (node, node, error) {
return
hashNode
(
emptyRoot
.
Bytes
()),
nil
,
nil
}
h
:=
newHasher
(
t
.
cachegen
,
t
.
cachelimit
)
defer
returnHasherToPool
(
h
)
return
h
.
hash
(
t
.
root
,
db
,
true
)
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment