Skip to content

Commit

Permalink
Merge pull request #162 from domob1812/simpler-priority
Browse files Browse the repository at this point in the history
Add "mild" caching for priority calculation.
  • Loading branch information
phelixbtc committed Aug 26, 2014
2 parents 22e0198 + c103ca4 commit b3ba912
Show file tree
Hide file tree
Showing 6 changed files with 79 additions and 61 deletions.
4 changes: 2 additions & 2 deletions src/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ bool AppInit2(int argc, char* argv[])

fDebug = GetBoolArg("-debug");
fAllowDNS = GetBoolArg("-dns");
fCacheTxPrev = !GetBoolArg ("-notxprevcache");
fCacheTxPrev = GetBoolArg ("-txprevcache");

#if !defined(WIN32) && !defined(QT_GUI)
fDaemon = GetBoolArg("-daemon");
Expand Down Expand Up @@ -645,7 +645,7 @@ std::string HelpMessage()
" -daemon \t\t " + _("Run in the background as a daemon and accept commands\n") +
#endif
" -testnet \t\t " + _("Use the test network\n") +
" -notxprevcache \t\t " + _("Disable caching of previous transactions (less RAM, more CPU)\n") +
" -txprevcache \t\t " + _("Enable caching of previous transactions (more RAM, less disk access)\n") +
" -rpcuser=<user> \t " + _("Username for JSON-RPC connections\n") +
" -rpcpassword=<pw>\t " + _("Password for JSON-RPC connections\n") +
" -rpcport=<port> \t\t " + _("Listen for JSON-RPC connections on <port> (default: 8336)\n") +
Expand Down
106 changes: 58 additions & 48 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -231,30 +231,43 @@ CTxIn::ClearCache () const
{
delete txPrev;
cleared = true;
txPrev = NULL;
}

txPrev = NULL;
prevHeight = -1;
assert (!txPrev);

return cleared;
}

void
CTxIn::InvalidateCache () const
{
ClearCache ();

fHasPrevInfo = false;
prevHeight = -1;
}

CTxIn&
CTxIn::operator= (const CTxIn& in)
{
prevout = in.prevout;
scriptSig = in.scriptSig;
nSequence = in.nSequence;

ClearCache ();
InvalidateCache ();

if (in.txPrev && fCacheTxPrev)
if (in.fHasPrevInfo)
{
txPrev = new CTransaction (*in.txPrev);
fHasPrevInfo = in.fHasPrevInfo;
prevPos = in.prevPos;
nValue = in.nValue;
prevHeight = in.prevHeight;
fChecked = in.fChecked;
}

if (in.txPrev && fCacheTxPrev)
txPrev = new CTransaction (*in.txPrev);

return *this;
}

