/** * Checks if a transaction is considered "standard" by the reference client's IsStandardTx and * AreInputsStandard functions. * * <p>Note that this method currently only implements a minimum of checks. More to be added later. */ public static RuleViolation isStandard(Transaction tx) { // TODO: Finish this function off. if (tx.getVersion() > 1 || tx.getVersion() < 1) { log.warn("TX considered non-standard due to unknown version number {}", tx.getVersion()); return RuleViolation.VERSION; } final List<TransactionOutput> outputs = tx.getOutputs(); for (int i = 0; i < outputs.size(); i++) { TransactionOutput output = outputs.get(i); RuleViolation violation = isOutputStandard(output); if (violation != RuleViolation.NONE) { log.warn("TX considered non-standard due to output {} violating rule {}", i, violation); return violation; } } final List<TransactionInput> inputs = tx.getInputs(); for (int i = 0; i < inputs.size(); i++) { TransactionInput input = inputs.get(i); RuleViolation violation = isInputStandard(input); if (violation != RuleViolation.NONE) { log.warn("TX considered non-standard due to input {} violating rule {}", i, violation); return violation; } } return RuleViolation.NONE; }
@Override public String toString() { if (!analyzed) return "Pending risk analysis for " + tx.getHashAsString(); else if (nonFinal != null) return "Risky due to non-finality of " + nonFinal.getHashAsString(); else if (nonStandard != null) return "Risky due to non-standard tx " + nonStandard.getHashAsString(); else return "Non-risky"; }
private Result analyzeIsFinal() { // Transactions we create ourselves are, by definition, not at risk of double spending against // us. if (tx.getConfidence().getSource() == TransactionConfidence.Source.SELF) return Result.OK; final int height = wallet.getLastBlockSeenHeight(); final long time = wallet.getLastBlockSeenTimeSecs(); // If the transaction has a lock time specified in blocks, we consider that if the tx would // become final in the // next block it is not risky (as it would confirm normally). final int adjustedHeight = height + 1; if (!tx.isFinal(adjustedHeight, time)) { nonFinal = tx; return Result.NON_FINAL; } for (Transaction dep : dependencies) { if (!dep.isFinal(adjustedHeight, time)) { nonFinal = dep; return Result.NON_FINAL; } } return Result.OK; }