// common validations for Send and Receive blocks protected APIResultCodes VerifyTransactionBlock(TransactionBlock block) { // Validate the account id if (!Signatures.ValidateAccountId(block.AccountID)) { return(APIResultCodes.InvalidAccountId); } if (!string.IsNullOrEmpty(block.PreviousHash)) // not for new account { // verify the entire account chain to make sure all account's blocks are valid TransactionBlock prevBlock, thisBlock = block; //while (thisBlock.BlockType != BlockTypes.OpenWithReceiveTransfer && thisBlock.BlockType != BlockTypes.OpenWithReceiveFee) while (!(thisBlock is IOpeningBlock)) { prevBlock = _accountCollection.FindBlockByHash(thisBlock.PreviousHash); if (!thisBlock.IsBlockValid(prevBlock)) { return(APIResultCodes.AccountChainBlockValidationFailed); } if (!Signatures.VerifyAccountSignature(thisBlock.Hash, thisBlock.AccountID, thisBlock.Signature)) { return(APIResultCodes.AccountChainSignatureValidationFailed); } thisBlock = prevBlock; } // verify the spending TransactionBlock previousTransaction = _accountCollection.FindBlockByHash(block.PreviousHash); foreach (var prevbalance in previousTransaction.Balances) { // make sure all balances from the previous block are present in a new block even if they are unchanged if (!block.Balances.ContainsKey(prevbalance.Key)) { return(APIResultCodes.AccountChainBalanceValidationFailed); } } // Verify fee if (block.BlockType == BlockTypes.SendTransfer) { if ((block as SendTransferBlock).Fee != _serviceAccount.GetLastServiceBlock().TransferFee) { return(APIResultCodes.InvalidFeeAmount); } } if (block.BlockType == BlockTypes.TokenGenesis) { if ((block as TokenGenesisBlock).Fee != _serviceAccount.GetLastServiceBlock().TokenGenerationFee) { return(APIResultCodes.InvalidFeeAmount); } } } var res = ValidateFee(block); if (res != APIResultCodes.Success) { return(res); } return(APIResultCodes.Success); }