Commit b697a171 authored by Tom Zander's avatar Tom Zander
Browse files

Add 'validationOnly' option to API

parent 630b8422
......@@ -1075,6 +1075,7 @@ public:
void run() override {
Streaming::MessageParser parser(m_request);
Tx tx;
bool validateOnly = false;
while (parser.next() == Streaming::FoundTag) {
if (parser.tag() == Api::LiveTransactions::Transaction
|| parser.tag() == Api::LiveTransactions::GenericByteData) {
......@@ -1082,11 +1083,15 @@ public:
throw Api::ParserException("Only one Tx per message allowed");
tx = Tx(parser.bytesDataBuffer());
}
if (parser.tag() == Api::LiveTransactions::ValidateOnly)
validateOnly = parser.boolData();
}
if (tx.data().isEmpty())
throw Api::ParserException("No transaction found in message");
std::uint32_t flags = Validation::ForwardGoodToPeers;
std::uint32_t flags = 0;
if (validateOnly)
flags += Validation::TxValidateOnly;
flags += Validation::RejectAbsurdFeeTx;
auto resultFuture = Application::instance()->validation()->addTransaction(tx, flags);
auto result = resultFuture.get(); // <= blocking call.
......
......@@ -178,6 +178,7 @@ enum Tags {
DSProofId,
FirstSeenTime, // long-int with seconds since epoch (UTC)
MatchingOutIndex, // int. Output index that matches the requested search.
ValidateOnly, // bool, if true then we stop after validation finished.
// for individual transaction you can select how they should be returned.
Include_TxId = 43, ///< bool.
......
......@@ -1826,7 +1826,7 @@ bool static ProcessMessage(CNode* pfrom, std::string strCommand, CDataStream& vR
mapAlreadyAskedFor.erase(inv.hash);
}
uint32_t opts = Validation::ForwardGoodToPeers;
uint32_t opts = 0;
if (!pfrom->fWhitelisted)
opts += Validation::PunishBadNode + Validation::RateLimitFreeTx;
flApp->validation()->addTransaction(Tx::fromOldTransaction(tx), opts, pfrom);
......
......@@ -877,7 +877,7 @@ UniValue sendrawtransaction(const UniValue& params, bool fHelp)
bool fHaveChain = utxo.isValid() && utxo.blockHeight() < 1000000000;
if (!fHaveMempool && !fHaveChain) {
// push to local node and sync with wallets
uint32_t flags = Validation::ForwardGoodToPeers;
uint32_t flags = 0;
if (!fOverrideFees)
flags |= Validation::RejectAbsurdFeeTx;
......
......@@ -47,7 +47,8 @@ enum ResultHandlingFlags {
ForwardGoodToPeers = 2,///< A successful block will get forwarded to peers.
PunishBadNode = 4, ///< Ban a bad node that gave us this block.
RateLimitFreeTx = 8,
RejectAbsurdFeeTx = 0x10
RejectAbsurdFeeTx = 0x10,
TxValidateOnly = 0x20
};
/// throws exception if transaction is malformed.
......
......@@ -400,7 +400,7 @@ void TxValidationState::checkTransaction()
parent->mempool->UpdateTransactionsFromBlock(me);
}
if (m_validationFlags & Validation::ForwardGoodToPeers)
if ((m_validationFlags & Validation::TxValidateOnly) == 0)
RelayTransaction(tx);
auto orphans = CTxOrphanCache::instance()->fetchTransactionsByPrev(txid);
......@@ -423,18 +423,19 @@ void TxValidationState::checkTransaction()
if (ex.id != -1) // to avoid log file confusion, don't mention this for anything but the first DS
logWarning(Log::TxValidation) << "Tx-Validation found a double spend";
m_doubleSpendTx = ex.otherTx;
m_doubleSpendProofId = ex.id;
if ((m_validationFlags & Validation::TxValidateOnly) == 0) {
m_doubleSpendTx = ex.otherTx;
m_doubleSpendProofId = ex.id;
parent->strand.post(std::bind(&TxValidationState::notifyDoubleSpend, shared_from_this()));
parent->strand.post(std::bind(&TxValidationState::notifyDoubleSpend, shared_from_this()));
std::lock_guard<std::mutex> rejects(parent->recentRejectsLock);
parent->recentTxRejects.insert(txid);
std::lock_guard<std::mutex> rejects(parent->recentRejectsLock);
parent->recentTxRejects.insert(txid);
}
} catch (const Exception &ex) {
raii.result = strprintf("%i: %s", ex.rejectCode(), ex.what());
if (inputsMissing) {// if missing inputs, add to orphan cache
DEBUGTX << "Tx missed inputs, can't add to mempool" << txid;
if ((m_validationFlags & FromMempool) == 0 && m_originatingNodeId < 0)
if ((m_validationFlags & Validation::TxValidateOnly) || m_originatingNodeId < 0)
return;
CTxOrphanCache *cache = CTxOrphanCache::instance();
// DoS prevention: do not allow CTxOrphanCache to grow unbounded
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment