@@ -36,6 +36,24 @@ type moder struct {
3636}
3737
3838func newSyncModer (mode ethconfig.SyncMode , chain BlockChain , disk ethdb.KeyValueReader ) * moder {
39+ m := & moder {
40+ chain : chain ,
41+ disk : disk ,
42+ }
43+ valid , reason , suggest := m .validate (mode )
44+ if ! valid {
45+ m .mode = suggest
46+ log .Info ("Switched sync mode" , "want" , mode , "use" , suggest , "reason" , reason )
47+ } else {
48+ m .mode = mode
49+ log .Info ("Initialized sync mode" , "mode" , mode )
50+ }
51+ return m
52+ }
53+
54+ // validate checks if the specified sync mode is compatible with local chain and
55+ // returns the suggested mode if it's not along with the reason.
56+ func (m * moder ) validate (mode ethconfig.SyncMode ) (bool , string , ethconfig.SyncMode ) {
3957 if mode == ethconfig .FullSync {
4058 // The database seems empty as the current block is the genesis. Yet the snap
4159 // block is ahead, so snap sync was enabled for this node at a certain point.
@@ -45,32 +63,24 @@ func newSyncModer(mode ethconfig.SyncMode, chain BlockChain, disk ethdb.KeyValue
4563 // * the last snap sync is not finished while user specifies a full sync this
4664 // time. But we don't have any recent state for full sync.
4765 // In these cases however it's safe to reenable snap sync.
48- fullBlock , snapBlock := chain .CurrentBlock (), chain .CurrentSnapBlock ()
66+ fullBlock , snapBlock := m . chain .CurrentBlock (), m . chain .CurrentSnapBlock ()
4967 if fullBlock .Number .Uint64 () == 0 && snapBlock .Number .Uint64 () > 0 {
50- mode = ethconfig .SnapSync
51- log .Warn ("Switch sync mode from full sync to snap sync" , "reason" , "snap sync incomplete" )
52- } else if ! chain .HasState (fullBlock .Root ) {
53- mode = ethconfig .SnapSync
54- log .Warn ("Switch sync mode from full sync to snap sync" , "reason" , "head state missing" )
68+ return false , "snap sync incomplete" , ethconfig .SnapSync
69+ } else if ! m .chain .HasState (fullBlock .Root ) {
70+ return false , "head state missing" , ethconfig .SnapSync
5571 } else {
56- // Grant the full sync mode
57- log . Info ( "Enabled full sync" , "head " , fullBlock . Number , "hash" , fullBlock . Hash ())
72+ // If full sync was requested and our chain is stateful, grant it
73+ return true , "" , ethconfig . FullSync
5874 }
5975 } else {
60- head := chain .CurrentBlock ()
61- if head .Number .Uint64 () > 0 && chain .HasState (head .Root ) {
62- mode = ethconfig .FullSync
63- log .Info ("Switch sync mode from snap sync to full sync" , "reason" , "snap sync complete" )
76+ head := m .chain .CurrentBlock ()
77+ if head .Number .Uint64 () > 0 && m .chain .HasState (head .Root ) {
78+ return false , "snap sync complete" , ethconfig .FullSync
6479 } else {
6580 // If snap sync was requested and our database is empty, grant it
66- log . Info ( "Enabled snap sync" , "head " , head . Number , "hash" , head . Hash ())
81+ return true , "" , ethconfig . SnapSync
6782 }
6883 }
69- return & moder {
70- mode : mode ,
71- chain : chain ,
72- disk : disk ,
73- }
7484}
7585
7686// getMode retrieves the current sync mode, either explicitly set, or derived
@@ -103,14 +113,19 @@ func (m *moder) getMode() ethconfig.SyncMode {
103113 return ethconfig .FullSync
104114}
105115
106- // disableSnap disables the snap sync mode, usually it's called after a successful
107- // snap sync.
108- func (m * moder ) disableSnap () {
116+ // setMode sets the sync mode with the specified one.
117+ func (m * moder ) setMode (mode ethconfig.SyncMode ) bool {
109118 m .lock .Lock ()
110119 defer m .lock .Unlock ()
111120
112- if m .mode == ethconfig .FullSync {
113- return
121+ if m .mode == mode {
122+ return true
123+ }
124+ if valid , _ , _ := m .validate (mode ); ! valid {
125+ return false
114126 }
115- m .mode = ethconfig .FullSync
127+ old := m .mode
128+ m .mode = mode
129+ log .Info ("Switched sync mode" , "old" , old , "new" , mode )
130+ return true
116131}
0 commit comments