From 554ba4f71df1668582e3635b5a342a6530d88943 Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Tue, 23 Apr 2013 06:07:21 -0700 Subject: [PATCH 1/7] Mark something we need to fix in the websocketpp code. --- src/cpp/websocketpp/src/messages/data.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cpp/websocketpp/src/messages/data.hpp b/src/cpp/websocketpp/src/messages/data.hpp index 3d2d83222..2aa50455b 100644 --- a/src/cpp/websocketpp/src/messages/data.hpp +++ b/src/cpp/websocketpp/src/messages/data.hpp @@ -94,9 +94,9 @@ public: << std::endl;*/ if (!m_avaliable.empty()) { - p = m_avaliable.front(); + p = m_avaliable.front(); // FIXME can call intrusive_ptr_add_ref (line 215) which can deadlock q = p; - m_avaliable.pop(); // FIXME can call intrusive_ptr_release(line 217) which can deadlock + m_avaliable.pop(); // FIXME can call intrusive_ptr_release (line 217) which can deadlock m_used[p->get_index()] = p; } else { if (m_cur_elements == m_max_elements) { From 84087e62cbfc7848c8eba7e8ffbee0330b9222a0 Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Tue, 23 Apr 2013 06:48:42 -0700 Subject: [PATCH 2/7] Smarter peer selection for acquires. --- src/cpp/ripple/LedgerAcquire.cpp | 19 ++++++++++++------- src/cpp/ripple/LedgerAcquire.h | 11 ++++++----- src/cpp/ripple/LedgerConsensus.cpp | 2 +- src/cpp/ripple/LedgerMaster.cpp | 6 +++--- src/cpp/ripple/NetworkOPs.cpp | 2 +- src/cpp/ripple/Peer.cpp | 9 +++++++-- src/cpp/ripple/Peer.h | 2 +- src/cpp/ripple/SHAMapSync.cpp | 1 - 8 files changed, 31 insertions(+), 21 deletions(-) diff --git a/src/cpp/ripple/LedgerAcquire.cpp b/src/cpp/ripple/LedgerAcquire.cpp index 51da537be..3c4a97f51 100644 --- a/src/cpp/ripple/LedgerAcquire.cpp +++ b/src/cpp/ripple/LedgerAcquire.cpp @@ -96,9 +96,9 @@ bool PeerSet::isActive() return !isDone(); } -LedgerAcquire::LedgerAcquire(const uint256& hash) : PeerSet(hash, LEDGER_ACQUIRE_TIMEOUT), +LedgerAcquire::LedgerAcquire(const uint256& hash, uint32 seq) : PeerSet(hash, LEDGER_ACQUIRE_TIMEOUT), mHaveBase(false), mHaveState(false), mHaveTransactions(false), mAborted(false), mSignaled(false), mAccept(false), - mByHash(true), mWaitCount(0) + mByHash(true), mWaitCount(0), mSeq(seq) { #ifdef LA_DEBUG cLog(lsTRACE) << "Acquiring ledger " << mHash; @@ -243,14 +243,15 @@ void LedgerAcquire::addPeers() // We traverse the peer list in random order so as not to favor any particular peer int firstPeer = rand() & vSize; - bool found = false; + int found = 0; for (int i = 0; i < vSize; ++i) { Peer::ref peer = peerList[(i + firstPeer) % vSize]; - if (peer->hasLedger(getHash())) + if (peer->hasLedger(getHash(), mSeq)) { - found = true; peerHas(peer); + if (++found == 3) + break; } } @@ -775,7 +776,7 @@ bool LedgerAcquire::takeTxRootNode(const std::vector& data, SMAdd mLedger->peekTransactionMap()->addRootNode(mLedger->getTransHash(), data, snfWIRE, &tFilter)); } -LedgerAcquire::pointer LedgerAcquireMaster::findCreate(const uint256& hash) +LedgerAcquire::pointer LedgerAcquireMaster::findCreate(const uint256& hash, uint32 seq) { assert(hash.isNonZero()); boost::mutex::scoped_lock sl(mLock); @@ -785,7 +786,7 @@ LedgerAcquire::pointer LedgerAcquireMaster::findCreate(const uint256& hash) ptr->touch(); return ptr; } - ptr = boost::make_shared(hash); + ptr = boost::make_shared(hash, seq); if (!ptr->isDone()) { ptr->addPeers(); @@ -941,6 +942,8 @@ void LedgerAcquireMaster::gotLedgerData(Job&, uint256 hash, } if (!san.isInvalid()) ledger->trigger(peer); + else + cLog(lsDEBUG) << "Peer sends invalid base data"; return; } @@ -975,6 +978,8 @@ void LedgerAcquireMaster::gotLedgerData(Job&, uint256 hash, ledger->takeAsNode(nodeIDs, nodeData, ret); if (!ret.isInvalid()) ledger->trigger(peer); + else + cLog(lsDEBUG) << "Peer sends invalid node data"; return; } diff --git a/src/cpp/ripple/LedgerAcquire.h b/src/cpp/ripple/LedgerAcquire.h index 4193ce96e..a375d58a2 100644 --- a/src/cpp/ripple/LedgerAcquire.h +++ b/src/cpp/ripple/LedgerAcquire.h @@ -85,9 +85,10 @@ public: typedef boost::shared_ptr pointer; protected: - Ledger::pointer mLedger; - bool mHaveBase, mHaveState, mHaveTransactions, mAborted, mSignaled, mAccept, mByHash; - int mWaitCount; + Ledger::pointer mLedger; + bool mHaveBase, mHaveState, mHaveTransactions, mAborted, mSignaled, mAccept, mByHash; + int mWaitCount; + uint32 mSeq; std::set mRecentTXNodes; std::set mRecentASNodes; @@ -104,7 +105,7 @@ protected: boost::weak_ptr pmDowncast(); public: - LedgerAcquire(const uint256& hash); + LedgerAcquire(const uint256& hash, uint32 seq); virtual ~LedgerAcquire() { ; } bool isBase() const { return mHaveBase; } @@ -149,7 +150,7 @@ protected: public: LedgerAcquireMaster() : mRecentFailures("LedgerAcquireRecentFailures", 0, LEDGER_REACQUIRE_INTERVAL) { ; } - LedgerAcquire::pointer findCreate(const uint256& hash); + LedgerAcquire::pointer findCreate(const uint256& hash, uint32 seq); LedgerAcquire::pointer find(const uint256& hash); bool hasLedger(const uint256& ledgerHash); void dropLedger(const uint256& ledgerHash); diff --git a/src/cpp/ripple/LedgerConsensus.cpp b/src/cpp/ripple/LedgerConsensus.cpp index af56d2824..52c1ca771 100644 --- a/src/cpp/ripple/LedgerConsensus.cpp +++ b/src/cpp/ripple/LedgerConsensus.cpp @@ -298,7 +298,7 @@ void LedgerConsensus::handleLCL(const uint256& lclHash) { // need to start acquiring the correct consensus LCL cLog(lsWARNING) << "Need consensus ledger " << mPrevLedgerHash; - mAcquiringLedger = theApp->getMasterLedgerAcquire().findCreate(mPrevLedgerHash); + mAcquiringLedger = theApp->getMasterLedgerAcquire().findCreate(mPrevLedgerHash, 0); mHaveCorrectLCL = false; return; } diff --git a/src/cpp/ripple/LedgerMaster.cpp b/src/cpp/ripple/LedgerMaster.cpp index 6368a580e..933824c6c 100644 --- a/src/cpp/ripple/LedgerMaster.cpp +++ b/src/cpp/ripple/LedgerMaster.cpp @@ -230,7 +230,7 @@ bool LedgerMaster::acquireMissingLedger(Ledger::ref origLedger, const uint256& l return false; } - mMissingLedger = theApp->getMasterLedgerAcquire().findCreate(ledgerHash); + mMissingLedger = theApp->getMasterLedgerAcquire().findCreate(ledgerHash, ledgerSeq); if (mMissingLedger->isComplete()) { Ledger::pointer lgr = mMissingLedger->getLedger(); @@ -270,7 +270,7 @@ bool LedgerMaster::acquireMissingLedger(Ledger::ref origLedger, const uint256& l if ((fetchCount < fetchMax) && (it.first < ledgerSeq) && !mCompleteLedgers.hasValue(it.first) && !theApp->getMasterLedgerAcquire().find(it.second)) { - LedgerAcquire::pointer acq = theApp->getMasterLedgerAcquire().findCreate(it.second); + LedgerAcquire::pointer acq = theApp->getMasterLedgerAcquire().findCreate(it.second, it.first); if (acq && acq->isComplete()) { acq->getLedger()->setAccepted(); @@ -602,7 +602,7 @@ void LedgerMaster::tryPublish() } else { - LedgerAcquire::pointer acq = theApp->getMasterLedgerAcquire().findCreate(hash); + LedgerAcquire::pointer acq = theApp->getMasterLedgerAcquire().findCreate(hash, 0); if (!acq->isDone()) { acq->setAccept(); diff --git a/src/cpp/ripple/NetworkOPs.cpp b/src/cpp/ripple/NetworkOPs.cpp index 901dcea11..94fdc4736 100644 --- a/src/cpp/ripple/NetworkOPs.cpp +++ b/src/cpp/ripple/NetworkOPs.cpp @@ -772,7 +772,7 @@ bool NetworkOPs::checkLastClosedLedger(const std::vector& peerLis { cLog(lsINFO) << "Acquiring consensus ledger " << closedLedger; if (!mAcquiringLedger || (mAcquiringLedger->getHash() != closedLedger)) - mAcquiringLedger = theApp->getMasterLedgerAcquire().findCreate(closedLedger); + mAcquiringLedger = theApp->getMasterLedgerAcquire().findCreate(closedLedger, 0); if (!mAcquiringLedger || mAcquiringLedger->isFailed()) { theApp->getMasterLedgerAcquire().dropLedger(closedLedger); diff --git a/src/cpp/ripple/Peer.cpp b/src/cpp/ripple/Peer.cpp index 6e252348d..94edb3be5 100644 --- a/src/cpp/ripple/Peer.cpp +++ b/src/cpp/ripple/Peer.cpp @@ -1488,11 +1488,14 @@ void Peer::recvGetLedger(ripple::TMGetLedger& packet) tLog(!ledger, lsTRACE) << "Don't have ledger " << ledgerhash; if (!ledger && (packet.has_querytype() && !packet.has_requestcookie())) { + uint32 seq = 0; + if (packet.has_ledgerseq()) + seq = packet.ledgerseq(); std::vector peerList = theApp->getConnectionPool().getPeerVector(); std::vector usablePeers; BOOST_FOREACH(Peer::ref peer, peerList) { - if (peer->hasLedger(ledgerhash) && (peer.get() != this)) + if (peer->hasLedger(ledgerhash, seq) && (peer.get() != this)) usablePeers.push_back(peer); } if (usablePeers.empty()) @@ -1716,8 +1719,10 @@ void Peer::recvLedger(const boost::shared_ptr& packet_ptr) punishPeer(LT_UnwantedData); } -bool Peer::hasLedger(const uint256& hash) const +bool Peer::hasLedger(const uint256& hash, uint32 seq) const { + if ((seq != 0) && (seq >= mMinLedger) && (seq <= mMaxLedger)) + return true; BOOST_FOREACH(const uint256& ledger, mRecentLedgers) if (ledger == hash) return true; diff --git a/src/cpp/ripple/Peer.h b/src/cpp/ripple/Peer.h index d0c48b2cd..d7bf83834 100644 --- a/src/cpp/ripple/Peer.h +++ b/src/cpp/ripple/Peer.h @@ -157,7 +157,7 @@ public: bool isOutbound() const { return !mInbound; } const uint256& getClosedLedgerHash() const { return mClosedLedgerHash; } - bool hasLedger(const uint256& hash) const; + bool hasLedger(const uint256& hash, uint32 seq) const; bool hasTxSet(const uint256& hash) const; uint64 getPeerId() const { return mPeerId; } diff --git a/src/cpp/ripple/SHAMapSync.cpp b/src/cpp/ripple/SHAMapSync.cpp index 3bafe4695..5ef58fadb 100644 --- a/src/cpp/ripple/SHAMapSync.cpp +++ b/src/cpp/ripple/SHAMapSync.cpp @@ -71,7 +71,6 @@ void SHAMap::getMissingNodes(std::vector& nodeIDs, std::vector(childID, nodeData, mSeq - 1, snfPREFIX, childHash, true); - cLog(lsTRACE) << "Got sync node from cache: " << *ptr; mTNByID[*ptr] = ptr; d = ptr.get(); filter->gotNode(true, childID, childHash, nodeData, ptr->getType()); From 4f7050609427107e81bee0a1223041b80aaa0d1e Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Tue, 23 Apr 2013 06:49:58 -0700 Subject: [PATCH 3/7] Include more information in fetch packs. --- src/cpp/ripple/NetworkOPs.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cpp/ripple/NetworkOPs.cpp b/src/cpp/ripple/NetworkOPs.cpp index 94fdc4736..cb786366a 100644 --- a/src/cpp/ripple/NetworkOPs.cpp +++ b/src/cpp/ripple/NetworkOPs.cpp @@ -2031,7 +2031,7 @@ void NetworkOPs::makeFetchPack(Job&, boost::weak_ptr wPeer, boost::shared_ newObj.set_ledgerseq(lSeq); std::list pack = wantLedger->peekAccountStateMap()->getFetchPack( - haveLedger->peekAccountStateMap().get(), false, 1024 - reply.objects().size()); + haveLedger->peekAccountStateMap().get(), true, 1024); BOOST_FOREACH(SHAMap::fetchPackEntry_t& node, pack) { ripple::TMIndexedObject& newObj = *reply.add_objects(); From 23acc3efef966097aebcef19dbb4fafa10d23c7e Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Tue, 23 Apr 2013 08:36:35 -0700 Subject: [PATCH 4/7] All reserve votees in validations. --- src/cpp/ripple/SerializedValidation.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/cpp/ripple/SerializedValidation.cpp b/src/cpp/ripple/SerializedValidation.cpp index f4031c0c7..633943f52 100644 --- a/src/cpp/ripple/SerializedValidation.cpp +++ b/src/cpp/ripple/SerializedValidation.cpp @@ -15,8 +15,10 @@ void SVFInit() sValidationFormat.push_back(SOElement(sfLedgerSequence, SOE_OPTIONAL)); sValidationFormat.push_back(SOElement(sfCloseTime, SOE_OPTIONAL)); sValidationFormat.push_back(SOElement(sfLoadFee, SOE_OPTIONAL)); - sValidationFormat.push_back(SOElement(sfBaseFee, SOE_OPTIONAL)); sValidationFormat.push_back(SOElement(sfFeatures, SOE_OPTIONAL)); + sValidationFormat.push_back(SOElement(sfBaseFee, SOE_OPTIONAL)); + sValidationFormat.push_back(SOElement(sfReserveBase, SOE_OPTIONAL)); + sValidationFormat.push_back(SOElement(sfReserveIncrement, SOE_OPTIONAL)); sValidationFormat.push_back(SOElement(sfSigningTime, SOE_REQUIRED)); sValidationFormat.push_back(SOElement(sfSigningPubKey, SOE_REQUIRED)); sValidationFormat.push_back(SOElement(sfSignature, SOE_OPTIONAL)); From 9c9fb267d9ec75d947a115e446a3d4042c1c92c6 Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Tue, 23 Apr 2013 09:57:08 -0700 Subject: [PATCH 5/7] Finish fee change logic. --- src/cpp/ripple/ChangeTransactor.cpp | 23 ++++++++- src/cpp/ripple/FeatureTable.cpp | 80 ++++++++++++++++++++++++++++- src/cpp/ripple/FeatureTable.h | 4 +- src/cpp/ripple/LedgerConsensus.cpp | 13 ++++- src/cpp/ripple/LedgerEntrySet.h | 2 - 5 files changed, 115 insertions(+), 7 deletions(-) diff --git a/src/cpp/ripple/ChangeTransactor.cpp b/src/cpp/ripple/ChangeTransactor.cpp index 1d3a80f27..0fd450ec4 100644 --- a/src/cpp/ripple/ChangeTransactor.cpp +++ b/src/cpp/ripple/ChangeTransactor.cpp @@ -1,4 +1,7 @@ #include "ChangeTransactor.h" +#include "Log.h" + +SETUP_LOG(); TER ChangeTransactor::doApply() { @@ -14,10 +17,16 @@ TER ChangeTransactor::doApply() TER ChangeTransactor::checkSig() { if (mTxn.getFieldAccount160(sfAccount).isNonZero()) + { + cLog(lsWARNING) << "Change transaction had bad source account"; return temBAD_SRC_ACCOUNT; + } if (!mTxn.getSigningPubKey().empty() || !mTxn.getSignature().empty()) + { + cLog(lsWARNING) << "Change transaction had bad signature"; return temBAD_SIGNATURE; + } return tesSUCCESS; } @@ -25,15 +34,26 @@ TER ChangeTransactor::checkSig() TER ChangeTransactor::checkSeq() { if (mTxn.getSequence() != 0) + { + cLog(lsWARNING) << "Change transaction had bad sequence"; return temBAD_SEQUENCE; - + } return tesSUCCESS; } TER ChangeTransactor::payFee() { + if (isSetBit(mParams, tapOPEN_LEDGER)) + { + cLog(lsWARNING) << "Change transaction against open ledger"; + return temINVALID; + } + if (mTxn.getTransactionFee() != STAmount()) + { + cLog(lsWARNING) << "Change transaction with non-zero fee"; return temBAD_FEE; + } return tesSUCCESS; } @@ -70,5 +90,6 @@ TER ChangeTransactor::applyFee() feeObject->setFieldU32(sfReserveIncrement, mTxn.getFieldU32(sfReserveIncrement)); mEngine->entryModify(feeObject); + cLog(lsWARNING) << "Fees have been changed"; return tesSUCCESS; } diff --git a/src/cpp/ripple/FeatureTable.cpp b/src/cpp/ripple/FeatureTable.cpp index 4c5808468..7154723cf 100644 --- a/src/cpp/ripple/FeatureTable.cpp +++ b/src/cpp/ripple/FeatureTable.cpp @@ -3,6 +3,9 @@ #include #include "Log.h" +#include "Application.h" +#include "ValidationCollection.h" +#include "HashPrefixes.h" SETUP_LOG(); @@ -243,6 +246,7 @@ protected: INT mTarget; // The setting we want std::map mVoteMap; +public: VotableInteger(INT current, INT target) : mCurrent(current), mTarget(target) { ++mVoteMap[mTarget]; // Add our vote @@ -268,8 +272,8 @@ protected: INT ourVote = mCurrent; int weight = 0; - typedef std::pair INTint_pair_t; - BOOST_FOREACH(INTint_pair_t& value, mVoteMap) + typedef typename std::map::value_type mapVType; + BOOST_FOREACH(const mapVType& value, mVoteMap) { // Take most voted value between current and target, inclusive if ((value.first <= std::max(mTarget, mCurrent)) && (value.first >= std::min(mTarget, mCurrent)) && @@ -284,16 +288,88 @@ protected: } }; +void FeeVote::doValidation(Ledger::ref lastClosedLedger, STObject& validation) +{ + if (lastClosedLedger->getBaseFee() != mTargetBaseFee) + { + cLog(lsINFO) << "Voting for base fee of " << mTargetBaseFee; + validation.setFieldU64(sfBaseFee, mTargetBaseFee); + } + + if (lastClosedLedger->getReserve(0) != mTargetReserveBase) + { + cLog(lsINFO) << "Voting for base resrve of " << mTargetReserveBase; + validation.setFieldU32(sfReserveBase, mTargetReserveBase); + } + + if (lastClosedLedger->getReserveInc() != mTargetReserveIncrement) + { + cLog(lsINFO) << "Voting for reserve increment of " << mTargetReserveIncrement; + validation.setFieldU32(sfReserveIncrement, mTargetReserveIncrement); + } +} + void FeeVote::doFeeVoting(Ledger::ref lastClosedLedger, SHAMap::ref initialPosition) { // LCL must be flag ledger assert((lastClosedLedger->getLedgerSeq() % 256) == 0); + VotableInteger baseFeeVote(lastClosedLedger->getBaseFee(), mTargetBaseFee); + VotableInteger baseReserveVote(lastClosedLedger->getReserve(0), mTargetReserveBase); + VotableInteger incReserveVote(lastClosedLedger->getReserveInc(), mTargetReserveIncrement); + // get validations for ledger before flag + ValidationSet set = theApp->getValidations().getValidations(lastClosedLedger->getParentHash()); + BOOST_FOREACH(ValidationSet::value_type& value, set) + { + SerializedValidation& val = *value.second; + if (val.isTrusted()) + { + if (val.isFieldPresent(sfBaseFee)) + baseFeeVote.addVote(val.getFieldU64(sfBaseFee)); + else + baseFeeVote.noVote(); + if (val.isFieldPresent(sfReserveBase)) + baseReserveVote.addVote(val.getFieldU32(sfReserveBase)); + else + baseReserveVote.noVote(); + if (val.isFieldPresent(sfReserveIncrement)) + incReserveVote.addVote(val.getFieldU32(sfReserveIncrement)); + else + incReserveVote.noVote(); + } + } // choose our positions + uint64 baseFee = baseFeeVote.getVotes(); + uint32 baseReserve = baseReserveVote.getVotes(); + uint32 incReserve = incReserveVote.getVotes(); // add transactions to our position + if ((baseFee != lastClosedLedger->getBaseFee()) || + (baseReserve != lastClosedLedger->getReserve(0)) || + (incReserve != lastClosedLedger->getReserveInc())) + { + cLog(lsWARNING) << "We are voting for a fee change: " << baseFee << "/" << baseReserve << "/" << incReserve; + SerializedTransaction trans(ttFEE); + trans.setFieldU64(sfBaseFee, baseFee); + trans.setFieldU32(sfReferenceFeeUnits, 10); + trans.setFieldU32(sfReserveBase, baseReserve); + trans.setFieldU32(sfReserveIncrement, incReserve); + + + Serializer s; + s.add32(sHP_TransactionID); + trans.add(s, true); + uint256 txID = s.getSHA512Half(); + cLog(lsWARNING) << "Vote: " << txID; + + SHAMapItem::pointer tItem = boost::make_shared(txID, s.peekData()); + if (!initialPosition->addGiveItem(tItem, true, false)) + { + cLog(lsWARNING) << "Ledger already had fee change"; + } + } } // vim:ts=4 diff --git a/src/cpp/ripple/FeatureTable.h b/src/cpp/ripple/FeatureTable.h index 0f6403813..fba08b557 100644 --- a/src/cpp/ripple/FeatureTable.h +++ b/src/cpp/ripple/FeatureTable.h @@ -93,8 +93,10 @@ public: mTargetReserveIncrement(targetReserveIncrement) { ; } - void doValidation(STObject& baseValidation); + // add our wishes to our validation + void doValidation(Ledger::ref lastClosedLedger, STObject& baseValidation); + // vote on the fee we want void doFeeVoting(Ledger::ref lastClosedLedger, SHAMap::ref initialPosition); }; diff --git a/src/cpp/ripple/LedgerConsensus.cpp b/src/cpp/ripple/LedgerConsensus.cpp index 52c1ca771..e2021a77f 100644 --- a/src/cpp/ripple/LedgerConsensus.cpp +++ b/src/cpp/ripple/LedgerConsensus.cpp @@ -317,7 +317,16 @@ void LedgerConsensus::handleLCL(const uint256& lclHash) void LedgerConsensus::takeInitialPosition(Ledger& initialLedger) { - SHAMap::pointer initialSet = initialLedger.peekTransactionMap()->snapShot(false); + SHAMap::pointer initialSet; + + if (mProposing && mHaveCorrectLCL && ((mPreviousLedger->getLedgerSeq() % 256) == 0)) + { // previous ledger was flag ledger + SHAMap::pointer preSet = initialLedger.peekTransactionMap()->snapShot(true); + theApp->getFeeVote().doFeeVoting(mPreviousLedger, preSet); + initialSet = preSet->snapShot(false); + } + else + initialSet = initialLedger.peekTransactionMap()->snapShot(false); uint256 txSet = initialSet->getHash(); cLog(lsINFO) << "initial position " << txSet; mapComplete(txSet, initialSet, false); @@ -1208,6 +1217,8 @@ void LedgerConsensus::accept(SHAMap::ref set, LoadEvent::pointer) SerializedValidation::pointer v = boost::make_shared (newLCLHash, theApp->getOPs().getValidationTimeNC(), mValPublic, mProposing); v->setFieldU32(sfLedgerSequence, newLCL->getLedgerSeq()); + if (((newLCL->getLedgerSeq() + 1) % 256) == 0) // next ledger is flag ledger + theApp->getFeeVote().doValidation(newLCL, *v); v->sign(signingHash, mValPrivate); v->setTrusted(); theApp->isNew(signingHash); // suppress it if we receive it diff --git a/src/cpp/ripple/LedgerEntrySet.h b/src/cpp/ripple/LedgerEntrySet.h index fb9affb7a..2edeab394 100644 --- a/src/cpp/ripple/LedgerEntrySet.h +++ b/src/cpp/ripple/LedgerEntrySet.h @@ -25,8 +25,6 @@ enum TransactionEngineParams tapRETRY = 0x20, // This is not the transaction's last pass // Transaction can be retried, soft failures allowed - tapAFTER_END = 0x40, // We are processing the transaction last - tapADMIN = 0x400, // Transaction came from a privileged source }; From 8b15cb8773d81731e6627b63ba03bd4dd0263cf7 Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Tue, 23 Apr 2013 11:39:40 -0700 Subject: [PATCH 6/7] Fee space was wrong. --- src/cpp/ripple/LedgerFormats.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cpp/ripple/LedgerFormats.h b/src/cpp/ripple/LedgerFormats.h index bfc692a66..537f3f193 100644 --- a/src/cpp/ripple/LedgerFormats.h +++ b/src/cpp/ripple/LedgerFormats.h @@ -33,7 +33,7 @@ enum LedgerNameSpace spaceContract = 'c', spaceSkipList = 's', spaceFeature = 'f', - spaceFee = 's', + spaceFee = 'e', }; enum LedgerSpecificFlags From b906cebf1298be108127a5a015ad1c38ea100db2 Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Tue, 23 Apr 2013 11:48:51 -0700 Subject: [PATCH 7/7] Fee change bugfixes. --- src/cpp/ripple/Application.cpp | 4 ++-- src/cpp/ripple/ChangeTransactor.cpp | 29 +++++++++++++++++++++++------ src/cpp/ripple/ChangeTransactor.h | 3 +++ src/cpp/ripple/FeatureTable.cpp | 7 +++---- src/cpp/ripple/LedgerConsensus.cpp | 3 ++- src/cpp/ripple/Transactor.cpp | 12 ++++++++---- src/cpp/ripple/Transactor.h | 2 ++ 7 files changed, 43 insertions(+), 17 deletions(-) diff --git a/src/cpp/ripple/Application.cpp b/src/cpp/ripple/Application.cpp index 8b1d75b09..7d91b4c05 100644 --- a/src/cpp/ripple/Application.cpp +++ b/src/cpp/ripple/Application.cpp @@ -54,9 +54,9 @@ Application::Application() : mSNTPClient(mAuxService), mJobQueue(mIOService), mFeeTrack(), #ifdef RESERVE_BASE_100 - mFeeVote(10, 100, 25), + mFeeVote(10, 100 * SYSTEM_CURRENCY_PARTS, 25 * SYSTEM_CURRENCY_PARTS), #else - mFeeVote(10, 200, 50), + mFeeVote(10, 200 * SYSTEM_CURRENCY_PARTS, 50 * SYSTEM_CURRENCY_PARTS), #endif mRpcDB(NULL), mTxnDB(NULL), mLedgerDB(NULL), mWalletDB(NULL), diff --git a/src/cpp/ripple/ChangeTransactor.cpp b/src/cpp/ripple/ChangeTransactor.cpp index 0fd450ec4..30da3e1eb 100644 --- a/src/cpp/ripple/ChangeTransactor.cpp +++ b/src/cpp/ripple/ChangeTransactor.cpp @@ -43,12 +43,6 @@ TER ChangeTransactor::checkSeq() TER ChangeTransactor::payFee() { - if (isSetBit(mParams, tapOPEN_LEDGER)) - { - cLog(lsWARNING) << "Change transaction against open ledger"; - return temINVALID; - } - if (mTxn.getTransactionFee() != STAmount()) { cLog(lsWARNING) << "Change transaction with non-zero fee"; @@ -58,6 +52,25 @@ TER ChangeTransactor::payFee() return tesSUCCESS; } +TER ChangeTransactor::preCheck() +{ + mTxnAccountID = mTxn.getSourceAccount().getAccountID(); + if (mTxnAccountID.isNonZero()) + { + cLog(lsWARNING) << "applyTransaction: bad source id"; + + return temBAD_SRC_ACCOUNT; + } + + if (isSetBit(mParams, tapOPEN_LEDGER)) + { + cLog(lsWARNING) << "Change transaction against open ledger"; + return temINVALID; + } + + return tesSUCCESS; +} + TER ChangeTransactor::applyFeature() { uint256 feature = mTxn.getFieldH256(sfFeature); @@ -84,12 +97,16 @@ TER ChangeTransactor::applyFee() if (!feeObject) feeObject = mEngine->entryCreate(ltFEE_SETTINGS, Ledger::getLedgerFeeIndex()); + cLog(lsINFO) << "Previous fee object: " << feeObject->getJson(0); + feeObject->setFieldU64(sfBaseFee, mTxn.getFieldU64(sfBaseFee)); feeObject->setFieldU32(sfReferenceFeeUnits, mTxn.getFieldU32(sfReferenceFeeUnits)); feeObject->setFieldU32(sfReserveBase, mTxn.getFieldU32(sfReserveBase)); feeObject->setFieldU32(sfReserveIncrement, mTxn.getFieldU32(sfReserveIncrement)); mEngine->entryModify(feeObject); + + cLog(lsINFO) << "New fee object: " << feeObject->getJson(0); cLog(lsWARNING) << "Fees have been changed"; return tesSUCCESS; } diff --git a/src/cpp/ripple/ChangeTransactor.h b/src/cpp/ripple/ChangeTransactor.h index 6c850d5fc..28f3a1947 100644 --- a/src/cpp/ripple/ChangeTransactor.h +++ b/src/cpp/ripple/ChangeTransactor.h @@ -7,6 +7,8 @@ protected: TER applyFeature(); TER applyFee(); + bool mustHaveValidAccount() { return false; } + public: ChangeTransactor(const SerializedTransaction& txn, TransactionEngineParams params, TransactionEngine *engine) : Transactor(txn, params, engine) @@ -16,6 +18,7 @@ public: TER checkSig(); TER checkSeq(); TER payFee(); + TER preCheck(); }; // vim:ts=4 diff --git a/src/cpp/ripple/FeatureTable.cpp b/src/cpp/ripple/FeatureTable.cpp index 7154723cf..781b9165b 100644 --- a/src/cpp/ripple/FeatureTable.cpp +++ b/src/cpp/ripple/FeatureTable.cpp @@ -352,17 +352,16 @@ void FeeVote::doFeeVoting(Ledger::ref lastClosedLedger, SHAMap::ref initialPosit { cLog(lsWARNING) << "We are voting for a fee change: " << baseFee << "/" << baseReserve << "/" << incReserve; SerializedTransaction trans(ttFEE); + trans.setFieldAccount(sfAccount, uint160()); trans.setFieldU64(sfBaseFee, baseFee); trans.setFieldU32(sfReferenceFeeUnits, 10); trans.setFieldU32(sfReserveBase, baseReserve); trans.setFieldU32(sfReserveIncrement, incReserve); - + uint256 txID = trans.getTransactionID(); + cLog(lsWARNING) << "Vote: " << txID; Serializer s; - s.add32(sHP_TransactionID); trans.add(s, true); - uint256 txID = s.getSHA512Half(); - cLog(lsWARNING) << "Vote: " << txID; SHAMapItem::pointer tItem = boost::make_shared(txID, s.peekData()); if (!initialPosition->addGiveItem(tItem, true, false)) diff --git a/src/cpp/ripple/LedgerConsensus.cpp b/src/cpp/ripple/LedgerConsensus.cpp index e2021a77f..850ca21fc 100644 --- a/src/cpp/ripple/LedgerConsensus.cpp +++ b/src/cpp/ripple/LedgerConsensus.cpp @@ -319,7 +319,8 @@ void LedgerConsensus::takeInitialPosition(Ledger& initialLedger) { SHAMap::pointer initialSet; - if (mProposing && mHaveCorrectLCL && ((mPreviousLedger->getLedgerSeq() % 256) == 0)) + if ((theConfig.RUN_STANDALONE || (mProposing && mHaveCorrectLCL)) + && ((mPreviousLedger->getLedgerSeq() % 256) == 0)) { // previous ledger was flag ledger SHAMap::pointer preSet = initialLedger.peekTransactionMap()->snapShot(true); theApp->getFeeVote().doFeeVoting(mPreviousLedger, preSet); diff --git a/src/cpp/ripple/Transactor.cpp b/src/cpp/ripple/Transactor.cpp index 050ad89b2..b9068e504 100644 --- a/src/cpp/ripple/Transactor.cpp +++ b/src/cpp/ripple/Transactor.cpp @@ -204,10 +204,13 @@ TER Transactor::apply() if (!mTxnAccount) { - cLog(lsTRACE) << boost::str(boost::format("applyTransaction: Delay transaction: source account does not exist: %s") % - mTxn.getSourceAccount().humanAccountID()); + if (mustHaveValidAccount()) + { + cLog(lsTRACE) << boost::str(boost::format("applyTransaction: Delay transaction: source account does not exist: %s") % + mTxn.getSourceAccount().humanAccountID()); - return terNO_ACCOUNT; + return terNO_ACCOUNT; + } } else { @@ -225,7 +228,8 @@ TER Transactor::apply() terResult = checkSig(); if (terResult != tesSUCCESS) return(terResult); - mEngine->entryModify(mTxnAccount); + if (mTxnAccount) + mEngine->entryModify(mTxnAccount); return doApply(); } diff --git a/src/cpp/ripple/Transactor.h b/src/cpp/ripple/Transactor.h index d72bd4b74..4c50a47be 100644 --- a/src/cpp/ripple/Transactor.h +++ b/src/cpp/ripple/Transactor.h @@ -36,6 +36,8 @@ protected: Transactor(const SerializedTransaction& txn, TransactionEngineParams params, TransactionEngine* engine); + virtual bool mustHaveValidAccount() { return true; } + public: typedef boost::shared_ptr pointer;