@@ -22,6 +22,15 @@ import (
22
22
"google.golang.org/protobuf/proto"
23
23
)
24
24
25
+ type ProtocolVersionMismatchError struct {
26
+ LocalVersion string
27
+ RemoteVersion string
28
+ }
29
+
30
+ func (e * ProtocolVersionMismatchError ) Error () string {
31
+ return fmt .Sprintf ("protocol version mismatch; local: %s, remote: %s" , e .LocalVersion , e .RemoteVersion )
32
+ }
33
+
25
34
type SyncerConfig struct {
26
35
execution.BlockGeneratorParams
27
36
@@ -79,30 +88,53 @@ func (s *Syncer) WaitComplete() {
79
88
s .waitForSync .Wait ()
80
89
}
81
90
82
- func (s * Syncer ) readLocalVersion (ctx context.Context ) (common.Hash , error ) {
91
+ func (s * Syncer ) readLocalVersion (ctx context.Context ) (* NodeVersion , error ) {
92
+ protocolVersion := s .networkManager .ProtocolVersion ()
93
+
83
94
rotx , err := s .db .CreateRoTx (ctx )
84
95
if err != nil {
85
- return common . EmptyHash , err
96
+ return nil , err
86
97
}
87
98
defer rotx .Rollback ()
88
99
89
100
res , err := db .ReadBlockHashByNumber (rotx , types .MainShardId , 0 )
90
- if errors .Is (err , db .ErrKeyNotFound ) {
91
- return common .EmptyHash , nil
101
+ if err != nil {
102
+ if errors .Is (err , db .ErrKeyNotFound ) {
103
+ return & NodeVersion {protocolVersion , common .EmptyHash }, nil
104
+ } else {
105
+ return nil , err
106
+ }
92
107
}
93
- return res , err
108
+ return & NodeVersion {protocolVersion , res }, err
109
+ }
110
+
111
+ type NodeVersion struct {
112
+ ProtocolVersion string
113
+ GenesisBlockHash common.Hash
94
114
}
95
115
96
- func (s * Syncer ) fetchRemoteVersion (ctx context.Context ) (common. Hash , error ) {
116
+ func (s * Syncer ) fetchRemoteVersion (ctx context.Context ) (NodeVersion , error ) {
97
117
var err error
98
118
for _ , peer := range s .config .BootstrapPeers {
119
+ var peerId network.PeerID
120
+ peerId , err = s .networkManager .Connect (ctx , peer )
121
+ if err != nil {
122
+ continue
123
+ }
124
+
125
+ var protocolVersion string
126
+ protocolVersion , err = s .networkManager .GetPeerProtocolVersion (peerId )
127
+ if err != nil {
128
+ continue
129
+ }
130
+
99
131
var res common.Hash
100
- res , err = fetchGenesisBlockHash (ctx , s .networkManager , peer )
132
+ res , err = fetchGenesisBlockHash (ctx , s .networkManager , peerId )
101
133
if err == nil {
102
- return res , nil
134
+ return NodeVersion { protocolVersion , res } , nil
103
135
}
104
136
}
105
- return common .EmptyHash , fmt .Errorf ("failed to fetch version from all peers; last error: %w" , err )
137
+ return NodeVersion { "" , common .EmptyHash } , fmt .Errorf ("failed to fetch version from all peers; last error: %w" , err )
106
138
}
107
139
108
140
func (s * Syncer ) fetchSnapshot (ctx context.Context ) error {
@@ -130,10 +162,6 @@ func (s *Syncer) Init(ctx context.Context, allowDbDrop bool) error {
130
162
if err != nil {
131
163
return err
132
164
}
133
- if version .Empty () {
134
- s .logger .Info ().Msg ("Local version is empty. Fetching snapshot..." )
135
- return s .fetchSnapshot (ctx )
136
- }
137
165
138
166
remoteVersion , err := s .fetchRemoteVersion (ctx )
139
167
if err != nil {
@@ -142,7 +170,20 @@ func (s *Syncer) Init(ctx context.Context, allowDbDrop bool) error {
142
170
"Failed to fetch remote version. For now we assume that local version %s is up to date" , version )
143
171
return nil
144
172
}
145
- if version == remoteVersion {
173
+
174
+ if version .ProtocolVersion != remoteVersion .ProtocolVersion {
175
+ return & ProtocolVersionMismatchError {
176
+ version .ProtocolVersion ,
177
+ remoteVersion .ProtocolVersion ,
178
+ }
179
+ }
180
+
181
+ if version .GenesisBlockHash .Empty () {
182
+ s .logger .Info ().Msg ("Local version is empty. Fetching snapshot..." )
183
+ return s .fetchSnapshot (ctx )
184
+ }
185
+
186
+ if version .GenesisBlockHash == remoteVersion .GenesisBlockHash {
146
187
s .logger .Info ().Msgf ("Local version %s is up to date. Finished initialization" , version )
147
188
return nil
148
189
}
@@ -297,6 +338,10 @@ func (s *Syncer) fetchBlocksRange(ctx context.Context) <-chan *types.BlockWithEx
297
338
if err != nil {
298
339
return nil
299
340
}
341
+ if lastBlock == nil {
342
+ s .logger .Warn ().Msg ("No last block found" )
343
+ return nil
344
+ }
300
345
301
346
for _ , p := range peers {
302
347
s .logger .Trace ().Msgf ("Requesting blocks from %d from peer %s" , lastBlock .Id + 1 , p )
@@ -335,7 +380,7 @@ func (s *Syncer) saveBlock(ctx context.Context, block *types.BlockWithExtractedD
335
380
return nil
336
381
}
337
382
338
- func (s * Syncer ) GenerateZerostate (ctx context.Context ) error {
383
+ func (s * Syncer ) GenerateZerostateIfShardIsEmpty (ctx context.Context ) error {
339
384
ctx , cancel := context .WithTimeout (ctx , s .config .Timeout )
340
385
defer cancel ()
341
386
0 commit comments