|
@ -8,6 +8,7 @@ import ( |
|
|
"time" |
|
|
"time" |
|
|
|
|
|
|
|
|
abci "github.com/tendermint/tendermint/abci/types" |
|
|
abci "github.com/tendermint/tendermint/abci/types" |
|
|
|
|
|
"github.com/tendermint/tendermint/config" |
|
|
tmsync "github.com/tendermint/tendermint/internal/libs/sync" |
|
|
tmsync "github.com/tendermint/tendermint/internal/libs/sync" |
|
|
"github.com/tendermint/tendermint/internal/p2p" |
|
|
"github.com/tendermint/tendermint/internal/p2p" |
|
|
"github.com/tendermint/tendermint/libs/log" |
|
|
"github.com/tendermint/tendermint/libs/log" |
|
@ -18,12 +19,9 @@ import ( |
|
|
) |
|
|
) |
|
|
|
|
|
|
|
|
const ( |
|
|
const ( |
|
|
// chunkFetchers is the number of concurrent chunk fetchers to run.
|
|
|
|
|
|
chunkFetchers = 4 |
|
|
|
|
|
// chunkTimeout is the timeout while waiting for the next chunk from the chunk queue.
|
|
|
// chunkTimeout is the timeout while waiting for the next chunk from the chunk queue.
|
|
|
chunkTimeout = 2 * time.Minute |
|
|
chunkTimeout = 2 * time.Minute |
|
|
// requestTimeout is the timeout before rerequesting a chunk, possibly from a different peer.
|
|
|
|
|
|
chunkRequestTimeout = 10 * time.Second |
|
|
|
|
|
|
|
|
|
|
|
// minimumDiscoveryTime is the lowest allowable time for a
|
|
|
// minimumDiscoveryTime is the lowest allowable time for a
|
|
|
// SyncAny discovery time.
|
|
|
// SyncAny discovery time.
|
|
|
minimumDiscoveryTime = 5 * time.Second |
|
|
minimumDiscoveryTime = 5 * time.Second |
|
@ -52,6 +50,7 @@ var ( |
|
|
// sync all snapshots in the pool (pausing to discover new ones), or Sync() to sync a specific
|
|
|
// sync all snapshots in the pool (pausing to discover new ones), or Sync() to sync a specific
|
|
|
// snapshot. Snapshots and chunks are fed via AddSnapshot() and AddChunk() as appropriate.
|
|
|
// snapshot. Snapshots and chunks are fed via AddSnapshot() and AddChunk() as appropriate.
|
|
|
type syncer struct { |
|
|
type syncer struct { |
|
|
|
|
|
cfg config.StateSyncConfig |
|
|
logger log.Logger |
|
|
logger log.Logger |
|
|
stateProvider StateProvider |
|
|
stateProvider StateProvider |
|
|
conn proxy.AppConnSnapshot |
|
|
conn proxy.AppConnSnapshot |
|
@ -67,6 +66,7 @@ type syncer struct { |
|
|
|
|
|
|
|
|
// newSyncer creates a new syncer.
|
|
|
// newSyncer creates a new syncer.
|
|
|
func newSyncer( |
|
|
func newSyncer( |
|
|
|
|
|
cfg config.StateSyncConfig, |
|
|
logger log.Logger, |
|
|
logger log.Logger, |
|
|
conn proxy.AppConnSnapshot, |
|
|
conn proxy.AppConnSnapshot, |
|
|
connQuery proxy.AppConnQuery, |
|
|
connQuery proxy.AppConnQuery, |
|
@ -75,6 +75,7 @@ func newSyncer( |
|
|
tempDir string, |
|
|
tempDir string, |
|
|
) *syncer { |
|
|
) *syncer { |
|
|
return &syncer{ |
|
|
return &syncer{ |
|
|
|
|
|
cfg: cfg, |
|
|
logger: logger, |
|
|
logger: logger, |
|
|
stateProvider: stateProvider, |
|
|
stateProvider: stateProvider, |
|
|
conn: conn, |
|
|
conn: conn, |
|
@ -256,7 +257,7 @@ func (s *syncer) Sync(snapshot *snapshot, chunks *chunkQueue) (sm.State, *types. |
|
|
// Spawn chunk fetchers. They will terminate when the chunk queue is closed or context canceled.
|
|
|
// Spawn chunk fetchers. They will terminate when the chunk queue is closed or context canceled.
|
|
|
ctx, cancel := context.WithCancel(context.Background()) |
|
|
ctx, cancel := context.WithCancel(context.Background()) |
|
|
defer cancel() |
|
|
defer cancel() |
|
|
for i := int32(0); i < chunkFetchers; i++ { |
|
|
|
|
|
|
|
|
for i := int32(0); i < s.cfg.ChunkFetchers; i++ { |
|
|
go s.fetchChunks(ctx, snapshot, chunks) |
|
|
go s.fetchChunks(ctx, snapshot, chunks) |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@ -410,16 +411,21 @@ func (s *syncer) fetchChunks(ctx context.Context, snapshot *snapshot, chunks *ch |
|
|
s.logger.Info("Fetching snapshot chunk", "height", snapshot.Height, |
|
|
s.logger.Info("Fetching snapshot chunk", "height", snapshot.Height, |
|
|
"format", snapshot.Format, "chunk", index, "total", chunks.Size()) |
|
|
"format", snapshot.Format, "chunk", index, "total", chunks.Size()) |
|
|
|
|
|
|
|
|
ticker := time.NewTicker(chunkRequestTimeout) |
|
|
|
|
|
|
|
|
ticker := time.NewTicker(s.cfg.ChunkRequestTimeout) |
|
|
defer ticker.Stop() |
|
|
defer ticker.Stop() |
|
|
|
|
|
|
|
|
s.requestChunk(snapshot, index) |
|
|
s.requestChunk(snapshot, index) |
|
|
|
|
|
|
|
|
select { |
|
|
select { |
|
|
case <-chunks.WaitFor(index): |
|
|
case <-chunks.WaitFor(index): |
|
|
|
|
|
|
|
|
case <-ticker.C: |
|
|
case <-ticker.C: |
|
|
s.requestChunk(snapshot, index) |
|
|
s.requestChunk(snapshot, index) |
|
|
|
|
|
|
|
|
case <-ctx.Done(): |
|
|
case <-ctx.Done(): |
|
|
return |
|
|
return |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
ticker.Stop() |
|
|
ticker.Stop() |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|