private BaseResponse <bool> AcceptBlock(DAM.Block.BlockBase incomingBlock, string senderNodeId) { if (incomingBlock == null) { return(new ErrorResponse <bool>("The incoming block cannot be null!", false)); } if (_blockchainService.BlockExists(incomingBlock.UniqueId)) { _statisticService.RegisterRejectedBlock(); return(new ErrorResponse <bool>("The block already exists!", false)); } var mappedBlock = LocalMapper.Map <BlockBase>(incomingBlock); if (incomingBlock is DAM.Block.Block block && !incomingBlock.IsGenesis) { var parentBlockValidationResult = ValidateParentBlock(block, senderNodeId); if (!parentBlockValidationResult.IsSuccess) { _statisticService.RegisterRejectedBlock(); return(parentBlockValidationResult); } var parentBlock = _blockchainService.GetBlock(block.ParentUniqueId); if (parentBlock == null || parentBlock.Depth + 1 != mappedBlock.Depth) { _statisticService.RegisterRejectedBlock(); return(new ErrorResponse <bool>("The depth of incoming block is incorrect!", false)); } var mappedParentBlock = LocalMapper.Map <BlockBase>(parentBlock); ((Block)mappedBlock).Parent = mappedParentBlock; } var duplicatesValidationResult = ValidateTransactionsDuplicates(mappedBlock); if (!duplicatesValidationResult.IsSuccess) { return(duplicatesValidationResult); } var validationResult = _blockchainValidator.Validate(mappedBlock); if (!validationResult.IsSuccess) { _statisticService.RegisterRejectedBlock(); return(new ErrorResponse <bool>("The validation for the block failed!", false, validationResult.Errors)); } _blockchainService.AddBlock(incomingBlock); return(new SuccessResponse <bool>("The block has been accepted and appended!", true)); }
public async Task <BlockchainAddResult> AddAsync(Block newBlock) { var duplicateBlock = _queryHandlerGetBlock.Handle(new GetBlockQuery() { BlockHash = newBlock.BlockHash }); if (duplicateBlock != null) { return(new BlockchainAddResult() { IsSuccessful = false, Error = BlockchainAddResultError.AlreadyAdded }); } var previousBlockDb = _queryHandlerGetBlock.Handle(new GetBlockQuery() { BlockHash = newBlock.BlockHashPrevious }); if (previousBlockDb == null) { return(new BlockchainAddResult() { IsSuccessful = false, Error = BlockchainAddResultError.LackOfPreviousBlock }); } var validationResult = _blockchainValidator.Validate(newBlock, new Block(previousBlockDb), _hashCash.Validate); if (!validationResult) { return(new BlockchainAddResult() { IsSuccessful = false, Error = BlockchainAddResultError.ValidationError }); } foreach (var msg in newBlock.Messages) { var result = await _messageStore.TryAddAsync(msg); } var queryResult = _queryHandlerAddBlock.Handle(new AddBlockQuery() { NewBlock = newBlock }); if (!queryResult) { return(new BlockchainAddResult() { IsSuccessful = false, Error = BlockchainAddResultError.InternalError }); } var markResult = _queryHandlerMarkMainChain.Handle(new MarkMainChainQuery() { }); if (!markResult) { return(new BlockchainAddResult() { IsSuccessful = false, Error = BlockchainAddResultError.InternalError }); } return(new BlockchainAddResult() { IsSuccessful = true, Error = BlockchainAddResultError.None }); }