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));
        }
Beispiel #2
0
        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));
        }