Task <BlockData> LoadBlock(long blockid) { BlockData result = null; try { if (blockid >= Protocol.GenesisBlockId) { var sliceIndex = BlockSliceInfo.GetSliceIndex(blockid); var blockStorage = _blocksStorage.Get(sliceIndex); if (blockStorage == null) { blockStorage = new BlockDiscStorage(_storage, ChainType, ChainId, ChainIndex, sliceIndex, true); if (blockStorage.Length > 0) { _blocksStorage.Add(sliceIndex, blockStorage); } } if (blockStorage.Length > 0) { var blockData = blockStorage.GetBlockData(blockid); if (blockData != null) { result = BlockData.Restore(blockData); _blockData.Add(blockid, result); } } } } catch (Exception ex) { Log.HandleException(ex, this); } return(Task.FromResult(result)); }
public async Task <BlockConsumeResult> StoreBlock(BlockData blockData) { var block = blockData.Block; lock (_lock) { if (!_active) { return(BlockConsumeResult.NotActive); } } await _consuming.WaitAsync(); var next = LastStoredBlockId + 1; if (block.BlockId > next) { _consuming.Release(); return(BlockConsumeResult.SyncRequired); } if (block.BlockId < next) { lock (_lock) { if (_blockSlices.Count > 0) { if (block.BlockId != (next - 1)) { _consuming.Release(); return(BlockConsumeResult.MissingBlock); } } } } if (block.BlockId < next) { _consuming.Release(); return(BlockConsumeResult.Ok); } if (LastBlock != null) { if (block.PreviousBlockHash != LastBlock.BlockHash) { _consuming.Release(); return(BlockConsumeResult.InvalidHash); } } var sliceIndex = BlockSliceInfo.GetSliceIndex(block.BlockId); if (_blockDiscStorage == null) { _blockDiscStorage = new BlockDiscStorage(_storage, ChainType, ChainId, ChainIndex, sliceIndex, false); } if (sliceIndex != _blockDiscStorage.SliceIndex) { _blockDiscStorage.Dispose(); DiscStorage.BuildChecksum(_storage, Path.Combine(_blocksPath, _blockDiscStorage.SliceIndex.ToString())); _blockDiscStorage = new BlockDiscStorage(_storage, ChainType, ChainId, ChainIndex, sliceIndex, false); } _blockDiscStorage.AddEntry(block.BlockId, blockData.ToByteArray()); _blockDiscStorage.Commit(); _blockData.Add(block.BlockId, blockData); lock (_lock) { if (_blockSlices.TryGetValue(sliceIndex, out var blockStorageInfo)) { blockStorageInfo.LastBlockId = block.BlockId; } else { blockStorageInfo = new BlockSliceInfo(sliceIndex) { FirstBlockId = block.BlockId, LastBlockId = block.BlockId }; _blockSlices.Add(sliceIndex, blockStorageInfo); } } if (!await History.Update(blockData)) { await History.Init(blockData); } lock (_lock) { LastBlock = block; LastBlockData = blockData; } _consuming.Release(); return(BlockConsumeResult.Ok); }