@@ -27,7 +27,6 @@ import (
2727
2828 "github.com/XinFinOrg/XDPoSChain"
2929 "github.com/XinFinOrg/XDPoSChain/common"
30- "github.com/XinFinOrg/XDPoSChain/core/rawdb"
3130 "github.com/XinFinOrg/XDPoSChain/core/types"
3231 "github.com/XinFinOrg/XDPoSChain/ethdb"
3332 "github.com/XinFinOrg/XDPoSChain/event"
4645 MaxSkeletonSize = 128 // Number of header fetches to need for a skeleton assembly
4746 MaxBodyFetch = 128 // Amount of block bodies to be fetched per retrieval request
4847 MaxReceiptFetch = 256 // Amount of transaction receipts to allow fetching per request
49- MaxStateFetch = 384 // Amount of node state values to allow fetching per request
5048
5149 MaxForkAncestry = 3 * params .EpochDuration // Maximum chain reorganisation
5250 rttMinEstimate = 2 * time .Second // Minimum round-trip time to target for download requests
@@ -66,11 +64,11 @@ var (
6664 reorgProtThreshold = 48 // Threshold number of recent blocks to disable mini reorg protection
6765 reorgProtHeaderDelay = 2 // Number of headers to delay delivering to cover mini reorgs
6866
69- fsHeaderCheckFrequency = 100 // Verification frequency of the downloaded headers during fast sync
67+ fsHeaderCheckFrequency = 100 // Verification frequency of the downloaded headers during snap sync
7068 fsHeaderSafetyNet = 2048 // Number of headers to discard in case a chain violation is detected
7169 fsHeaderForceVerify = 24 // Number of headers to verify before and after the pivot to accept it
7270 fsHeaderContCheck = 3 * time .Second // Time interval to check for header continuations during state download
73- fsMinFullBlocks = 64 // Number of blocks to retrieve fully even in fast sync
71+ fsMinFullBlocks = 64 // Number of blocks to retrieve fully even in snap sync
7472)
7573
7674var (
@@ -89,11 +87,13 @@ var (
8987 errCancelStateFetch = errors .New ("state data download canceled (requested)" )
9088 errCancelContentProcessing = errors .New ("content processing canceled (requested)" )
9189 errCanceled = errors .New ("syncing canceled (requested)" )
92- errNoSyncActive = errors .New ("no sync active" )
9390 errTooOld = errors .New ("peer doesn't speak recent enough protocol version (need version >= 62)" )
9491 errEnoughBlock = errors .New ("downloader download enough block" )
9592)
9693
94+ // peerDropFn is a callback type for dropping a peer detected as malicious.
95+ type peerDropFn func (id string )
96+
9797type Downloader struct {
9898 mode uint32 // Synchronisation mode defining the strategy used (per sync cycle)
9999 mux * event.TypeMux // Event multiplexer to announce sync operation events
@@ -106,9 +106,8 @@ type Downloader struct {
106106 rttConfidence uint64 // Confidence in the estimated RTT (unit: millionths to allow atomic ops)
107107
108108 // Statistics
109- syncStatsChainOrigin uint64 // Origin block number where syncing started at
110- syncStatsChainHeight uint64 // Highest block number known when syncing started
111- syncStatsState stateSyncStats
109+ syncStatsChainOrigin uint64 // Origin block number where syncing started at
110+ syncStatsChainHeight uint64 // Highest block number known when syncing started
112111 syncStatsLock sync.RWMutex // Lock protecting the sync stats fields
113112
114113 lightchain LightChain
@@ -125,20 +124,13 @@ type Downloader struct {
125124 committed int32
126125
127126 // Channels
128- headerCh chan dataPack // [eth/62] Channel receiving inbound block headers
129- bodyCh chan dataPack // [eth/62] Channel receiving inbound block bodies
130- receiptCh chan dataPack // [eth/63] Channel receiving inbound receipts
131- bodyWakeCh chan bool // [eth/62] Channel to signal the block body fetcher of new tasks
132- receiptWakeCh chan bool // [eth/63] Channel to signal the receipt fetcher of new tasks
133- headerProcCh chan []* types.Header // [eth/62] Channel to feed the header processor new tasks
127+ headerProcCh chan []* types.Header // Channel to feed the header processor new tasks
134128
135129 // State sync
136130 pivotHeader * types.Header // Pivot block header to dynamically push the syncing state root
137131 pivotLock sync.RWMutex // Lock protecting pivot header reads from updates
138132
139133 stateSyncStart chan * stateSync
140- trackStateReq chan * stateReq
141- stateCh chan dataPack // [eth/63] Channel receiving inbound node state data
142134
143135 // Cancellation and termination
144136 cancelPeer string // Identifier of the peer currently being used as the master (cancel on drop)
@@ -177,15 +169,15 @@ type LightChain interface {
177169 Rollback ([]common.Hash )
178170}
179171
180- // BlockChain encapsulates functions required to sync a (full or fast ) blockchain.
172+ // BlockChain encapsulates functions required to sync a (full or snap ) blockchain.
181173type BlockChain interface {
182174 Config () * params.ChainConfig
183175 LightChain
184176
185177 // HasBlock verifies a block's presence in the local chain.
186178 HasBlock (common.Hash , uint64 ) bool
187179
188- // HasFastBlock verifies a fast block's presence in the local chain.
180+ // HasFastBlock verifies a snap block's presence in the local chain.
189181 HasFastBlock (common.Hash , uint64 ) bool
190182
191183 // GetBlockByHash retrieves a block from the local chain.
@@ -194,11 +186,11 @@ type BlockChain interface {
194186 // CurrentBlock retrieves the head block from the local chain.
195187 CurrentBlock () * types.Block
196188
197- // CurrentFastBlock retrieves the head fast block from the local chain.
189+ // CurrentFastBlock retrieves the head snap block from the local chain.
198190 CurrentFastBlock () * types.Block
199191
200- // FastSyncCommitHead directly commits the head block to a certain entity.
201- FastSyncCommitHead (common.Hash ) error
192+ // SnapSyncCommitHead directly commits the head block to a certain entity.
193+ SnapSyncCommitHead (common.Hash ) error
202194
203195 // InsertChain inserts a batch of blocks into the local chain.
204196 InsertChain (types.Blocks ) (int , error )
@@ -224,19 +216,9 @@ func New(stateDb ethdb.Database, mux *event.TypeMux, chain BlockChain, lightchai
224216 lightchain : lightchain ,
225217 dropPeer : dropPeer ,
226218 handleProposedBlock : handleProposedBlock ,
227- headerCh : make (chan dataPack , 1 ),
228- bodyCh : make (chan dataPack , 1 ),
229- receiptCh : make (chan dataPack , 1 ),
230- bodyWakeCh : make (chan bool , 1 ),
231- receiptWakeCh : make (chan bool , 1 ),
232219 headerProcCh : make (chan []* types.Header , 1 ),
233220 quitCh : make (chan struct {}),
234- stateCh : make (chan dataPack ),
235221 stateSyncStart : make (chan * stateSync ),
236- syncStatsState : stateSyncStats {
237- processed : rawdb .ReadFastTrieProgress (stateDb ),
238- },
239- trackStateReq : make (chan * stateReq ),
240222 }
241223 go dl .qosTuner ()
242224 go dl .stateFetcher ()
@@ -247,7 +229,7 @@ func New(stateDb ethdb.Database, mux *event.TypeMux, chain BlockChain, lightchai
247229// block where synchronisation started at (may have failed/suspended); the block
248230// or header sync is currently at; and the latest known block which the sync targets.
249231//
250- // In addition, during the state download phase of fast synchronisation the number
232+ // In addition, during the state download phase of snap synchronisation the number
251233// of processed and the total number of known states are also returned. Otherwise
252234// these are zero.
253235func (d * Downloader ) Progress () XDPoSChain.SyncProgress {
@@ -260,19 +242,31 @@ func (d *Downloader) Progress() XDPoSChain.SyncProgress {
260242 switch {
261243 case d .blockchain != nil && mode == FullSync :
262244 current = d .blockchain .CurrentBlock ().NumberU64 ()
263- case d .blockchain != nil && mode == FastSync :
245+ case d .blockchain != nil && mode == SnapSync :
264246 current = d .blockchain .CurrentFastBlock ().NumberU64 ()
265247 case d .lightchain != nil :
266248 current = d .lightchain .CurrentHeader ().Number .Uint64 ()
267249 default :
268250 log .Error ("Unknown downloader chain/mode combo" , "light" , d .lightchain != nil , "full" , d .blockchain != nil , "mode" , mode )
269251 }
252+ progress , pending := d .SnapSyncer .Progress ()
253+
270254 return XDPoSChain.SyncProgress {
271- StartingBlock : d .syncStatsChainOrigin ,
272- CurrentBlock : current ,
273- HighestBlock : d .syncStatsChainHeight ,
274- PulledStates : d .syncStatsState .processed ,
275- KnownStates : d .syncStatsState .processed + d .syncStatsState .pending ,
255+ StartingBlock : d .syncStatsChainOrigin ,
256+ CurrentBlock : current ,
257+ HighestBlock : d .syncStatsChainHeight ,
258+ SyncedAccounts : progress .AccountSynced ,
259+ SyncedAccountBytes : uint64 (progress .AccountBytes ),
260+ SyncedBytecodes : progress .BytecodeSynced ,
261+ SyncedBytecodeBytes : uint64 (progress .BytecodeBytes ),
262+ SyncedStorage : progress .StorageSynced ,
263+ SyncedStorageBytes : uint64 (progress .StorageBytes ),
264+ HealedTrienodes : progress .TrienodeHealSynced ,
265+ HealedTrienodeBytes : uint64 (progress .TrienodeHealBytes ),
266+ HealedBytecodes : progress .BytecodeHealSynced ,
267+ HealedBytecodeBytes : uint64 (progress .BytecodeHealBytes ),
268+ HealingTrienodes : pending .TrienodeHeal ,
269+ HealingBytecode : pending .BytecodeHeal ,
276270 }
277271}
278272
@@ -365,21 +359,12 @@ func (d *Downloader) synchronise(id string, hash common.Hash, td *big.Int, mode
365359 d .queue .Reset (blockCacheMaxItems , blockCacheInitialItems )
366360 d .peers .Reset ()
367361
368- for _ , ch := range []chan bool {d .bodyWakeCh , d .receiptWakeCh } {
362+ for _ , ch := range []chan bool {d .queue . blockWakeCh , d . queue .receiptWakeCh } {
369363 select {
370364 case <- ch :
371365 default :
372366 }
373367 }
374- for _ , ch := range []chan dataPack {d .headerCh , d .bodyCh , d .receiptCh } {
375- for empty := false ; ! empty ; {
376- select {
377- case <- ch :
378- default :
379- empty = true
380- }
381- }
382- }
383368 for empty := false ; ! empty ; {
384369 select {
385370 case <- d .headerProcCh :
@@ -457,8 +442,14 @@ func (d *Downloader) syncWithPeer(p *peerConnection, hash common.Hash, td *big.I
457442 d .syncStatsChainHeight = height
458443 d .syncStatsLock .Unlock ()
459444
445+ << << << < HEAD
460446 // Ensure our origin point is below any fast sync pivot point
461447 if mode == FastSync {
448+ == == == =
449+ // Ensure our origin point is below any snap sync pivot point
450+ pivot := uint64 (0 )
451+ if mode == SnapSync {
452+ >> >> >> > 9 ea89b0e8 (fix )
462453 if height <= uint64 (fsMinFullBlocks ) {
463454 origin = 0
464455 } else {
@@ -469,7 +460,11 @@ func (d *Downloader) syncWithPeer(p *peerConnection, hash common.Hash, td *big.I
469460 }
470461 }
471462 d .committed = 1
463+ << << << < HEAD
472464 if mode == FastSync && pivot .Number .Uint64 () != 0 {
465+ == == == =
466+ if mode == SnapSync && pivot != 0 {
467+ >> >> >> > 9 ea89b0e8 (fix )
473468 d.committed = 0
474469 }
475470 // Initiate the sync using a concurrent header and content retrieval algorithm
@@ -479,6 +474,7 @@ func (d *Downloader) syncWithPeer(p *peerConnection, hash common.Hash, td *big.I
479474 }
480475
481476 fetchers := []func () error {
477+ << << << < HEAD
482478 func () error { return d .fetchHeaders (p , origin + 1 ) }, // Headers are always retrieved
483479 func () error { return d .fetchBodies (origin + 1 ) }, // Bodies are retrieved during normal and fast sync
484480 func () error { return d .fetchReceipts (origin + 1 ) }, // Receipts are retrieved during fast sync
@@ -490,6 +486,15 @@ func (d *Downloader) syncWithPeer(p *peerConnection, hash common.Hash, td *big.I
490486 d .pivotLock .Unlock ()
491487
492488 fetchers = append (fetchers , func () error { return d .processFastSyncContent () })
489+ == == == =
490+ func () error { return d .fetchHeaders (p , origin + 1 , latest .Number .Uint64 (), pivot ) }, // Headers are always retrieved
491+ func () error { return d .fetchBodies (origin + 1 ) }, // Bodies are retrieved during normal and snap sync
492+ func () error { return d .fetchReceipts (origin + 1 ) }, // Receipts are retrieved during snap sync
493+ func () error { return d .processHeaders (origin + 1 , pivot , td ) },
494+ }
495+ if mode == SnapSync {
496+ fetchers = append (fetchers , func () error { return d .processSnapSyncContent (latest ) })
497+ >> >> >> > 9 ea89b0e8 (fix )
493498 } else if mode == FullSync {
494499 fetchers = append (fetchers , func () error { return d .processFullSyncContent (height ) })
495500 }
@@ -1461,7 +1466,7 @@ func (d *Downloader) processHeaders(origin uint64, td *big.Int) error {
14611466 // This check cannot be executed "as is" for full imports, since blocks may still be
14621467 // queued for processing when the header download completes. However, as long as the
14631468 // peer gave us something useful, we're already happy/progressed (above check).
1464- if mode == FastSync || mode == LightSync {
1469+ if mode == SnapSync || mode == LightSync {
14651470 head := d .lightchain .CurrentHeader ()
14661471 if td .Cmp (d .lightchain .GetTd (head .Hash (), head .Number .Uint64 ())) > 0 {
14671472 return errStallingPeer
@@ -1488,7 +1493,7 @@ func (d *Downloader) processHeaders(origin uint64, td *big.Int) error {
14881493 }
14891494 chunk := headers [:limit ]
14901495 // In case of header only syncing, validate the chunk immediately
1491- if mode == FastSync || mode == LightSync {
1496+ if mode == SnapSync || mode == LightSync {
14921497 // Collect the yet unknown headers to mark them as uncertain
14931498 unknown := make ([]* types.Header , 0 , len (headers ))
14941499 for _ , header := range chunk {
@@ -1525,7 +1530,7 @@ func (d *Downloader) processHeaders(origin uint64, td *big.Int) error {
15251530 }
15261531 }
15271532 // Unless we're doing light chains, schedule the headers for associated content retrieval
1528- if mode == FullSync || mode == FastSync {
1533+ if mode == FullSync || mode == SnapSync {
15291534 // If we've reached the allowed number of pending headers, stall a bit
15301535 for d .queue .PendingBlocks () >= maxQueuedHeaders || d .queue .PendingReceipts () >= maxQueuedHeaders {
15311536 select {
0 commit comments