protected APIResultCodes VerifyBlock(TransactionBlock block, TransactionBlock previousBlock) { if (NodeGlobalParameters.Network_Id != block.NetworkId) { return(APIResultCodes.InvalidNetworkId); } if (!block.IsBlockValid(previousBlock)) { return(APIResultCodes.BlockValidationFailed); } //if (!Signatures.VerifySignature(block.Hash, block.AccountID, block.Signature)) // return APIResultCodes.BlockSignatureValidationFailed; if (!block.VerifySignature(block.AccountID)) { return(APIResultCodes.BlockSignatureValidationFailed); } // check if this Index already exists (double-spending, kind of) if (_accountCollection.FindBlockByIndex(block.AccountID, block.Index) != null) { return(APIResultCodes.BlockWithThisIndexAlreadyExists); } // This is the double-spending check for send block! if (!string.IsNullOrEmpty(block.PreviousHash) && _accountCollection.FindBlockByPreviousBlockHash(block.PreviousHash) != null) { return(APIResultCodes.BlockWithThisPreviousHashAlreadyExists); } if (block.Index <= 0) { return(APIResultCodes.InvalidIndexSequence); } if (block.Index > 1 && previousBlock == null) { return(APIResultCodes.CouldNotFindLatestBlock); } if (block.Index == 1 && previousBlock != null) { return(APIResultCodes.InvalidIndexSequence); } if (previousBlock != null && block.Index != previousBlock.Index + 1) { return(APIResultCodes.InvalidIndexSequence); } if (!ValidateRenewalDate(block, previousBlock)) { return(APIResultCodes.TokenExpired); } return(APIResultCodes.Success); }
// common validations for Send and Receive blocks protected async Task <APIResultCodes> VerifyTransactionBlockAsync(DagSystem sys, 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)) if (!(thisBlock is IOpeningBlock)) //save time { prevBlock = await sys.Storage.FindBlockByHashAsync(thisBlock.PreviousHash) as TransactionBlock; if (!thisBlock.IsBlockValid(prevBlock)) { return(APIResultCodes.AccountChainBlockValidationFailed); } //if(block.ContainsTag(Block.MANAGEDTAG)) //{ // var svcBlock = await sys.Storage.FindBlockByHashAsync(block.ServiceHash) as ServiceBlock; // var result = Signatures.VerifyAccountSignature(thisBlock.Hash, svcBlock.Leader, thisBlock.Signature); // if (!result) // return APIResultCodes.AccountChainSignatureValidationFailed; //} //else //{ // var result = Signatures.VerifyAccountSignature(thisBlock.Hash, thisBlock.AccountID, thisBlock.Signature); // if (!result) // return APIResultCodes.AccountChainSignatureValidationFailed; //} thisBlock = prevBlock; } // verify the spending TransactionBlock previousTransaction = await sys.Storage.FindBlockByHashAsync(block.PreviousHash) as TransactionBlock; 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); } } } return(APIResultCodes.Success); }
// 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); }