Merge branch 'master' of github.com:jedmccaleb/NewCoin

This commit is contained in:
Arthur Britto
2012-12-31 16:37:48 -08:00
6 changed files with 63 additions and 41 deletions

View File

@@ -935,55 +935,49 @@ uint256 Ledger::getLedgerHashIndex(uint32 desiredLedgerIndex)
return s.getSHA512Half();
}
int Ledger::getLedgerHashOffset(uint32 ledgerIndex)
{ // get the offset for this ledger's hash (or the first one after it) in the every-256-ledger table
return (ledgerIndex >> 8) % 256;
}
int Ledger::getLedgerHashOffset(uint32 desiredLedgerIndex, uint32 currentLedgerIndex)
{ // get the offset for this ledger's hash in the every-ledger table, -1 if not in it
if (desiredLedgerIndex >= currentLedgerIndex)
return -1;
if (currentLedgerIndex < 256)
return desiredLedgerIndex;
if (desiredLedgerIndex < (currentLedgerIndex - 256))
return -1;
return currentLedgerIndex - desiredLedgerIndex - 1;
}
uint256 Ledger::getLedgerHash(uint32 ledgerIndex)
{ // return the hash of the specified ledger, 0 if not available
// easy cases
if (ledgerIndex > mLedgerSeq)
return uint256();
if (ledgerIndex == mLedgerSeq)
return getHash();
if (ledgerIndex == (mLedgerSeq - 1))
return mParentHash;
// within 255
int offset = getLedgerHashOffset(ledgerIndex, mLedgerSeq);
if (offset != -1)
// within 256
int diff = mLedgerSeq - ledgerIndex;
if (diff <= 256)
{
SLE::pointer hashIndex = getSLE(getLedgerHashIndex());
if (hashIndex)
return hashIndex->getFieldV256(sfHashes).peekValue().at(offset);
else
assert(false);
{
assert(hashIndex->getFieldU32(sfLastLedgerSequence) == (mLedgerSeq - 1));
STVector256 vec = hashIndex->getFieldV256(sfHashes);
if (vec.size() >= diff)
return vec.at(vec.size() - diff);
}
}
if ((ledgerIndex & 0xff) != 0)
return uint256();
// in skiplist
SLE::pointer hashIndex = getSLE(getLedgerHashIndex(ledgerIndex));
if (hashIndex)
return hashIndex->getFieldV256(sfHashes).peekValue().at(getLedgerHashOffset(ledgerIndex, mLedgerSeq));
else
assert(false);
{
int lastSeq = hashIndex->getFieldU32(sfLastLedgerSequence);
assert(lastSeq >= ledgerIndex);
assert((lastSeq & 0xff) == 0);
int sDiff = (lastSeq - ledgerIndex) >> 8;
STVector256 vec = hashIndex->getFieldV256(sfHashes);
if (vec.size() > sDiff)
return vec.at(vec.size() - sDiff - 1);
}
return uint256();
}
@@ -1144,9 +1138,7 @@ void Ledger::updateSkipList()
std::vector<uint256> hashes;
if (!skipList)
{
skipList = boost::make_shared<SLE>(ltLEDGER_HASHES, hash);
}
else
hashes = skipList->getFieldV256(sfHashes).peekValue();

View File

@@ -224,6 +224,8 @@ void LedgerAcquire::trigger(Peer::ref peer, bool timer)
tmGL.set_itype(ripple::liBASE);
cLog(lsTRACE) << "Sending base request to " << (peer ? "selected peer" : "all peers");
sendRequest(tmGL, peer);
if (timer)
resetTimer();
return;
}

View File

