コード例 #1
0
        async Task <bool> DownloadTransactionSlices(RemoteSyncItem remote, ChainSyncItem chainSyncItem)
        {
            var chainId    = chainSyncItem.ChainId;
            var chainType  = chainSyncItem.ChainType;
            var chainIndex = chainSyncItem.ChainIndex;

            chainSyncItem.UpdateLastBlockInfo((await remote.Client.DownloadLastBlockInfo(chainType, chainId, chainIndex)).Data);

            var localStartSlice = 0;
            var localLast       = TransactionStorage.GetTransactionSlices(_storage, chainType, chainId, chainIndex, true).LastOrDefault();

            if (localLast.Value != null)
            {
                localStartSlice = localLast.Value.SliceId + 1;
            }

            var remoteLastAvailableSlice = TransactionSliceInfo.GetSliceIndex(chainSyncItem.BlockState.LastTransactionId) - 1;

            if (remoteLastAvailableSlice < 0) // -1: ignore last "hot" slice
            {
                Log.Debug($"Skipping transaction slice download for chain {chainId}/{chainIndex}, no available remote stored slice found.", this);
                return(true);
            }

            var count = 0;

            if (remoteLastAvailableSlice >= 0 && remoteLastAvailableSlice >= localStartSlice)
            {
                for (var sliceId = localStartSlice; sliceId <= remoteLastAvailableSlice; sliceId++)
                {
                    Log.Trace($"Downloading transaction slice {sliceId}/{remoteLastAvailableSlice} for chain {chainId}.", this);
                    var sliceData = (await remote.Client.DownloadTransactionSlice(_storage, chainType, chainId, chainIndex, sliceId)).Data;

                    var error = false;
                    if (sliceData == null || !sliceData.Move())
                    {
                        Log.Trace($"Slice {sliceId} download for chain {chainId}/{chainIndex} failed.", this);
                        sliceData?.Delete();
                        error = true;
                    }

                    sliceData?.Dispose();

                    if (error)
                    {
                        return(false);
                    }

                    count++;
                }
            }

            if (count > 0) // check for new slices
            {
                return(await DownloadTransactionSlices(remote, chainSyncItem));
            }

            return(true);
        }
コード例 #2
0
        async Task <bool> DownloadBlockSlices(RemoteSyncItem remote, ChainSyncItem chainSyncItem)
        {
            var chainType  = chainSyncItem.ChainType;
            var chainId    = chainSyncItem.ChainId;
            var chainIndex = chainSyncItem.ChainIndex;

            chainSyncItem.UpdateLastBlockInfo((await remote.Client.DownloadLastBlockInfo(chainType, chainId, chainIndex)).Data);

            var lastBlockId = chainSyncItem.BlockState.LastBlockId;

            if (lastBlockId <= Protocol.InvalidBlockId)
            {
                Log.Debug($"Skipping block slice download for chain {chainId}/{chainIndex}, blockid invalid.", this);
                return(true);
            }

            var remoteLastAvailableSlice = BlockSliceInfo.GetSliceIndex(lastBlockId) - 1;

            if (remoteLastAvailableSlice < 0) // -1: ignore last "hot" slice
            {
                Log.Debug($"Skipping block slice download for chain {chainId}/{chainIndex}, no available remote stored slice found.", this);
                return(true);
            }

            var localStartSlice = 0L;
            var localLast       = BlockStorage.GetBlockSlices(_storage, chainType, chainId, chainIndex, true).LastOrDefault();

            if (localLast.Value != null)
            {
                localStartSlice = localLast.Value.SliceIndex + 1;
            }

            if (!(chainSyncItem.LowestFoundBlockSliceId <= localStartSlice))
            {
                Log.Error($"Download block slices for chain {chainId}/{chainIndex} failed, last local slice is {localStartSlice}, lowest remote slice found is {chainSyncItem.LowestFoundBlockSliceId}.", this);
                return(false);
            }

            var count = 0;

            for (var sliceIndex = localStartSlice; sliceIndex <= remoteLastAvailableSlice; sliceIndex++)
            {
                Log.Trace($"Downloading block slice {sliceIndex}/{remoteLastAvailableSlice} for chain {chainId}/{chainIndex}.", this);
                var sliceData = (await remote.Client.DownloadBlockSlice(_storage, chainType, chainId, chainIndex, sliceIndex)).Data;

                var error = false;
                if (sliceData == null || !sliceData.Move())
                {
                    Log.Trace($"Block slice {sliceIndex} download failed.", this);
                    sliceData?.Delete();
                    error = true;
                }

                sliceData?.Dispose();

                if (error)
                {
                    return(false);
                }

                count++;
            }

            if (count > 0)
            {
                return(await DownloadBlockSlices(remote, chainSyncItem));
            }

            return(true);
        }
コード例 #3
0
        async Task <bool> DownloadBlocks(RemoteSyncItem remote, ChainSyncItem chainSyncItem)
        {
            var chainType  = chainSyncItem.ChainType;
            var chainId    = chainSyncItem.ChainId;
            var chainIndex = chainSyncItem.ChainIndex;

            chainSyncItem.UpdateLastBlockInfo((await remote.Client.DownloadLastBlockInfo(chainType, chainId, chainIndex)).Data);

            var chain            = _chainManager.GetChain(chainSyncItem.ChainType, chainId, chainIndex);
            var lastChainBlockId = chainSyncItem.BlockState.LastBlockId;

            var lastBlock   = chain.BlockStorage.LastBlock;
            var nextBlockId = Protocol.GenesisBlockId;

            if (lastBlock != null)
            {
                nextBlockId = lastBlock.BlockId + 1;
            }

            var sync      = chainSyncItem.Sync;
            var newBlocks = chainSyncItem.Sync.NewBlocks;
            var lockitem  = chainSyncItem.Sync.Lock;

            var count = 0;

            for (var blockId = nextBlockId; blockId <= lastChainBlockId; blockId++)
            {
                Log.Trace($"Downloading block {blockId}/{lastChainBlockId} for chain {chainId}/{chainIndex}.", this);

                var blockData = (await remote.Client.DownloadBlockData(chainType, chainId, chainIndex, blockId)).Data;
                if (blockData == null)
                {
                    Log.Trace($"Block {blockId} download failed.", this);
                    return(false);
                }

                //await HandleBlock(blockData, null);
                lock (lockitem)
                {
                    if (newBlocks.TryGetValue(blockId, out var dl))
                    {
                        if (dl.BlockData == null)
                        {
                            dl.UpdateBlockData(blockData);
                        }
                    }
                    else
                    {
                        sync.Add(blockId, new SyncDownload(blockId).UpdateBlockData(blockData));
                    }
                }
                count++;
            }

            if (newBlocks.ContainsKey(nextBlockId))
            {
                var last = chainSyncItem.Sync.NewBlocks[nextBlockId];
                await HandleBlockData(last.BlockData, null);
            }

            if (count > 0)
            {
                return(await DownloadBlocks(remote, chainSyncItem));
            }

            return(true);
        }