Skip to content

Commit

Permalink
Fixed bug where indeterminate values were being returned by RoundAbso…
Browse files Browse the repository at this point in the history
…lute() with mode ROUND_SIGNAL; resulting in incorrect blocks being generated on some platforms including Ubuntu 12.04 amd64; also added various debugging outputs that were useful for tracking down this error.
  • Loading branch information
Mark Friedenbach committed Dec 7, 2012
1 parent 7cff22e commit 91b35a4
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 7 deletions.
8 changes: 8 additions & 0 deletions contrib/debian/changelog
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
freicoin (0.0.0+1beta5~precise3) precise; urgency=low

[ Mark Friedenbach ]
* Fix bug resulting in indeterminate rounding, resulting in incorrect
blocks on some platforms (observed on Ubuntu 12.04 amd64).

-- Mark Friedenbach <[email protected]> Thu, 7 Dec 2012 18:00:00 -0800

freicoin (0.0.0+1beta5~precise2) precise; urgency=low

[ Mark Friedenbach ]
Expand Down
11 changes: 6 additions & 5 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1955,7 +1955,7 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex, bool fJustCheck)
{
bool fInvalid;
if (!tx.FetchInputs(txdb, mapQueuedChanges, true, false, mapInputs, fInvalid))
return false;
return error("ConnectBlock() : unable to fetch inputs for transaction %s", tx.GetHash().ToString().c_str());

if (fStrictPayToScriptHash)
{
Expand All @@ -1974,15 +1974,16 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex, bool fJustCheck)
nFees += GetTimeAdjustedValue(qNet, pindex->nHeight - tx.nRefHeight);

if (!tx.ConnectInputs(mapInputs, mapQueuedChanges, posThisTx, pindex, true, false, fStrictPayToScriptHash))
return false;
return error("ConnectBlock() : unable to connect inputs");
}

mapQueuedChanges[hashTx] = CTxIndex(posThisTx, tx.vout.size());
}

mpq qCoinbaseValue = vtx[0].GetValueOut();
if ( GetTimeAdjustedValue(qCoinbaseValue, pindex->nHeight - vtx[0].nRefHeight) > GetBlockValue(pindex->nHeight, nFees) )
return false;
mpq qActualCoinbaseValue = GetTimeAdjustedValue(vtx[0].GetValueOut(), pindex->nHeight - vtx[0].nRefHeight);
mpq qAllowedCoinbaseValue = GetBlockValue(pindex->nHeight, nFees);
if ( qActualCoinbaseValue > qAllowedCoinbaseValue )
return error("ConnectBlock() : too many coins generated by coinbase: %s > %s", FormatMoney(qActualCoinbaseValue).c_str(), FormatMoney(qAllowedCoinbaseValue).c_str());

std::map<CTxDestination, mpq> mapBudget;

Expand Down
5 changes: 3 additions & 2 deletions src/util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -511,7 +511,7 @@ mpq RoundAbsolute(const mpq &q, int mode, int magnitude)
const mpq qOffset = q / qUnits;
const mpz quotient = qOffset.get_num() / qOffset.get_den();
const mpz remainder = qOffset.get_num() % qOffset.get_den();
const mpz remainder_times_two = abs(remainder *2);
const mpz remainder_times_two = abs(remainder) * 2;

bool ret_next;
switch (mode) {
Expand Down Expand Up @@ -546,11 +546,12 @@ mpq RoundAbsolute(const mpq &q, int mode, int magnitude)
case ROUND_SIGNAL:
if (remainder != 0)
throw std::runtime_error("RoundAbsolute() : non-zero remainder in ROUND_SIGNAL mode");
ret_next = false;
break;
}

if (ret_next) {
if (quotient > 0)
if (quotient >= 0)
return (quotient + 1) * qUnits;
else
return (quotient - 1) * qUnits;
Expand Down

0 comments on commit 91b35a4

Please sign in to comment.