diff --git a/newcoin.vcxproj b/newcoin.vcxproj index 273a5a4197..f168aef821 100644 --- a/newcoin.vcxproj +++ b/newcoin.vcxproj @@ -123,7 +123,6 @@ - @@ -135,7 +134,9 @@ + + @@ -274,8 +275,8 @@ Document - d:/code/protoc-2.4.1-win32/protoc -I=..\newcoin --cpp_out=D:\code\newcoin\obj\ ..\newcoin/src/ripple.proto - D:\code\newcoin\obj\src\ripple.pb.h + /code/protoc-2.4.1-win32/protoc -I=..\newcoin --cpp_out=\code\newcoin\obj\ ..\newcoin/src/ripple.proto + \code\newcoin\obj\src\ripple.pb.h diff --git a/newcoin.vcxproj.filters b/newcoin.vcxproj.filters index a404ec7bab..8aa2cf9ad0 100644 --- a/newcoin.vcxproj.filters +++ b/newcoin.vcxproj.filters @@ -99,9 +99,6 @@ Source Files - - Source Files - Source Files @@ -306,6 +303,12 @@ Source Files + + Source Files + + + Source Files + diff --git a/src/Application.cpp b/src/Application.cpp index 975b0411f0..b898cbdcc2 100644 --- a/src/Application.cpp +++ b/src/Application.cpp @@ -70,9 +70,10 @@ void Application::run() { assert(mTxnDB == NULL); if (!theConfig.DEBUG_LOGFILE.empty()) - { // Let DEBUG messages go to the file but only WARNING or higher to regular output + { // Let DEBUG messages go to the file but only WARNING or higher to regular output (unless verbose) Log::setLogFile(theConfig.DEBUG_LOGFILE); - LogPartition::setSeverity(lsDEBUG); + if (Log::getMinSeverity() > lsDEBUG) + LogPartition::setSeverity(lsDEBUG); } boost::thread auxThread(boost::bind(&boost::asio::io_service::run, &mAuxService)); diff --git a/src/Config.cpp b/src/Config.cpp index 12eac48859..2faed71d30 100644 --- a/src/Config.cpp +++ b/src/Config.cpp @@ -35,9 +35,9 @@ #define SECTION_VALIDATORS "validators" #define SECTION_VALIDATORS_SITE "validators_site" -// Fees are in XNB. -#define DEFAULT_FEE_DEFAULT 100 -#define DEFAULT_FEE_ACCOUNT_CREATE 1000 +// Fees are in XNS. +#define DEFAULT_FEE_DEFAULT 10 +#define DEFAULT_FEE_ACCOUNT_CREATE 1000*SYSTEM_CURRENCY_PARTS #define DEFAULT_FEE_NICKNAME_CREATE 1000 #define DEFAULT_FEE_OFFER DEFAULT_FEE_DEFAULT #define DEFAULT_FEE_OPERATION 1 @@ -234,7 +234,14 @@ void Config::load() WEBSOCKET_PORT = boost::lexical_cast(strTemp); if (sectionSingleB(secConfig, SECTION_VALIDATION_SEED, strTemp)) + { VALIDATION_SEED.setSeedGeneric(strTemp); + if (VALIDATION_SEED.isValid()) + { + VALIDATION_PUB = RippleAddress::createNodePublic(VALIDATION_SEED); + VALIDATION_PRIV = RippleAddress::createNodePrivate(VALIDATION_SEED); + } + } (void) sectionSingleB(secConfig, SECTION_PEER_SSL_CIPHER_LIST, PEER_SSL_CIPHER_LIST); diff --git a/src/Config.h b/src/Config.h index ae9cc73d1d..2bc0662e5f 100644 --- a/src/Config.h +++ b/src/Config.h @@ -93,7 +93,7 @@ public: bool RPC_ALLOW_REMOTE; // Validation - RippleAddress VALIDATION_SEED; + RippleAddress VALIDATION_SEED, VALIDATION_PUB, VALIDATION_PRIV; // Fees uint64 FEE_DEFAULT; // Default fee. diff --git a/src/FieldNames.cpp b/src/FieldNames.cpp index 2f84ec7abc..67695731d8 100644 --- a/src/FieldNames.cpp +++ b/src/FieldNames.cpp @@ -26,6 +26,31 @@ SField sfIndex(STI_HASH256, 258, "index"); #undef FIELD #undef TYPE +static int initFields() +{ + sfHighQualityIn.setMeta(SFM_CHANGE); sfHighQualityOut.setMeta(SFM_CHANGE); + sfLowQualityIn.setMeta(SFM_CHANGE); sfLowQualityOut.setMeta(SFM_CHANGE); + + sfLowLimit.setMeta(SFM_ALWAYS); sfHighLimit.setMeta(SFM_ALWAYS); + sfTakerPays.setMeta(SFM_ALWAYS); sfTakerGets.setMeta(SFM_ALWAYS); + sfQualityIn.setMeta(SFM_ALWAYS); sfQualityOut.setMeta(SFM_ALWAYS); + + sfBalance.setMeta(SFM_ALWAYS); + + sfPublicKey.setMeta(SFM_CHANGE); sfMessageKey.setMeta(SFM_CHANGE); + sfSigningPubKey.setMeta(SFM_CHANGE); sfAuthorizedKey.setMeta(SFM_CHANGE); + sfSigningAccounts.setMeta(SFM_CHANGE); + + sfWalletLocator.setMeta(SFM_CHANGE); + sfNickname.setMeta(SFM_CHANGE); + sfAmount.setMeta(SFM_ALWAYS); + sfDomain.setMeta(SFM_CHANGE); + sfOwner.setMeta(SFM_ALWAYS); + + return 0; +} +static const int f = initFields(); + SField::SField(SerializedTypeID tid, int fv) : fieldCode(FIELD_CODE(tid, fv)), fieldType(tid), fieldValue(fv) { // call with the map mutex diff --git a/src/FieldNames.h b/src/FieldNames.h index 3a09f67a47..cdb11ad6b7 100644 --- a/src/FieldNames.h +++ b/src/FieldNames.h @@ -33,6 +33,14 @@ enum SOE_Flags SOE_OPTIONAL = 1, // optional }; +enum SF_Meta +{ + SFM_NEVER = 0, + SFM_CHANGE = 1, + SFM_DELETE = 2, + SFM_ALWAYS = 3 +}; + class SField { public: @@ -51,16 +59,17 @@ public: const SerializedTypeID fieldType; // STI_* const int fieldValue; // Code number for protocol std::string fieldName; + SF_Meta fieldMeta; SField(int fc, SerializedTypeID tid, int fv, const char* fn) : - fieldCode(fc), fieldType(tid), fieldValue(fv), fieldName(fn) + fieldCode(fc), fieldType(tid), fieldValue(fv), fieldName(fn), fieldMeta(SFM_NEVER) { boost::mutex::scoped_lock sl(mapMutex); codeToField[fieldCode] = this; } SField(SerializedTypeID tid, int fv, const char *fn) : - fieldCode(FIELD_CODE(tid, fv)), fieldType(tid), fieldValue(fv), fieldName(fn) + fieldCode(FIELD_CODE(tid, fv)), fieldType(tid), fieldValue(fv), fieldName(fn), fieldMeta(SFM_NEVER) { boost::mutex::scoped_lock sl(mapMutex); codeToField[fieldCode] = this; @@ -84,6 +93,11 @@ public: bool isBinary() const { return fieldValue < 256; } bool isDiscardable() const { return fieldValue > 256; } + SF_Meta getMeta() const { return fieldMeta; } + bool shouldMetaDel() const { return (fieldMeta == SFM_DELETE) || (fieldMeta == SFM_ALWAYS); } + bool shouldMetaMod() const { return (fieldMeta == SFM_CHANGE) || (fieldMeta == SFM_ALWAYS); } + void setMeta(SF_Meta m) { fieldMeta = m; } + bool operator==(const SField& f) const { return fieldCode == f.fieldCode; } bool operator!=(const SField& f) const { return fieldCode != f.fieldCode; } diff --git a/src/HashedObject.cpp b/src/HashedObject.cpp index 34874e9917..537270336c 100644 --- a/src/HashedObject.cpp +++ b/src/HashedObject.cpp @@ -59,15 +59,15 @@ void HashedObjectStore::waitWrite() void HashedObjectStore::bulkWrite() { - std::vector< boost::shared_ptr > set; while (1) { - set.clear(); + std::vector< boost::shared_ptr > set; set.reserve(128); { boost::unique_lock sl(mWriteMutex); mWriteSet.swap(set); + assert(mWriteSet.empty()); if (set.empty()) { mWritePending = false; diff --git a/src/Ledger.cpp b/src/Ledger.cpp index 4cdc152d19..af61e7993b 100644 --- a/src/Ledger.cpp +++ b/src/Ledger.cpp @@ -339,7 +339,7 @@ uint256 Ledger::getHash() void Ledger::saveAcceptedLedger(bool fromConsensus) { // can be called in a different thread - cLog(lsTRACE) << "saveAcceptedLedger " << (fromConsensus ? "fromConsensus" : "fromAcquire") << getLedgerSeq(); + cLog(lsTRACE) << "saveAcceptedLedger " << (fromConsensus ? "fromConsensus " : "fromAcquire ") << getLedgerSeq(); static boost::format ledgerExists("SELECT LedgerSeq FROM Ledgers where LedgerSeq = %d;"); static boost::format deleteLedger("DELETE FROM Ledgers WHERE LedgerSeq = %d;"); static boost::format AcctTransExists("SELECT LedgerSeq FROM AccountTransactions WHERE TransId = '%s';"); @@ -432,9 +432,10 @@ void Ledger::saveAcceptedLedger(bool fromConsensus) if (!fromConsensus) return; + theApp->getMasterLedger().setFullLedger(shared_from_this()); + theApp->getOPs().pubLedger(shared_from_this()); - theApp->getMasterLedger().setFullLedger(shared_from_this()); } Ledger::pointer Ledger::getSQL(const std::string& sql) diff --git a/src/LedgerAcquire.cpp b/src/LedgerAcquire.cpp index f3bdaea9b3..6559ce7157 100644 --- a/src/LedgerAcquire.cpp +++ b/src/LedgerAcquire.cpp @@ -12,7 +12,7 @@ SETUP_LOG(); -// #define LA_DEBUG +#define LA_DEBUG #define LEDGER_ACQUIRE_TIMEOUT 750 #define TRUST_NETWORK @@ -74,7 +74,7 @@ void PeerSet::invokeOnTimer() if (!mProgress) { ++mTimeouts; - cLog(lsWARNING) << "Timeout " << mTimeouts << " acquiring " << mHash; + cLog(lsWARNING) << "Timeout(" << mTimeouts << ") pc=" << mPeers.size() << " acquiring " << mHash; } else mProgress = false; @@ -144,7 +144,8 @@ void LedgerAcquire::onTimer() setFailed(); done(); } - else trigger(Peer::pointer(), true); + else + trigger(Peer::pointer(), true); } boost::weak_ptr LedgerAcquire::pmDowncast() diff --git a/src/LedgerConsensus.cpp b/src/LedgerConsensus.cpp index 0b83ee3b2d..e0917da0ed 100644 --- a/src/LedgerConsensus.cpp +++ b/src/LedgerConsensus.cpp @@ -84,8 +84,8 @@ void TransactionAcquire::trigger(Peer::ref peer, bool timer) ripple::TMGetLedger tmGL; tmGL.set_ledgerhash(mHash.begin(), mHash.size()); tmGL.set_itype(ripple::liTS_CANDIDATE); - for (std::vector::iterator it = nodeIDs.begin(); it != nodeIDs.end(); ++it) - *(tmGL.add_nodeids()) = it->getRawString(); + BOOST_FOREACH(SHAMapNode& it, nodeIDs) + *(tmGL.add_nodeids()) = it.getRawString(); sendRequest(tmGL, peer); } } @@ -222,7 +222,8 @@ bool LCTransaction::updateVote(int percentTime, bool proposing) LedgerConsensus::LedgerConsensus(const uint256& prevLCLHash, Ledger::ref previousLedger, uint32 closeTime) : mState(lcsPRE_CLOSE), mCloseTime(closeTime), mPrevLedgerHash(prevLCLHash), mPreviousLedger(previousLedger), - mValSeed(theConfig.VALIDATION_SEED), mCurrentMSeconds(0), mClosePercent(0), mHaveCloseTimeConsensus(false), + mValPublic(theConfig.VALIDATION_PUB), mValPrivate(theConfig.VALIDATION_PRIV), + mCurrentMSeconds(0), mClosePercent(0), mHaveCloseTimeConsensus(false), mConsensusStartTime(boost::posix_time::microsec_clock::universal_time()) { cLog(lsDEBUG) << "Creating consensus object"; @@ -234,12 +235,11 @@ LedgerConsensus::LedgerConsensus(const uint256& prevLCLHash, Ledger::ref previou mCloseResolution = ContinuousLedgerTiming::getNextLedgerTimeResolution( mPreviousLedger->getCloseResolution(), mPreviousLedger->getCloseAgree(), previousLedger->getLedgerSeq() + 1); - if (mValSeed.isValid()) + if (mValPublic.isValid() && mValPrivate.isValid()) { cLog(lsINFO) << "Entering consensus process, validating"; mValidating = true; mProposing = theApp->getOPs().getOperatingMode() == NetworkOPs::omFULL; - mValPublic = RippleAddress::createNodePublic(mValSeed); } else { @@ -380,7 +380,7 @@ void LedgerConsensus::takeInitialPosition(Ledger& initialLedger) if (mValidating) mOurPosition = boost::make_shared - (mValSeed, initialLedger.getParentHash(), txSet, mCloseTime); + (mValPublic, mValPrivate, initialLedger.getParentHash(), txSet, mCloseTime); else mOurPosition = boost::make_shared(initialLedger.getParentHash(), txSet, mCloseTime); @@ -410,17 +410,19 @@ void LedgerConsensus::createDisputes(SHAMap::ref m1, SHAMap::ref m2) { SHAMap::SHAMapDiff differences; m1->compare(m2, differences, 16384); - for (SHAMap::SHAMapDiff::iterator pos = differences.begin(), end = differences.end(); pos != end; ++pos) + + typedef std::pair u256_diff_pair; + BOOST_FOREACH (u256_diff_pair& pos, differences) { // create disputed transactions (from the ledger that has them) - if (pos->second.first) + if (pos.second.first) { // transaction is in first map - assert(!pos->second.second); - addDisputedTransaction(pos->first, pos->second.first->peekData()); + assert(!pos.second.second); + addDisputedTransaction(pos.first, pos.second.first->peekData()); } - else if (pos->second.second) + else if (pos.second.second) { // transaction is in second map - assert(!pos->second.first); - addDisputedTransaction(pos->first, pos->second.second->peekData()); + assert(!pos.second.first); + addDisputedTransaction(pos.first, pos.second.second->peekData()); } else // No other disagreement over a transaction should be possible assert(false); @@ -1141,7 +1143,8 @@ void LedgerConsensus::accept(SHAMap::ref set) { uint256 signingHash; SerializedValidation::pointer v = boost::make_shared - (newLCLHash, theApp->getOPs().getValidationTimeNC(), mValSeed, mProposing, boost::ref(signingHash)); + (newLCLHash, theApp->getOPs().getValidationTimeNC(), mValPublic, mValPrivate, + mProposing, boost::ref(signingHash)); v->setTrusted(); theApp->isNew(signingHash); // suppress it if we receive it theApp->getValidations().addValidation(v); diff --git a/src/LedgerConsensus.h b/src/LedgerConsensus.h index 4b3e87e068..38a2dde9f2 100644 --- a/src/LedgerConsensus.h +++ b/src/LedgerConsensus.h @@ -87,7 +87,7 @@ protected: Ledger::pointer mPreviousLedger; LedgerAcquire::pointer mAcquiringLedger; LedgerProposal::pointer mOurPosition; - RippleAddress mValSeed, mValPublic; + RippleAddress mValPublic, mValPrivate; bool mProposing, mValidating, mHaveCorrectLCL; int mCurrentMSeconds, mClosePercent, mCloseResolution; diff --git a/src/LedgerEntrySet.cpp b/src/LedgerEntrySet.cpp index 5cbca45df0..2e1fd606a8 100644 --- a/src/LedgerEntrySet.cpp +++ b/src/LedgerEntrySet.cpp @@ -319,9 +319,11 @@ bool LedgerEntrySet::threadTx(SLE::ref threadTo, Ledger::ref ledger, uint32 prevLgrID; if (!threadTo->thread(mSet.getTxID(), mSet.getLgrSeq(), prevTxID, prevLgrID)) return false; - if (TransactionMetaSet::thread(mSet.getAffectedNode(threadTo->getIndex(), sfModifiedNode), + + if (prevTxID.isZero() || TransactionMetaSet::thread(mSet.getAffectedNode(threadTo->getIndex(), sfModifiedNode), prevTxID, prevLgrID)) return true; + assert(false); return false; } @@ -403,34 +405,26 @@ void LedgerEntrySet::calcRawMeta(Serializer& s, TER result) assert(origNode); threadOwners(origNode, mLedger, newMod); - if (origNode->isFieldPresent(sfAmount)) - { // node has an amount, covers ripple state nodes - STAmount amount = origNode->getFieldAmount(sfAmount); - if (amount.isNonZero()) - mSet.getAffectedNode(it.first).setFieldAmount(sfPreviousBalance, amount); - amount = curNode->getFieldAmount(sfAmount); - if (amount.isNonZero()) - mSet.getAffectedNode(it.first).setFieldAmount(sfFinalBalance, amount); - - if (origNode->getType() == ltRIPPLE_STATE) - { - mSet.getAffectedNode(it.first).setFieldAccount(sfLowID, - RippleAddress::createAccountID(origNode->getFieldAmount(sfLowLimit).getIssuer())); - mSet.getAffectedNode(it.first).setFieldAccount(sfHighID, - RippleAddress::createAccountID(origNode->getFieldAmount(sfHighLimit).getIssuer())); - } + STObject finals(sfFinalFields); + BOOST_FOREACH(const SerializedType& obj, *curNode) + { // search the deleted node for values saved on delete + if (obj.getFName().shouldMetaDel() && !obj.isDefault()) + finals.addObject(obj); } + if (!finals.empty()) + mSet.getAffectedNode(it.first, *type).addObject(finals); + } - if (origNode->getType() == ltOFFER) - { // check for non-zero balances - STAmount amount = origNode->getFieldAmount(sfTakerPays); - if (amount.isNonZero()) - mSet.getAffectedNode(it.first).setFieldAmount(sfFinalTakerPays, amount); - amount = origNode->getFieldAmount(sfTakerGets); - if (amount.isNonZero()) - mSet.getAffectedNode(it.first).setFieldAmount(sfFinalTakerGets, amount); + if ((type == &sfDeletedNode || type == &sfModifiedNode)) + { + STObject mods(sfPreviousFields); + BOOST_FOREACH(const SerializedType& obj, *origNode) + { // search the original node for values saved on modify + if (obj.getFName().shouldMetaMod() && !obj.isDefault() && !curNode->hasMatchingEntry(obj)) + mods.addObject(obj); } - + if (!mods.empty()) + mSet.getAffectedNode(it.first, *type).addObject(mods); } if (type == &sfCreatedNode) // if created, thread to owner(s) @@ -444,28 +438,6 @@ void LedgerEntrySet::calcRawMeta(Serializer& s, TER result) if (curNode->isThreadedType()) // always thread to self threadTx(curNode, mLedger, newMod); } - - if (type == &sfModifiedNode) - { - assert(origNode); - if (origNode->isFieldPresent(sfAmount)) - { // node has an amount, covers account root nodes and ripple nodes - STAmount amount = origNode->getFieldAmount(sfAmount); - if (amount != curNode->getFieldAmount(sfAmount)) - mSet.getAffectedNode(it.first).setFieldAmount(sfPreviousBalance, amount); - } - - if (origNode->getType() == ltOFFER) - { - STAmount amount = origNode->getFieldAmount(sfTakerPays); - if (amount != curNode->getFieldAmount(sfTakerPays)) - mSet.getAffectedNode(it.first).setFieldAmount(sfPreviousTakerPays, amount); - amount = origNode->getFieldAmount(sfTakerGets); - if (amount != curNode->getFieldAmount(sfTakerGets)) - mSet.getAffectedNode(it.first).setFieldAmount(sfPreviousTakerGets, amount); - } - - } } // add any new modified nodes to the modification set @@ -473,9 +445,7 @@ void LedgerEntrySet::calcRawMeta(Serializer& s, TER result) it != end; ++it) entryModify(it->second); -#ifdef META_DEBUG - cLog(lsINFO) << "Metadata:" << mSet.getJson(0); -#endif + cLog(lsTRACE) << "Metadata:" << mSet.getJson(0); mSet.addRaw(s, result); } diff --git a/src/LedgerFormats.cpp b/src/LedgerFormats.cpp index c696d72ed2..c187286cd0 100644 --- a/src/LedgerFormats.cpp +++ b/src/LedgerFormats.cpp @@ -4,10 +4,10 @@ std::map LedgerEntryFormat::byType; std::map LedgerEntryFormat::byName; -#define LEF_BASE \ - << SOElement(sfLedgerIndex, SOE_OPTIONAL) \ - << SOElement(sfLedgerEntryType, SOE_REQUIRED) \ - << SOElement(sfFlags, SOE_REQUIRED) +#define LEF_BASE \ + << SOElement(sfLedgerIndex, SOE_OPTIONAL) \ + << SOElement(sfLedgerEntryType, SOE_REQUIRED) \ + << SOElement(sfFlags, SOE_REQUIRED) #define DECLARE_LEF(name, type) lef = new LedgerEntryFormat(#name, type); (*lef) LEF_BASE @@ -16,74 +16,74 @@ static bool LEFInit() LedgerEntryFormat* lef; DECLARE_LEF(AccountRoot, ltACCOUNT_ROOT) - << SOElement(sfAccount, SOE_REQUIRED) - << SOElement(sfSequence, SOE_REQUIRED) - << SOElement(sfBalance, SOE_REQUIRED) - << SOElement(sfLastTxnID, SOE_REQUIRED) - << SOElement(sfLastTxnSeq, SOE_REQUIRED) - << SOElement(sfAuthorizedKey, SOE_OPTIONAL) - << SOElement(sfEmailHash, SOE_OPTIONAL) - << SOElement(sfWalletLocator, SOE_OPTIONAL) - << SOElement(sfMessageKey, SOE_OPTIONAL) - << SOElement(sfTransferRate, SOE_OPTIONAL) - << SOElement(sfDomain, SOE_OPTIONAL) - << SOElement(sfPublishHash, SOE_OPTIONAL) - << SOElement(sfPublishSize, SOE_OPTIONAL) + << SOElement(sfAccount, SOE_REQUIRED) + << SOElement(sfSequence, SOE_REQUIRED) + << SOElement(sfBalance, SOE_REQUIRED) + << SOElement(sfPreviousTxnID, SOE_REQUIRED) + << SOElement(sfPreviousTxnLgrSeq, SOE_REQUIRED) + << SOElement(sfAuthorizedKey, SOE_OPTIONAL) + << SOElement(sfEmailHash, SOE_OPTIONAL) + << SOElement(sfWalletLocator, SOE_OPTIONAL) + << SOElement(sfMessageKey, SOE_OPTIONAL) + << SOElement(sfTransferRate, SOE_OPTIONAL) + << SOElement(sfDomain, SOE_OPTIONAL) + << SOElement(sfPublishHash, SOE_OPTIONAL) + << SOElement(sfPublishSize, SOE_OPTIONAL) ; DECLARE_LEF(Contract, ltCONTRACT) - << SOElement(sfAccount, SOE_REQUIRED) - << SOElement(sfBalance, SOE_REQUIRED) - << SOElement(sfLastTxnID, SOE_REQUIRED) - << SOElement(sfLastTxnSeq, SOE_REQUIRED) - << SOElement(sfIssuer, SOE_REQUIRED) - << SOElement(sfOwner, SOE_REQUIRED) - << SOElement(sfExpiration, SOE_REQUIRED) - << SOElement(sfBondAmount, SOE_REQUIRED) - << SOElement(sfCreateCode, SOE_REQUIRED) - << SOElement(sfFundCode, SOE_REQUIRED) - << SOElement(sfRemoveCode, SOE_REQUIRED) - << SOElement(sfExpireCode, SOE_REQUIRED) + << SOElement(sfAccount, SOE_REQUIRED) + << SOElement(sfBalance, SOE_REQUIRED) + << SOElement(sfPreviousTxnID, SOE_REQUIRED) + << SOElement(sfPreviousTxnLgrSeq, SOE_REQUIRED) + << SOElement(sfIssuer, SOE_REQUIRED) + << SOElement(sfOwner, SOE_REQUIRED) + << SOElement(sfExpiration, SOE_REQUIRED) + << SOElement(sfBondAmount, SOE_REQUIRED) + << SOElement(sfCreateCode, SOE_REQUIRED) + << SOElement(sfFundCode, SOE_REQUIRED) + << SOElement(sfRemoveCode, SOE_REQUIRED) + << SOElement(sfExpireCode, SOE_REQUIRED) ; DECLARE_LEF(DirectoryNode, ltDIR_NODE) - << SOElement(sfIndexes, SOE_REQUIRED) - << SOElement(sfIndexNext, SOE_OPTIONAL) - << SOElement(sfIndexPrevious, SOE_OPTIONAL) + << SOElement(sfIndexes, SOE_REQUIRED) + << SOElement(sfIndexNext, SOE_OPTIONAL) + << SOElement(sfIndexPrevious, SOE_OPTIONAL) ; DECLARE_LEF(GeneratorMap, ltGENERATOR_MAP) - << SOElement(sfGenerator, SOE_REQUIRED) + << SOElement(sfGenerator, SOE_REQUIRED) ; DECLARE_LEF(Nickname, ltNICKNAME) - << SOElement(sfAccount, SOE_REQUIRED) - << SOElement(sfMinimumOffer, SOE_OPTIONAL) + << SOElement(sfAccount, SOE_REQUIRED) + << SOElement(sfMinimumOffer, SOE_OPTIONAL) ; DECLARE_LEF(Offer, ltOFFER) - << SOElement(sfAccount, SOE_REQUIRED) - << SOElement(sfSequence, SOE_REQUIRED) - << SOElement(sfTakerPays, SOE_REQUIRED) - << SOElement(sfTakerGets, SOE_REQUIRED) - << SOElement(sfBookDirectory, SOE_REQUIRED) - << SOElement(sfBookNode, SOE_REQUIRED) - << SOElement(sfOwnerNode, SOE_REQUIRED) - << SOElement(sfLastTxnID, SOE_REQUIRED) - << SOElement(sfLastTxnSeq, SOE_REQUIRED) - << SOElement(sfExpiration, SOE_OPTIONAL) + << SOElement(sfAccount, SOE_REQUIRED) + << SOElement(sfSequence, SOE_REQUIRED) + << SOElement(sfTakerPays, SOE_REQUIRED) + << SOElement(sfTakerGets, SOE_REQUIRED) + << SOElement(sfBookDirectory, SOE_REQUIRED) + << SOElement(sfBookNode, SOE_REQUIRED) + << SOElement(sfOwnerNode, SOE_REQUIRED) + << SOElement(sfPreviousTxnID, SOE_REQUIRED) + << SOElement(sfPreviousTxnLgrSeq, SOE_REQUIRED) + << SOElement(sfExpiration, SOE_OPTIONAL) ; DECLARE_LEF(RippleState, ltRIPPLE_STATE) - << SOElement(sfBalance, SOE_REQUIRED) - << SOElement(sfLowLimit, SOE_REQUIRED) - << SOElement(sfHighLimit, SOE_REQUIRED) - << SOElement(sfLastTxnID, SOE_REQUIRED) - << SOElement(sfLastTxnSeq, SOE_REQUIRED) - << SOElement(sfLowQualityIn, SOE_OPTIONAL) - << SOElement(sfLowQualityOut, SOE_OPTIONAL) - << SOElement(sfHighQualityIn, SOE_OPTIONAL) - << SOElement(sfHighQualityOut, SOE_OPTIONAL) + << SOElement(sfBalance, SOE_REQUIRED) + << SOElement(sfLowLimit, SOE_REQUIRED) + << SOElement(sfHighLimit, SOE_REQUIRED) + << SOElement(sfPreviousTxnID, SOE_REQUIRED) + << SOElement(sfPreviousTxnLgrSeq, SOE_REQUIRED) + << SOElement(sfLowQualityIn, SOE_OPTIONAL) + << SOElement(sfLowQualityOut, SOE_OPTIONAL) + << SOElement(sfHighQualityIn, SOE_OPTIONAL) + << SOElement(sfHighQualityOut, SOE_OPTIONAL) ; return true; diff --git a/src/LedgerHistory.cpp b/src/LedgerHistory.cpp index c0149431b5..45ccaad465 100644 --- a/src/LedgerHistory.cpp +++ b/src/LedgerHistory.cpp @@ -50,7 +50,8 @@ Ledger::pointer LedgerHistory::getLedgerBySeq(uint32 index) sl.unlock(); Ledger::pointer ret(Ledger::loadByIndex(index)); - if (!ret) return ret; + if (!ret) + return ret; assert(ret->getLedgerSeq() == index); sl.lock(); diff --git a/src/LedgerMaster.cpp b/src/LedgerMaster.cpp index 2619c893ee..872be89203 100644 --- a/src/LedgerMaster.cpp +++ b/src/LedgerMaster.cpp @@ -98,6 +98,11 @@ TER LedgerMaster::doTransaction(const SerializedTransaction& txn, TransactionEng void LedgerMaster::acquireMissingLedger(const uint256& ledgerHash, uint32 ledgerSeq) { mMissingLedger = theApp->getMasterLedgerAcquire().findCreate(ledgerHash); + if (mMissingLedger->isComplete()) + { + mMissingLedger = LedgerAcquire::pointer(); + return; + } mMissingSeq = ledgerSeq; if (mMissingLedger->setAccept()) mMissingLedger->addOnComplete(boost::bind(&LedgerMaster::missingAcquireComplete, this, _1)); @@ -107,20 +112,20 @@ void LedgerMaster::missingAcquireComplete(LedgerAcquire::pointer acq) { boost::recursive_mutex::scoped_lock ml(mLock); - if (acq->isFailed()) + if (acq->isFailed() && (mMissingSeq != 0)) { - if (mMissingSeq != 0) - { - cLog(lsWARNING) << "Acquire failed, invalidating following ledger " << mMissingSeq + 1; - mCompleteLedgers.clearValue(mMissingSeq + 1); - } + cLog(lsWARNING) << "Acquire failed for " << mMissingSeq; } mMissingLedger = LedgerAcquire::pointer(); mMissingSeq = 0; if (!acq->isFailed()) + { + boost::thread thread(boost::bind(&Ledger::saveAcceptedLedger, acq->getLedger(), false)); + thread.detach(); setFullLedger(acq->getLedger()); + } } void LedgerMaster::setFullLedger(Ledger::ref ledger) @@ -139,6 +144,9 @@ void LedgerMaster::setFullLedger(Ledger::ref ledger) } } + if (mMissingLedger && mMissingLedger->isComplete()) + mMissingLedger = LedgerAcquire::pointer(); + if (mMissingLedger || !theConfig.FULL_HISTORY) return; @@ -154,11 +162,15 @@ void LedgerMaster::setFullLedger(Ledger::ref ledger) if (prevMissing != RangeSet::RangeSetAbsent) { cLog(lsINFO) << "Ledger " << prevMissing << " is missing"; - Ledger::pointer nextLedger = getLedgerBySeq(prevMissing); + assert(!mCompleteLedgers.hasValue(prevMissing)); + Ledger::pointer nextLedger = getLedgerBySeq(prevMissing + 1); if (nextLedger) acquireMissingLedger(nextLedger->getParentHash(), nextLedger->getLedgerSeq() - 1); else - cLog(lsWARNING) << "We have a ledger gap we can't quite fix"; + { + mCompleteLedgers.clearValue(prevMissing); + cLog(lsWARNING) << "We have a gap we can't fix: " << prevMissing + 1; + } } } } diff --git a/src/LedgerMaster.h b/src/LedgerMaster.h index bccf9c2ed0..278b256239 100644 --- a/src/LedgerMaster.h +++ b/src/LedgerMaster.h @@ -62,6 +62,8 @@ public: void switchLedgers(Ledger::ref lastClosed, Ledger::ref newCurrent); + std::string getCompleteLedgers() { return mCompleteLedgers.toString(); } + Ledger::pointer closeLedger(); Ledger::pointer getLedgerBySeq(uint32 index) diff --git a/src/LedgerProposal.cpp b/src/LedgerProposal.cpp index 4cc9a52efa..775f7b93dd 100644 --- a/src/LedgerProposal.cpp +++ b/src/LedgerProposal.cpp @@ -20,12 +20,11 @@ LedgerProposal::LedgerProposal(const uint256& pLgr, uint32 seq, const uint256& t } -LedgerProposal::LedgerProposal(const RippleAddress& naSeed, const uint256& prevLgr, - const uint256& position, uint32 closeTime) : +LedgerProposal::LedgerProposal(const RippleAddress& naPub, const RippleAddress& naPriv, + const uint256& prevLgr, const uint256& position, uint32 closeTime) : mPreviousLedger(prevLgr), mCurrentHash(position), mCloseTime(closeTime), mProposeSeq(0), - mPublicKey(RippleAddress::createNodePublic(naSeed)), - mPrivateKey(RippleAddress::createNodePrivate(naSeed)) -{ + mPublicKey(naPub), mPrivateKey(naPriv) +{ // OPTIMIZEME: This is expensive. We create both the public and private keys separately each time mPeerID = mPublicKey.getNodeID(); mTime = boost::posix_time::second_clock::universal_time(); } diff --git a/src/LedgerProposal.h b/src/LedgerProposal.h index 34ff239b75..4119a444d6 100644 --- a/src/LedgerProposal.h +++ b/src/LedgerProposal.h @@ -35,8 +35,8 @@ public: uint32 closeTime, const RippleAddress& naPeerPublic); // our first proposal - LedgerProposal(const RippleAddress& privKey, const uint256& prevLedger, const uint256& position, - uint32 closeTime); + LedgerProposal(const RippleAddress& pubKey, const RippleAddress& privKey, + const uint256& prevLedger, const uint256& position, uint32 closeTime); // an unsigned "dummy" proposal for nodes not validating LedgerProposal(const uint256& prevLedger, const uint256& position, uint32 closeTime); diff --git a/src/NetworkOPs.cpp b/src/NetworkOPs.cpp index 4a9b0046d1..b3ee6079bd 100644 --- a/src/NetworkOPs.cpp +++ b/src/NetworkOPs.cpp @@ -678,7 +678,7 @@ bool NetworkOPs::haveConsensusObject() bool ledgerChange = checkLastClosedLedger(peerList, networkClosed); if (!ledgerChange) { - cLog(lsWARNING) << "Beginning consensus due to peer action"; + cLog(lsINFO) << "Beginning consensus due to peer action"; beginConsensus(networkClosed, mLedgerMaster->getCurrentLedger()); } return mConsensus; @@ -881,14 +881,16 @@ Json::Value NetworkOPs::getServerInfo() default: info["serverState"] = "unknown"; } - if (!theConfig.VALIDATION_SEED.isValid()) + if (!theConfig.VALIDATION_PUB.isValid()) info["serverState"] = "none"; else - info["validationPKey"] = RippleAddress::createNodePublic(theConfig.VALIDATION_SEED).humanNodePublic(); + info["validationPKey"] = theConfig.VALIDATION_PUB.humanNodePublic(); if (mNeedNetworkLedger) info["networkLedger"] = "waiting"; + info["completeLedgers"] = theApp->getMasterLedger().getCompleteLedgers(); + Json::Value lastClose = Json::objectValue; lastClose["proposers"] = theApp->getOPs().getPreviousProposers(); lastClose["convergeTime"] = theApp->getOPs().getPreviousConvergeTime(); diff --git a/src/Peer.cpp b/src/Peer.cpp index 9c5664ed32..8dd7a5c8c6 100644 --- a/src/Peer.cpp +++ b/src/Peer.cpp @@ -384,7 +384,8 @@ void Peer::processReadBuffer() ripple::TMHello msg; if (msg.ParseFromArray(&mReadbuf[HEADER_SIZE], mReadbuf.size() - HEADER_SIZE)) recvHello(msg); - else std::cerr << "parse error: " << type << std::endl; + else + cLog(lsWARNING) << "parse error: " << type; } break; @@ -393,7 +394,8 @@ void Peer::processReadBuffer() ripple::TMErrorMsg msg; if (msg.ParseFromArray(&mReadbuf[HEADER_SIZE], mReadbuf.size() - HEADER_SIZE)) recvErrorMessage(msg); - else std::cerr << "parse error: " << type << std::endl; + else + cLog(lsWARNING) << "parse error: " << type; } break; @@ -402,7 +404,8 @@ void Peer::processReadBuffer() ripple::TMPing msg; if (msg.ParseFromArray(&mReadbuf[HEADER_SIZE], mReadbuf.size() - HEADER_SIZE)) recvPing(msg); - else std::cerr << "parse error: " << type << std::endl; + else + cLog(lsWARNING) << "parse error: " << type; } break; @@ -411,7 +414,8 @@ void Peer::processReadBuffer() ripple::TMGetContacts msg; if (msg.ParseFromArray(&mReadbuf[HEADER_SIZE], mReadbuf.size() - HEADER_SIZE)) recvGetContacts(msg); - else std::cerr << "parse error: " << type << std::endl; + else + cLog(lsWARNING) << "parse error: " << type; } break; @@ -420,7 +424,8 @@ void Peer::processReadBuffer() ripple::TMContact msg; if (msg.ParseFromArray(&mReadbuf[HEADER_SIZE], mReadbuf.size() - HEADER_SIZE)) recvContact(msg); - else std::cerr << "parse error: " << type << std::endl; + else + cLog(lsWARNING) << "parse error: " << type; } break; case ripple::mtGET_PEERS: @@ -428,7 +433,8 @@ void Peer::processReadBuffer() ripple::TMGetPeers msg; if (msg.ParseFromArray(&mReadbuf[HEADER_SIZE], mReadbuf.size() - HEADER_SIZE)) recvGetPeers(msg); - else std::cerr << "parse error: " << type << std::endl; + else + cLog(lsWARNING) << "parse error: " << type; } break; case ripple::mtPEERS: @@ -436,7 +442,8 @@ void Peer::processReadBuffer() ripple::TMPeers msg; if (msg.ParseFromArray(&mReadbuf[HEADER_SIZE], mReadbuf.size() - HEADER_SIZE)) recvPeers(msg); - else std::cerr << "parse error: " << type << std::endl; + else + cLog(lsWARNING) << "parse error: " << type; } break; @@ -445,7 +452,8 @@ void Peer::processReadBuffer() ripple::TMSearchTransaction msg; if (msg.ParseFromArray(&mReadbuf[HEADER_SIZE], mReadbuf.size() - HEADER_SIZE)) recvSearchTransaction(msg); - else std::cerr << "parse error: " << type << std::endl; + else + cLog(lsWARNING) << "parse error: " << type; } break; @@ -454,7 +462,8 @@ void Peer::processReadBuffer() ripple::TMGetAccount msg; if (msg.ParseFromArray(&mReadbuf[HEADER_SIZE], mReadbuf.size() - HEADER_SIZE)) recvGetAccount(msg); - else std::cerr << "parse error: " << type << std::endl; + else + cLog(lsWARNING) << "parse error: " << type; } break; @@ -463,7 +472,8 @@ void Peer::processReadBuffer() ripple::TMAccount msg; if (msg.ParseFromArray(&mReadbuf[HEADER_SIZE], mReadbuf.size() - HEADER_SIZE)) recvAccount(msg); - else std::cerr << "parse error: " << type << std::endl; + else + cLog(lsWARNING) << "parse error: " << type; } break; @@ -472,7 +482,8 @@ void Peer::processReadBuffer() ripple::TMTransaction msg; if (msg.ParseFromArray(&mReadbuf[HEADER_SIZE], mReadbuf.size() - HEADER_SIZE)) recvTransaction(msg); - else std::cerr << "parse error: " << type << std::endl; + else + cLog(lsWARNING) << "parse error: " << type; } break; @@ -481,7 +492,8 @@ void Peer::processReadBuffer() ripple::TMStatusChange msg; if (msg.ParseFromArray(&mReadbuf[HEADER_SIZE], mReadbuf.size() - HEADER_SIZE)) recvStatus(msg); - else std::cerr << "parse error: " << type << std::endl; + else + cLog(lsWARNING) << "parse error: " << type; } break; @@ -490,7 +502,8 @@ void Peer::processReadBuffer() ripple::TMProposeSet msg; if (msg.ParseFromArray(&mReadbuf[HEADER_SIZE], mReadbuf.size() - HEADER_SIZE)) recvPropose(msg); - else std::cerr << "parse error: " << type << std::endl; + else + cLog(lsWARNING) << "parse error: " << type; } break; @@ -499,7 +512,8 @@ void Peer::processReadBuffer() ripple::TMGetLedger msg; if (msg.ParseFromArray(&mReadbuf[HEADER_SIZE], mReadbuf.size() - HEADER_SIZE)) recvGetLedger(msg); - else std::cerr << "parse error: " << type << std::endl; + else + cLog(lsWARNING) << "parse error: " << type; } break; @@ -508,7 +522,8 @@ void Peer::processReadBuffer() ripple::TMLedgerData msg; if (msg.ParseFromArray(&mReadbuf[HEADER_SIZE], mReadbuf.size() - HEADER_SIZE)) recvLedger(msg); - else std::cerr << "parse error: " << type << std::endl; + else + cLog(lsWARNING) << "parse error: " << type; } break; @@ -517,7 +532,8 @@ void Peer::processReadBuffer() ripple::TMHaveTransactionSet msg; if (msg.ParseFromArray(&mReadbuf[HEADER_SIZE], mReadbuf.size() - HEADER_SIZE)) recvHaveTxSet(msg); - else std::cerr << "parse error: " << type << std::endl; + else + cLog(lsWARNING) << "parse error: " << type; } break; @@ -526,7 +542,8 @@ void Peer::processReadBuffer() ripple::TMValidation msg; if (msg.ParseFromArray(&mReadbuf[HEADER_SIZE], mReadbuf.size() - HEADER_SIZE)) recvValidation(msg); - else std::cerr << "parse error: " << type << std::endl; + else + cLog(lsWARNING) << "parse error: " << type; } break; #if 0 @@ -535,7 +552,8 @@ void Peer::processReadBuffer() ripple::TM msg; if (msg.ParseFromArray(&mReadbuf[HEADER_SIZE], mReadbuf.size() - HEADER_SIZE)) recv(msg); - else std::cerr << "parse error: " << type << std::endl; + else + cLog(lsWARNING) << "parse error: " << type; } break; @@ -545,13 +563,14 @@ void Peer::processReadBuffer() ripple::TMGetObjectByHash msg; if (msg.ParseFromArray(&mReadbuf[HEADER_SIZE], mReadbuf.size() - HEADER_SIZE)) recvGetObjectByHash(msg); - else std::cerr << "parse error: " << type << std::endl; + else + cLog(lsWARNING) << "parse error: " << type; } break; default: - std::cerr << "Unknown Msg: " << type << std::endl; - std::cerr << strHex(&mReadbuf[0], mReadbuf.size()); + cLog(lsWARNING) << "Unknown Msg: " << type; + cLog(lsWARNING) << strHex(&mReadbuf[0], mReadbuf.size()); } } } @@ -669,9 +688,7 @@ void Peer::recvHello(ripple::TMHello& packet) void Peer::recvTransaction(ripple::TMTransaction& packet) { -#ifdef DEBUG - std::cerr << "Got transaction from peer" << std::endl; -#endif + cLog(lsDEBUG) << "Got transaction from peer"; Transaction::pointer tx; #ifndef TRUST_NETWORK @@ -758,6 +775,9 @@ void Peer::recvValidation(ripple::TMValidation& packet) return; } +// OPTIMIZEME: Should just defer validation checking to another thread +// checking the signature is expensive (but should do 'isNew' check here) + #ifndef TRUST_NETWORK try #endif diff --git a/src/RPCHandler.cpp b/src/RPCHandler.cpp index f08fa0d8c5..c6c8e9dba7 100644 --- a/src/RPCHandler.cpp +++ b/src/RPCHandler.cpp @@ -2063,14 +2063,20 @@ Json::Value RPCHandler::doValidationSeed(const Json::Value& params) { std::cerr << "Unset validation seed." << std::endl; theConfig.VALIDATION_SEED.clear(); + theConfig.VALIDATION_PUB.clear(); + theConfig.VALIDATION_PRIV.clear(); } else if (!theConfig.VALIDATION_SEED.setSeedGeneric(params[0u].asString())) { + theConfig.VALIDATION_PUB.clear(); + theConfig.VALIDATION_PRIV.clear(); return rpcError(rpcBAD_SEED); } else { - obj["validation_public_key"] = RippleAddress::createNodePublic(theConfig.VALIDATION_SEED).humanNodePublic(); + theConfig.VALIDATION_PUB = RippleAddress::createNodePublic(theConfig.VALIDATION_SEED); + theConfig.VALIDATION_PRIV = RippleAddress::createNodePrivate(theConfig.VALIDATION_SEED); + obj["validation_public_key"] = theConfig.VALIDATION_PUB.humanNodePublic(); obj["validation_seed"] = theConfig.VALIDATION_SEED.humanSeed(); obj["validation_key"] = theConfig.VALIDATION_SEED.humanSeed1751(); } @@ -2606,9 +2612,9 @@ Json::Value RPCHandler::doLogLevel(const Json::Value& params) ret["base"] = Log::severityToString(Log::getMinSeverity()); std::vector< std::pair > logTable = LogPartition::getSeverities(); - for (std::vector< std::pair >::iterator it = logTable.begin(); - it != logTable.end(); ++it) - ret[it->first] = it->second; + typedef std::pair stringPair; + BOOST_FOREACH(const stringPair& it, logTable) + ret[it.first] = it.second; return ret; } diff --git a/src/RPCServer.cpp b/src/RPCServer.cpp index 541d1b6b1e..01568d9996 100644 --- a/src/RPCServer.cpp +++ b/src/RPCServer.cpp @@ -115,7 +115,7 @@ void RPCServer::handle_read_line(const boost::system::error_code& e) std::string RPCServer::handleRequest(const std::string& requestStr) { - std::cout << "handleRequest " << requestStr << std::endl; + cLog(lsTRACE) << "handleRequest " << requestStr; Json::Value id; // Parse request diff --git a/src/RangeSet.cpp b/src/RangeSet.cpp index fe218df391..e9c4b38f9a 100644 --- a/src/RangeSet.cpp +++ b/src/RangeSet.cpp @@ -54,15 +54,18 @@ uint32 RangeSet::getPrev(uint32 v) const uint32 RangeSet::prevMissing(uint32 v) const { // largest number not in the set that is less than the given number + cLog(lsTRACE) << "prevMissing(" << v << ") " << toString(); for (const_reverse_iterator it = rbegin(); it != rend(); ++it) { - if (lower(it) <= v) - { - if (upper(it) < v) - return upper(it) + 1; + if ((upper(it) + 1) < v) + return upper(it) + 1; + if (lower(it) == 0) + return RangeSetAbsent; + if ((lower(it) - 1) < v) return lower(it) - 1; - } } + if (v > 0) + return v - 1; return RangeSetAbsent; } diff --git a/src/RippleAddress.cpp b/src/RippleAddress.cpp index 03abd40529..46d769d302 100644 --- a/src/RippleAddress.cpp +++ b/src/RippleAddress.cpp @@ -1,17 +1,24 @@ #include "RippleAddress.h" + +#include +#include +#include + +#include +#include +#include + +#include + #include "key.h" #include "Config.h" #include "BitcoinUtil.h" #include "rfc1751.h" #include "utils.h" +#include "Log.h" + +SETUP_LOG(); -#include -#include -#include -#include -#include -#include -#include RippleAddress::RippleAddress() { @@ -402,7 +409,7 @@ bool RippleAddress::accountPublicVerify(const uint256& uHash, const std::vector< if (!ckPublic.SetPubKey(getAccountPublic())) { // Bad private key. - std::cerr << "accountPublicVerify: Bad private key." << std::endl; + cLog(lsWARNING) << "accountPublicVerify: Bad private key."; bVerified = false; } else @@ -497,14 +504,13 @@ bool RippleAddress::accountPrivateSign(const uint256& uHash, std::vector RippleAddress::accountPrivateEncrypt(const RippleAddr if (!ckPublic.SetPubKey(naPublicTo.getAccountPublic())) { // Bad public key. - std::cerr << "accountPrivateEncrypt: Bad public key." << std::endl; + cLog(lsWARNING) << "accountPrivateEncrypt: Bad public key."; } else if (!ckPrivate.SetPrivateKeyU(getAccountPrivate())) { // Bad private key. - std::cerr << "accountPrivateEncrypt: Bad private key." << std::endl; + cLog(lsWARNING) << "accountPrivateEncrypt: Bad private key."; } else { - try { + try + { vucCipherText = ckPrivate.encryptECIES(ckPublic, vucPlainText); } catch (...) @@ -570,12 +577,12 @@ std::vector RippleAddress::accountPrivateDecrypt(const RippleAddr if (!ckPublic.SetPubKey(naPublicFrom.getAccountPublic())) { // Bad public key. - std::cerr << "accountPrivateDecrypt: Bad public key." << std::endl; + cLog(lsWARNING) << "accountPrivateDecrypt: Bad public key."; } else if (!ckPrivate.SetPrivateKeyU(getAccountPrivate())) { // Bad private key. - std::cerr << "accountPrivateDecrypt: Bad private key." << std::endl; + cLog(lsWARNING) << "accountPrivateDecrypt: Bad private key."; } else { diff --git a/src/SHAMap.cpp b/src/SHAMap.cpp index 85bbf3a61d..b7a775778a 100644 --- a/src/SHAMap.cpp +++ b/src/SHAMap.cpp @@ -123,12 +123,12 @@ void SHAMap::dirtyUp(std::stack& stack, const uint256& if (!node->setChildHash(branch, prevHash)) { - std::cerr << "dirtyUp terminates early" << std::endl; + cLog(lsFATAL) << "dirtyUp terminates early"; assert(false); return; } #ifdef ST_DEBUG - std::cerr << "dirtyUp sets branch " << branch << " to " << prevHash << std::endl; + cLog(lsTRACE) << "dirtyUp sets branch " << branch << " to " << prevHash; #endif prevHash = node->getNodeHash(); assert(prevHash.isNonZero()); diff --git a/src/SHAMap.h b/src/SHAMap.h index 6973f6ce3d..107d3d8b65 100644 --- a/src/SHAMap.h +++ b/src/SHAMap.h @@ -282,7 +282,8 @@ public: typedef boost::shared_ptr pointer; typedef const boost::shared_ptr& ref; - typedef std::map > SHAMapDiff; + typedef std::pair SHAMapDiffItem; + typedef std::map SHAMapDiff; typedef boost::unordered_map SHADirtyMap; private: diff --git a/src/SNTPClient.cpp b/src/SNTPClient.cpp index cdafc0698f..d9663d134b 100644 --- a/src/SNTPClient.cpp +++ b/src/SNTPClient.cpp @@ -2,6 +2,7 @@ #include #include +#include #include @@ -200,9 +201,8 @@ void SNTPClient::init(const std::vector& servers) Log(lsINFO) << "SNTP: no server specified"; return; } - do - addServer(*it++); - while (it != servers.end()); + BOOST_FOREACH(const std::string& it, servers) + addServer(it); queryAll(); } diff --git a/src/SerializeProto.h b/src/SerializeProto.h index 1a7b676412..2fa8dbf007 100644 --- a/src/SerializeProto.h +++ b/src/SerializeProto.h @@ -35,7 +35,7 @@ FIELD(Flags, UINT32, 2) FIELD(SourceTag, UINT32, 3) FIELD(Sequence, UINT32, 4) - FIELD(LastTxnSeq, UINT32, 5) + FIELD(PreviousTxnLgrSeq, UINT32, 5) FIELD(LedgerSequence, UINT32, 6) FIELD(CloseTime, UINT32, 7) FIELD(ParentCloseTime, UINT32, 8) @@ -71,7 +71,7 @@ FIELD(ParentHash, HASH256, 2) FIELD(TransactionHash, HASH256, 3) FIELD(AccountHash, HASH256, 4) - FIELD(LastTxnID, HASH256, 5) + FIELD(PreviousTxnID, HASH256, 5) FIELD(LedgerIndex, HASH256, 6) FIELD(WalletLocator, HASH256, 7) FIELD(PublishHash, HASH256, 8) @@ -95,12 +95,6 @@ // currency amount (uncommon) FIELD(MinimumOffer, AMOUNT, 16) FIELD(RippleEscrow, AMOUNT, 17) - FIELD(PreviousBalance, AMOUNT, 18) - FIELD(FinalBalance, AMOUNT, 19) - FIELD(PreviousTakerPays, AMOUNT, 20) - FIELD(PreviousTakerGets, AMOUNT, 21) - FIELD(FinalTakerPays, AMOUNT, 22) - FIELD(FinalTakerGets, AMOUNT, 23) // variable length FIELD(PublicKey, VL, 1) @@ -123,11 +117,6 @@ FIELD(Target, ACCOUNT, 7) FIELD(AuthorizedKey, ACCOUNT, 8) - // account (uncommon) - FIELD(PreviousAccount, ACCOUNT, 16) - FIELD(LowID, ACCOUNT, 17) - FIELD(HighID, ACCOUNT, 18) - // path set FIELD(Paths, PATHSET, 1) @@ -141,6 +130,8 @@ FIELD(CreatedNode, OBJECT, 3) FIELD(DeletedNode, OBJECT, 4) FIELD(ModifiedNode, OBJECT, 5) + FIELD(PreviousFields, OBJECT, 6) + FIELD(FinalFields, OBJECT, 7) // array of objects // ARRAY/1 is reserved for end of array diff --git a/src/SerializedLedger.cpp b/src/SerializedLedger.cpp index 0e22a190ec..359a93fa58 100644 --- a/src/SerializedLedger.cpp +++ b/src/SerializedLedger.cpp @@ -75,37 +75,37 @@ Json::Value SerializedLedgerEntry::getJson(int options) const bool SerializedLedgerEntry::isThreadedType() { - return getFieldIndex(sfLastTxnID) != -1; + return getFieldIndex(sfPreviousTxnID) != -1; } bool SerializedLedgerEntry::isThreaded() { - return isFieldPresent(sfLastTxnID); + return isFieldPresent(sfPreviousTxnID); } uint256 SerializedLedgerEntry::getThreadedTransaction() { - return getFieldH256(sfLastTxnID); + return getFieldH256(sfPreviousTxnID); } uint32 SerializedLedgerEntry::getThreadedLedger() { - return getFieldU32(sfLastTxnSeq); + return getFieldU32(sfPreviousTxnLgrSeq); } bool SerializedLedgerEntry::thread(const uint256& txID, uint32 ledgerSeq, uint256& prevTxID, uint32& prevLedgerID) { - uint256 oldPrevTxID = getFieldH256(sfLastTxnID); + uint256 oldPrevTxID = getFieldH256(sfPreviousTxnID); Log(lsTRACE) << "Thread Tx:" << txID << " prev:" << oldPrevTxID; if (oldPrevTxID == txID) { // this transaction is already threaded - assert(getFieldU32(sfLastTxnSeq) == ledgerSeq); + assert(getFieldU32(sfPreviousTxnLgrSeq) == ledgerSeq); return false; } prevTxID = oldPrevTxID; - prevLedgerID = getFieldU32(sfLastTxnSeq); - setFieldH256(sfLastTxnID, txID); - setFieldU32(sfLastTxnSeq, ledgerSeq); + prevLedgerID = getFieldU32(sfPreviousTxnLgrSeq); + setFieldH256(sfPreviousTxnID, txID); + setFieldU32(sfPreviousTxnLgrSeq, ledgerSeq); return true; } diff --git a/src/SerializedObject.cpp b/src/SerializedObject.cpp index 1dfe373dd5..1477a23937 100644 --- a/src/SerializedObject.cpp +++ b/src/SerializedObject.cpp @@ -206,6 +206,8 @@ bool STObject::isValidForType() bool STObject::isFieldAllowed(SField::ref field) { + if (isFree()) + return true; BOOST_FOREACH(SOElement::ptr elem, mType) { // are any required elemnents missing if (elem->e_field == field) @@ -242,6 +244,14 @@ std::auto_ptr STObject::deserialize(SerializerIterator& sit, SFi return object; } +bool STObject::hasMatchingEntry(const SerializedType& t) +{ + const SerializedType* o = peekAtPField(t.getFName()); + if (!o) + return false; + return t == *o; +} + std::string STObject::getFullText() const { std::string ret; @@ -565,7 +575,8 @@ uint160 STObject::getFieldH160(SField::ref field) const uint256 STObject::getFieldH256(SField::ref field) const { const SerializedType* rf = peekAtPField(field); - if (!rf) throw std::runtime_error("Field not found"); + if (!rf) + throw std::runtime_error("Field not found"); SerializedTypeID id = rf->getSType(); if (id == STI_NOTPRESENT) return uint256(); // optional field not present const STHash256 *cf = dynamic_cast(rf); @@ -577,17 +588,12 @@ RippleAddress STObject::getFieldAccount(SField::ref field) const { const SerializedType* rf = peekAtPField(field); if (!rf) - { -#ifdef DEBUG - std::cerr << "Account field not found" << std::endl; - std::cerr << getFullText() << std::endl; -#endif throw std::runtime_error("Field not found"); - } SerializedTypeID id = rf->getSType(); if (id == STI_NOTPRESENT) return RippleAddress(); // optional field not present const STAccount* cf = dynamic_cast(rf); - if (!cf) throw std::runtime_error("Wrong field type"); + if (!cf) + throw std::runtime_error("Wrong field type"); return cf->getValueNCA(); } @@ -596,18 +602,13 @@ uint160 STObject::getFieldAccount160(SField::ref field) const uint160 a; const SerializedType* rf = peekAtPField(field); if (!rf) - { -#ifdef DEBUG - std::cerr << "Account field not found" << std::endl; - std::cerr << getFullText() << std::endl; -#endif throw std::runtime_error("Field not found"); - } SerializedTypeID id = rf->getSType(); if (id != STI_NOTPRESENT) { const STAccount* cf = dynamic_cast(rf); - if (!cf) throw std::runtime_error("Wrong field type"); + if (!cf) + throw std::runtime_error("Wrong field type"); cf->getValueH160(a); } return a; diff --git a/src/SerializedObject.h b/src/SerializedObject.h index 02587d36bd..00c89ed1eb 100644 --- a/src/SerializedObject.h +++ b/src/SerializedObject.h @@ -58,6 +58,7 @@ public: virtual SerializedTypeID getSType() const { return STI_OBJECT; } virtual bool isEquivalent(const SerializedType& t) const; + virtual bool isDefault() const { return mData.empty(); } virtual void add(Serializer& s) const { add(s, true); } // just inner elements void add(Serializer& s, bool withSignature) const; @@ -156,6 +157,9 @@ public: iterator end() { return mData.end(); } const_iterator begin() const { return mData.begin(); } const_iterator end() const { return mData.end(); } + bool empty() const { return mData.empty(); } + + bool hasMatchingEntry(const SerializedType&); bool operator==(const STObject& o) const; bool operator!=(const STObject& o) const { return ! (*this == o); } @@ -238,6 +242,7 @@ public: virtual SerializedTypeID getSType() const { return STI_ARRAY; } virtual bool isEquivalent(const SerializedType& t) const; + virtual bool isDefault() const { return value.empty(); } }; inline STArray::iterator range_begin(STArray& x) { return x.begin(); } diff --git a/src/SerializedTransaction.cpp b/src/SerializedTransaction.cpp index 34df4f863f..d6b7a02916 100644 --- a/src/SerializedTransaction.cpp +++ b/src/SerializedTransaction.cpp @@ -77,10 +77,9 @@ std::vector SerializedTransaction::getAffectedAccounts() const { bool found = false; RippleAddress na = sa->getValueNCA(); - for (std::vector::iterator it = accounts.begin(), end = accounts.end(); - it != end; ++it) + BOOST_FOREACH(const RippleAddress& it, accounts) { - if (*it == na) + if (it == na) { found = true; break; diff --git a/src/SerializedTypes.h b/src/SerializedTypes.h index f54c377cfd..62f7347c85 100644 --- a/src/SerializedTypes.h +++ b/src/SerializedTypes.h @@ -72,6 +72,8 @@ public: { return (getSType() == t.getSType()) && isEquivalent(t); } bool operator!=(const SerializedType& t) const { return (getSType() != t.getSType()) || !isEquivalent(t); } + + virtual bool isDefault() const { return true; } }; inline SerializedType* new_clone(const SerializedType& s) { return s.clone().release(); } @@ -103,6 +105,7 @@ public: operator unsigned char() const { return value; } virtual bool isEquivalent(const SerializedType& t) const; + virtual bool isDefault() const { return value == 0; } }; class STUInt16 : public SerializedType @@ -130,6 +133,7 @@ public: operator uint16() const { return value; } virtual bool isEquivalent(const SerializedType& t) const; + virtual bool isDefault() const { return value == 0; } }; class STUInt32 : public SerializedType @@ -157,6 +161,7 @@ public: operator uint32() const { return value; } virtual bool isEquivalent(const SerializedType& t) const; + virtual bool isDefault() const { return value == 0; } }; class STUInt64 : public SerializedType @@ -184,6 +189,7 @@ public: operator uint64() const { return value; } virtual bool isEquivalent(const SerializedType& t) const; + virtual bool isDefault() const { return value == 0; } }; class STAmount : public SerializedType @@ -300,6 +306,7 @@ public: void setValue(const STAmount &); virtual bool isEquivalent(const SerializedType& t) const; + virtual bool isDefault() const { return mValue == 0 && mIssuer.isZero() && mCurrency.isZero(); } bool operator==(const STAmount&) const; bool operator!=(const STAmount&) const; @@ -403,6 +410,7 @@ public: operator uint128() const { return value; } virtual bool isEquivalent(const SerializedType& t) const; + virtual bool isDefault() const { return value.isZero(); } }; class STHash160 : public SerializedType @@ -433,6 +441,7 @@ public: operator uint160() const { return value; } virtual bool isEquivalent(const SerializedType& t) const; + virtual bool isDefault() const { return value.isZero(); } }; class STHash256 : public SerializedType @@ -463,6 +472,7 @@ public: operator uint256() const { return value; } virtual bool isEquivalent(const SerializedType& t) const; + virtual bool isDefault() const { return value.isZero(); } }; class STVariableLength : public SerializedType @@ -494,6 +504,7 @@ public: operator std::vector() const { return value; } virtual bool isEquivalent(const SerializedType& t) const; + virtual bool isDefault() const { return value.empty(); } }; class STAccount : public STVariableLength @@ -673,6 +684,7 @@ public: void addPath(const STPath& e) { value.push_back(e); } virtual bool isEquivalent(const SerializedType& t) const; + virtual bool isDefault() const { return value.empty(); } void printDebug(); @@ -740,6 +752,7 @@ public: const std::vector& peekValue() const { return mValue; } std::vector& peekValue() { return mValue; } virtual bool isEquivalent(const SerializedType& t) const; + virtual bool isDefault() const { return mValue.empty(); } std::vector getValue() const { return mValue; } bool isEmpty() const { return mValue.empty(); } diff --git a/src/SerializedValidation.cpp b/src/SerializedValidation.cpp index cc643b5cca..313577a2c4 100644 --- a/src/SerializedValidation.cpp +++ b/src/SerializedValidation.cpp @@ -37,24 +37,22 @@ SerializedValidation::SerializedValidation(SerializerIterator& sit, bool checkSi } SerializedValidation::SerializedValidation(const uint256& ledgerHash, uint32 signTime, - const RippleAddress& naSeed, bool isFull, uint256& signingHash) + const RippleAddress& naPub, const RippleAddress& naPriv, bool isFull, uint256& signingHash) : STObject(sValidationFormat, sfValidation), mTrusted(false) { setFieldH256(sfLedgerHash, ledgerHash); setFieldU32(sfSigningTime, signTime); - if (naSeed.isValid()) - { - RippleAddress np = RippleAddress::createNodePublic(naSeed); - setFieldVL(sfSigningPubKey, np.getNodePublic()); - mNodeID = np.getNodeID(); - assert(mNodeID.isNonZero()); - } + + setFieldVL(sfSigningPubKey, naPub.getNodePublic()); + mNodeID = naPub.getNodeID(); + assert(mNodeID.isNonZero()); + if (!isFull) setFlag(sFullFlag); signingHash = getSigningHash(); std::vector signature; - RippleAddress::createNodePrivate(naSeed).signNodePrivate(signingHash, signature); + naPriv.signNodePrivate(signingHash, signature); setFieldVL(sfSignature, signature); // XXX Check if this can fail. // if (!RippleAddress::createNodePrivate(naSeed).signNodePrivate(getSigningHash(), mSignature.peekValue())) diff --git a/src/SerializedValidation.h b/src/SerializedValidation.h index 61808c2f1b..eae4dffad8 100644 --- a/src/SerializedValidation.h +++ b/src/SerializedValidation.h @@ -21,8 +21,8 @@ public: // These throw if the object is not valid SerializedValidation(SerializerIterator& sit, bool checkSignature = true); - SerializedValidation(const uint256& ledgerHash, uint32 signTime, const RippleAddress& naSeed, bool isFull, - uint256& signingHash); + SerializedValidation(const uint256& ledgerHash, uint32 signTime, const RippleAddress& naPub, + const RippleAddress& naPriv, bool isFull, uint256& signingHash); uint256 getLedgerHash() const; uint32 getSignTime() const; diff --git a/src/Serializer.cpp b/src/Serializer.cpp index efce6138c2..8b67d3b657 100644 --- a/src/Serializer.cpp +++ b/src/Serializer.cpp @@ -7,6 +7,7 @@ #include #include +#include #include "key.h" #include "Log.h" @@ -376,11 +377,13 @@ int Serializer::addTaggedList(const std::list& list) if (size > 255) return -1; int ret = add8(size); if (size != 0) - for (std::list::const_iterator it = list.begin(); it != list.end(); ++it) + { + BOOST_FOREACH(const TaggedListItem& it, list) { - add8(it->first); - addVL(it->second); + add8(it.first); + addVL(it.second); } + } return ret; } @@ -390,11 +393,13 @@ int Serializer::addTaggedList(const std::vector& list) if (size > 255) return -1; int ret = add8(size); if (size != 0) - for (std::vector::const_iterator it = list.begin(); it != list.end(); ++it) + { + BOOST_FOREACH(const TaggedListItem& it, list) { - add8(it->first); - addVL(it->second); + add8(it.first); + addVL(it.second); } + } return ret; } @@ -404,8 +409,10 @@ int Serializer::getTaggedListLength(const std::list& list) if (size > 255) return -1; int ret = 1; if (size != 0) - for (std::list::const_iterator it = list.begin(); it != list.end(); ++it) - ret += 1 + it->second.size() + Serializer::encodeLengthLength(it->second.size()); + { + BOOST_FOREACH(const TaggedListItem& it, list) + ret += 1 + it.second.size() + Serializer::encodeLengthLength(it.second.size()); + } return ret; } @@ -415,8 +422,10 @@ int Serializer::getTaggedListLength(const std::vector& list) if (size > 255) return -1; int ret = 1; if (size != 0) - for (std::vector::const_iterator it = list.begin(); it != list.end(); ++it) - ret += 1 + it->second.size() + Serializer::encodeLengthLength(it->second.size()); + { + BOOST_FOREACH(const TaggedListItem& it, list) + ret += 1 + it.second.size() + Serializer::encodeLengthLength(it.second.size()); + } return ret; } diff --git a/src/Transaction.cpp b/src/Transaction.cpp index a9f8be1a23..2fca627427 100644 --- a/src/Transaction.cpp +++ b/src/Transaction.cpp @@ -705,7 +705,7 @@ bool Transaction::convertToTransactions(uint32 firstLedgerSeq, uint32 secondLedg std::map >& outMap) { // convert a straight SHAMap payload difference to a transaction difference table // return value: true=ledgers are valid, false=a ledger is invalid - std::map >::const_iterator it; + SHAMap::SHAMapDiff::const_iterator it; for(it = inMap.begin(); it != inMap.end(); ++it) { const uint256& id = it->first; diff --git a/src/TransactionMeta.cpp b/src/TransactionMeta.cpp index 2a504247c3..f8fdff08df 100644 --- a/src/TransactionMeta.cpp +++ b/src/TransactionMeta.cpp @@ -101,15 +101,15 @@ void TransactionMetaSet::swap(TransactionMetaSet& s) bool TransactionMetaSet::thread(STObject& node, const uint256& prevTxID, uint32 prevLgrID) { - if (node.getFieldIndex(sfLastTxnID) == -1) + if (node.getFieldIndex(sfPreviousTxnID) == -1) { - assert(node.getFieldIndex(sfLastTxnSeq) == -1); - node.setFieldH256(sfLastTxnID, prevTxID); - node.setFieldU32(sfLastTxnSeq, prevLgrID); + assert(node.getFieldIndex(sfPreviousTxnLgrSeq) == -1); + node.setFieldH256(sfPreviousTxnID, prevTxID); + node.setFieldU32(sfPreviousTxnLgrSeq, prevLgrID); return true; } - assert(node.getFieldH256(sfLastTxnID) == prevTxID); - assert(node.getFieldU32(sfLastTxnSeq) == prevLgrID); + assert(node.getFieldH256(sfPreviousTxnID) == prevTxID); + assert(node.getFieldU32(sfPreviousTxnLgrSeq) == prevLgrID); return false; }