Browse Source

WIP: Keva mempool test.

cn
Jianping Wu 6 years ago
parent
commit
ceefe25a87
  1. 15
      src/keva/main.cpp
  2. 344
      src/test/keva_tests.cpp
  3. 2
      src/txmempool.h

15
src/keva/main.cpp

@ -54,7 +54,7 @@ CKevaMemPool::addUnchecked (const uint256& hash, const CTxMemPoolEntry& entry)
listUnconfirmedNamespaces.push_back(std::make_tuple(hash, nameSpace, entry.getDisplayName())); listUnconfirmedNamespaces.push_back(std::make_tuple(hash, nameSpace, entry.getDisplayName()));
} }
if (entry.isNamespaceKeyUpdate ()) { if (entry.isKeyUpdate()) {
const valtype& nameSpace = entry.getNamespace(); const valtype& nameSpace = entry.getNamespace();
listUnconfirmedKeyValues.push_back(std::make_tuple(hash, nameSpace, entry.getKey(), entry.getValue())); listUnconfirmedKeyValues.push_back(std::make_tuple(hash, nameSpace, entry.getKey(), entry.getValue()));
} }
@ -113,7 +113,7 @@ void CKevaMemPool::remove(const CTxMemPoolEntry& entry)
} }
} }
if (entry.isNamespaceKeyUpdate()) { if (entry.isKeyUpdate()) {
auto hash = entry.GetTx().GetHash(); auto hash = entry.GetTx().GetHash();
for (auto iter = listUnconfirmedKeyValues.begin(); iter != listUnconfirmedKeyValues.end(); ++iter) { for (auto iter = listUnconfirmedKeyValues.begin(); iter != listUnconfirmedKeyValues.end(); ++iter) {
if (std::get<0>(*iter) == hash) { if (std::get<0>(*iter) == hash) {
@ -152,6 +152,9 @@ CKevaMemPool::removeConflicts(const CTransaction& tx)
bool CKevaMemPool::validateNamespace(const CTransaction& tx, const valtype& nameSpace) const bool CKevaMemPool::validateNamespace(const CTransaction& tx, const valtype& nameSpace) const
{ {
if (tx.vin.size() == 0) {
return false;
}
valtype kevaNamespace = ToByteVector(Hash160(ToByteVector(tx.vin[0].prevout.hash))); valtype kevaNamespace = ToByteVector(Hash160(ToByteVector(tx.vin[0].prevout.hash)));
const std::vector<unsigned char>& ns_prefix = Params().Base58Prefix(CChainParams::KEVA_NAMESPACE); const std::vector<unsigned char>& ns_prefix = Params().Base58Prefix(CChainParams::KEVA_NAMESPACE);
kevaNamespace.insert(kevaNamespace.begin(), ns_prefix.begin(), ns_prefix.end()); kevaNamespace.insert(kevaNamespace.begin(), ns_prefix.begin(), ns_prefix.end());
@ -161,17 +164,17 @@ bool CKevaMemPool::validateNamespace(const CTransaction& tx, const valtype& name
bool bool
CKevaMemPool::checkTx(const CTransaction& tx) const CKevaMemPool::checkTx(const CTransaction& tx) const
{ {
AssertLockHeld (pool.cs); AssertLockHeld(pool.cs);
if (!tx.IsKevacoin ()) { if (!tx.IsKevacoin()) {
return true; return true;
} }
for (const auto& txout : tx.vout) { for (const auto& txout : tx.vout) {
const CKevaScript nameOp(txout.scriptPubKey); const CKevaScript nameOp(txout.scriptPubKey);
if (!nameOp.isKevaOp ()) if (!nameOp.isKevaOp())
continue; continue;
switch (nameOp.getKevaOp ()) { switch (nameOp.getKevaOp()) {
case OP_KEVA_NAMESPACE: case OP_KEVA_NAMESPACE:
{ {
const valtype& nameSpace = nameOp.getOpNamespace(); const valtype& nameSpace = nameOp.getOpNamespace();

344
src/test/keva_tests.cpp

@ -63,7 +63,6 @@ BOOST_AUTO_TEST_CASE(keva_scripts)
BOOST_CHECK(opNew.getKevaOp() == OP_KEVA_NAMESPACE); BOOST_CHECK(opNew.getKevaOp() == OP_KEVA_NAMESPACE);
BOOST_CHECK(opNew.getOpNamespace() == nameSpace); BOOST_CHECK(opNew.getOpNamespace() == nameSpace);
//SelectParams(CBaseChainParams::MAIN);
const uint256 txId = uint256S("0x78f49add562dc33e4cd61aa45c54012509ed4a53308908dd07f5634437939273"); const uint256 txId = uint256S("0x78f49add562dc33e4cd61aa45c54012509ed4a53308908dd07f5634437939273");
valtype actualNamespace; valtype actualNamespace;
script = CKevaScript::replaceKevaNamespace(script, txId, actualNamespace, Params()); script = CKevaScript::replaceKevaNamespace(script, txId, actualNamespace, Params());
@ -99,7 +98,7 @@ BOOST_AUTO_TEST_CASE (name_database)
const valtype name1 = ValtypeFromString ("database-test-name-1"); const valtype name1 = ValtypeFromString ("database-test-name-1");
const valtype name2 = ValtypeFromString ("database-test-name-2"); const valtype name2 = ValtypeFromString ("database-test-name-2");
const valtype value = ValtypeFromString ("my-value"); const valtype value = ValtypeFromString ("my-value");
const CScript addr = getTestAddress (); const CScript addr = getTestAddress();
/* Choose two height values. To verify that serialisation of the /* Choose two height values. To verify that serialisation of the
expiration entries works as it should, make sure that the values expiration entries works as it should, make sure that the values
@ -110,15 +109,15 @@ BOOST_AUTO_TEST_CASE (name_database)
CNameData dataHeight1, dataHeight2, data2; CNameData dataHeight1, dataHeight2, data2;
CScript updateScript = CNameScript::buildNameUpdate (addr, name1, value); CScript updateScript = CNameScript::buildNameUpdate (addr, name1, value);
const CNameScript nameOp(updateScript); const CNameScript nameOp(updateScript);
dataHeight1.fromScript (height1, COutPoint (uint256 (), 0), nameOp); dataHeight1.fromScript (height1, COutPoint (uint256(), 0), nameOp);
dataHeight2.fromScript (height2, COutPoint (uint256 (), 0), nameOp); dataHeight2.fromScript (height2, COutPoint (uint256(), 0), nameOp);
std::set<valtype> setExpected, setRet; std::set<valtype> setExpected, setRet;
CCoinsViewCache& view = *pcoinsTip; CCoinsViewCache& view = *pcoinsTip;
setExpected.clear (); setExpected.clear();
setRet.clear (); setRet.clear();
setRet.insert (name1); setRet.insert (name1);
BOOST_CHECK (view.GetNamesForHeight (height2, setRet)); BOOST_CHECK (view.GetNamesForHeight (height2, setRet));
BOOST_CHECK (setRet == setExpected); BOOST_CHECK (setRet == setExpected);
@ -134,7 +133,7 @@ BOOST_AUTO_TEST_CASE (name_database)
BOOST_CHECK (view.GetNamesForHeight (height2, setRet)); BOOST_CHECK (view.GetNamesForHeight (height2, setRet));
BOOST_CHECK (setRet == setExpected); BOOST_CHECK (setRet == setExpected);
BOOST_CHECK (view.Flush ()); BOOST_CHECK (view.Flush());
BOOST_CHECK (view.GetName (name1, data2)); BOOST_CHECK (view.GetName (name1, data2));
BOOST_CHECK (dataHeight2 == data2); BOOST_CHECK (dataHeight2 == data2);
@ -145,7 +144,7 @@ BOOST_AUTO_TEST_CASE (name_database)
view.DeleteName (name1); view.DeleteName (name1);
BOOST_CHECK (!view.GetName (name1, data2)); BOOST_CHECK (!view.GetName (name1, data2));
BOOST_CHECK (view.Flush ()); BOOST_CHECK (view.Flush());
BOOST_CHECK (!view.GetName (name1, data2)); BOOST_CHECK (!view.GetName (name1, data2));
BOOST_CHECK (view.GetNamesForHeight (height2, setRet)); BOOST_CHECK (view.GetNamesForHeight (height2, setRet));
@ -153,11 +152,11 @@ BOOST_AUTO_TEST_CASE (name_database)
BOOST_CHECK (setRet == setExpected); BOOST_CHECK (setRet == setExpected);
view.SetName (name2, dataHeight1, false); view.SetName (name2, dataHeight1, false);
BOOST_CHECK (view.Flush ()); BOOST_CHECK (view.Flush());
view.SetName (name1, dataHeight1, false); view.SetName (name1, dataHeight1, false);
BOOST_CHECK (view.GetNamesForHeight (height2, setRet)); BOOST_CHECK (view.GetNamesForHeight (height2, setRet));
setExpected.clear (); setExpected.clear();
BOOST_CHECK (setRet == setExpected); BOOST_CHECK (setRet == setExpected);
BOOST_CHECK (view.GetNamesForHeight (height1, setRet)); BOOST_CHECK (view.GetNamesForHeight (height1, setRet));
setExpected.insert (name1); setExpected.insert (name1);
@ -200,9 +199,9 @@ private:
public: public:
CNameIterator* CNameIterator*
IterateNames () const IterateNames() const
{ {
return new Iterator (); return new Iterator();
} }
}; };
@ -255,7 +254,7 @@ private:
* increments the counter, so that each returned value is unique. * increments the counter, so that each returned value is unique.
* @return A new CNameData object. * @return A new CNameData object.
*/ */
CNameData getNextData (); CNameData getNextData();
/** /**
* Iterate all names in a view and return the result as an ordered * Iterate all names in a view and return the result as an ordered
@ -286,7 +285,7 @@ public:
* Verify consistency of all views. This also flushes the hybrid cache * Verify consistency of all views. This also flushes the hybrid cache
* between verifying it and the base db view. * between verifying it and the base db view.
*/ */
void verify (); void verify();
/** /**
* Add a new name with created dummy data. * Add a new name with created dummy data.
@ -315,16 +314,16 @@ NameIterationTester::NameIterationTester (CCoinsViewDB& base)
} }
CNameData CNameData
NameIterationTester::getNextData () NameIterationTester::getNextData()
{ {
const CScript addr = getTestAddress (); const CScript addr = getTestAddress();
const valtype name = ValtypeFromString ("dummy"); const valtype name = ValtypeFromString ("dummy");
const valtype value = ValtypeFromString ("abc"); const valtype value = ValtypeFromString ("abc");
const CScript updateScript = CNameScript::buildNameUpdate (addr, name, value); const CScript updateScript = CNameScript::buildNameUpdate (addr, name, value);
const CNameScript nameOp(updateScript); const CNameScript nameOp(updateScript);
CNameData res; CNameData res;
res.fromScript (++counter, COutPoint (uint256 (), 0), nameOp); res.fromScript (++counter, COutPoint (uint256(), 0), nameOp);
return res; return res;
} }
@ -337,11 +336,11 @@ NameIterationTester::verify (const CCoinsView& view) const
a single iterator and seeking vs using a fresh iterator. */ a single iterator and seeking vs using a fresh iterator. */
valtype start; valtype start;
EntryList remaining(data.begin (), data.end ()); EntryList remaining(data.begin(), data.end());
/* Seek the iterator to the end first for "maximum confusion". This ensures /* Seek the iterator to the end first for "maximum confusion". This ensures
that seeking to valtype() works. */ that seeking to valtype() works. */
std::unique_ptr<CNameIterator> iter(view.IterateNames ()); std::unique_ptr<CNameIterator> iter(view.IterateNames());
const valtype end = ValtypeFromString ("zzzzzzzzzzzzzzzz"); const valtype end = ValtypeFromString ("zzzzzzzzzzzzzzzz");
{ {
valtype name; valtype name;
@ -360,31 +359,31 @@ NameIterationTester::verify (const CCoinsView& view) const
got = getNamesFromIterator (*iter); got = getNamesFromIterator (*iter);
BOOST_CHECK (got == remaining); BOOST_CHECK (got == remaining);
if (remaining.empty ()) if (remaining.empty())
break; break;
if (start == remaining.front ().first) if (start == remaining.front().first)
remaining.pop_front (); remaining.pop_front();
if (remaining.empty ()) if (remaining.empty())
start = end; start = end;
else else
start = remaining.front ().first; start = remaining.front().first;
} }
} }
void void
NameIterationTester::verify () NameIterationTester::verify()
{ {
verify (hybrid); verify (hybrid);
/* Flush calls BatchWrite internally, and for that to work, we need to have /* Flush calls BatchWrite internally, and for that to work, we need to have
a non-zero block hash. Just set the block hash based on our counter. */ a non-zero block hash. Just set the block hash based on our counter. */
uint256 dummyBlockHash; uint256 dummyBlockHash;
*reinterpret_cast<unsigned*> (dummyBlockHash.begin ()) = counter; *reinterpret_cast<unsigned*> (dummyBlockHash.begin()) = counter;
hybrid.SetBestBlock (dummyBlockHash); hybrid.SetBestBlock (dummyBlockHash);
hybrid.Flush (); hybrid.Flush();
verify (db); verify (db);
verify (cache); verify (cache);
} }
@ -393,7 +392,7 @@ NameIterationTester::EntryList
NameIterationTester::getNamesFromView (const CCoinsView& view, NameIterationTester::getNamesFromView (const CCoinsView& view,
const valtype& start) const valtype& start)
{ {
std::unique_ptr<CNameIterator> iter(view.IterateNames ()); std::unique_ptr<CNameIterator> iter(view.IterateNames());
iter->seek (start); iter->seek (start);
return getNamesFromIterator (*iter); return getNamesFromIterator (*iter);
@ -416,26 +415,26 @@ void
NameIterationTester::add (const std::string& n) NameIterationTester::add (const std::string& n)
{ {
const valtype& name = ValtypeFromString (n); const valtype& name = ValtypeFromString (n);
const CNameData testData = getNextData (); const CNameData testData = getNextData();
assert (data.count (name) == 0); assert (data.count (name) == 0);
data[name] = testData; data[name] = testData;
hybrid.SetName (name, testData, false); hybrid.SetName (name, testData, false);
cache.SetName (name, testData, false); cache.SetName (name, testData, false);
verify (); verify();
} }
void void
NameIterationTester::update (const std::string& n) NameIterationTester::update (const std::string& n)
{ {
const valtype& name = ValtypeFromString (n); const valtype& name = ValtypeFromString (n);
const CNameData testData = getNextData (); const CNameData testData = getNextData();
assert (data.count (name) == 1); assert (data.count (name) == 1);
data[name] = testData; data[name] = testData;
hybrid.SetName (name, testData, false); hybrid.SetName (name, testData, false);
cache.SetName (name, testData, false); cache.SetName (name, testData, false);
verify (); verify();
} }
void void
@ -447,14 +446,14 @@ NameIterationTester::remove (const std::string& n)
data.erase (name); data.erase (name);
hybrid.DeleteName (name); hybrid.DeleteName (name);
cache.DeleteName (name); cache.DeleteName (name);
verify (); verify();
} }
BOOST_AUTO_TEST_CASE (name_iteration) BOOST_AUTO_TEST_CASE (name_iteration)
{ {
NameIterationTester tester(*pcoinsdbview); NameIterationTester tester(*pcoinsdbview);
tester.verify (); tester.verify();
tester.add (""); tester.add ("");
tester.add ("a"); tester.add ("a");
@ -498,7 +497,7 @@ addTestCoin (const CScript& scr, unsigned nHeight, CCoinsViewCache& view)
const CTransaction tx(mtx); const CTransaction tx(mtx);
Coin coin(txout, nHeight, false); Coin coin(txout, nHeight, false);
const COutPoint outp(tx.GetHash (), 0); const COutPoint outp(tx.GetHash(), 0);
view.AddCoin (outp, std::move (coin), false); view.AddCoin (outp, std::move (coin), false);
return outp; return outp;
@ -513,11 +512,11 @@ BOOST_AUTO_TEST_CASE (name_tx_verification)
const valtype tooLongName(256, 'x'); const valtype tooLongName(256, 'x');
const valtype tooLongValue(1024, 'x'); const valtype tooLongValue(1024, 'x');
const CScript addr = getTestAddress (); const CScript addr = getTestAddress();
const valtype rand(20, 'x'); const valtype rand(20, 'x');
valtype toHash(rand); valtype toHash(rand);
toHash.insert (toHash.end (), name1.begin (), name1.end ()); toHash.insert (toHash.end(), name1.begin(), name1.end());
const uint160 hash = Hash160 (toHash); const uint160 hash = Hash160 (toHash);
/* We use a basic coin view as standard situation for all the tests. /* We use a basic coin view as standard situation for all the tests.
@ -554,14 +553,14 @@ BOOST_AUTO_TEST_CASE (name_tx_verification)
/* Non-name tx should be non-Namecoin version. */ /* Non-name tx should be non-Namecoin version. */
BOOST_CHECK (CheckNameTransaction (baseTx, 200000, view, state, 0)); BOOST_CHECK (CheckNameTransaction (baseTx, 200000, view, state, 0));
mtx.SetNamecoin (); mtx.SetNamecoin();
BOOST_CHECK (!CheckNameTransaction (mtx, 200000, view, state, 0)); BOOST_CHECK (!CheckNameTransaction (mtx, 200000, view, state, 0));
/* Name tx should be Namecoin version. */ /* Name tx should be Namecoin version. */
mtx = CMutableTransaction (baseTx); mtx = CMutableTransaction (baseTx);
mtx.vin.push_back (CTxIn (inNew)); mtx.vin.push_back (CTxIn (inNew));
BOOST_CHECK (!CheckNameTransaction (mtx, 200000, view, state, 0)); BOOST_CHECK (!CheckNameTransaction (mtx, 200000, view, state, 0));
mtx.SetNamecoin (); mtx.SetNamecoin();
mtx.vin.push_back (CTxIn (inUpdate)); mtx.vin.push_back (CTxIn (inUpdate));
BOOST_CHECK (!CheckNameTransaction (mtx, 200000, view, state, 0)); BOOST_CHECK (!CheckNameTransaction (mtx, 200000, view, state, 0));
@ -569,7 +568,7 @@ BOOST_AUTO_TEST_CASE (name_tx_verification)
mtx = CMutableTransaction (baseTx); mtx = CMutableTransaction (baseTx);
mtx.vout.push_back (CTxOut (COIN, scrNew)); mtx.vout.push_back (CTxOut (COIN, scrNew));
BOOST_CHECK (!CheckNameTransaction (mtx, 200000, view, state, 0)); BOOST_CHECK (!CheckNameTransaction (mtx, 200000, view, state, 0));
mtx.SetNamecoin (); mtx.SetNamecoin();
BOOST_CHECK (CheckNameTransaction (mtx, 200000, view, state, 0)); BOOST_CHECK (CheckNameTransaction (mtx, 200000, view, state, 0));
mtx.vout.push_back (CTxOut (COIN, scrNew)); mtx.vout.push_back (CTxOut (COIN, scrNew));
BOOST_CHECK (!CheckNameTransaction (mtx, 200000, view, state, 0)); BOOST_CHECK (!CheckNameTransaction (mtx, 200000, view, state, 0));
@ -579,7 +578,7 @@ BOOST_AUTO_TEST_CASE (name_tx_verification)
/* Basic verification of NAME_NEW. */ /* Basic verification of NAME_NEW. */
mtx = CMutableTransaction (baseTx); mtx = CMutableTransaction (baseTx);
mtx.SetNamecoin (); mtx.SetNamecoin();
mtx.vout.push_back (CTxOut (COIN, scrNew)); mtx.vout.push_back (CTxOut (COIN, scrNew));
BOOST_CHECK (CheckNameTransaction (mtx, 200000, view, state, 0)); BOOST_CHECK (CheckNameTransaction (mtx, 200000, view, state, 0));
mtx.vin.push_back (CTxIn (inNew)); mtx.vin.push_back (CTxIn (inNew));
@ -587,7 +586,7 @@ BOOST_AUTO_TEST_CASE (name_tx_verification)
BOOST_CHECK (IsStandardTx (mtx, reason)); BOOST_CHECK (IsStandardTx (mtx, reason));
/* Greedy names. */ /* Greedy names. */
mtx.vin.clear (); mtx.vin.clear();
mtx.vout[1].nValue = COIN / 100; mtx.vout[1].nValue = COIN / 100;
BOOST_CHECK (CheckNameTransaction (mtx, 212500, view, state, 0)); BOOST_CHECK (CheckNameTransaction (mtx, 212500, view, state, 0));
mtx.vout[1].nValue = COIN / 100 - 1; mtx.vout[1].nValue = COIN / 100 - 1;
@ -608,7 +607,7 @@ BOOST_AUTO_TEST_CASE (name_tx_verification)
/* Check update of UPDATE output, plus expiry. */ /* Check update of UPDATE output, plus expiry. */
mtx = CMutableTransaction (baseTx); mtx = CMutableTransaction (baseTx);
mtx.SetNamecoin (); mtx.SetNamecoin();
mtx.vout.push_back (CTxOut (COIN, scrUpdate)); mtx.vout.push_back (CTxOut (COIN, scrUpdate));
BOOST_CHECK (!CheckNameTransaction (mtx, 135999, viewUpd, state, 0)); BOOST_CHECK (!CheckNameTransaction (mtx, 135999, viewUpd, state, 0));
mtx.vin.push_back (CTxIn (inUpdate)); mtx.vin.push_back (CTxIn (inUpdate));
@ -617,7 +616,7 @@ BOOST_AUTO_TEST_CASE (name_tx_verification)
BOOST_CHECK (IsStandardTx (mtx, reason)); BOOST_CHECK (IsStandardTx (mtx, reason));
/* Check update of FIRSTUPDATE output, plus expiry. */ /* Check update of FIRSTUPDATE output, plus expiry. */
mtx.vin.clear (); mtx.vin.clear();
mtx.vin.push_back (CTxIn (inFirst)); mtx.vin.push_back (CTxIn (inFirst));
BOOST_CHECK (CheckNameTransaction (mtx, 135999, viewFirst, state, 0)); BOOST_CHECK (CheckNameTransaction (mtx, 135999, viewFirst, state, 0));
BOOST_CHECK (!CheckNameTransaction (mtx, 136000, viewFirst, state, 0)); BOOST_CHECK (!CheckNameTransaction (mtx, 136000, viewFirst, state, 0));
@ -629,21 +628,21 @@ BOOST_AUTO_TEST_CASE (name_tx_verification)
/* Value length limits. */ /* Value length limits. */
mtx = CMutableTransaction (baseTx); mtx = CMutableTransaction (baseTx);
mtx.SetNamecoin (); mtx.SetNamecoin();
mtx.vin.push_back (CTxIn (inUpdate)); mtx.vin.push_back (CTxIn (inUpdate));
scr = CNameScript::buildNameUpdate (addr, name1, tooLongValue); scr = CNameScript::buildNameUpdate (addr, name1, tooLongValue);
mtx.vout.push_back (CTxOut (COIN, scr)); mtx.vout.push_back (CTxOut (COIN, scr));
BOOST_CHECK (!CheckNameTransaction (mtx, 110000, viewUpd, state, 0)); BOOST_CHECK (!CheckNameTransaction (mtx, 110000, viewUpd, state, 0));
/* Name mismatch to prev out. */ /* Name mismatch to prev out. */
mtx.vout.clear (); mtx.vout.clear();
scr = CNameScript::buildNameUpdate (addr, name2, value); scr = CNameScript::buildNameUpdate (addr, name2, value);
mtx.vout.push_back (CTxOut (COIN, scr)); mtx.vout.push_back (CTxOut (COIN, scr));
BOOST_CHECK (!CheckNameTransaction (mtx, 110000, viewUpd, state, 0)); BOOST_CHECK (!CheckNameTransaction (mtx, 110000, viewUpd, state, 0));
/* Previous NAME_NEW is not allowed! */ /* Previous NAME_NEW is not allowed! */
mtx = CMutableTransaction (baseTx); mtx = CMutableTransaction (baseTx);
mtx.SetNamecoin (); mtx.SetNamecoin();
mtx.vout.push_back (CTxOut (COIN, scrUpdate)); mtx.vout.push_back (CTxOut (COIN, scrUpdate));
mtx.vin.push_back (CTxIn (inNew)); mtx.vin.push_back (CTxIn (inNew));
CCoinsViewCache viewNew(&view); CCoinsViewCache viewNew(&view);
@ -658,7 +657,7 @@ BOOST_AUTO_TEST_CASE (name_tx_verification)
/* Basic valid transaction. */ /* Basic valid transaction. */
mtx = CMutableTransaction (baseTx); mtx = CMutableTransaction (baseTx);
mtx.SetNamecoin (); mtx.SetNamecoin();
mtx.vout.push_back (CTxOut (COIN, scrFirst)); mtx.vout.push_back (CTxOut (COIN, scrFirst));
BOOST_CHECK (!CheckNameTransaction (mtx, 100012, viewClean, state, 0)); BOOST_CHECK (!CheckNameTransaction (mtx, 100012, viewClean, state, 0));
mtx.vin.push_back (CTxIn (inNew)); mtx.vin.push_back (CTxIn (inNew));
@ -682,17 +681,17 @@ BOOST_AUTO_TEST_CASE (name_tx_verification)
BOOST_CHECK (!CheckNameTransaction (mtx, 212500, viewClean, state, 0)); BOOST_CHECK (!CheckNameTransaction (mtx, 212500, viewClean, state, 0));
/* Rand mismatch (wrong name activated). */ /* Rand mismatch (wrong name activated). */
mtx.vout.clear (); mtx.vout.clear();
scr = CNameScript::buildNameFirstupdate (addr, name2, value, rand); scr = CNameScript::buildNameFirstupdate (addr, name2, value, rand);
BOOST_CHECK (!CheckNameTransaction (mtx, 100012, viewClean, state, 0)); BOOST_CHECK (!CheckNameTransaction (mtx, 100012, viewClean, state, 0));
/* Non-NAME_NEW prev output. */ /* Non-NAME_NEW prev output. */
mtx = CMutableTransaction (baseTx); mtx = CMutableTransaction (baseTx);
mtx.SetNamecoin (); mtx.SetNamecoin();
mtx.vout.push_back (CTxOut (COIN, scrFirst)); mtx.vout.push_back (CTxOut (COIN, scrFirst));
mtx.vin.push_back (CTxIn (inUpdate)); mtx.vin.push_back (CTxIn (inUpdate));
BOOST_CHECK (!CheckNameTransaction (mtx, 100012, viewClean, state, 0)); BOOST_CHECK (!CheckNameTransaction (mtx, 100012, viewClean, state, 0));
mtx.vin.clear (); mtx.vin.clear();
mtx.vin.push_back (CTxIn (inFirst)); mtx.vin.push_back (CTxIn (inFirst));
BOOST_CHECK (!CheckNameTransaction (mtx, 100012, viewClean, state, 0)); BOOST_CHECK (!CheckNameTransaction (mtx, 100012, viewClean, state, 0));
} }
@ -701,7 +700,7 @@ BOOST_AUTO_TEST_CASE (name_tx_verification)
/* ************************************************************************** */ /* ************************************************************************** */
BOOST_AUTO_TEST_CASE(name_updates_undo) BOOST_AUTO_TEST_CASE(keva_updates_undo)
{ {
/* Enable name history to test this on the go. */ /* Enable name history to test this on the go. */
fNameHistory = true; fNameHistory = true;
@ -778,216 +777,171 @@ BOOST_AUTO_TEST_CASE(name_updates_undo)
} }
/* ************************************************************************** */ /* ************************************************************************** */
#if 0
/* ************************************************************************** */ BOOST_AUTO_TEST_CASE(keva_mempool)
BOOST_AUTO_TEST_CASE (name_mempool)
{ {
LOCK(mempool.cs); LOCK(mempool.cs);
mempool.clear (); mempool.clear();
const valtype nameReg = ValtypeFromString ("name-reg"); const valtype nameSpace1 = ValtypeFromString ("namespace-dummy-1");
const valtype nameUpd = ValtypeFromString ("name-upd"); const valtype nameSpace2 = ValtypeFromString ("namespace-dummy-2");
const valtype value = ValtypeFromString ("value"); const valtype displayName = ValtypeFromString ("display name");
const valtype keyA = ValtypeFromString ("key-a");
const valtype keyB = ValtypeFromString ("key-b");
const valtype valueA = ValtypeFromString ("value-a"); const valtype valueA = ValtypeFromString ("value-a");
const valtype valueB = ValtypeFromString ("value-b"); const valtype valueB = ValtypeFromString ("value-b");
const CScript addr = getTestAddress (); const CScript addr = getTestAddress();
const valtype rand1(20, 'a');
const valtype rand2(20, 'b');
const uint160 hash1 = Hash160 (rand1);
const uint160 hash2 = Hash160 (rand2);
const valtype vchHash1(hash1.begin (), hash1.end ());
const valtype vchHash2(hash2.begin (), hash2.end ());
const CScript addr2 = (CScript (addr) << OP_RETURN); const CScript addr2 = (CScript (addr) << OP_RETURN);
const CScript new1 const CScript new1 = CKevaScript::buildKevaNamespace(addr, nameSpace1, displayName);
= CNameScript::buildNameNew (addr, hash1); const CScript new2 = CKevaScript::buildKevaNamespace(addr, nameSpace2, displayName);
const CScript new1p const CScript upd1 = CKevaScript::buildKevaPut(addr, nameSpace1, keyA, valueA);
= CNameScript::buildNameNew (addr2, hash1); const CScript upd2 = CKevaScript::buildKevaPut(addr, nameSpace2, keyB, valueB);
const CScript new2
= CNameScript::buildNameNew (addr, hash2);
const CScript first1
= CNameScript::buildNameFirstupdate (addr, nameReg, value, rand1);
const CScript first2
= CNameScript::buildNameFirstupdate (addr, nameReg, value, rand2);
const CScript upd1 = CNameScript::buildNameUpdate (addr, nameUpd, valueA);
const CScript upd2 = CNameScript::buildNameUpdate (addr, nameUpd, valueB);
/* The constructed tx needs not be valid. We only test /* The constructed tx needs not be valid. We only test
the mempool acceptance and not validation. */ the mempool acceptance and not validation. */
CMutableTransaction txNew1; CMutableTransaction txNew1;
txNew1.SetNamecoin (); txNew1.SetKevacoin();
txNew1.vout.push_back (CTxOut (COIN, new1)); txNew1.vout.push_back(CTxOut(COIN, new1));
CMutableTransaction txNew1p;
txNew1p.SetNamecoin ();
txNew1p.vout.push_back (CTxOut (COIN, new1p));
CMutableTransaction txNew2; CMutableTransaction txNew2;
txNew2.SetNamecoin (); txNew2.SetKevacoin();
txNew2.vout.push_back (CTxOut (COIN, new2)); txNew2.vout.push_back(CTxOut(COIN, new2));
CMutableTransaction txReg1;
txReg1.SetNamecoin ();
txReg1.vout.push_back (CTxOut (COIN, first1));
CMutableTransaction txReg2;
txReg2.SetNamecoin ();
txReg2.vout.push_back (CTxOut (COIN, first2));
CMutableTransaction txUpd1; CMutableTransaction txUpd1;
txUpd1.SetNamecoin (); txUpd1.SetKevacoin();
txUpd1.vout.push_back (CTxOut (COIN, upd1)); txUpd1.vout.push_back(CTxOut(COIN, upd1));
CMutableTransaction txUpd2; CMutableTransaction txUpd2;
txUpd2.SetNamecoin (); txUpd2.SetKevacoin();
txUpd2.vout.push_back (CTxOut (COIN, upd2)); txUpd2.vout.push_back(CTxOut(COIN, upd2));
/* Build an invalid transaction. It should not crash (assert fail) /* Build an invalid transaction. It should not crash (assert fail)
the mempool check. */ the mempool check. */
CMutableTransaction txInvalid; CMutableTransaction txInvalid;
txInvalid.SetNamecoin (); txInvalid.SetKevacoin();
mempool.checkNameOps (txInvalid); mempool.checkKevaOps(txInvalid);
txInvalid.vout.push_back (CTxOut (COIN, new1)); txInvalid.vout.push_back(CTxOut (COIN, new1));
txInvalid.vout.push_back (CTxOut (COIN, new2)); txInvalid.vout.push_back(CTxOut (COIN, new2));
txInvalid.vout.push_back (CTxOut (COIN, first1)); txInvalid.vout.push_back(CTxOut (COIN, upd1));
txInvalid.vout.push_back (CTxOut (COIN, first2)); txInvalid.vout.push_back(CTxOut (COIN, upd2));
txInvalid.vout.push_back (CTxOut (COIN, upd1)); mempool.checkKevaOps(txInvalid);
txInvalid.vout.push_back (CTxOut (COIN, upd2));
mempool.checkNameOps (txInvalid);
/* For an empty mempool, all tx should be fine. */ /* For an empty mempool, all tx should be fine. */
BOOST_CHECK (!mempool.registersName (nameReg)); std::vector<std::tuple<valtype, valtype, uint256>> unconfirmedNamespace;
BOOST_CHECK (!mempool.updatesName (nameUpd)); mempool.getUnconfirmedNamespaceList(unconfirmedNamespace);
BOOST_CHECK (mempool.checkNameOps (txNew1) && mempool.checkNameOps (txNew1p) BOOST_CHECK(unconfirmedNamespace.size() == 0);
&& mempool.checkNameOps (txNew2));
BOOST_CHECK (mempool.checkNameOps (txReg1) && mempool.checkNameOps (txReg2));
BOOST_CHECK (mempool.checkNameOps (txUpd1) && mempool.checkNameOps (txUpd2));
/* Add name_new's with "stealing" check. */
const LockPoints lp;
const CTxMemPoolEntry entryNew1(MakeTransactionRef(txNew1), 0, 0, 100,
false, 1, lp);
const CTxMemPoolEntry entryNew2(MakeTransactionRef(txNew2), 0, 0, 100,
false, 1, lp);
BOOST_CHECK (entryNew1.isNameNew () && entryNew2.isNameNew ());
BOOST_CHECK (entryNew1.getNameNewHash () == vchHash1
&& entryNew2.getNameNewHash () == vchHash2);
mempool.addUnchecked (entryNew1.GetTx ().GetHash (), entryNew1);
mempool.addUnchecked (entryNew2.GetTx ().GetHash (), entryNew2);
BOOST_CHECK (!mempool.checkNameOps (txNew1p));
BOOST_CHECK (mempool.checkNameOps (txNew1) && mempool.checkNameOps (txNew2));
/* Add a name registration. */ /* Add a name registration. */
const CTxMemPoolEntry entryReg(MakeTransactionRef(txReg1), 0, 0, 100, const LockPoints lp;
const CTxMemPoolEntry entryReg(MakeTransactionRef(txNew1), 0, 0, 100,
false, 1, lp); false, 1, lp);
BOOST_CHECK (entryReg.isNameRegistration () && !entryReg.isNameUpdate ()); BOOST_CHECK(entryReg.isNamespaceRegistration() && !entryReg.isKeyUpdate());
BOOST_CHECK (entryReg.getName () == nameReg); BOOST_CHECK(entryReg.getNamespace() == nameSpace1);
mempool.addUnchecked (entryReg.GetTx ().GetHash (), entryReg); mempool.addUnchecked(entryReg.GetTx().GetHash(), entryReg);
BOOST_CHECK (mempool.registersName (nameReg)); mempool.getUnconfirmedNamespaceList(unconfirmedNamespace);
BOOST_CHECK (!mempool.updatesName (nameReg)); BOOST_CHECK(unconfirmedNamespace.size() == 1);
BOOST_CHECK (!mempool.checkNameOps (txReg2) && mempool.checkNameOps (txUpd1)); BOOST_CHECK(std::get<0>(unconfirmedNamespace[0]) == nameSpace1);
/* Add a name update. */ /* Add a name update. */
const CTxMemPoolEntry entryUpd(MakeTransactionRef(txUpd1), 0, 0, 100, const CTxMemPoolEntry entryUpd(MakeTransactionRef(txUpd1), 0, 0, 100,
false, 1, lp); false, 1, lp);
BOOST_CHECK (!entryUpd.isNameRegistration () && entryUpd.isNameUpdate ()); BOOST_CHECK(!entryUpd.isNamespaceRegistration() && entryUpd.isKeyUpdate());
BOOST_CHECK (entryUpd.getName () == nameUpd); BOOST_CHECK(entryUpd.getNamespace() == nameSpace1);
mempool.addUnchecked (entryUpd.GetTx ().GetHash (), entryUpd); mempool.addUnchecked (entryUpd.GetTx().GetHash(), entryUpd);
BOOST_CHECK (!mempool.registersName (nameUpd)); valtype valResult;
BOOST_CHECK (mempool.updatesName (nameUpd)); mempool.getUnconfirmedKeyValue(nameSpace1, keyA, valResult);
BOOST_CHECK (!mempool.checkNameOps (txUpd2)); BOOST_CHECK(valResult == valueA);
std::vector<std::tuple<valtype, valtype, valtype, uint256>> keyValueList;
/* Check getTxForName. */ mempool.getUnconfirmedKeyValueList(keyValueList, nameSpace1);
BOOST_CHECK (mempool.getTxForName (nameReg) == txReg1.GetHash ()); BOOST_CHECK(keyValueList.size() == 1);
BOOST_CHECK (mempool.getTxForName (nameUpd) == txUpd1.GetHash ());
/* Run mempool sanity check. */ /* Run mempool sanity check. */
#if 0
CCoinsViewCache view(pcoinsTip.get()); CCoinsViewCache view(pcoinsTip.get());
const CNameScript nameOp(upd1); const CKevaScript nameOp(upd1);
CNameData data; CKevaData data;
data.fromScript (100, COutPoint (uint256 (), 0), nameOp); data.fromScript(100, COutPoint (uint256(), 0), nameOp);
view.SetName (nameUpd, data, false); view.SetName(nameUpd, data, false);
mempool.checkNames (&view); mempool.checkNames(&view);
#endif
/* Remove the transactions again. */ /* Remove the transactions again. */
mempool.removeRecursive(txNew1);
mempool.removeRecursive (txReg1); std::vector<std::tuple<valtype, valtype, uint256>> unconfirmedNS;
BOOST_CHECK (!mempool.registersName (nameReg)); mempool.getUnconfirmedNamespaceList(unconfirmedNS);
BOOST_CHECK (mempool.checkNameOps (txReg1) && mempool.checkNameOps (txReg2)); BOOST_CHECK(unconfirmedNS.size() == 0);
BOOST_CHECK (!mempool.checkNameOps (txUpd2)); #if 0
mempool.removeRecursive(txUpd1);
mempool.removeRecursive (txUpd1); BOOST_CHECK(!mempool.updatesName (nameUpd));
BOOST_CHECK (!mempool.updatesName (nameUpd)); BOOST_CHECK(mempool.checkNameOps (txUpd1) && mempool.checkNameOps (txUpd2));
BOOST_CHECK (mempool.checkNameOps (txUpd1) && mempool.checkNameOps (txUpd2)); BOOST_CHECK(mempool.checkNameOps (txReg1));
BOOST_CHECK (mempool.checkNameOps (txReg1));
mempool.removeRecursive (txNew1); mempool.removeRecursive (txNew1);
mempool.removeRecursive (txNew2); mempool.removeRecursive (txNew2);
BOOST_CHECK (!mempool.checkNameOps (txNew1p)); BOOST_CHECK(!mempool.checkNameOps (txNew1p));
BOOST_CHECK (mempool.checkNameOps (txNew1) && mempool.checkNameOps (txNew2)); BOOST_CHECK(mempool.checkNameOps (txNew1) && mempool.checkNameOps (txNew2));
/* Check getTxForName with non-existent names. */ /* Check getTxForName with non-existent names. */
BOOST_CHECK (mempool.getTxForName (nameReg).IsNull ()); BOOST_CHECK(mempool.getTxForName (nameReg).IsNull());
BOOST_CHECK (mempool.getTxForName (nameUpd).IsNull ()); BOOST_CHECK(mempool.getTxForName (nameUpd).IsNull());
/* Check removing of conflicted name registrations. */ /* Check removing of conflicted name registrations. */
mempool.addUnchecked (entryReg.GetTx ().GetHash (), entryReg); mempool.addUnchecked (entryReg.GetTx().GetHash(), entryReg);
BOOST_CHECK (mempool.registersName (nameReg)); BOOST_CHECK(mempool.registersName (nameReg));
BOOST_CHECK (!mempool.checkNameOps (txReg2)); BOOST_CHECK(!mempool.checkNameOps (txReg2));
{ {
CNameConflictTracker tracker(mempool); CNameConflictTracker tracker(mempool);
mempool.removeConflicts (txReg2); mempool.removeConflicts (txReg2);
BOOST_CHECK (tracker.GetNameConflicts ()->size () == 1); BOOST_CHECK(tracker.GetNameConflicts()->size() == 1);
BOOST_CHECK (tracker.GetNameConflicts ()->front ()->GetHash () BOOST_CHECK(tracker.GetNameConflicts()->front()->GetHash()
== txReg1.GetHash ()); == txReg1.GetHash());
} }
BOOST_CHECK (!mempool.registersName (nameReg)); BOOST_CHECK(!mempool.registersName (nameReg));
BOOST_CHECK (mempool.mapTx.empty ()); BOOST_CHECK(mempool.mapTx.empty());
/* Check removing of conflicts after name expiration. */ /* Check removing of conflicts after name expiration. */
mempool.addUnchecked (entryUpd.GetTx ().GetHash (), entryUpd); mempool.addUnchecked (entryUpd.GetTx().GetHash(), entryUpd);
BOOST_CHECK (mempool.updatesName (nameUpd)); BOOST_CHECK(mempool.updatesName (nameUpd));
BOOST_CHECK (!mempool.checkNameOps (txUpd2)); BOOST_CHECK(!mempool.checkNameOps (txUpd2));
std::set<valtype> names; std::set<valtype> names;
names.insert (nameUpd); names.insert(nameUpd);
{ {
CNameConflictTracker tracker(mempool); CNameConflictTracker tracker(mempool);
mempool.removeExpireConflicts (names); mempool.removeExpireConflicts(names);
BOOST_CHECK (tracker.GetNameConflicts ()->size () == 1); BOOST_CHECK(tracker.GetNameConflicts()->size() == 1);
BOOST_CHECK (tracker.GetNameConflicts ()->front ()->GetHash () BOOST_CHECK(tracker.GetNameConflicts()->front()->GetHash()
== txUpd1.GetHash ()); == txUpd1.GetHash());
} }
BOOST_CHECK (!mempool.updatesName (nameUpd)); BOOST_CHECK(!mempool.updatesName (nameUpd));
BOOST_CHECK (mempool.mapTx.empty ()); BOOST_CHECK(mempool.mapTx.empty());
/* Check removing of conflicts after name unexpiration. */ /* Check removing of conflicts after name unexpiration. */
mempool.addUnchecked (entryReg.GetTx ().GetHash (), entryReg); mempool.addUnchecked (entryReg.GetTx().GetHash(), entryReg);
BOOST_CHECK (mempool.registersName (nameReg)); BOOST_CHECK(mempool.registersName (nameReg));
BOOST_CHECK (!mempool.checkNameOps (txReg2)); BOOST_CHECK(!mempool.checkNameOps (txReg2));
names.clear (); names.clear();
names.insert (nameReg); names.insert(nameReg);
{ {
CNameConflictTracker tracker(mempool); CNameConflictTracker tracker(mempool);
mempool.removeUnexpireConflicts (names); mempool.removeUnexpireConflicts(names);
BOOST_CHECK (tracker.GetNameConflicts ()->size () == 1); BOOST_CHECK(tracker.GetNameConflicts()->size() == 1);
BOOST_CHECK (tracker.GetNameConflicts ()->front ()->GetHash () BOOST_CHECK(tracker.GetNameConflicts()->front()->GetHash()
== txReg1.GetHash ()); == txReg1.GetHash());
} }
BOOST_CHECK (!mempool.registersName (nameReg)); BOOST_CHECK(!mempool.registersName (nameReg));
BOOST_CHECK (mempool.mapTx.empty ()); BOOST_CHECK(mempool.mapTx.empty());
#endif
} }
/* ************************************************************************** */ /* ************************************************************************** */
#endif BOOST_AUTO_TEST_SUITE_END()
BOOST_AUTO_TEST_SUITE_END ()

2
src/txmempool.h

@ -137,7 +137,7 @@ public:
return kevaOp.isKevaOp() && kevaOp.getKevaOp() == OP_KEVA_NAMESPACE; return kevaOp.isKevaOp() && kevaOp.getKevaOp() == OP_KEVA_NAMESPACE;
} }
inline bool isNamespaceKeyUpdate() const inline bool isKeyUpdate() const
{ {
return kevaOp.isKevaOp() && kevaOp.getKevaOp() == OP_KEVA_PUT; return kevaOp.isKevaOp() && kevaOp.getKevaOp() == OP_KEVA_PUT;
} }

Loading…
Cancel
Save