Expand Down Expand Up @@ -617,7 +630,7 @@ bool CWalletTx::AcceptWalletTransaction()
const CBlockIndex*
CTxIndex::GetContainingBlock (const CDiskTxPos& pos)
{
if (pos == CDiskTxPos(1, 1, 1))
if (pos.IsNull () || pos == CDiskTxPos(1, 1, 1))
return NULL;

// Read block header
Expand Down Expand Up @@ -1114,8 +1127,6 @@ CTransaction::ConnectInputs (DatabaseSet& dbset,
if (!newTxPrev->ReadFromDisk (txindex.pos))
return error ("ConnectInputs: %s ReadFromDisk prev tx %s failed", GetHash().ToString().substr(0,10).c_str(), prevout.hash.ToString().substr(0,10).c_str());
}
vin[i].prevPos = txindex.pos;
vin[i].fChecked = false;

if (fCacheTxPrev)
{
Expand All @@ -1124,6 +1135,17 @@ CTransaction::ConnectInputs (DatabaseSet& dbset,
}
else
txPrev = newTxPrev.get ();

/* If we didn't have any cache info, add it and
set signature check to false. We update the
prevPos in any case, because it changes when a
transaction gets confirmed out of the mempool. */
if (!vin[i].fHasPrevInfo)
{
vin[i].fHasPrevInfo = true;
vin[i].fChecked = false;
}
vin[i].prevPos = txindex.pos;
}
else
{
Expand All @@ -1132,6 +1154,7 @@ CTransaction::ConnectInputs (DatabaseSet& dbset,
printf ("ConnectInputs: using cached txPrev for %s/%d\n",
GetHash ().ToString ().substr (0, 10).c_str (), i);
}
assert (vin[i].fHasPrevInfo);
assert (txPrev);

if (prevout.n >= txPrev->vout.size ())
Expand Down Expand Up @@ -1161,9 +1184,9 @@ CTransaction::ConnectInputs (DatabaseSet& dbset,
return fMiner ? false : error("ConnectInputs() : %s prev tx already spent", GetHash().ToString().substr(0,10).c_str());

// Check for negative or overflow input values
const int64 nValue = txPrev->vout[prevout.n].nValue;
nValueIn += nValue;
if (!MoneyRange(nValue) || !MoneyRange(nValueIn))
vin[i].nValue = txPrev->vout[prevout.n].nValue;
nValueIn += vin[i].nValue;
if (!MoneyRange(vin[i].nValue) || !MoneyRange(nValueIn))
return error("ConnectInputs() : txin values out of range");

// Mark outpoints as spent
Expand Down Expand Up @@ -3302,49 +3325,32 @@ CBlock* CreateNewBlock(CReserveKey& reservekey)
double dPriority = 0;
BOOST_FOREACH(const CTxIn& txin, tx.vin)
{
int64 nValueIn;
int nConf;
/* We should always have cached txprev info on the
input, since this should have been added when accepting
it to the mempool. Be not too strict about it, though. */
if (!txin.fHasPrevInfo)
{
printf ("WARNING: CreateNewBlock: ignoring tx without prev info\n");
goto skipTransaction;
}

bool dependency = false;
if (txin.txPrev)
int nHeight;
if (txin.prevHeight != -1)
{
nHeight = txin.prevHeight;
if (fDebug)
printf ("CreateNewBlock: using cached txPrev %s\n",
tx.GetHash ().ToString ().substr (0, 10).c_str ());
nValueIn = txin.txPrev->vout[txin.prevout.n].nValue;

int nHeight;
if (txin.prevHeight != -1)
{
nHeight = txin.prevHeight;
if (fDebug)
printf (" also using cached height %d\n", nHeight);
}
else
{
nHeight = CTxIndex::GetHeight (txin.prevPos);
if (nHeight == -1)
dependency = true;

if (nHeight + MIN_PRIORITY_CACHE_CONF < nBestHeight)
txin.prevHeight = nHeight;
}

nConf = 1 + nBestHeight - nHeight;
printf (" also using cached height %d\n", nHeight);
}
else
{
CTransaction txPrev;
CTxIndex txindex;
if (txPrev.ReadFromDisk (dbset.tx (), txin.prevout, txindex))
{
nValueIn = txPrev.vout[txin.prevout.n].nValue;
nConf = txindex.GetDepthInMainChain ();
}
else
nHeight = CTxIndex::GetHeight (txin.prevPos);
if (nHeight == -1)
dependency = true;
}

if (nHeight + MIN_PRIORITY_CACHE_CONF < nBestHeight)
txin.prevHeight = nHeight;
}

if (dependency)
{
Expand All @@ -3359,12 +3365,14 @@ CBlock* CreateNewBlock(CReserveKey& reservekey)
porphan->setDependsOn.insert (txin.prevout.hash);
continue;
}

const int nConf = 1 + nBestHeight - nHeight;
assert (nConf > 0);

dPriority += (double)nValueIn * nConf;
dPriority += static_cast<double> (txin.nValue) * nConf;

if (fDebug && GetBoolArg("-printpriority"))
printf("priority nValueIn=%-12I64d nConf=%-5d dPriority=%-20.1f\n", nValueIn, nConf, dPriority);
printf("priority nValueIn=%-12I64d nConf=%-5d dPriority=%-20.1f\n", txin.nValue, nConf, dPriority);
}

// Priority is sum(valuein * age) / txsize
Expand All @@ -3382,6 +3390,8 @@ CBlock* CreateNewBlock(CReserveKey& reservekey)
porphan->print();
printf("\n");
}

skipTransaction:;
}

