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
7b7b327f
Unverified
Commit
7b7b327f
authored
Nov 09, 2020
by
Péter Szilágyi
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
core/state/snapshot: update generator marker in sync with flushes
parent
97fc1c3b
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
58 additions
and
42 deletions
+58
-42
blockchain_snapshot_test.go
core/blockchain_snapshot_test.go
+2
-2
generate.go
core/state/snapshot/generate.go
+46
-2
journal.go
core/state/snapshot/journal.go
+8
-22
snapshot.go
core/state/snapshot/snapshot.go
+2
-16
No files found.
core/blockchain_snapshot_test.go
View file @
7b7b327f
...
@@ -675,7 +675,7 @@ func testSnapshot(t *testing.T, tt *snapshotTest) {
...
@@ -675,7 +675,7 @@ func testSnapshot(t *testing.T, tt *snapshotTest) {
if
_
,
err
:=
chain
.
InsertChain
(
blocks
[
startPoint
:
]);
err
!=
nil
{
if
_
,
err
:=
chain
.
InsertChain
(
blocks
[
startPoint
:
]);
err
!=
nil
{
t
.
Fatalf
(
"Failed to import canonical chain tail: %v"
,
err
)
t
.
Fatalf
(
"Failed to import canonical chain tail: %v"
,
err
)
}
}
// Set the flag for writing legacy journal if ncessary
// Set the flag for writing legacy journal if n
e
cessary
if
tt
.
legacy
{
if
tt
.
legacy
{
chain
.
writeLegacyJournal
=
true
chain
.
writeLegacyJournal
=
true
}
}
...
@@ -708,7 +708,6 @@ func testSnapshot(t *testing.T, tt *snapshotTest) {
...
@@ -708,7 +708,6 @@ func testSnapshot(t *testing.T, tt *snapshotTest) {
}
else
if
tt
.
gapped
>
0
{
}
else
if
tt
.
gapped
>
0
{
// Insert blocks without enabling snapshot if gapping is required.
// Insert blocks without enabling snapshot if gapping is required.
chain
.
Stop
()
chain
.
Stop
()
gappedBlocks
,
_
:=
GenerateChain
(
params
.
TestChainConfig
,
blocks
[
len
(
blocks
)
-
1
],
engine
,
gendb
,
tt
.
gapped
,
func
(
i
int
,
b
*
BlockGen
)
{})
gappedBlocks
,
_
:=
GenerateChain
(
params
.
TestChainConfig
,
blocks
[
len
(
blocks
)
-
1
],
engine
,
gendb
,
tt
.
gapped
,
func
(
i
int
,
b
*
BlockGen
)
{})
// Insert a few more blocks without enabling snapshot
// Insert a few more blocks without enabling snapshot
...
@@ -766,6 +765,7 @@ func testSnapshot(t *testing.T, tt *snapshotTest) {
...
@@ -766,6 +765,7 @@ func testSnapshot(t *testing.T, tt *snapshotTest) {
defer
chain
.
Stop
()
defer
chain
.
Stop
()
}
else
{
}
else
{
chain
.
Stop
()
chain
.
Stop
()
// Restart the chain normally
// Restart the chain normally
chain
,
err
=
NewBlockChain
(
db
,
nil
,
params
.
AllEthashProtocolChanges
,
engine
,
vm
.
Config
{},
nil
,
nil
)
chain
,
err
=
NewBlockChain
(
db
,
nil
,
params
.
AllEthashProtocolChanges
,
engine
,
vm
.
Config
{},
nil
,
nil
)
if
err
!=
nil
{
if
err
!=
nil
{
...
...
core/state/snapshot/generate.go
View file @
7b7b327f
...
@@ -19,6 +19,7 @@ package snapshot
...
@@ -19,6 +19,7 @@ package snapshot
import
(
import
(
"bytes"
"bytes"
"encoding/binary"
"encoding/binary"
"fmt"
"math/big"
"math/big"
"time"
"time"
...
@@ -116,6 +117,38 @@ func generateSnapshot(diskdb ethdb.KeyValueStore, triedb *trie.Database, cache i
...
@@ -116,6 +117,38 @@ func generateSnapshot(diskdb ethdb.KeyValueStore, triedb *trie.Database, cache i
return
base
return
base
}
}
// journalProgress persists the generator stats into the database to resume later.
func
journalProgress
(
db
ethdb
.
KeyValueWriter
,
marker
[]
byte
,
stats
*
generatorStats
)
{
// Write out the generator marker. Note it's a standalone disk layer generator
// which is not mixed with journal. It's ok if the generator is persisted while
// journal is not.
entry
:=
journalGenerator
{
Done
:
marker
==
nil
,
Marker
:
marker
,
}
if
stats
!=
nil
{
entry
.
Wiping
=
(
stats
.
wiping
!=
nil
)
entry
.
Accounts
=
stats
.
accounts
entry
.
Slots
=
stats
.
slots
entry
.
Storage
=
uint64
(
stats
.
storage
)
}
blob
,
err
:=
rlp
.
EncodeToBytes
(
entry
)
if
err
!=
nil
{
panic
(
err
)
// Cannot happen, here to catch dev errors
}
var
logstr
string
switch
len
(
marker
)
{
case
0
:
logstr
=
"done"
case
common
.
HashLength
:
logstr
=
fmt
.
Sprintf
(
"%#x"
,
marker
)
default
:
logstr
=
fmt
.
Sprintf
(
"%#x:%#x"
,
marker
[
:
common
.
HashLength
],
marker
[
common
.
HashLength
:
])
}
log
.
Debug
(
"Journalled generator progress"
,
"progress"
,
logstr
)
rawdb
.
WriteSnapshotGenerator
(
db
,
blob
)
}
// generate is a background thread that iterates over the state and storage tries,
// generate is a background thread that iterates over the state and storage tries,
// constructing the state snapshot. All the arguments are purely for statistics
// constructing the state snapshot. All the arguments are purely for statistics
// gethering and logging, since the method surfs the blocks as they arrive, often
// gethering and logging, since the method surfs the blocks as they arrive, often
...
@@ -187,11 +220,15 @@ func (dl *diskLayer) generate(stats *generatorStats) {
...
@@ -187,11 +220,15 @@ func (dl *diskLayer) generate(stats *generatorStats) {
if
batch
.
ValueSize
()
>
ethdb
.
IdealBatchSize
||
abort
!=
nil
{
if
batch
.
ValueSize
()
>
ethdb
.
IdealBatchSize
||
abort
!=
nil
{
// Only write and set the marker if we actually did something useful
// Only write and set the marker if we actually did something useful
if
batch
.
ValueSize
()
>
0
{
if
batch
.
ValueSize
()
>
0
{
// Ensure the generator entry is in sync with the data
marker
:=
accountHash
[
:
]
journalProgress
(
batch
,
marker
,
stats
)
batch
.
Write
()
batch
.
Write
()
batch
.
Reset
()
batch
.
Reset
()
dl
.
lock
.
Lock
()
dl
.
lock
.
Lock
()
dl
.
genMarker
=
accountHash
[
:
]
dl
.
genMarker
=
marker
dl
.
lock
.
Unlock
()
dl
.
lock
.
Unlock
()
}
}
if
abort
!=
nil
{
if
abort
!=
nil
{
...
@@ -228,11 +265,15 @@ func (dl *diskLayer) generate(stats *generatorStats) {
...
@@ -228,11 +265,15 @@ func (dl *diskLayer) generate(stats *generatorStats) {
if
batch
.
ValueSize
()
>
ethdb
.
IdealBatchSize
||
abort
!=
nil
{
if
batch
.
ValueSize
()
>
ethdb
.
IdealBatchSize
||
abort
!=
nil
{
// Only write and set the marker if we actually did something useful
// Only write and set the marker if we actually did something useful
if
batch
.
ValueSize
()
>
0
{
if
batch
.
ValueSize
()
>
0
{
// Ensure the generator entry is in sync with the data
marker
:=
append
(
accountHash
[
:
],
storeIt
.
Key
...
)
journalProgress
(
batch
,
marker
,
stats
)
batch
.
Write
()
batch
.
Write
()
batch
.
Reset
()
batch
.
Reset
()
dl
.
lock
.
Lock
()
dl
.
lock
.
Lock
()
dl
.
genMarker
=
append
(
accountHash
[
:
],
storeIt
.
Key
...
)
dl
.
genMarker
=
marker
dl
.
lock
.
Unlock
()
dl
.
lock
.
Unlock
()
}
}
if
abort
!=
nil
{
if
abort
!=
nil
{
...
@@ -264,6 +305,9 @@ func (dl *diskLayer) generate(stats *generatorStats) {
...
@@ -264,6 +305,9 @@ func (dl *diskLayer) generate(stats *generatorStats) {
}
}
// Snapshot fully generated, set the marker to nil
// Snapshot fully generated, set the marker to nil
if
batch
.
ValueSize
()
>
0
{
if
batch
.
ValueSize
()
>
0
{
// Ensure the generator entry is in sync with the data
journalProgress
(
batch
,
nil
,
stats
)
batch
.
Write
()
batch
.
Write
()
}
}
log
.
Info
(
"Generated state snapshot"
,
"accounts"
,
stats
.
accounts
,
"slots"
,
stats
.
slots
,
log
.
Info
(
"Generated state snapshot"
,
"accounts"
,
stats
.
accounts
,
"slots"
,
stats
.
slots
,
...
...
core/state/snapshot/journal.go
View file @
7b7b327f
...
@@ -276,8 +276,8 @@ func loadDiffLayer(parent snapshot, r *rlp.Stream) (snapshot, error) {
...
@@ -276,8 +276,8 @@ func loadDiffLayer(parent snapshot, r *rlp.Stream) (snapshot, error) {
return
loadDiffLayer
(
newDiffLayer
(
parent
,
root
,
destructSet
,
accountData
,
storageData
),
r
)
return
loadDiffLayer
(
newDiffLayer
(
parent
,
root
,
destructSet
,
accountData
,
storageData
),
r
)
}
}
// Journal
writes the persistent layer generator stats into a buffer to be stored
// Journal
terminates any in-progress snapshot generation, also implicitly pushing
//
in the database as the snapshot journal
.
//
the progress into the database
.
func
(
dl
*
diskLayer
)
Journal
(
buffer
*
bytes
.
Buffer
)
(
common
.
Hash
,
error
)
{
func
(
dl
*
diskLayer
)
Journal
(
buffer
*
bytes
.
Buffer
)
(
common
.
Hash
,
error
)
{
// If the snapshot is currently being generated, abort it
// If the snapshot is currently being generated, abort it
var
stats
*
generatorStats
var
stats
*
generatorStats
...
@@ -296,25 +296,10 @@ func (dl *diskLayer) Journal(buffer *bytes.Buffer) (common.Hash, error) {
...
@@ -296,25 +296,10 @@ func (dl *diskLayer) Journal(buffer *bytes.Buffer) (common.Hash, error) {
if
dl
.
stale
{
if
dl
.
stale
{
return
common
.
Hash
{},
ErrSnapshotStale
return
common
.
Hash
{},
ErrSnapshotStale
}
}
// Write out the generator marker. Note it's a standalone disk layer generator
// Ensure the generator stats is written even if none was ran this cycle
// which is not mixed with journal. It's ok if the generator is persisted while
journalProgress
(
dl
.
diskdb
,
dl
.
genMarker
,
stats
)
// journal is not.
entry
:=
journalGenerator
{
log
.
Debug
(
"Journalled disk layer"
,
"root"
,
dl
.
root
)
Done
:
dl
.
genMarker
==
nil
,
Marker
:
dl
.
genMarker
,
}
if
stats
!=
nil
{
entry
.
Wiping
=
(
stats
.
wiping
!=
nil
)
entry
.
Accounts
=
stats
.
accounts
entry
.
Slots
=
stats
.
slots
entry
.
Storage
=
uint64
(
stats
.
storage
)
}
blob
,
err
:=
rlp
.
EncodeToBytes
(
entry
)
if
err
!=
nil
{
return
common
.
Hash
{},
err
}
log
.
Debug
(
"Journalled disk layer"
,
"root"
,
dl
.
root
,
"complete"
,
dl
.
genMarker
==
nil
)
rawdb
.
WriteSnapshotGenerator
(
dl
.
diskdb
,
blob
)
return
dl
.
root
,
nil
return
dl
.
root
,
nil
}
}
...
@@ -401,6 +386,7 @@ func (dl *diskLayer) LegacyJournal(buffer *bytes.Buffer) (common.Hash, error) {
...
@@ -401,6 +386,7 @@ func (dl *diskLayer) LegacyJournal(buffer *bytes.Buffer) (common.Hash, error) {
entry
.
Slots
=
stats
.
slots
entry
.
Slots
=
stats
.
slots
entry
.
Storage
=
uint64
(
stats
.
storage
)
entry
.
Storage
=
uint64
(
stats
.
storage
)
}
}
log
.
Debug
(
"Legacy journalled disk layer"
,
"root"
,
dl
.
root
)
if
err
:=
rlp
.
Encode
(
buffer
,
entry
);
err
!=
nil
{
if
err
:=
rlp
.
Encode
(
buffer
,
entry
);
err
!=
nil
{
return
common
.
Hash
{},
err
return
common
.
Hash
{},
err
}
}
...
@@ -455,6 +441,6 @@ func (dl *diffLayer) LegacyJournal(buffer *bytes.Buffer) (common.Hash, error) {
...
@@ -455,6 +441,6 @@ func (dl *diffLayer) LegacyJournal(buffer *bytes.Buffer) (common.Hash, error) {
if
err
:=
rlp
.
Encode
(
buffer
,
storage
);
err
!=
nil
{
if
err
:=
rlp
.
Encode
(
buffer
,
storage
);
err
!=
nil
{
return
common
.
Hash
{},
err
return
common
.
Hash
{},
err
}
}
log
.
Debug
(
"
Journalled diff
layer"
,
"root"
,
dl
.
root
,
"parent"
,
dl
.
parent
.
Root
())
log
.
Debug
(
"
Legacy journalled disk
layer"
,
"root"
,
dl
.
root
,
"parent"
,
dl
.
parent
.
Root
())
return
base
,
nil
return
base
,
nil
}
}
core/state/snapshot/snapshot.go
View file @
7b7b327f
...
@@ -512,22 +512,8 @@ func diffToDisk(bottom *diffLayer) *diskLayer {
...
@@ -512,22 +512,8 @@ func diffToDisk(bottom *diffLayer) *diskLayer {
// Update the snapshot block marker and write any remainder data
// Update the snapshot block marker and write any remainder data
rawdb
.
WriteSnapshotRoot
(
batch
,
bottom
.
root
)
rawdb
.
WriteSnapshotRoot
(
batch
,
bottom
.
root
)
// Write out the generator marker
// Write out the generator progress marker and report
entry
:=
journalGenerator
{
journalProgress
(
batch
,
base
.
genMarker
,
stats
)
Done
:
base
.
genMarker
==
nil
,
Marker
:
base
.
genMarker
,
}
if
stats
!=
nil
{
entry
.
Wiping
=
(
stats
.
wiping
!=
nil
)
entry
.
Accounts
=
stats
.
accounts
entry
.
Slots
=
stats
.
slots
entry
.
Storage
=
uint64
(
stats
.
storage
)
}
blob
,
err
:=
rlp
.
EncodeToBytes
(
entry
)
if
err
!=
nil
{
panic
(
fmt
.
Sprintf
(
"Failed to RLP encode generator %v"
,
err
))
}
rawdb
.
WriteSnapshotGenerator
(
batch
,
blob
)
// Flush all the updates in the single db operation. Ensure the
// Flush all the updates in the single db operation. Ensure the
// disk layer transition is atomic.
// disk layer transition is atomic.
...
...
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