Skip to content

Commit

Permalink
Add mempool ability to remove invalid transactions for getblocktempla…
Browse files Browse the repository at this point in the history
…te, fix unit test
  • Loading branch information
blondfrogs authored Feb 5, 2020
2 parents 5ea4799 + 586e706 commit 3499cad
Show file tree
Hide file tree
Showing 9 changed files with 114 additions and 43 deletions.
2 changes: 1 addition & 1 deletion configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ dnl require autoconf 2.60 (AS_ECHO/AS_ECHO_N)
AC_PREREQ([2.60])
define(_CLIENT_VERSION_MAJOR, 3)
define(_CLIENT_VERSION_MINOR, 3)
define(_CLIENT_VERSION_REVISION, 1)
define(_CLIENT_VERSION_REVISION, 2)
define(_CLIENT_VERSION_BUILD, 0)
define(_CLIENT_VERSION_IS_RELEASE, true)
define(_COPYRIGHT_YEAR, 2019)
Expand Down
78 changes: 39 additions & 39 deletions src/consensus/tx_verify.cpp

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions src/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,7 @@ std::string HelpMessage(HelpMessageMode mode)
strUsage += HelpMessageOpt("-par=<n>", strprintf(_("Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)"),
-GetNumCores(), MAX_SCRIPTCHECK_THREADS, DEFAULT_SCRIPTCHECK_THREADS));
strUsage += HelpMessageOpt("-autofixmempool", strprintf(_("When set, if the CreateNewBlock fails because of a transaction. The mempool will be cleared. (default: %d)"), false));
strUsage += HelpMessageOpt("-bypassdownload", strprintf(_("When set, if the chain is in initialblockdownload the getblocktemplate rpc call will still return block data (default: %d)"), false));
#ifndef WIN32
strUsage += HelpMessageOpt("-pid=<file>", strprintf(_("Specify pid file (default: %s)"), RAVEN_PID_FILENAME));
#endif
Expand Down
13 changes: 12 additions & 1 deletion src/miner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -198,11 +198,22 @@ std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& sc
{
TRY_LOCK(mempool.cs, fLockMempool);
if (fLockMempool) {
LogPrintf("%s failed because of a transaction %s. Clearing the mempool.", __func__,
LogPrintf("%s failed because of a transaction %s. -autofixmempool is set to true. Clearing the mempool\n", __func__,
state.GetFailedTransaction().GetHex());
mempool.clear();
}
}
} else {
{
TRY_LOCK(mempool.cs, fLockMempool);
if (fLockMempool) {
auto mempoolTx = mempool.get(state.GetFailedTransaction());
if (mempoolTx) {
LogPrintf("%s : Failed because of a transaction %s. Trying to remove the transaction from the mempool\n", __func__, state.GetFailedTransaction().GetHex());
mempool.removeRecursive(*mempoolTx, MemPoolRemovalReason::CONFLICT);
}
}
}
}
}
throw std::runtime_error(strprintf("%s: TestBlockValidity failed: %s", __func__, FormatStateMessage(state)));
Expand Down
2 changes: 1 addition & 1 deletion src/rpc/mining.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -451,7 +451,7 @@ UniValue getblocktemplate(const JSONRPCRequest& request)
if (g_connman->GetNodeCount(CConnman::CONNECTIONS_ALL) == 0)
throw JSONRPCError(RPC_CLIENT_NOT_CONNECTED, "Raven is not connected!");

if (IsInitialBlockDownload())
if (IsInitialBlockDownload() && !gArgs.GetBoolArg("-bypassdownload", false))
throw JSONRPCError(RPC_CLIENT_IN_INITIAL_DOWNLOAD, "Raven is downloading blocks...");

static unsigned int nTransactionsUpdatedLast;
Expand Down
25 changes: 25 additions & 0 deletions src/txmempool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -703,6 +703,26 @@ void CTxMemPool::removeUnchecked(txiter it, MemPoolRemovalReason reason)
}
mapHashGlobalUnFreezingAssetTransactions.erase(hash);
}

if (mapHashToAddressAddedTag.count(hash)) {
for (auto item : mapHashToAddressAddedTag.at(hash)) {
if (mapAddressAddedTag.count(item)) {
mapAddressAddedTag.at(item).erase(hash);
if (mapAddressAddedTag.at(item).size() == 0)
mapAddressAddedTag.erase(item);
}
}
}

