private BaseResponse <bool> ValidateParentBlock(DAM.Block.Block block, string senderNodeId) { if (_blockchainService.BlockExists(block.ParentUniqueId)) { return(new SuccessResponse <bool>("The parent block exists!", true)); } var serverNode = ServerNodes.Values.FirstOrDefault(n => n.Id == senderNodeId); if (serverNode == null) { return(new ErrorResponse <bool>( $"Could not find the server for parent block with id: {block.ParentUniqueId} don't exist!", false)); } const string methodName = nameof(ConsensusHub.GetBlocksFromBranchJson); var json = serverNode.HubConnection.Invoke <string>(methodName, block.ParentUniqueId); if (json != null) { var externalBlocks = BlockchainConverter.DeserializeBlocks(json).OrderBy(b => b.Depth); var results = externalBlocks.Select(eb => AcceptBlock(eb, senderNodeId)); if (results.All(r => r.IsSuccess || r.Message == "The block already exists!")) { return(new SuccessResponse <bool>("The parent block exists!", true)); } } return(new ErrorResponse <bool>($"The parent block with id: {block.ParentUniqueId} don't exist!", false)); }
public BlockchainTree GetBlockchainTree() { var blocks = _cache.GetOrCreate(CacheKeys.BlockchainTree, entry => { lock (_padlock) { using (var stream = _fileRepository.GetFileReader(_blockchainFileName)) using (var reader = new JsonTextReader(stream)) { return(stream == StreamReader.Null ? null : BlockchainConverter.DeserializeBlockchain(reader)); } } })?.Blocks?.ToList(); return(new BlockchainTree { Blocks = blocks }); }
public void AcceptExternalBlock(EncodedBlock encodedBlock) { _backgroundQueue.Enqueue(token => new Task(() => { if (encodedBlock?.Base64Block != null && !_encodedBlocksStorage.EncodedBlocksIds.Contains(encodedBlock.Id)) { _encodedBlocksStorage.EncodedBlocksIds.Add(encodedBlock.Id); var blockchainJson = Encoding.UTF8.GetString(Convert.FromBase64String(encodedBlock.Base64Block)); var incomingBlock = BlockchainConverter.DeserializeBlock(blockchainJson); var result = AcceptBlock(incomingBlock, encodedBlock.NodeSenderId); if (result.IsSuccess) { DistributeBlock(encodedBlock); } } }, token)); }
public BaseResponse <bool> SynchronizeWithOtherNodes() { var blocks = new ConcurrentDictionary <string, DAM.Block.BlockBase>(); ServerNodes.Values.ParallelForEach(node => { var json = node.HubConnection.Invoke <string>(nameof(ConsensusHub.GetLastBlockJson)); if (json != null) { blocks.TryAdd(node.Id, BlockchainConverter.DeserializeBlock(json)); } }); var currentLastBlock = _blockchainService.GetLastBlock(); if (blocks.IsEmpty && currentLastBlock == null) { return(new ErrorResponse <bool>( "The current blockchain is empty and there is no block to synchronize", false)); } if (blocks.IsEmpty) { return(new ErrorResponse <bool>("There is no blocks to synchronize with!", false)); } var longestBlock = blocks.OrderBy(b => b.Value.Depth).ThenBy(b => b.Value.Header.TimeStamp).First(); if (currentLastBlock == null) { return(AcceptBlock(longestBlock.Value, longestBlock.Key)); } return(currentLastBlock.Depth >= longestBlock.Value.Depth ? new SuccessResponse <bool>("There is no need for synchronization!", false) : AcceptBlock(longestBlock.Value, longestBlock.Key)); }