Browse Source

WIP: tried to compile keva/main.cpp.

cn
Jianping Wu 6 years ago
parent
commit
d05ab948e2
  1. 249
      src/keva/main.cpp
  2. 23
      src/keva/main.h
  3. 26
      src/txmempool.h

249
src/keva/main.cpp

@ -46,25 +46,25 @@ CKevaTxUndo::apply(CCoinsViewCache& view) const
/* CKevaMemPool. */ /* CKevaMemPool. */
uint256 uint256
CKevaMemPool::getTxForName(const valtype& name) const CKevaMemPool::getTxForNamespace(const valtype& nameSpace) const
{ {
NameTxMap::const_iterator mi; #if 0
// JWU TODO: implement this!
NamespaceTxMap::const_iterator mi;
mi = mapNameRegs.find (name); mi = mapNamespaceRegs.find(nameSpace);
if (mi != mapNameRegs.end ()) if (mi != mapNamespaceRegs.end()) {
{ assert(mapNamespaceKeyUpdates.count(name) == 0);
assert (mapNameUpdates.count (name) == 0);
return mi->second; return mi->second;
} }
mi = mapNameUpdates.find (name); mi = mapNamespaceKeyUpdates.find(name);
if (mi != mapNameUpdates.end ()) if (mi != mapNameUpdates.end ()) {
{
assert (mapNameRegs.count (name) == 0); assert (mapNameRegs.count (name) == 0);
return mi->second; return mi->second;
} }
#endif
return uint256 (); return uint256();
} }
void void
@ -72,28 +72,18 @@ CKevaMemPool::addUnchecked (const uint256& hash, const CTxMemPoolEntry& entry)
{ {
AssertLockHeld (pool.cs); AssertLockHeld (pool.cs);
if (entry.isNameNew ()) if (entry.isNamespaceRegistration()) {
{ const valtype& nameSpace = entry.getNamespace();
const valtype& newHash = entry.getNameNewHash (); assert(mapNamespaceRegs.count(nameSpace) == 0);
const NameTxMap::const_iterator mit = mapNameNews.find (newHash); mapNamespaceRegs.insert(std::make_pair (nameSpace, hash));
if (mit != mapNameNews.end ())
assert (mit->second == hash);
else
mapNameNews.insert (std::make_pair (newHash, hash));
}
if (entry.isNameRegistration ())
{
const valtype& name = entry.getName ();
assert (mapNameRegs.count (name) == 0);
mapNameRegs.insert (std::make_pair (name, hash));
} }
if (entry.isNameUpdate ()) if (entry.isNamespaceKeyUpdate ()) {
{ const valtype& nameSpace = entry.getNamespace();
const valtype& name = entry.getName (); const valtype& key = entry.getKey();
assert (mapNameUpdates.count (name) == 0); NamespaceKeyTuple tuple(nameSpace, key);
mapNameUpdates.insert (std::make_pair (name, hash)); assert(mapNamespaceKeyUpdates.count(tuple) == 0);
mapNamespaceKeyUpdates.insert (std::make_pair (name, hash));
} }
} }
@ -102,17 +92,17 @@ CKevaMemPool::remove (const CTxMemPoolEntry& entry)
{ {
AssertLockHeld (pool.cs); AssertLockHeld (pool.cs);
if (entry.isNameRegistration ()) if (entry.isNamespaceRegistration ()) {
{ const NamespaceTxMap::iterator mit = mapNamespaceRegs.find (entry.getNamespace());
const NameTxMap::iterator mit = mapNameRegs.find (entry.getName ()); assert (mit != mapNamespaceRegs.end());
assert (mit != mapNameRegs.end ()); mapNamespaceRegs.erase (mit);
mapNameRegs.erase (mit);
} }
if (entry.isNameUpdate ())
{ if (entry.isNamespaceKeyUpdate ()) {
const NameTxMap::iterator mit = mapNameUpdates.find (entry.getName ()); NamespaceKeyTuple tuple(entry.getNamespace(), entry.getKey());
assert (mit != mapNameUpdates.end ()); const NamespaceKeyTxMap::iterator mit = mapNamespaceKeyUpdates.find(tuple);
mapNameUpdates.erase (mit); assert (mit != mapNamespaceKeyUpdates.end());
mapNamespaceKeyUpdates.erase (mit);
} }
} }
@ -121,29 +111,27 @@ CKevaMemPool::removeConflicts (const CTransaction& tx)
{ {
AssertLockHeld (pool.cs); AssertLockHeld (pool.cs);
if (!tx.IsNamecoin ()) if (!tx.IsKevacoin ())
return; return;
for (const auto& txout : tx.vout) for (const auto& txout : tx.vout)
{ {
const CNameScript nameOp(txout.scriptPubKey); const CKevaScript nameOp(txout.scriptPubKey);
if (nameOp.isNameOp () && nameOp.getNameOp () == OP_NAME_FIRSTUPDATE) if (nameOp.isKevaOp () && nameOp.getKevaOp () == OP_KEVA_PUT) {
{ const valtype& nameSpace = nameOp.getOpNamespace();
const valtype& name = nameOp.getOpName (); const NamespaceTxMap::const_iterator mit = mapNamespaceRegs.find(nameSpace);
const NameTxMap::const_iterator mit = mapNameRegs.find (name); if (mit != mapNamespaceRegs.end ()) {
if (mit != mapNameRegs.end ())
{
const CTxMemPool::txiter mit2 = pool.mapTx.find (mit->second); const CTxMemPool::txiter mit2 = pool.mapTx.find (mit->second);
assert (mit2 != pool.mapTx.end ()); assert (mit2 != pool.mapTx.end ());
pool.removeRecursive (mit2->GetTx (), pool.removeRecursive (mit2->GetTx (),
MemPoolRemovalReason::NAME_CONFLICT); MemPoolRemovalReason::KEVA_CONFLICT);
} }
} }
} }
} }
void void
CKevaMemPool::check (const CCoinsView& coins) const CKevaMemPool::check(const CCoinsView& coins) const
{ {
AssertLockHeld (pool.cs); AssertLockHeld (pool.cs);
@ -156,39 +144,27 @@ CKevaMemPool::check (const CCoinsView& coins) const
std::set<valtype> nameRegs; std::set<valtype> nameRegs;
std::set<valtype> nameUpdates; std::set<valtype> nameUpdates;
for (const auto& entry : pool.mapTx) for (const auto& entry : pool.mapTx) {
{
const uint256 txHash = entry.GetTx ().GetHash (); const uint256 txHash = entry.GetTx ().GetHash ();
if (entry.isNameNew ()) if (entry.isNamespaceRegistration()) {
{ const valtype& nameSpace = entry.getNamespace();
const valtype& newHash = entry.getNameNewHash ();
const NameTxMap::const_iterator mit = mapNameNews.find (newHash);
assert (mit != mapNameNews.end ()); const NamespaceTxMap::const_iterator mit = mapNamespaceRegs.find(nameSpace);
assert (mit != mapNamespaceRegs.end());
assert (mit->second == txHash); assert (mit->second == txHash);
}
if (entry.isNameRegistration ()) assert (nameRegs.count(nameSpace) == 0);
{ nameRegs.insert(nameSpace);
const valtype& name = entry.getName ();
const NameTxMap::const_iterator mit = mapNameRegs.find (name);
assert (mit != mapNameRegs.end ());
assert (mit->second == txHash);
assert (nameRegs.count (name) == 0);
nameRegs.insert (name);
/* The old name should be expired already. Note that we use /* The old name should be expired already. Note that we use
nHeight+1 for the check, because that's the height at which nHeight+1 for the check, because that's the height at which
the mempool tx will actually be mined. */ the mempool tx will actually be mined. */
CNameData data; CKevaData data;
if (coins.GetName (name, data)) if (coins.GetName(name, data))
assert (data.isExpired (nHeight + 1)); assert (data.isExpired (nHeight + 1));
} }
if (entry.isNameUpdate ()) if (entry.isNamespaceKeyUpdate()) {
{
const valtype& name = entry.getName (); const valtype& name = entry.getName ();
const NameTxMap::const_iterator mit = mapNameUpdates.find (name); const NameTxMap::const_iterator mit = mapNameUpdates.find (name);
@ -196,11 +172,11 @@ CKevaMemPool::check (const CCoinsView& coins) const
assert (mit->second == txHash); assert (mit->second == txHash);
assert (nameUpdates.count (name) == 0); assert (nameUpdates.count (name) == 0);
nameUpdates.insert (name); nameUpdates.insert(name);
/* As above, use nHeight+1 for the expiration check. */ /* As above, use nHeight+1 for the expiration check. */
CNameData data; CKevaData data;
if (!coins.GetName (name, data)) if (!coins.GetName(name, data))
assert (false); assert (false);
assert (!data.isExpired (nHeight + 1)); assert (!data.isExpired (nHeight + 1));
} }
@ -223,7 +199,7 @@ CKevaMemPool::checkTx (const CTransaction& tx) const
{ {
AssertLockHeld (pool.cs); AssertLockHeld (pool.cs);
if (!tx.IsNamecoin ()) if (!tx.IsKevacoin ())
return true; return true;
/* In principle, multiple name_updates could be performed within the /* In principle, multiple name_updates could be performed within the
@ -231,36 +207,27 @@ CKevaMemPool::checkTx (const CTransaction& tx) const
since the current mempool implementation does not like it. (We keep since the current mempool implementation does not like it. (We keep
track of only a single update tx for each name.) */ track of only a single update tx for each name.) */
for (const auto& txout : tx.vout) for (const auto& txout : tx.vout) {
{ const CKevaScript nameOp(txout.scriptPubKey);
const CNameScript nameOp(txout.scriptPubKey); if (!nameOp.isKevaOp ())
if (!nameOp.isNameOp ())
continue; continue;
switch (nameOp.getNameOp ()) switch (nameOp.getKevaOp ()) {
case OP_KEVA_NAMESPACE:
{ {
case OP_NAME_NEW: const valtype& nameSpace = nameOp.getOpNamespace();
{
const valtype& newHash = nameOp.getOpHash ();
std::map<valtype, uint256>::const_iterator mi; std::map<valtype, uint256>::const_iterator mi;
mi = mapNameNews.find (newHash); mi = mapNamespaceRegs.find(nameSpace);
if (mi != mapNameNews.end () && mi->second != tx.GetHash ()) if (mi != mapNamespaceRegs.end ())
return false;
break;
}
case OP_NAME_FIRSTUPDATE:
{
const valtype& name = nameOp.getOpName ();
if (registersName (name))
return false; return false;
break; break;
} }
case OP_NAME_UPDATE: case OP_KEVA_PUT:
{ {
const valtype& name = nameOp.getOpName (); const valtype& nameSpace = nameOp.getOpNamespace();
if (updatesName (name)) const valtype& key = nameOp.getOpKey();
if (updatesKey(nameSpace, key))
return false; return false;
break; break;
} }
@ -284,7 +251,7 @@ ConflictTrackerNotifyEntryRemoved (CNameConflictTracker* tracker,
CTransactionRef txRemoved, CTransactionRef txRemoved,
MemPoolRemovalReason reason) MemPoolRemovalReason reason)
{ {
if (reason == MemPoolRemovalReason::NAME_CONFLICT) if (reason == MemPoolRemovalReason::KEVA_CONFLICT)
tracker->AddConflictedEntry (txRemoved); tracker->AddConflictedEntry (txRemoved);
} }
@ -320,17 +287,19 @@ CheckNameTransaction (const CTransaction& tx, unsigned nHeight,
const char* txid = strTxid.c_str (); const char* txid = strTxid.c_str ();
const bool fMempool = (flags & SCRIPT_VERIFY_NAMES_MEMPOOL); const bool fMempool = (flags & SCRIPT_VERIFY_NAMES_MEMPOOL);
#if 0
/* Ignore historic bugs. */ /* Ignore historic bugs. */
CChainParams::BugType type; CChainParams::BugType type;
if (Params ().IsHistoricBug (tx.GetHash (), nHeight, type)) if (Params ().IsHistoricBug (tx.GetHash (), nHeight, type))
return true; return true;
#endif
/* As a first step, try to locate inputs and outputs of the transaction /* As a first step, try to locate inputs and outputs of the transaction
that are name scripts. At most one input and output should be that are name scripts. At most one input and output should be
a name operation. */ a name operation. */
int nameIn = -1; int nameIn = -1;
CNameScript nameOpIn; CKevaScript nameOpIn;
Coin coinIn; Coin coinIn;
for (unsigned i = 0; i < tx.vin.size (); ++i) for (unsigned i = 0; i < tx.vin.size (); ++i)
{ {
@ -339,9 +308,8 @@ CheckNameTransaction (const CTransaction& tx, unsigned nHeight,
if (!view.GetCoin (prevout, coin)) if (!view.GetCoin (prevout, coin))
return error ("%s: failed to fetch input coin for %s", __func__, txid); return error ("%s: failed to fetch input coin for %s", __func__, txid);
const CNameScript op(coin.out.scriptPubKey); const CKevaScript op(coin.out.scriptPubKey);
if (op.isNameOp ()) if (op.isKevaOp()) {
{
if (nameIn != -1) if (nameIn != -1)
return state.Invalid (error ("%s: multiple name inputs into" return state.Invalid (error ("%s: multiple name inputs into"
" transaction %s", __func__, txid)); " transaction %s", __func__, txid));
@ -352,12 +320,10 @@ CheckNameTransaction (const CTransaction& tx, unsigned nHeight,
} }
int nameOut = -1; int nameOut = -1;
CNameScript nameOpOut; CKevaScript nameOpOut;
for (unsigned i = 0; i < tx.vout.size (); ++i) for (unsigned i = 0; i < tx.vout.size (); ++i) {
{ const CKevaScript op(tx.vout[i].scriptPubKey);
const CNameScript op(tx.vout[i].scriptPubKey); if (op.isKevaOp()) {
if (op.isNameOp ())
{
if (nameOut != -1) if (nameOut != -1)
return state.Invalid (error ("%s: multiple name outputs from" return state.Invalid (error ("%s: multiple name outputs from"
" transaction %s", __func__, txid)); " transaction %s", __func__, txid));
@ -370,8 +336,7 @@ CheckNameTransaction (const CTransaction& tx, unsigned nHeight,
If that's the case, all is fine. For a Namecoin tx instead, there If that's the case, all is fine. For a Namecoin tx instead, there
should be at least an output (for NAME_NEW, no inputs are expected). */ should be at least an output (for NAME_NEW, no inputs are expected). */
if (!tx.IsNamecoin ()) if (!tx.IsKevacoin ()) {
{
if (nameIn != -1) if (nameIn != -1)
return state.Invalid (error ("%s: non-Namecoin tx %s has name inputs", return state.Invalid (error ("%s: non-Namecoin tx %s has name inputs",
__func__, txid)); __func__, txid));
@ -383,7 +348,7 @@ CheckNameTransaction (const CTransaction& tx, unsigned nHeight,
return true; return true;
} }
assert (tx.IsNamecoin ()); assert(tx.IsKevacoin ());
if (nameOut == -1) if (nameOut == -1)
return state.Invalid (error ("%s: Namecoin tx %s has no name outputs", return state.Invalid (error ("%s: Namecoin tx %s has no name outputs",
__func__, txid)); __func__, txid));
@ -393,6 +358,7 @@ CheckNameTransaction (const CTransaction& tx, unsigned nHeight,
if (tx.vout[nameOut].nValue < params.rules->MinNameCoinAmount(nHeight)) if (tx.vout[nameOut].nValue < params.rules->MinNameCoinAmount(nHeight))
return state.Invalid (error ("%s: greedy name", __func__)); return state.Invalid (error ("%s: greedy name", __func__));
#if 0
/* Handle NAME_NEW now, since this is easy and different from the other /* Handle NAME_NEW now, since this is easy and different from the other
operations. */ operations. */
@ -411,54 +377,65 @@ CheckNameTransaction (const CTransaction& tx, unsigned nHeight,
/* Now that we have ruled out NAME_NEW, check that we have a previous /* Now that we have ruled out NAME_NEW, check that we have a previous
name input that is being updated. */ name input that is being updated. */
#endif
assert (nameOpOut.isAnyUpdate ()); assert (nameOpOut.isAnyUpdate());
if (nameIn == -1) if (nameIn == -1) {
return state.Invalid (error ("CheckNameTransaction: update without" return state.Invalid(error("CheckNameTransaction: update without"
" previous name input")); " previous name input"));
const valtype& name = nameOpOut.getOpName (); }
if (name.size () > MAX_NAME_LENGTH) const valtype& key = nameOpOut.getOpKey();
return state.Invalid (error ("CheckNameTransaction: name too long")); if (key.size() > MAX_KEY_LENGTH) {
if (nameOpOut.getOpValue ().size () > MAX_VALUE_LENGTH) return state.Invalid (error ("CheckNameTransaction: key too long"));
return state.Invalid (error ("CheckNameTransaction: value too long")); }
/* Process NAME_UPDATE next. */ if (nameOpOut.getOpValue().size () > MAX_VALUE_LENGTH) {
return state.Invalid (error ("CheckNameTransaction: value too long"));
}
if (nameOpOut.getNameOp () == OP_NAME_UPDATE) /* Process KEVA_PUT next. */
{ const valtype& nameSpace = nameOpOut.getOpNamespace();
if (!nameOpIn.isAnyUpdate ()) if (nameOpOut.getKevaOp() == OP_KEVA_PUT) {
return state.Invalid (error ("CheckNameTransaction: NAME_UPDATE with" if (!nameOpIn.isAnyUpdate ()) {
return state.Invalid(error("CheckNameTransaction: KEVA_PUT with"
" prev input that is no update")); " prev input that is no update"));
}
if (name != nameOpIn.getOpName ()) if (nameSpace != nameOpIn.getOpNamespace()) {
return state.Invalid (error ("%s: NAME_UPDATE name mismatch to prev tx" return state.Invalid (error ("%s: KEVA_PUT namespace mismatch to prev tx"
" found in %s", __func__, txid)); " found in %s", __func__, txid));
}
/* This is actually redundant, since expired names are removed /* This is actually redundant, since expired names are removed
from the UTXO set and thus not available to be spent anyway. from the UTXO set and thus not available to be spent anyway.
But it does not hurt to enforce this here, too. It is also But it does not hurt to enforce this here, too. It is also
exercised by the unit tests. */ exercised by the unit tests. */
CNameData oldName; CKevaData oldName;
if (!view.GetName (name, oldName)) const valtype& namespaceIn = nameOpIn.getOpNamespace();
return state.Invalid (error ("%s: NAME_UPDATE name does not exist", const valtype& keyIn = nameOpIn.getOpKey();
if (!view.GetName(namespaceIn, keyIn, oldName)) {
return state.Invalid (error ("%s: KEVA_PUT name does not exist",
__func__)); __func__));
}
#if 0
if (oldName.isExpired (nHeight)) if (oldName.isExpired (nHeight))
return state.Invalid (error ("%s: trying to update expired name", return state.Invalid (error ("%s: trying to update expired name",
__func__)); __func__));
#endif
/* This is an internal consistency check. If everything is fine, /* This is an internal consistency check. If everything is fine,
the input coins from the UTXO database should match the the input coins from the UTXO database should match the
name database. */ name database. */
assert (static_cast<unsigned> (coinIn.nHeight) == oldName.getHeight ()); assert (static_cast<unsigned> (coinIn.nHeight) == oldName.getHeight());
assert (tx.vin[nameIn].prevout == oldName.getUpdateOutpoint ()); assert (tx.vin[nameIn].prevout == oldName.getUpdateOutpoint());
return true; return true;
} }
#if 0
/* Finally, NAME_FIRSTUPDATE. */ /* Finally, NAME_FIRSTUPDATE. */
assert (nameOpOut.getNameOp () == OP_NAME_FIRSTUPDATE); assert(nameOpOut.getNameOp () == OP_NAME_FIRSTUPDATE);
if (nameOpIn.getNameOp () != OP_NAME_NEW) if (nameOpIn.getNameOp () != OP_NAME_NEW)
return state.Invalid (error ("CheckNameTransaction: NAME_FIRSTUPDATE" return state.Invalid (error ("CheckNameTransaction: NAME_FIRSTUPDATE"
" with non-NAME_NEW prev tx")); " with non-NAME_NEW prev tx"));
@ -495,7 +472,7 @@ CheckNameTransaction (const CTransaction& tx, unsigned nHeight,
/* We don't have to specifically check that miners don't create blocks with /* We don't have to specifically check that miners don't create blocks with
conflicting NAME_FIRSTUPDATE's, since the mining's CCoinsViewCache conflicting NAME_FIRSTUPDATE's, since the mining's CCoinsViewCache
takes care of this with the check above already. */ takes care of this with the check above already. */
#endif
return true; return true;
} }
@ -553,6 +530,7 @@ ApplyNameTransaction (const CTransaction& tx, unsigned nHeight,
} }
} }
#if 0
bool bool
ExpireNames (unsigned nHeight, CCoinsViewCache& view, CBlockUndo& undo, ExpireNames (unsigned nHeight, CCoinsViewCache& view, CBlockUndo& undo,
std::set<valtype>& names) std::set<valtype>& names)
@ -672,6 +650,7 @@ UnexpireNames (unsigned nHeight, CBlockUndo& undo, CCoinsViewCache& view,
return true; return true;
} }
#endif
void void
CheckNameDB (bool disconnect) CheckNameDB (bool disconnect)

23
src/keva/main.h

@ -126,13 +126,13 @@ private:
NamespaceTxMap mapNamespaceRegs; NamespaceTxMap mapNamespaceRegs;
/** Map pending name updates to transaction IDs. */ /** Map pending name updates to transaction IDs. */
NamespaceTxMap mapNamespaceUpdates; //NamespaceTxMap mapNamespaceUpdates;
/** /**
* Keep track of key that are registered by transactions in the pool. * Keep track of key that are updated by transactions in the pool.
* Map key to registering transaction. * Map key to registering transaction.
*/ */
NamespaceKeyTxMap mapNamespaceKeyRegs; NamespaceKeyTxMap mapNamespaceKeyUpdates;
public: public:
@ -163,10 +163,10 @@ public:
* @return True iff there's a matching name update in the pool. * @return True iff there's a matching name update in the pool.
*/ */
inline bool inline bool
updatesName (const valtype& name) const updatesKey (const valtype& nameSpace, const valtype& key) const
{ {
//return mapNameUpdates.count (name) > 0; NamespaceKeyTuple tuple(nameSpace, key);
return true; return mapNamespaceKeyUpdates.count(tuple) > 0;
} }
/** /**
@ -175,7 +175,9 @@ public:
* @param name The name to check for. * @param name The name to check for.
* @return The txid that registers/updates it. Null if none. * @return The txid that registers/updates it. Null if none.
*/ */
uint256 getTxForName (const valtype& name) const; uint256 getTxForNamespace(const valtype& nameSpace) const;
uint256 getTxForNamespaceKey(const valtype& nameSpace, const valtype& key) const;
/** /**
* Clear all data. * Clear all data.
@ -183,11 +185,8 @@ public:
inline void inline void
clear () clear ()
{ {
/* mapNamespaceRegs.clear();
mapNameRegs.clear (); mapNamespaceKeyUpdates.clear();
mapNameUpdates.clear ();
mapNameNews.clear ();
*/
} }
/** /**

26
src/txmempool.h

@ -88,6 +88,9 @@ private:
CAmount nModFeesWithAncestors; CAmount nModFeesWithAncestors;
int64_t nSigOpCostWithAncestors; int64_t nSigOpCostWithAncestors;
/* Cache keva operation (if any) performed by this tx. */
CKevaScript kevaOp;
public: public:
CTxMemPoolEntry(const CTransactionRef& _tx, const CAmount& _nFee, CTxMemPoolEntry(const CTransactionRef& _tx, const CAmount& _nFee,
int64_t _nTime, unsigned int _entryHeight, int64_t _nTime, unsigned int _entryHeight,
@ -127,6 +130,26 @@ public:
CAmount GetModFeesWithAncestors() const { return nModFeesWithAncestors; } CAmount GetModFeesWithAncestors() const { return nModFeesWithAncestors; }
int64_t GetSigOpCostWithAncestors() const { return nSigOpCostWithAncestors; } int64_t GetSigOpCostWithAncestors() const { return nSigOpCostWithAncestors; }
inline bool isNamespaceRegistration() const
{
return kevaOp.isKevaOp() && kevaOp.getKevaOp() == OP_KEVA_NAMESPACE;
}
inline bool isNamespaceKeyUpdate() const
{
return kevaOp.isKevaOp() && kevaOp.getKevaOp() == OP_KEVA_PUT;
}
inline const valtype& getNamespace() const
{
return kevaOp.getOpNamespace();
}
inline const valtype& getKey() const
{
return kevaOp.getOpKey();
}
mutable size_t vTxHashesIdx; //!< Index in mempool's vTxHashes mutable size_t vTxHashesIdx; //!< Index in mempool's vTxHashes
}; };
@ -345,7 +368,8 @@ enum class MemPoolRemovalReason {
REORG, //! Removed for reorganization REORG, //! Removed for reorganization
BLOCK, //! Removed for block BLOCK, //! Removed for block
CONFLICT, //! Removed for conflict with in-block transaction CONFLICT, //! Removed for conflict with in-block transaction
REPLACED //! Removed for replacement REPLACED, //! Removed for replacement,
KEVA_CONFLICT
}; };
class SaltedTxidHasher class SaltedTxidHasher

Loading…
Cancel
Save