/// <inheritdoc /> public bool ValidateTransaction(Transaction transaction, bool checkSignature = false) { lock (this.lockObject) { // All the input UTXO's should be present in spending details of the multi-sig address. List <Coin> coins = checkSignature ? new List <Coin>() : null; // Verify that the transaction has valid UTXOs. if (!this.TransactionHasValidUTXOs(transaction, coins)) { return(false); } // Verify that there are no earlier unspent UTXOs. Comparer <TransactionData> comparer = Comparer <TransactionData> .Create((x, y) => FederationWalletTransactionBuilder.CompareTransactionData(x, y)); TransactionData earliestUnspent = this.Wallet.MultiSigAddress.Transactions.Where(t => t.SpendingDetails == null).OrderBy(t => t, comparer).FirstOrDefault(); if (earliestUnspent != null) { TransactionData oldestInput = transaction.Inputs.Select(i => this.outpointLookup[i.PrevOut]).OrderByDescending(t => t, comparer).FirstOrDefault(); if (oldestInput != null && FederationWalletTransactionBuilder.CompareTransactionData(earliestUnspent, oldestInput) < 0) { return(false); } } // Verify that all inputs are signed. if (checkSignature) { TransactionBuilder builder = new TransactionBuilder(this.Wallet.Network).AddCoins(coins); if (!builder.Verify(transaction, this.federationGatewaySettings.TransactionFee, out TransactionPolicyError[] errors))
/// <inheritdoc /> public int CompareOutpoints(OutPoint outPoint1, OutPoint outPoint2) { lock (this.lockObject) { TransactionData transactionData1 = this.outpointLookup[outPoint1]; TransactionData transactionData2 = this.outpointLookup[outPoint2]; return(FederationWalletTransactionBuilder.CompareTransactionData(transactionData1, transactionData2)); } }