@@ -102,7 +102,7 @@ func testCheckpointSyncing(t *testing.T, protocol int, syncMode int) {
102
102
}
103
103
104
104
done := make (chan error )
105
- client .handler .backend . oracle . syncDoneHook = func () {
105
+ client .handler .syncDone = func () {
106
106
header := client .handler .backend .blockchain .CurrentHeader ()
107
107
if header .Number .Uint64 () == expected {
108
108
done <- nil
@@ -131,3 +131,102 @@ func testCheckpointSyncing(t *testing.T, protocol int, syncMode int) {
131
131
t .Error ("checkpoint syncing timeout" )
132
132
}
133
133
}
134
+
135
+ func TestMissOracleBackend (t * testing.T ) { testMissOracleBackend (t , true ) }
136
+ func TestMissOracleBackendNoCheckpoint (t * testing.T ) { testMissOracleBackend (t , false ) }
137
+
138
+ func testMissOracleBackend (t * testing.T , hasCheckpoint bool ) {
139
+ config := light .TestServerIndexerConfig
140
+
141
+ waitIndexers := func (cIndexer , bIndexer , btIndexer * core.ChainIndexer ) {
142
+ for {
143
+ cs , _ , _ := cIndexer .Sections ()
144
+ bts , _ , _ := btIndexer .Sections ()
145
+ if cs >= 1 && bts >= 1 {
146
+ break
147
+ }
148
+ time .Sleep (10 * time .Millisecond )
149
+ }
150
+ }
151
+ // Generate 512+4 blocks (totally 1 CHT sections)
152
+ server , client , tearDown := newClientServerEnv (t , int (config .ChtSize + config .ChtConfirms ), 3 , waitIndexers , nil , 0 , false , false )
153
+ defer tearDown ()
154
+
155
+ expected := config .ChtSize + config .ChtConfirms
156
+
157
+ s , _ , head := server .chtIndexer .Sections ()
158
+ cp := & params.TrustedCheckpoint {
159
+ SectionIndex : 0 ,
160
+ SectionHead : head ,
161
+ CHTRoot : light .GetChtRoot (server .db , s - 1 , head ),
162
+ BloomRoot : light .GetBloomTrieRoot (server .db , s - 1 , head ),
163
+ }
164
+ // Register the assembled checkpoint into oracle.
165
+ header := server .backend .Blockchain ().CurrentHeader ()
166
+
167
+ data := append ([]byte {0x19 , 0x00 }, append (registrarAddr .Bytes (), append ([]byte {0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }, cp .Hash ().Bytes ()... )... )... )
168
+ sig , _ := crypto .Sign (crypto .Keccak256 (data ), signerKey )
169
+ sig [64 ] += 27 // Transform V from 0/1 to 27/28 according to the yellow paper
170
+ if _ , err := server .handler .server .oracle .contract .RegisterCheckpoint (bind .NewKeyedTransactor (signerKey ), cp .SectionIndex , cp .Hash ().Bytes (), new (big.Int ).Sub (header .Number , big .NewInt (1 )), header .ParentHash , [][]byte {sig }); err != nil {
171
+ t .Error ("register checkpoint failed" , err )
172
+ }
173
+ server .backend .Commit ()
174
+
175
+ // Wait for the checkpoint registration
176
+ for {
177
+ _ , hash , _ , err := server .handler .server .oracle .contract .Contract ().GetLatestCheckpoint (nil )
178
+ if err != nil || hash == [32 ]byte {} {
179
+ time .Sleep (100 * time .Millisecond )
180
+ continue
181
+ }
182
+ break
183
+ }
184
+ expected += 1
185
+
186
+ // Explicitly set the oracle as nil. In normal use case it can happen
187
+ // that user wants to unlock something which blocks the oracle backend
188
+ // initialisation. But at the same time syncing starts.
189
+ //
190
+ // See https://github.com/ethereum/go-ethereum/issues/20097 for more detail.
191
+ //
192
+ // In this case, client should run light sync or legacy checkpoint sync
193
+ // if hardcoded checkpoint is configured.
194
+ client .handler .backend .oracle = nil
195
+
196
+ // For some private networks it can happen checkpoint syncing is enabled
197
+ // but there is no hardcoded checkpoint configured.
198
+ if hasCheckpoint {
199
+ client .handler .checkpoint = cp
200
+ client .handler .backend .blockchain .AddTrustedCheckpoint (cp )
201
+ }
202
+
203
+ done := make (chan error )
204
+ client .handler .syncDone = func () {
205
+ header := client .handler .backend .blockchain .CurrentHeader ()
206
+ if header .Number .Uint64 () == expected {
207
+ done <- nil
208
+ } else {
209
+ done <- fmt .Errorf ("blockchain length mismatch, want %d, got %d" , expected , header .Number )
210
+ }
211
+ }
212
+
213
+ // Create connected peer pair.
214
+ _ , err1 , _ , err2 := newTestPeerPair ("peer" , 2 , server .handler , client .handler )
215
+ select {
216
+ case <- time .After (time .Millisecond * 100 ):
217
+ case err := <- err1 :
218
+ t .Fatalf ("peer 1 handshake error: %v" , err )
219
+ case err := <- err2 :
220
+ t .Fatalf ("peer 2 handshake error: %v" , err )
221
+ }
222
+
223
+ select {
224
+ case err := <- done :
225
+ if err != nil {
226
+ t .Error ("sync failed" , err )
227
+ }
228
+ return
229
+ case <- time .NewTimer (10 * time .Second ).C :
230
+ t .Error ("checkpoint syncing timeout" )
231
+ }
232
+ }
0 commit comments