public GenericResponse NewBlockAnnouncement(BlockHeader header) { try { if (ApplicationState.ConsensusState != ConsensusStates.WaitingForSpeaker && ApplicationState.ConsensusState != ConsensusStates.CreatingBlock) { return(new GenericResponse(null, ResponseCodes.Success, ResponseMessages.Success)); } //TODO: verify sender signature //VerifySignature(callerNode.WalletAddress); ApplicationLog.Info("Received new block"); DataServices dataServices = new DataServices(); //Validate if sender is current speaker if (callerNode.ServerAddress != ApplicationState.CurrentSpeaker.ServerAddress && callerNode.WalletAddress != ApplicationState.CurrentSpeaker.WalletAddress) { ApplicationLog.Info("Speaker Not Recognized"); return(new GenericResponse(null, ResponseCodes.SpeakerNotRecognized, ResponseMessages.SpeakerNotRecognized)); } //If first epoch, no need to validate as transactions will unlikely tally due to different start consensus time if (ApplicationState.LiveEpochCount == 1 && ApplicationState.CurrentSpeaker.ServerAddress != ApplicationState.Node.ServerAddress) { dataServices.ClearPendingTxUpToId(header.LastTransactionId); return(new GenericResponse(null, ResponseCodes.Success, ResponseMessages.Success)); } //Validate block transactions with local pending transactions //Note: If somehow this node received all transactions but not in the correct order, block will be discarded //and wait for correction during re-sync in subsequent epochs if (header.Hash != dataServices.HashBlockHeaderAndTransactions(header, dataServices.GetPendingTxUpTo(header.LastTransactionId))) { //Pending Transaction And Block Mismatch ApplicationLog.Info("Pending Transaction And Block Mismatch"); return(new GenericResponse(null, ResponseCodes.PendingTransactionAndBlockMismatch, ResponseMessages.PendingTransactionAndBlockMismatch)); } //Create Block var newBlock = dataServices.CreateBlockAndClearPendingTx(header); //Attach block fee newBlock = dataServices.AttachBlockFee(newBlock, ApplicationState.CurrentSpeaker); //Add block to chain dataServices.SaveBlockToChain(newBlock); ApplicationLog.Info("New block added to chain. Index: " + header.Index); return(new GenericResponse(null, ResponseCodes.Success, ResponseMessages.Success)); } catch (Exception ex) { ApplicationLog.Exception(ex); return(new GenericResponse(null, ResponseCodes.Error, ResponseMessages.Error)); } finally { //Resume next iteration of consensus ConsensusServices consensusServices = new ConsensusServices(); consensusServices.NextEpoch(); } }