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
886478b1
Commit
886478b1
authored
Jan 20, 2016
by
Péter Szilágyi
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
core/state, trie: don't leak database writes before commit
parent
5945a333
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
103 additions
and
8 deletions
+103
-8
statedb.go
core/state/statedb.go
+7
-3
statedb_test.go
core/state/statedb_test.go
+52
-0
secure_trie.go
trie/secure_trie.go
+44
-5
No files found.
core/state/statedb.go
View file @
886478b1
...
...
@@ -206,9 +206,6 @@ func (self *StateDB) Delete(addr common.Address) bool {
// Update the given state object and apply it to state trie
func
(
self
*
StateDB
)
UpdateStateObject
(
stateObject
*
StateObject
)
{
if
len
(
stateObject
.
code
)
>
0
{
self
.
db
.
Put
(
stateObject
.
codeHash
,
stateObject
.
code
)
}
addr
:=
stateObject
.
Address
()
data
,
err
:=
rlp
.
EncodeToBytes
(
stateObject
)
if
err
!=
nil
{
...
...
@@ -375,8 +372,15 @@ func (s *StateDB) commit(db trie.DatabaseWriter) (common.Hash, error) {
// and just mark it for deletion in the trie.
s
.
DeleteStateObject
(
stateObject
)
}
else
{
// Write any contract code associated with the state object
if
len
(
stateObject
.
code
)
>
0
{
if
err
:=
db
.
Put
(
stateObject
.
codeHash
,
stateObject
.
code
);
err
!=
nil
{
return
common
.
Hash
{},
err
}
}
// Write any storage changes in the state object to its trie.
stateObject
.
Update
()
// Commit the trie of the object to the batch.
// This updates the trie root internally, so
// getting the root hash of the storage trie
...
...
core/state/statedb_test.go
0 → 100644
View file @
886478b1
// Copyright 2015 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
state
import
(
"math/big"
"testing"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/ethdb"
)
// Tests that updating a state trie does not leak any database writes prior to
// actually committing the state.
func
TestUpdateLeaks
(
t
*
testing
.
T
)
{
// Create an empty state database
db
,
_
:=
ethdb
.
NewMemDatabase
()
state
,
_
:=
New
(
common
.
Hash
{},
db
)
// Update it with some accounts
for
i
:=
byte
(
0
);
i
<
255
;
i
++
{
obj
:=
state
.
GetOrNewStateObject
(
common
.
BytesToAddress
([]
byte
{
i
}))
obj
.
AddBalance
(
big
.
NewInt
(
int64
(
11
*
i
)))
obj
.
SetNonce
(
uint64
(
42
*
i
))
if
i
%
2
==
0
{
obj
.
SetState
(
common
.
BytesToHash
([]
byte
{
i
,
i
,
i
}),
common
.
BytesToHash
([]
byte
{
i
,
i
,
i
,
i
}))
}
if
i
%
3
==
0
{
obj
.
SetCode
([]
byte
{
i
,
i
,
i
,
i
,
i
})
}
state
.
UpdateStateObject
(
obj
)
}
// Ensure that no data was leaked into the database
for
_
,
key
:=
range
db
.
Keys
()
{
value
,
_
:=
db
.
Get
(
key
)
t
.
Errorf
(
"State leaked into database: %x -> %x"
,
key
,
value
)
}
}
trie/secure_trie.go
View file @
886478b1
...
...
@@ -41,8 +41,9 @@ type SecureTrie struct {
*
Trie
hash
hash
.
Hash
secKeyBuf
[]
byte
hashKeyBuf
[]
byte
secKeyBuf
[]
byte
secKeyCache
map
[
string
][]
byte
}
// NewSecure creates a trie with an existing root node from db.
...
...
@@ -59,7 +60,10 @@ func NewSecure(root common.Hash, db Database) (*SecureTrie, error) {
if
err
!=
nil
{
return
nil
,
err
}
return
&
SecureTrie
{
Trie
:
trie
},
nil
return
&
SecureTrie
{
Trie
:
trie
,
secKeyCache
:
make
(
map
[
string
][]
byte
),
},
nil
}
// Get returns the value for key stored in the trie.
...
...
@@ -105,7 +109,7 @@ func (t *SecureTrie) TryUpdate(key, value []byte) error {
if
err
!=
nil
{
return
err
}
t
.
Trie
.
db
.
Put
(
t
.
secKey
(
hk
),
key
)
t
.
secKeyCache
[
string
(
hk
)]
=
key
return
nil
}
...
...
@@ -125,10 +129,45 @@ func (t *SecureTrie) TryDelete(key []byte) error {
// GetKey returns the sha3 preimage of a hashed key that was
// previously used to store a value.
func
(
t
*
SecureTrie
)
GetKey
(
shaKey
[]
byte
)
[]
byte
{
if
key
,
ok
:=
t
.
secKeyCache
[
string
(
shaKey
)];
ok
{
return
key
}
key
,
_
:=
t
.
Trie
.
db
.
Get
(
t
.
secKey
(
shaKey
))
return
key
}
// Commit writes all nodes and the secure hash pre-images to the trie's database.
// Nodes are stored with their sha3 hash as the key.
//
// Committing flushes nodes from memory. Subsequent Get calls will load nodes
// from the database.
func
(
t
*
SecureTrie
)
Commit
()
(
root
common
.
Hash
,
err
error
)
{
return
t
.
CommitTo
(
t
.
db
)
}
// CommitTo writes all nodes and the secure hash pre-images to the given database.
// Nodes are stored with their sha3 hash as the key.
//
// Committing flushes nodes from memory. Subsequent Get calls will load nodes from
// the trie's database. Calling code must ensure that the changes made to db are
// written back to the trie's attached database before using the trie.
func
(
t
*
SecureTrie
)
CommitTo
(
db
DatabaseWriter
)
(
root
common
.
Hash
,
err
error
)
{
if
len
(
t
.
secKeyCache
)
>
0
{
for
hk
,
key
:=
range
t
.
secKeyCache
{
if
err
:=
db
.
Put
(
t
.
secKey
([]
byte
(
hk
)),
key
);
err
!=
nil
{
return
common
.
Hash
{},
err
}
}
t
.
secKeyCache
=
make
(
map
[
string
][]
byte
)
}
n
,
err
:=
t
.
hashRoot
(
db
)
if
err
!=
nil
{
return
(
common
.
Hash
{}),
err
}
t
.
root
=
n
return
common
.
BytesToHash
(
n
.
(
hashNode
)),
nil
}
func
(
t
*
SecureTrie
)
secKey
(
key
[]
byte
)
[]
byte
{
t
.
secKeyBuf
=
append
(
t
.
secKeyBuf
[
:
0
],
secureKeyPrefix
...
)
t
.
secKeyBuf
=
append
(
t
.
secKeyBuf
,
key
...
)
...
...
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