// Collect transactions into block
Expand Down
13 changes: 8 additions & 5 deletions src/main.h
Original file line number Diff line number Diff line change
Expand Up @@ -309,31 +309,33 @@ class CTxIn
in the chain so that we assume no reorgs happen). It is -1 if we
don't cache it. */
mutable const CTransaction* txPrev;
mutable bool fHasPrevInfo;
mutable CDiskTxPos prevPos;
mutable int64 nValue;
mutable int prevHeight;
mutable bool fChecked;

inline CTxIn ()
: nSequence(UINT_MAX), txPrev(NULL)
: nSequence(UINT_MAX), txPrev(NULL), fHasPrevInfo(false)
{}

inline CTxIn (const CTxIn& in)
: txPrev(NULL)
: txPrev(NULL), fHasPrevInfo(false)
{
operator= (in);
}

explicit inline CTxIn (COutPoint prevoutIn, CScript scriptSigIn = CScript(),
unsigned int nSequenceIn = UINT_MAX)
: prevout(prevoutIn), scriptSig(scriptSigIn), nSequence(nSequenceIn),
txPrev(NULL)
txPrev(NULL), fHasPrevInfo(false)
{}

inline CTxIn (uint256 hashPrevTx, unsigned int nOut,
CScript scriptSigIn = CScript(),
unsigned int nSequenceIn = UINT_MAX)
: prevout(hashPrevTx, nOut), scriptSig(scriptSigIn),
nSequence(nSequenceIn), txPrev(NULL)
nSequence(nSequenceIn), txPrev(NULL), fHasPrevInfo(false)
{}

~CTxIn ();
Expand All @@ -345,10 +347,11 @@ class CTxIn
READWRITE(nSequence);

if (fRead)
ClearCache ();
InvalidateCache ();
)

bool ClearCache () const;
void InvalidateCache () const;

bool IsFinal() const
{
Expand Down
9 changes: 6 additions & 3 deletions src/script.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1292,7 +1292,7 @@ bool VerifySignature(const CTransaction& txFrom, const CTransaction& txTo, unsig
if (txin.prevout.hash != txFrom.GetHash())
return false;

if (txin.txPrev && txin.fChecked)
if (txin.fHasPrevInfo && txin.fChecked)
{
if (fDebug)
printf ("VerifySignature: skipped cached verification for %s/%u\n",
Expand All @@ -1304,9 +1304,12 @@ bool VerifySignature(const CTransaction& txFrom, const CTransaction& txTo, unsig
return false;

/* If we are caching, remember the successful verification. */
if (txin.txPrev)
if (txin.fHasPrevInfo)
{
assert (*txin.txPrev == txFrom);
#ifndef NDEBUG
if (txin.txPrev)
assert (*txin.txPrev == txFrom);
#endif // NDEBUG?
txin.fChecked = true;
}

Expand Down
2 changes: 1 addition & 1 deletion src/util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ string strMiscWarning;
bool fTestNet = false;
bool fNoListen = false;
bool fLogTimestamps = false;
bool fCacheTxPrev = true;
bool fCacheTxPrev = false;



Expand Down
6 changes: 4 additions & 2 deletions src/wallet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -566,9 +566,11 @@ void CWallet::ReacceptWalletTransactions()
}
else
{
// Reaccept any txes of ours that aren't already in a block
/* Reaccept any txes of ours that aren't already in a block.
We have to check the inputs to make sure that the
prev tx cache is filled properly. */
if (!wtx.IsCoinBase())
wtx.AcceptWalletTransaction (dbset, false);
wtx.AcceptWalletTransaction (dbset);
}
}
if (hasMissingTx)
Expand Down

0 comments on commit b3ba912

Please sign in to comment.