static bool ToMemPool(CMutableTransaction& tx) { LOCK(cs_main); CValidationState state; return AcceptToMemoryPool(mempool, state, tx, false, NULL, true, false); }
static bool ToMemPool(const CMutableTransaction& tx) { LOCK(cs_main); CValidationState state; return AcceptToMemoryPool(mempool, state, MakeTransactionRef(tx), nullptr /* pfMissingInputs */, nullptr /* plTxnReplaced */, true /* bypass_limits */, 0 /* nAbsurdFee */); }
// check to make sure the collateral provided by the client is valid bool CPrivateSend::IsCollateralValid(const CTransaction& txCollateral) { if(txCollateral.vout.empty()) return false; if(txCollateral.nLockTime != 0) return false; CAmount nValueIn = 0; CAmount nValueOut = 0; for (const auto& txout : txCollateral.vout) { nValueOut += txout.nValue; bool fAllowData = true; if(!txout.scriptPubKey.IsPayToPublicKeyHash() && !(fAllowData && txout.scriptPubKey.IsUnspendable())) { LogPrintf ("CPrivateSend::IsCollateralValid -- Invalid Script, txCollateral=%s", txCollateral.ToString()); return false; } } for (const auto& txin : txCollateral.vin) { Coin coin; if(!GetUTXOCoin(txin.prevout, coin)) { LogPrint("privatesend", "CPrivateSend::IsCollateralValid -- Unknown inputs in collateral transaction, txCollateral=%s", txCollateral.ToString()); return false; } nValueIn += coin.out.nValue; } //collateral transactions are required to pay out a small fee to the miners if(nValueIn - nValueOut < GetCollateralAmount()) { LogPrint("privatesend", "CPrivateSend::IsCollateralValid -- did not include enough fees in transaction: fees: %d, txCollateral=%s", nValueOut - nValueIn, txCollateral.ToString()); return false; } LogPrint("privatesend", "CPrivateSend::IsCollateralValid -- %s", txCollateral.ToString()); { LOCK(cs_main); CValidationState validationState; if(!AcceptToMemoryPool(mempool, validationState, MakeTransactionRef(txCollateral), false, NULL, NULL, false, maxTxFee, true)) { LogPrint("privatesend", "CPrivateSend::IsCollateralValid -- didn't pass AcceptToMemoryPool()\n"); return false; } } return true; }
void SellsPage::on_refundButton_clicked() { QItemSelectionModel* selectionModel = ui->buysTableWidget->selectionModel(); QModelIndexList selected = selectionModel->selectedRows(); if(selected.count() == 0) return; QModelIndex index = selected.at(0); int r = index.row(); std::string id = ui->buysTableWidget->item(r, 4)->text().toStdString(); uint256 listingIdHash = uint256(id); std::string rid = ui->buysTableWidget->item(r, 5)->text().toStdString(); uint256 requestIdHash = uint256(rid); // ask the user if they really want to accept the buy request QMessageBox::StandardButton reply; reply = QMessageBox::question(this, "Refund Buy", "Are you sure you want to refund the buyer for this item? This will return the security deposit to both buyer and seller.", QMessageBox::Yes|QMessageBox::No); if (reply == QMessageBox::Yes) { // Construct a transaction that spends the escrow multisig and sends the security deposit back to // the seller as well as the buyer CBuyRequest buyRequest = mapBuyRequests[requestIdHash]; // get the raw tx off of the request //std::string rawTx = RefundEscrow(buyRequest.buyerEscrowLockTxHash, buyRequest.sellerEscrowLockTxHash, mapListings[buyRequest.listingId].listing.sellerKey, 2*mapListings[buyRequest.listingId].listing.nValue, buyRequest.buyerKey, strErrors); std::string rawTx = SignMultiSigTransaction(buyRequest.rawTx); // broadcast the payment transaction CTransaction tx; vector<unsigned char> txData(ParseHex(rawTx)); CDataStream ssData(txData, SER_NETWORK, PROTOCOL_VERSION); ssData >> tx; AcceptToMemoryPool(mempool, tx, false, NULL); LoadSells(); LoadBuyRequests(); }
/** * Ensure that the mempool won't accept coinbase transactions. */ BOOST_FIXTURE_TEST_CASE(tx_mempool_reject_coinbase, TestChain100Setup) { CScript scriptPubKey = CScript() << ToByteVector(coinbaseKey.GetPubKey()) << OP_CHECKSIG; CMutableTransaction coinbaseTx; coinbaseTx.nVersion = 1; coinbaseTx.vin.resize(1); coinbaseTx.vout.resize(1); coinbaseTx.vin[0].scriptSig = CScript() << OP_11 << OP_EQUAL; coinbaseTx.vout[0].nValue = 1 * CENT; coinbaseTx.vout[0].scriptPubKey = scriptPubKey; BOOST_CHECK(CTransaction(coinbaseTx).IsCoinBase()); CValidationState state; LOCK(cs_main); unsigned int initialPoolSize = mempool.size(); BOOST_CHECK_EQUAL( false, AcceptToMemoryPool(mempool, state, MakeTransactionRef(coinbaseTx), nullptr /* pfMissingInputs */, nullptr /* plTxnReplaced */, true /* bypass_limits */, 0 /* nAbsurdFee */)); // Check that the transaction hasn't been added to mempool. BOOST_CHECK_EQUAL(mempool.size(), initialPoolSize); // Check that the validation state reflects the unsuccessful attempt. BOOST_CHECK(state.IsInvalid()); BOOST_CHECK_EQUAL(state.GetRejectReason(), "coinbase"); int nDoS; BOOST_CHECK_EQUAL(state.IsInvalid(nDoS), true); BOOST_CHECK_EQUAL(nDoS, 100); }
void MultisigDialog::commitMultisigTx() { CMutableTransaction tx(multisigTx); try{ #ifdef ENABLE_WALLET CWalletTx wtx(pwalletMain, tx); CReserveKey keyChange(pwalletMain); if (!pwalletMain->CommitTransaction(wtx, keyChange)) throw runtime_error(string("Transaction rejected - Failed to commit")); #else uint256 hashTx = tx.GetHash(); CCoinsViewCache& view = *pcoinsTip; const CCoins* existingCoins = view.AccessCoins(hashTx); bool fOverrideFees = false; bool fHaveMempool = mempool.exists(hashTx); bool fHaveChain = existingCoins && existingCoins->nHeight < 1000000000; if (!fHaveMempool && !fHaveChain) { // push to local node and sync with wallets CValidationState state; if (!AcceptToMemoryPool(mempool, state, tx, false, NULL, !fOverrideFees)) { if (state.IsInvalid()) throw runtime_error(strprintf("Transaction rejected - %i: %s", state.GetRejectCode(), state.GetRejectReason())); else throw runtime_error(string("Transaction rejected - ") + state.GetRejectReason()); } } else if (fHaveChain) { throw runtime_error("transaction already in block chain"); } RelayTransaction(tx); #endif //disable commit if successfully committed ui->commitButton->setEnabled(false); ui->signButtonStatus->setText(strprintf("Transaction has been successfully published with transaction ID:\n %s", tx.GetHash().GetHex()).c_str()); }catch(const runtime_error& e){ ui->signButtonStatus->setText(e.what()); } }
UniValue sendrawtransaction(const JSONRPCRequest& request) { if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) throw std::runtime_error( "sendrawtransaction \"hexstring\" ( allowhighfees )\n" "\nSubmits raw transaction (serialized, hex-encoded) to local node and network.\n" "\nAlso see createrawtransaction and signrawtransaction calls.\n" "\nArguments:\n" "1. \"hexstring\" (string, required) The hex string of the raw transaction)\n" "2. allowhighfees (boolean, optional, default=false) Allow high fees\n" "\nResult:\n" "\"hex\" (string) The transaction hash in hex\n" "\nExamples:\n" "\nCreate a transaction\n" + HelpExampleCli("createrawtransaction", "\"[{\\\"txid\\\" : \\\"mytxid\\\",\\\"vout\\\":0}]\" \"{\\\"myaddress\\\":0.01}\"") + "Sign the transaction, and get back the hex\n" + HelpExampleCli("signrawtransaction", "\"myhex\"") + "\nSend the transaction (signed hex)\n" + HelpExampleCli("sendrawtransaction", "\"signedhex\"") + "\nAs a json rpc call\n" + HelpExampleRpc("sendrawtransaction", "\"signedhex\"") ); ObserveSafeMode(); LOCK(cs_main); RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VBOOL}); // parse hex string from parameter CMutableTransaction mtx; if (!DecodeHexTx(mtx, request.params[0].get_str())) throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed"); CTransactionRef tx(MakeTransactionRef(std::move(mtx))); const uint256& hashTx = tx->GetHash(); CAmount nMaxRawTxFee = maxTxFee; if (!request.params[1].isNull() && request.params[1].get_bool()) nMaxRawTxFee = 0; CCoinsViewCache &view = *pcoinsTip; bool fHaveChain = false; for (size_t o = 0; !fHaveChain && o < tx->vout.size(); o++) { const Coin& existingCoin = view.AccessCoin(COutPoint(hashTx, o)); fHaveChain = !existingCoin.IsSpent(); } bool fHaveMempool = mempool.exists(hashTx); if (!fHaveMempool && !fHaveChain) { // push to local node and sync with wallets CValidationState state; bool fMissingInputs; bool fLimitFree = true; if (!AcceptToMemoryPool(mempool, state, std::move(tx), fLimitFree, &fMissingInputs, nullptr, false, nMaxRawTxFee)) { if (state.IsInvalid()) { throw JSONRPCError(RPC_TRANSACTION_REJECTED, strprintf("%i: %s", state.GetRejectCode(), state.GetRejectReason())); } else { if (fMissingInputs) { throw JSONRPCError(RPC_TRANSACTION_ERROR, "Missing inputs"); } throw JSONRPCError(RPC_TRANSACTION_ERROR, state.GetRejectReason()); } } } else if (fHaveChain) { throw JSONRPCError(RPC_TRANSACTION_ALREADY_IN_CHAIN, "transaction already in block chain"); } if(!g_connman) throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled"); CInv inv(MSG_TX, hashTx); g_connman->ForEachNode([&inv](CNode* pnode) { pnode->PushInventory(inv); }); return hashTx.GetHex(); }