@@ -425,8 +425,8 @@ void LedgerConsensus::handleLCL(const uint256& lclHash)
cLog(lsINFO) << "Have the consensus ledger " << mPrevLedgerHash;
mHaveCorrectLCL = true;
mAcquiringLedger.reset();
theApp->getOPs().clearNeedNetworkLedger();
if (mAcquiringLedger->isComplete())
theApp->getOPs().clearNeedNetworkLedger();
mCloseResolution = ContinuousLedgerTiming::getNextLedgerTimeResolution(
mPreviousLedger->getCloseResolution(), mPreviousLedger->getCloseAgree(),
mPreviousLedger->getLedgerSeq() + 1);

View File

@@ -78,7 +78,6 @@ void LedgerMaster::storeLedger(Ledger::ref ledger)
mLedgerHistory.addAcceptedLedger(ledger, false);
}
Ledger::pointer LedgerMaster::closeLedger(bool recover)
{
boost::recursive_mutex::scoped_lock sl(mLock);
@@ -208,6 +207,37 @@ void LedgerMaster::resumeAcquiring()
}
}
void LedgerMaster::fixMismatch(Ledger::ref ledger)
{
int invalidate = 0;
for (uint32 lSeq = ledger->getLedgerSeq() - 1; lSeq > 0; --lSeq)
if (mCompleteLedgers.hasValue(lSeq))
{
uint256 hash = ledger->getLedgerHash(lSeq);
if (hash.isNonZero())
{ // try to close the seam
Ledger::pointer otherLedger = getLedgerBySeq(lSeq);
if (otherLedger && (otherLedger->getHash() == hash))
{ // we closed the seam
tLog(invalidate != 0, lsWARNING) << "Match at " << lSeq << ", " <<
invalidate << " prior ledgers invalidated";
return;
}
}
mCompleteLedgers.clearValue(lSeq);
if (mMissingSeq == lSeq)
{
mMissingLedger.reset();
mMissingSeq = 0;
}
++invalidate;
}
// all prior ledgers invalidated
tLog(invalidate != 0, lsWARNING) << "All " << invalidate << " prior ledgers invalidated";
}
void LedgerMaster::setFullLedger(Ledger::ref ledger)
{ // A new ledger has been accepted as part of the trusted chain
cLog(lsDEBUG) << "Ledger " << ledger->getLedgerSeq() << " accepted :" << ledger->getHash();
@@ -219,15 +249,11 @@ void LedgerMaster::setFullLedger(Ledger::ref ledger)
if ((ledger->getLedgerSeq() != 0) && mCompleteLedgers.hasValue(ledger->getLedgerSeq() - 1))
{ // we think we have the previous ledger, double check
Ledger::pointer prevLedger = getLedgerBySeq(ledger->getLedgerSeq() - 1);
if (!prevLedger)
if (!prevLedger || (prevLedger->getHash() != ledger->getParentHash()))
{
cLog(lsWARNING) << "Ledger " << ledger->getLedgerSeq() - 1 << " missing";
mCompleteLedgers.clearValue(ledger->getLedgerSeq() - 1);
}
else if (prevLedger->getHash() != ledger->getParentHash())
{
cLog(lsWARNING) << "Ledger " << ledger->getLedgerSeq() << " invalidates prior ledger";
mCompleteLedgers.clearValue(prevLedger->getLedgerSeq());
cLog(lsWARNING) << "Acquired ledger invalidates previous ledger: " <<
(prevLedger ? "hashMismatch" : "missingLedger");
fixMismatch(ledger);
}
}

View File

@@ -93,6 +93,7 @@ public:
void setLedgerRangePresent(uint32 minV, uint32 maxV) { mCompleteLedgers.setRange(minV, maxV); }
void addHeldTransaction(const Transaction::pointer& trans);
void fixMismatch(Ledger::ref ledger);
bool haveLedgerRange(uint32 from, uint32 to);

View File

@@ -770,6 +770,7 @@ bool NetworkOPs::checkLastClosedLedger(const std::vector<Peer::pointer>& peerLis
}
return true;
}
clearNeedNetworkLedger();
consensus = mAcquiringLedger->getLedger();
}