@@ -11,9 +11,11 @@ import (
1111 "sync"
1212 "time"
1313
14+ "github.com/oasisprotocol/oasis-core/go/p2p/rpc"
1415 storageApi "github.com/oasisprotocol/oasis-core/go/storage/api"
1516 "github.com/oasisprotocol/oasis-core/go/storage/mkvs/checkpoint"
16- storageSync "github.com/oasisprotocol/oasis-core/go/worker/storage/p2p/sync"
17+ "github.com/oasisprotocol/oasis-core/go/worker/storage/p2p/checkpointsync"
18+ "github.com/oasisprotocol/oasis-core/go/worker/storage/p2p/synclegacy"
1719)
1820
1921const (
@@ -55,7 +57,7 @@ type chunk struct {
5557 * checkpoint.ChunkMetadata
5658
5759 // checkpoint points to the checkpoint this chunk originated from.
58- checkpoint * storageSync .Checkpoint
60+ checkpoint * checkpointsync .Checkpoint
5961}
6062
6163type chunkHeap struct {
@@ -101,12 +103,7 @@ func (n *Node) checkpointChunkFetcher(
101103 defer cancel ()
102104
103105 // Fetch chunk from peers.
104- rsp , pf , err := n .storageSync .GetCheckpointChunk (chunkCtx , & storageSync.GetCheckpointChunkRequest {
105- Version : chunk .Version ,
106- Root : chunk .Root ,
107- Index : chunk .Index ,
108- Digest : chunk .Digest ,
109- }, chunk .checkpoint )
106+ rsp , pf , err := n .fetchChunk (chunkCtx , chunk )
110107 if err != nil {
111108 n .logger .Error ("failed to fetch chunk from peers" ,
112109 "err" , err ,
@@ -117,7 +114,7 @@ func (n *Node) checkpointChunkFetcher(
117114 }
118115
119116 // Restore fetched chunk.
120- done , err := n .localStorage .Checkpointer ().RestoreChunk (chunkCtx , chunk .Index , bytes .NewBuffer (rsp . Chunk ))
117+ done , err := n .localStorage .Checkpointer ().RestoreChunk (chunkCtx , chunk .Index , bytes .NewBuffer (rsp ))
121118 cancel ()
122119
123120 switch {
@@ -157,7 +154,47 @@ func (n *Node) checkpointChunkFetcher(
157154 }
158155}
159156
160- func (n * Node ) handleCheckpoint (check * storageSync.Checkpoint , maxParallelRequests uint ) (cpStatus int , rerr error ) {
157+ // fetchChunk fetches chunk using checkpoint sync p2p protocol client.
158+ //
159+ // In case of no peers or error, it fallbacks to the legacy storage sync protocol.
160+ func (n * Node ) fetchChunk (ctx context.Context , chunk * chunk ) ([]byte , rpc.PeerFeedback , error ) {
161+ rsp1 , pf , err := n .checkpointSync .GetCheckpointChunk (
162+ ctx ,
163+ & checkpointsync.GetCheckpointChunkRequest {
164+ Version : chunk .Version ,
165+ Root : chunk .Root ,
166+ Index : chunk .Index ,
167+ Digest : chunk .Digest ,
168+ },
169+ & checkpointsync.Checkpoint {
170+ Metadata : chunk .checkpoint .Metadata ,
171+ Peers : chunk .checkpoint .Peers ,
172+ },
173+ )
174+ if err == nil { // if NO error
175+ return rsp1 .Chunk , pf , nil
176+ }
177+
178+ rsp2 , pf , err := n .legacyStorageSync .GetCheckpointChunk (
179+ ctx ,
180+ & synclegacy.GetCheckpointChunkRequest {
181+ Version : chunk .Version ,
182+ Root : chunk .Root ,
183+ Index : chunk .Index ,
184+ Digest : chunk .Digest ,
185+ },
186+ & synclegacy.Checkpoint {
187+ Metadata : chunk .checkpoint .Metadata ,
188+ Peers : chunk .checkpoint .Peers ,
189+ },
190+ )
191+ if err != nil {
192+ return nil , nil , err
193+ }
194+ return rsp2 .Chunk , pf , nil
195+ }
196+
197+ func (n * Node ) handleCheckpoint (check * checkpointsync.Checkpoint , maxParallelRequests uint ) (cpStatus int , rerr error ) {
161198 if err := n .localStorage .Checkpointer ().StartRestore (n .ctx , check .Metadata ); err != nil {
162199 // Any previous restores were already aborted by the driver up the call stack, so
163200 // things should have been going smoothly here; bail.
@@ -276,13 +313,11 @@ func (n *Node) handleCheckpoint(check *storageSync.Checkpoint, maxParallelReques
276313 }
277314}
278315
279- func (n * Node ) getCheckpointList () ([]* storageSync .Checkpoint , error ) {
316+ func (n * Node ) getCheckpointList () ([]* checkpointsync .Checkpoint , error ) {
280317 ctx , cancel := context .WithTimeout (n .ctx , cpListsTimeout )
281318 defer cancel ()
282319
283- list , err := n .storageSync .GetCheckpoints (ctx , & storageSync.GetCheckpointsRequest {
284- Version : 1 ,
285- })
320+ list , err := n .fetchCheckpoints (ctx )
286321 if err != nil {
287322 n .logger .Error ("failed to retrieve any checkpoints" ,
288323 "err" , err ,
@@ -296,9 +331,36 @@ func (n *Node) getCheckpointList() ([]*storageSync.Checkpoint, error) {
296331 return list , nil
297332}
298333
334+ // fetchCheckpoints fetches checkpoints using checkpoint sync p2p protocol client.
335+ //
336+ // In case of no peers, error or no checkpoints, it fallbacks to the legacy storage sync protocol.
337+ func (n * Node ) fetchCheckpoints (ctx context.Context ) ([]* checkpointsync.Checkpoint , error ) {
338+ list1 , err := n .checkpointSync .GetCheckpoints (ctx , & checkpointsync.GetCheckpointsRequest {
339+ Version : 1 ,
340+ })
341+ if err == nil && len (list1 ) > 0 { // if NO error and at least one checkpoint
342+ return list1 , nil
343+ }
344+
345+ list2 , err := n .legacyStorageSync .GetCheckpoints (ctx , & synclegacy.GetCheckpointsRequest {
346+ Version : 1 ,
347+ })
348+ if err != nil {
349+ return nil , err
350+ }
351+ var cps []* checkpointsync.Checkpoint
352+ for _ , cp := range list2 {
353+ cps = append (cps , & checkpointsync.Checkpoint {
354+ Metadata : cp .Metadata ,
355+ Peers : cp .Peers ,
356+ })
357+ }
358+ return cps , nil
359+ }
360+
299361// sortCheckpoints sorts the slice in-place (descending by version, peers, hash).
300- func sortCheckpoints (s []* storageSync .Checkpoint ) {
301- slices .SortFunc (s , func (a , b * storageSync .Checkpoint ) int {
362+ func sortCheckpoints (s []* checkpointsync .Checkpoint ) {
363+ slices .SortFunc (s , func (a , b * checkpointsync .Checkpoint ) int {
302364 return cmp .Or (
303365 cmp .Compare (b .Root .Version , a .Root .Version ),
304366 cmp .Compare (len (b .Peers ), len (a .Peers )),
@@ -307,7 +369,7 @@ func sortCheckpoints(s []*storageSync.Checkpoint) {
307369 })
308370}
309371
310- func (n * Node ) checkCheckpointUsable (cp * storageSync .Checkpoint , remainingMask outstandingMask , genesisRound uint64 ) bool {
372+ func (n * Node ) checkCheckpointUsable (cp * checkpointsync .Checkpoint , remainingMask outstandingMask , genesisRound uint64 ) bool {
311373 namespace := n .commonNode .Runtime .ID ()
312374 if ! namespace .Equal (& cp .Root .Namespace ) {
313375 // Not for the right runtime.
@@ -357,7 +419,7 @@ func (n *Node) syncCheckpoints(genesisRound uint64, wantOnlyGenesis bool) (*bloc
357419
358420 // If we only want the genesis checkpoint, filter it out.
359421 if wantOnlyGenesis && len (cps ) > 0 {
360- var filteredCps []* storageSync .Checkpoint
422+ var filteredCps []* checkpointsync .Checkpoint
361423 for _ , cp := range cps {
362424 if cp .Root .Version == genesisRound {
363425 filteredCps = append (filteredCps , cp )
0 commit comments