void MultisigDialog::on_sendTransactionButton_clicked() { int64_t transactionSize = ui->signedTransaction->text().size() / 2; if(transactionSize == 0) return; // Check the fee int64_t fee = (int64_t ) (ui->fee->text().toDouble() * COIN); int64_t minFee = MIN_TX_FEE * (1 + (int64_t) transactionSize / 1000); if(fee < minFee) { QMessageBox::StandardButton ret = QMessageBox::question(this, tr("Confirm send transaction"), tr("The fee of the transaction (%1 XBTC21) is smaller than the expected fee (%2 XBTC21). Do you want to send the transaction anyway?").arg((double) fee / COIN).arg((double) minFee / COIN), QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Cancel); if(ret != QMessageBox::Yes) return; } else if(fee > minFee) { QMessageBox::StandardButton ret = QMessageBox::question(this, tr("Confirm send transaction"), tr("The fee of the transaction (%1 XBTC21) is bigger than the expected fee (%2 XBTC21). Do you want to send the transaction anyway?").arg((double) fee / COIN).arg((double) minFee / COIN), QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Cancel); if(ret != QMessageBox::Yes) return; } // Decode the raw transaction std::vector<unsigned char> txData(ParseHex(ui->signedTransaction->text().toStdString())); CDataStream ssData(txData, SER_NETWORK, PROTOCOL_VERSION); CTransaction tx; try { ssData >> tx; } catch(std::exception &e) { (void)e; return; } uint256 txHash = tx.GetHash(); // Check if the transaction is already in the blockchain CTransaction existingTx; uint256 blockHash = 0; if(GetTransaction(txHash, existingTx, blockHash)) { if(blockHash != 0) return; } // Send the transaction to the local node CTxDB txdb("r"); if(!tx.AcceptToMemoryPool(txdb, false)) return; SyncWithWallets(tx, NULL, true); //(CInv(MSG_TX, txHash), tx); RelayTransaction(tx, txHash); }
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()); } }
void OutgoingResourceLimiter::ForwardTransaction(uint160 hash) { SignedTransaction tx = creditdata[hash]["tx"]; RelayTransaction(tx); }