From 08bfd302fec861e9c3c84f9deb60d09d2b7e6db1 Mon Sep 17 00:00:00 2001 From: Vinnie Falco Date: Thu, 2 Jul 2015 10:54:39 -0700 Subject: [PATCH] Apply tx to new open ledger on switch (RIPD-972): When the last closed ledger jumps, transactions from the old open ledger and local transactions need to be applied to the new open ledger or else transactions could get lost locally (but still relayed, and therefore make it into a ledger). A harmful effect is that rippled will report that the transaction was not applied even when it was, making robust transaction submission malfunction. --- src/ripple/app/misc/NetworkOPs.cpp | 31 +++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/src/ripple/app/misc/NetworkOPs.cpp b/src/ripple/app/misc/NetworkOPs.cpp index 01168947f7..ae8402c4bd 100644 --- a/src/ripple/app/misc/NetworkOPs.cpp +++ b/src/ripple/app/misc/NetworkOPs.cpp @@ -1399,25 +1399,38 @@ bool NetworkOPsImp::checkLastClosedLedger ( } void NetworkOPsImp::switchLastClosedLedger ( - Ledger::pointer newLedger, bool duringConsensus) + Ledger::pointer newLCL, bool duringConsensus) { - // set the newledger as our last closed ledger -- this is abnormal code + // set the newLCL as our last closed ledger -- this is abnormal code auto msg = duringConsensus ? "JUMPdc" : "JUMP"; - m_journal.error << msg << " last closed ledger to " << newLedger->getHash (); + m_journal.error << msg << " last closed ledger to " << newLCL->getHash (); clearNeedNetworkLedger (); - newLedger->setClosed (); - auto openLedger = std::make_shared (false, std::ref (*newLedger)); - m_ledgerMaster.switchLedgers (newLedger, openLedger); + newLCL->setClosed (); + auto newOL = std::make_shared (false, std::ref (*newLCL)); + // Caller must own master lock + { + // Apply tx in old open ledger to new + // open ledger. Then apply local tx. + auto const oldOL = + m_ledgerMaster.getCurrentLedger(); + MetaView accum(*newLCL, tapNONE); + auto retries = m_localTX->getTxSet(); + applyTransactions (&oldOL->txMap(), + accum, newLCL, retries); + accum.apply(*newOL, m_journal); + } + + m_ledgerMaster.switchLedgers (newLCL, newOL); protocol::TMStatusChange s; s.set_newevent (protocol::neSWITCHED_LEDGER); - s.set_ledgerseq (newLedger->getLedgerSeq ()); + s.set_ledgerseq (newLCL->getLedgerSeq ()); s.set_networktime (getApp().getOPs ().getNetworkTimeNC ()); - uint256 hash = newLedger->getParentHash (); + uint256 hash = newLCL->getParentHash (); s.set_ledgerhashprevious (hash.begin (), hash.size ()); - hash = newLedger->getHash (); + hash = newLCL->getHash (); s.set_ledgerhash (hash.begin (), hash.size ()); getApp ().overlay ().foreach (send_always (