if (mapHashToAddressRemoveTag.count(hash)) {
for (auto item : mapHashToAddressRemoveTag.at(hash)) {
if (mapAddressRemoveTag.count(item)) {
mapAddressRemoveTag.at(item).erase(hash);
if (mapAddressRemoveTag.at(item).size() == 0)
mapAddressRemoveTag.erase(item);
}
}
}
/** RVN END */
}

Expand Down Expand Up @@ -1018,6 +1038,11 @@ void CTxMemPool::_clear()
mapAssetVerifierChanged.clear();
mapHashVerifierChanged.clear();

mapHashToAddressAddedTag.clear();
mapAddressAddedTag.clear();
mapHashToAddressRemoveTag.clear();
mapAddressRemoveTag.clear();

mapGlobalFreezingAssetTransactions.clear();
mapHashGlobalFreezingAssetTransactions.clear();

Expand Down
8 changes: 8 additions & 0 deletions src/txmempool.h
Original file line number Diff line number Diff line change
Expand Up @@ -492,6 +492,14 @@ class CTxMemPool
std::map<std::string, std::set<uint256>> mapGlobalFreezingAssetTransactions;
std::map<uint256, std::set<std::string>> mapHashGlobalFreezingAssetTransactions;

// Helper map for when a qualfier is added to an address
std::map<std::pair<std::string, std::string>, std::set<uint256> > mapAddressAddedTag;
std::map<uint256, std::set<std::pair<std::string, std::string>>> mapHashToAddressAddedTag;

// Helper map for when a qualfier is added to an address
std::map<std::pair<std::string, std::string>, std::set<uint256> > mapAddressRemoveTag;
std::map<uint256, std::set<std::pair<std::string, std::string>>> mapHashToAddressRemoveTag;

std::map<std::string, std::set<uint256>> mapGlobalUnFreezingAssetTransactions;
std::map<uint256, std::set<std::string>> mapHashGlobalUnFreezingAssetTransactions;

Expand Down
26 changes: 26 additions & 0 deletions src/validation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1008,6 +1008,32 @@ static bool AcceptToMemoryPoolWorker(const CChainParams& chainparams, CTxMemPool
}
}
}
} else if (out.scriptPubKey.IsNullAssetTxDataScript()) {
// We need to track all tags that are being adding to address, that live in the mempool
// This will allow us to keep the mempool clean, and only allow one tag per address at a time into the mempool
CNullAssetTxData addressNullData;
std::string address;
if (AssetNullDataFromScript(out.scriptPubKey, addressNullData, address)) {
if (IsAssetNameAQualifier(addressNullData.asset_name)) {
if (addressNullData.flag == (int) QualifierType::ADD_QUALIFIER) {
if (pool.mapAddressAddedTag.count(std::make_pair(address, addressNullData.asset_name))) {
return state.DoS(0, false, REJECT_INVALID,
"bad-txns-adding-tag-already-in-mempool");
}
// Adding a qualifier to an address
pool.mapAddressAddedTag[std::make_pair(address, addressNullData.asset_name)].insert(tx.GetHash());
pool.mapHashToAddressAddedTag[tx.GetHash()].insert(std::make_pair(address, addressNullData.asset_name));
} else {
if (pool.mapAddressRemoveTag.count(std::make_pair(address, addressNullData.asset_name))) {
return state.DoS(0, false, REJECT_INVALID,
"bad-txns-remove-tag-already-in-mempool");
}

pool.mapAddressRemoveTag[std::make_pair(address, addressNullData.asset_name)].insert(tx.GetHash());
pool.mapHashToAddressRemoveTag[tx.GetHash()].insert(std::make_pair(address, addressNullData.asset_name));
}
}
}
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion test/functional/feature_uacomment.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ def run_test(self):

self.log.info("test -uacomment max length")
self.stop_node(0)
expected = "Total length of network version string (288) exceeds maximum length (256). Reduce the number or size of uacomments."
expected = "Total length of network version string (286) exceeds maximum length (256). Reduce the number or size of uacomments."
self.assert_start_raises_init_error(0, ["-uacomment=" + 'a' * 256], expected)

self.log.info("test -uacomment unsafe characters")
Expand Down

0 comments on commit 3499cad

Please sign in to comment.