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
90d25514
Unverified
Commit
90d25514
authored
Feb 21, 2023
by
Péter Szilágyi
Committed by
GitHub
Feb 21, 2023
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
core, eth: merge snap-sync chain download progress logs (#26676)
parent
7d4db696
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
106 additions
and
42 deletions
+106
-42
blockchain.go
core/blockchain.go
+1
-1
headerchain.go
core/headerchain.go
+1
-1
accessors_chain.go
core/rawdb/accessors_chain.go
+13
-13
ancient_scheme.go
core/rawdb/ancient_scheme.go
+15
-15
chain_freezer.go
core/rawdb/chain_freezer.go
+5
-5
chain_iterator.go
core/rawdb/chain_iterator.go
+1
-1
database.go
core/rawdb/database.go
+1
-1
downloader.go
eth/downloader/downloader.go
+64
-1
queue.go
eth/downloader/queue.go
+5
-4
No files found.
core/blockchain.go
View file @
90d25514
...
...
@@ -1278,7 +1278,7 @@ func (bc *BlockChain) InsertReceiptChain(blockChain types.Blocks, receiptChain [
if
stats
.
ignored
>
0
{
context
=
append
(
context
,
[]
interface
{}{
"ignored"
,
stats
.
ignored
}
...
)
}
log
.
Info
(
"Imported new block receipts"
,
context
...
)
log
.
Debug
(
"Imported new block receipts"
,
context
...
)
return
0
,
nil
}
...
...
core/headerchain.go
View file @
90d25514
...
...
@@ -389,7 +389,7 @@ func (hc *HeaderChain) InsertHeaderChain(chain []*types.Header, start time.Time,
if
res
.
ignored
>
0
{
context
=
append
(
context
,
[]
interface
{}{
"ignored"
,
res
.
ignored
}
...
)
}
log
.
Info
(
"Imported new block headers"
,
context
...
)
log
.
Debug
(
"Imported new block headers"
,
context
...
)
return
res
.
status
,
err
}
...
...
core/rawdb/accessors_chain.go
View file @
90d25514
...
...
@@ -37,7 +37,7 @@ import (
func
ReadCanonicalHash
(
db
ethdb
.
Reader
,
number
uint64
)
common
.
Hash
{
var
data
[]
byte
db
.
ReadAncients
(
func
(
reader
ethdb
.
AncientReaderOp
)
error
{
data
,
_
=
reader
.
Ancient
(
c
hainFreezerHashTable
,
number
)
data
,
_
=
reader
.
Ancient
(
C
hainFreezerHashTable
,
number
)
if
len
(
data
)
==
0
{
// Get it by hash from leveldb
data
,
_
=
db
.
Get
(
headerHashKey
(
number
))
...
...
@@ -334,7 +334,7 @@ func ReadHeaderRange(db ethdb.Reader, number uint64, count uint64) []rlp.RawValu
}
// read remaining from ancients
max
:=
count
*
700
data
,
err
:=
db
.
AncientRange
(
c
hainFreezerHeaderTable
,
i
+
1
-
count
,
count
,
max
)
data
,
err
:=
db
.
AncientRange
(
C
hainFreezerHeaderTable
,
i
+
1
-
count
,
count
,
max
)
if
err
==
nil
&&
uint64
(
len
(
data
))
==
count
{
// the data is on the order [h, h+1, .., n] -- reordering needed
for
i
:=
range
data
{
...
...
@@ -351,7 +351,7 @@ func ReadHeaderRLP(db ethdb.Reader, hash common.Hash, number uint64) rlp.RawValu
// First try to look up the data in ancient database. Extra hash
// comparison is necessary since ancient database only maintains
// the canonical data.
data
,
_
=
reader
.
Ancient
(
c
hainFreezerHeaderTable
,
number
)
data
,
_
=
reader
.
Ancient
(
C
hainFreezerHeaderTable
,
number
)
if
len
(
data
)
>
0
&&
crypto
.
Keccak256Hash
(
data
)
==
hash
{
return
nil
}
...
...
@@ -427,7 +427,7 @@ func deleteHeaderWithoutNumber(db ethdb.KeyValueWriter, hash common.Hash, number
// isCanon is an internal utility method, to check whether the given number/hash
// is part of the ancient (canon) set.
func
isCanon
(
reader
ethdb
.
AncientReaderOp
,
number
uint64
,
hash
common
.
Hash
)
bool
{
h
,
err
:=
reader
.
Ancient
(
c
hainFreezerHashTable
,
number
)
h
,
err
:=
reader
.
Ancient
(
C
hainFreezerHashTable
,
number
)
if
err
!=
nil
{
return
false
}
...
...
@@ -443,7 +443,7 @@ func ReadBodyRLP(db ethdb.Reader, hash common.Hash, number uint64) rlp.RawValue
db
.
ReadAncients
(
func
(
reader
ethdb
.
AncientReaderOp
)
error
{
// Check if the data is in ancients
if
isCanon
(
reader
,
number
,
hash
)
{
data
,
_
=
reader
.
Ancient
(
c
hainFreezerBodiesTable
,
number
)
data
,
_
=
reader
.
Ancient
(
C
hainFreezerBodiesTable
,
number
)
return
nil
}
// If not, try reading from leveldb
...
...
@@ -458,7 +458,7 @@ func ReadBodyRLP(db ethdb.Reader, hash common.Hash, number uint64) rlp.RawValue
func
ReadCanonicalBodyRLP
(
db
ethdb
.
Reader
,
number
uint64
)
rlp
.
RawValue
{
var
data
[]
byte
db
.
ReadAncients
(
func
(
reader
ethdb
.
AncientReaderOp
)
error
{
data
,
_
=
reader
.
Ancient
(
c
hainFreezerBodiesTable
,
number
)
data
,
_
=
reader
.
Ancient
(
C
hainFreezerBodiesTable
,
number
)
if
len
(
data
)
>
0
{
return
nil
}
...
...
@@ -526,7 +526,7 @@ func ReadTdRLP(db ethdb.Reader, hash common.Hash, number uint64) rlp.RawValue {
db
.
ReadAncients
(
func
(
reader
ethdb
.
AncientReaderOp
)
error
{
// Check if the data is in ancients
if
isCanon
(
reader
,
number
,
hash
)
{
data
,
_
=
reader
.
Ancient
(
c
hainFreezerDifficultyTable
,
number
)
data
,
_
=
reader
.
Ancient
(
C
hainFreezerDifficultyTable
,
number
)
return
nil
}
// If not, try reading from leveldb
...
...
@@ -586,7 +586,7 @@ func ReadReceiptsRLP(db ethdb.Reader, hash common.Hash, number uint64) rlp.RawVa
db
.
ReadAncients
(
func
(
reader
ethdb
.
AncientReaderOp
)
error
{
// Check if the data is in ancients
if
isCanon
(
reader
,
number
,
hash
)
{
data
,
_
=
reader
.
Ancient
(
c
hainFreezerReceiptTable
,
number
)
data
,
_
=
reader
.
Ancient
(
C
hainFreezerReceiptTable
,
number
)
return
nil
}
// If not, try reading from leveldb
...
...
@@ -787,19 +787,19 @@ func WriteAncientBlocks(db ethdb.AncientWriter, blocks []*types.Block, receipts
func
writeAncientBlock
(
op
ethdb
.
AncientWriteOp
,
block
*
types
.
Block
,
header
*
types
.
Header
,
receipts
[]
*
types
.
ReceiptForStorage
,
td
*
big
.
Int
)
error
{
num
:=
block
.
NumberU64
()
if
err
:=
op
.
AppendRaw
(
c
hainFreezerHashTable
,
num
,
block
.
Hash
()
.
Bytes
());
err
!=
nil
{
if
err
:=
op
.
AppendRaw
(
C
hainFreezerHashTable
,
num
,
block
.
Hash
()
.
Bytes
());
err
!=
nil
{
return
fmt
.
Errorf
(
"can't add block %d hash: %v"
,
num
,
err
)
}
if
err
:=
op
.
Append
(
c
hainFreezerHeaderTable
,
num
,
header
);
err
!=
nil
{
if
err
:=
op
.
Append
(
C
hainFreezerHeaderTable
,
num
,
header
);
err
!=
nil
{
return
fmt
.
Errorf
(
"can't append block header %d: %v"
,
num
,
err
)
}
if
err
:=
op
.
Append
(
c
hainFreezerBodiesTable
,
num
,
block
.
Body
());
err
!=
nil
{
if
err
:=
op
.
Append
(
C
hainFreezerBodiesTable
,
num
,
block
.
Body
());
err
!=
nil
{
return
fmt
.
Errorf
(
"can't append block body %d: %v"
,
num
,
err
)
}
if
err
:=
op
.
Append
(
c
hainFreezerReceiptTable
,
num
,
receipts
);
err
!=
nil
{
if
err
:=
op
.
Append
(
C
hainFreezerReceiptTable
,
num
,
receipts
);
err
!=
nil
{
return
fmt
.
Errorf
(
"can't append block %d receipts: %v"
,
num
,
err
)
}
if
err
:=
op
.
Append
(
c
hainFreezerDifficultyTable
,
num
,
td
);
err
!=
nil
{
if
err
:=
op
.
Append
(
C
hainFreezerDifficultyTable
,
num
,
td
);
err
!=
nil
{
return
fmt
.
Errorf
(
"can't append block %d total difficulty: %v"
,
num
,
err
)
}
return
nil
...
...
core/rawdb/ancient_scheme.go
View file @
90d25514
...
...
@@ -18,30 +18,30 @@ package rawdb
// The list of table names of chain freezer.
const
(
//
c
hainFreezerHeaderTable indicates the name of the freezer header table.
c
hainFreezerHeaderTable
=
"headers"
//
C
hainFreezerHeaderTable indicates the name of the freezer header table.
C
hainFreezerHeaderTable
=
"headers"
//
c
hainFreezerHashTable indicates the name of the freezer canonical hash table.
c
hainFreezerHashTable
=
"hashes"
//
C
hainFreezerHashTable indicates the name of the freezer canonical hash table.
C
hainFreezerHashTable
=
"hashes"
//
c
hainFreezerBodiesTable indicates the name of the freezer block body table.
c
hainFreezerBodiesTable
=
"bodies"
//
C
hainFreezerBodiesTable indicates the name of the freezer block body table.
C
hainFreezerBodiesTable
=
"bodies"
//
c
hainFreezerReceiptTable indicates the name of the freezer receipts table.
c
hainFreezerReceiptTable
=
"receipts"
//
C
hainFreezerReceiptTable indicates the name of the freezer receipts table.
C
hainFreezerReceiptTable
=
"receipts"
//
c
hainFreezerDifficultyTable indicates the name of the freezer total difficulty table.
c
hainFreezerDifficultyTable
=
"diffs"
//
C
hainFreezerDifficultyTable indicates the name of the freezer total difficulty table.
C
hainFreezerDifficultyTable
=
"diffs"
)
// chainFreezerNoSnappy configures whether compression is disabled for the ancient-tables.
// Hashes and difficulties don't compress well.
var
chainFreezerNoSnappy
=
map
[
string
]
bool
{
c
hainFreezerHeaderTable
:
false
,
c
hainFreezerHashTable
:
true
,
c
hainFreezerBodiesTable
:
false
,
c
hainFreezerReceiptTable
:
false
,
c
hainFreezerDifficultyTable
:
true
,
C
hainFreezerHeaderTable
:
false
,
C
hainFreezerHashTable
:
true
,
C
hainFreezerBodiesTable
:
false
,
C
hainFreezerReceiptTable
:
false
,
C
hainFreezerDifficultyTable
:
true
,
}
// The list of identifiers of ancient stores.
...
...
core/rawdb/chain_freezer.go
View file @
90d25514
...
...
@@ -280,19 +280,19 @@ func (f *chainFreezer) freezeRange(nfdb *nofreezedb, number, limit uint64) (hash
}
// Write to the batch.
if
err
:=
op
.
AppendRaw
(
c
hainFreezerHashTable
,
number
,
hash
[
:
]);
err
!=
nil
{
if
err
:=
op
.
AppendRaw
(
C
hainFreezerHashTable
,
number
,
hash
[
:
]);
err
!=
nil
{
return
fmt
.
Errorf
(
"can't write hash to Freezer: %v"
,
err
)
}
if
err
:=
op
.
AppendRaw
(
c
hainFreezerHeaderTable
,
number
,
header
);
err
!=
nil
{
if
err
:=
op
.
AppendRaw
(
C
hainFreezerHeaderTable
,
number
,
header
);
err
!=
nil
{
return
fmt
.
Errorf
(
"can't write header to Freezer: %v"
,
err
)
}
if
err
:=
op
.
AppendRaw
(
c
hainFreezerBodiesTable
,
number
,
body
);
err
!=
nil
{
if
err
:=
op
.
AppendRaw
(
C
hainFreezerBodiesTable
,
number
,
body
);
err
!=
nil
{
return
fmt
.
Errorf
(
"can't write body to Freezer: %v"
,
err
)
}
if
err
:=
op
.
AppendRaw
(
c
hainFreezerReceiptTable
,
number
,
receipts
);
err
!=
nil
{
if
err
:=
op
.
AppendRaw
(
C
hainFreezerReceiptTable
,
number
,
receipts
);
err
!=
nil
{
return
fmt
.
Errorf
(
"can't write receipts to Freezer: %v"
,
err
)
}
if
err
:=
op
.
AppendRaw
(
c
hainFreezerDifficultyTable
,
number
,
td
);
err
!=
nil
{
if
err
:=
op
.
AppendRaw
(
C
hainFreezerDifficultyTable
,
number
,
td
);
err
!=
nil
{
return
fmt
.
Errorf
(
"can't write td to Freezer: %v"
,
err
)
}
...
...
core/rawdb/chain_iterator.go
View file @
90d25514
...
...
@@ -50,7 +50,7 @@ func InitDatabaseFromFreezer(db ethdb.Database) {
if
i
+
count
>
frozen
{
count
=
frozen
-
i
}
data
,
err
:=
db
.
AncientRange
(
c
hainFreezerHashTable
,
i
,
count
,
32
*
count
)
data
,
err
:=
db
.
AncientRange
(
C
hainFreezerHashTable
,
i
,
count
,
32
*
count
)
if
err
!=
nil
{
log
.
Crit
(
"Failed to init database from freezer"
,
"err"
,
err
)
}
...
...
core/rawdb/database.go
View file @
90d25514
...
...
@@ -231,7 +231,7 @@ func NewDatabaseWithFreezer(db ethdb.KeyValueStore, ancient string, namespace st
// If the freezer already contains something, ensure that the genesis blocks
// match, otherwise we might mix up freezers across chains and destroy both
// the freezer and the key-value store.
frgenesis
,
err
:=
frdb
.
Ancient
(
c
hainFreezerHashTable
,
0
)
frgenesis
,
err
:=
frdb
.
Ancient
(
C
hainFreezerHashTable
,
0
)
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"failed to retrieve genesis from ancient %v"
,
err
)
}
else
if
!
bytes
.
Equal
(
kvgenesis
,
frgenesis
)
{
...
...
eth/downloader/downloader.go
View file @
90d25514
...
...
@@ -154,6 +154,11 @@ type Downloader struct {
bodyFetchHook
func
([]
*
types
.
Header
)
// Method to call upon starting a block body fetch
receiptFetchHook
func
([]
*
types
.
Header
)
// Method to call upon starting a receipt fetch
chainInsertHook
func
([]
*
fetchResult
)
// Method to call upon inserting a chain of blocks (possibly in multiple invocations)
// Progress reporting metrics
syncStartBlock
uint64
// Head snap block when Geth was started
syncStartTime
time
.
Time
// Time instance when chain sync started
syncLogTime
time
.
Time
// Time instance when status was last reported
}
// LightChain encapsulates functions required to synchronise a light chain.
...
...
@@ -231,7 +236,9 @@ func New(checkpoint uint64, stateDb ethdb.Database, mux *event.TypeMux, chain Bl
quitCh
:
make
(
chan
struct
{}),
SnapSyncer
:
snap
.
NewSyncer
(
stateDb
,
chain
.
TrieDB
()
.
Scheme
()),
stateSyncStart
:
make
(
chan
*
stateSync
),
syncStartBlock
:
chain
.
CurrentFastBlock
()
.
NumberU64
(),
}
// Create the post-merge skeleton syncer and start the process
dl
.
skeleton
=
newSkeleton
(
stateDb
,
dl
.
peers
,
dropPeer
,
newBeaconBackfiller
(
dl
,
success
))
go
dl
.
stateFetcher
()
...
...
@@ -1614,6 +1621,7 @@ func (d *Downloader) processSnapSyncContent() error {
if
len
(
results
)
==
0
{
// If pivot sync is done, stop
if
oldPivot
==
nil
{
d
.
reportSnapSyncProgress
(
true
)
return
sync
.
Cancel
()
}
// If sync failed, stop
...
...
@@ -1627,6 +1635,8 @@ func (d *Downloader) processSnapSyncContent() error {
if
d
.
chainInsertHook
!=
nil
{
d
.
chainInsertHook
(
results
)
}
d
.
reportSnapSyncProgress
(
false
)
// If we haven't downloaded the pivot block yet, check pivot staleness
// notifications from the header downloader
d
.
pivotLock
.
RLock
()
...
...
@@ -1739,7 +1749,7 @@ func (d *Downloader) commitSnapSyncData(results []*fetchResult, stateSync *state
}
default
:
}
// Retrieve the
a
batch of results to import
// Retrieve the batch of results to import
first
,
last
:=
results
[
0
]
.
Header
,
results
[
len
(
results
)
-
1
]
.
Header
log
.
Debug
(
"Inserting snap-sync blocks"
,
"items"
,
len
(
results
),
"firstnum"
,
first
.
Number
,
"firsthash"
,
first
.
Hash
(),
...
...
@@ -1820,3 +1830,56 @@ func (d *Downloader) readHeaderRange(last *types.Header, count int) []*types.Hea
}
return
headers
}
// reportSnapSyncProgress calculates various status reports and provides it to the user.
func
(
d
*
Downloader
)
reportSnapSyncProgress
(
force
bool
)
{
// Initialize the sync start time if it's the first time we're reporting
if
d
.
syncStartTime
.
IsZero
()
{
d
.
syncStartTime
=
time
.
Now
()
.
Add
(
-
time
.
Millisecond
)
// -1ms offset to avoid division by zero
}
// Don't report all the events, just occasionally
if
!
force
&&
time
.
Since
(
d
.
syncLogTime
)
<
8
*
time
.
Second
{
return
}
// Don't report anything until we have a meaningful progress
var
(
headerBytes
,
_
=
d
.
stateDB
.
AncientSize
(
rawdb
.
ChainFreezerHeaderTable
)
bodyBytes
,
_
=
d
.
stateDB
.
AncientSize
(
rawdb
.
ChainFreezerBodiesTable
)
receiptBytes
,
_
=
d
.
stateDB
.
AncientSize
(
rawdb
.
ChainFreezerReceiptTable
)
)
syncedBytes
:=
common
.
StorageSize
(
headerBytes
+
bodyBytes
+
receiptBytes
)
if
syncedBytes
==
0
{
return
}
var
(
header
=
d
.
blockchain
.
CurrentHeader
()
block
=
d
.
blockchain
.
CurrentFastBlock
()
)
syncedBlocks
:=
block
.
NumberU64
()
-
d
.
syncStartBlock
if
syncedBlocks
==
0
{
return
}
// Retrieve the current chain head and calculate the ETA
latest
,
_
,
err
:=
d
.
skeleton
.
Bounds
()
if
err
!=
nil
{
// We're going to cheat for non-merged networks, but that's fine
latest
=
d
.
pivotHeader
}
if
latest
==
nil
{
// This should really never happen, but add some defensive code for now.
// TODO(karalabe): Remove it eventually if we don't see it blow.
log
.
Error
(
"Nil latest block in sync progress report"
)
return
}
var
(
left
=
latest
.
Number
.
Uint64
()
-
block
.
NumberU64
()
eta
=
time
.
Since
(
d
.
syncStartTime
)
/
time
.
Duration
(
syncedBlocks
)
*
time
.
Duration
(
left
)
progress
=
fmt
.
Sprintf
(
"%.2f%%"
,
float64
(
block
.
NumberU64
())
*
100
/
float64
(
latest
.
Number
.
Uint64
()))
headers
=
fmt
.
Sprintf
(
"%v@%v"
,
log
.
FormatLogfmtUint64
(
header
.
Number
.
Uint64
()),
common
.
StorageSize
(
headerBytes
)
.
TerminalString
())
bodies
=
fmt
.
Sprintf
(
"%v@%v"
,
log
.
FormatLogfmtUint64
(
block
.
NumberU64
()),
common
.
StorageSize
(
bodyBytes
)
.
TerminalString
())
receipts
=
fmt
.
Sprintf
(
"%v@%v"
,
log
.
FormatLogfmtUint64
(
block
.
NumberU64
()),
common
.
StorageSize
(
receiptBytes
)
.
TerminalString
())
)
log
.
Info
(
"Syncing: chain download in progress"
,
"synced"
,
progress
,
"chain"
,
syncedBytes
,
"headers"
,
headers
,
"bodies"
,
bodies
,
"receipts"
,
receipts
,
"eta"
,
common
.
PrettyDuration
(
eta
))
d
.
syncLogTime
=
time
.
Now
()
}
eth/downloader/queue.go
View file @
90d25514
...
...
@@ -144,7 +144,7 @@ type queue struct {
active
*
sync
.
Cond
closed
bool
l
astStatLog
time
.
Time
l
ogTime
time
.
Time
// Time instance when status was last reported
}
// newQueue creates a new download queue for scheduling block retrieval.
...
...
@@ -390,11 +390,12 @@ func (q *queue) Results(block bool) []*fetchResult {
}
}
// Log some info at certain times
if
time
.
Since
(
q
.
lastStatLog
)
>
60
*
time
.
Second
{
q
.
lastStatLog
=
time
.
Now
()
if
time
.
Since
(
q
.
logTime
)
>=
60
*
time
.
Second
{
q
.
logTime
=
time
.
Now
()
info
:=
q
.
Stats
()
info
=
append
(
info
,
"throttle"
,
throttleThreshold
)
log
.
Info
(
"Downloader queue stats"
,
info
...
)
log
.
Debug
(
"Downloader queue stats"
,
info
...
)
}
return
results
}
...
...
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