// remove bool IsTransactionValid(Types.Transaction tx, byte[] txHash, out TransactionValidation.PointedTransaction ptx) { if (_BlockChain.BlockStore.TxStore.ContainsKey(_DbTx, txHash) && _BlockChain.BlockStore.TxStore.Get(_DbTx, txHash).Value.InMainChain) { BlockChainTrace.Information("Tx already in store", txHash); ptx = null; return(false); } switch (_BlockChain.IsOrphanTx(_DbTx, tx, true, out ptx)) { case BlockChain.IsTxOrphanResult.Orphan: BlockChainTrace.Information("tx invalid - orphan", tx); return(false); case BlockChain.IsTxOrphanResult.Invalid: BlockChainTrace.Information("tx invalid - reference(s)", tx); return(false); } if (_BlockChain.IsDoubleSpend(_DbTx, tx, true)) { return(false); } //TODO: coinbase validation + check that witness has blocknumber if (!BlockChain.IsValidUserGeneratedTx(_DbTx, ptx)) { BlockChainTrace.Information("tx invalid - structural", ptx); return(false); } byte[] contractHash; switch (BlockChain.IsContractGeneratedTx(ptx, out contractHash)) { case BlockChain.IsContractGeneratedTxResult.ContractGenerated: if (!_BlockChain.ActiveContractSet.IsActive(_DbTx, contractHash)) { BlockChainTrace.Information("tx invalid - contract not active", tx); return(false); } var contractFunction = _BlockChain.ActiveContractSet.GetContractFunction(_DbTx, contractHash); if (!BlockChain.IsValidAutoTx(ptx, UtxoLookup, contractHash, contractFunction)) { BlockChainTrace.Information("auto-tx invalid", ptx); return(false); } break; case BlockChain.IsContractGeneratedTxResult.Invalid: BlockChainTrace.Information("tx invalid - input locks", tx); return(false); } return(true); }