From 3e4cf426bde10589858de0d080c2710221e755c1 Mon Sep 17 00:00:00 2001 From: Mark Travis Date: Fri, 30 May 2014 09:27:01 +0000 Subject: [PATCH 01/10] Detect paths with illegal bridging offers --- src/ripple_app/paths/PathState.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/ripple_app/paths/PathState.cpp b/src/ripple_app/paths/PathState.cpp index b44111c75..358a99256 100644 --- a/src/ripple_app/paths/PathState.cpp +++ b/src/ripple_app/paths/PathState.cpp @@ -356,13 +356,19 @@ TER PathState::pushNode ( if (!!pnCur.uCurrencyID != !!pnCur.uIssuerID) { - WriteLog (lsDEBUG, RippleCalc) << "pushNode: currency is inconsistent with issuer."; - + WriteLog (lsDEBUG, RippleCalc) << + "pushNode: currency is inconsistent with issuer."; terResult = temBAD_PATH; } - else if (!!pnPrv.uAccountID) + else if (pnPrv.uCurrencyID == pnCur.uCurrencyID && + pnPrv.uIssuerID == pnCur.uIssuerID) + { + WriteLog (lsDEBUG, RippleCalc) << + "pushNode: bad path: offer to same currency and issuer"; + terResult = temBAD_PATH; + } + else { - // Previous is an account. WriteLog (lsTRACE, RippleCalc) << "pushNode: imply for offer."; // Insert intermediary issuer account if needed. From e70d618affb6d239836e98b222931895a9876b7f Mon Sep 17 00:00:00 2001 From: Mark Travis Date: Sun, 1 Jun 2014 22:51:13 +0000 Subject: [PATCH 02/10] Set version to 0.25.2-rc1 --- Builds/rpm/rippled.spec | 2 +- src/ripple_data/protocol/BuildInfo.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Builds/rpm/rippled.spec b/Builds/rpm/rippled.spec index a77b6656c..00afa5dda 100644 --- a/Builds/rpm/rippled.spec +++ b/Builds/rpm/rippled.spec @@ -1,5 +1,5 @@ Name: rippled -Version: 0.25.1 +Version: 0.25.2-rc1 Release: 1%{?dist} Summary: Ripple peer-to-peer network daemon diff --git a/src/ripple_data/protocol/BuildInfo.cpp b/src/ripple_data/protocol/BuildInfo.cpp index d099f52b4..e9841bee3 100644 --- a/src/ripple_data/protocol/BuildInfo.cpp +++ b/src/ripple_data/protocol/BuildInfo.cpp @@ -31,7 +31,7 @@ char const* BuildInfo::getRawVersionString () // // The build version number (edit this for each release) // - "0.25.1" + "0.25.2-rc1" // // Must follow the format described here: // From d06092212f830da4f8758f96f72c611fd1630de6 Mon Sep 17 00:00:00 2001 From: David Schwartz Date: Fri, 20 Jun 2014 09:53:19 -0700 Subject: [PATCH 03/10] Tighten up some serialization checks --- src/ripple_app/tx/TransactionMeta.cpp | 2 +- src/ripple_data/protocol/FieldNames.cpp | 7 +++--- src/ripple_data/protocol/FieldNames.h | 6 ++++- src/ripple_data/protocol/STParsedJSON.cpp | 2 +- src/ripple_data/protocol/SerializedObject.cpp | 24 +++++++++++++++++++ src/ripple_data/protocol/SerializedTypes.cpp | 4 ++++ src/ripple_data/protocol/SerializedTypes.h | 20 +++++++++++++++- 7 files changed, 58 insertions(+), 7 deletions(-) diff --git a/src/ripple_app/tx/TransactionMeta.cpp b/src/ripple_app/tx/TransactionMeta.cpp index ceab83338..f5cf4e60b 100644 --- a/src/ripple_app/tx/TransactionMeta.cpp +++ b/src/ripple_app/tx/TransactionMeta.cpp @@ -29,7 +29,7 @@ TransactionMetaSet::TransactionMetaSet (uint256 const& txid, std::uint32_t ledge Serializer s (vec); SerializerIterator sit (s); - std::unique_ptr pobj = STObject::deserialize (sit, sfAffectedNodes); + std::unique_ptr pobj = STObject::deserialize (sit, sfMetadata); STObject* obj = static_cast (pobj.get ()); if (!obj) diff --git a/src/ripple_data/protocol/FieldNames.cpp b/src/ripple_data/protocol/FieldNames.cpp index 864aab9a1..88d083b7d 100644 --- a/src/ripple_data/protocol/FieldNames.cpp +++ b/src/ripple_data/protocol/FieldNames.cpp @@ -32,9 +32,10 @@ SField::StaticLockType& SField::getMutex () } SField sfInvalid (-1), sfGeneric (0); -SField sfLedgerEntry (STI_LEDGERENTRY, 1, "LedgerEntry"); -SField sfTransaction (STI_TRANSACTION, 1, "Transaction"); -SField sfValidation (STI_VALIDATION, 1, "Validation"); +SField sfLedgerEntry (STI_LEDGERENTRY, 257, "LedgerEntry"); +SField sfTransaction (STI_TRANSACTION, 257, "Transaction"); +SField sfValidation (STI_VALIDATION, 257, "Validation"); +SField sfMetadata (STI_METADATA, 257, "Metadata"); SField sfHash (STI_HASH256, 257, "hash"); SField sfIndex (STI_HASH256, 258, "index"); diff --git a/src/ripple_data/protocol/FieldNames.h b/src/ripple_data/protocol/FieldNames.h index 858cb01e1..550c21afc 100644 --- a/src/ripple_data/protocol/FieldNames.h +++ b/src/ripple_data/protocol/FieldNames.h @@ -39,9 +39,11 @@ enum SerializedTypeID #undef FIELD // high level types + // cannot be serialized inside other types STI_TRANSACTION = 10001, STI_LEDGERENTRY = 10002, STI_VALIDATION = 10003, + STI_METADATA = 10004, }; /** Identifies fields. @@ -239,7 +241,9 @@ protected: SField (SerializedTypeID id, int val); }; -extern SField sfInvalid, sfGeneric, sfLedgerEntry, sfTransaction, sfValidation; +extern SField + sfInvalid, sfGeneric, + sfLedgerEntry, sfTransaction, sfValidation, sfMetadata; #define FIELD(name, type, index) extern SField sf##name; #define TYPE(name, type, index) diff --git a/src/ripple_data/protocol/STParsedJSON.cpp b/src/ripple_data/protocol/STParsedJSON.cpp index b014354b6..78fde9b60 100644 --- a/src/ripple_data/protocol/STParsedJSON.cpp +++ b/src/ripple_data/protocol/STParsedJSON.cpp @@ -705,7 +705,7 @@ bool STParsedJSON::parse (std::string const& json_name, "[" << i << "]." << objectName; bool const success (parse (ss.str (), objectFields, nameField, depth + 1, sub_object_)); - if (! success) + if (! success || (sub_object_->getFName().fieldType != STI_OBJECT)) return false; } tail->push_back (*sub_object_); diff --git a/src/ripple_data/protocol/SerializedObject.cpp b/src/ripple_data/protocol/SerializedObject.cpp index 7ae1fdd5c..ab3ac609f 100644 --- a/src/ripple_data/protocol/SerializedObject.cpp +++ b/src/ripple_data/protocol/SerializedObject.cpp @@ -277,6 +277,12 @@ bool STObject::set (SerializerIterator& sit, int depth) reachedEndOfObject = (type == STI_OBJECT) && (field == 1); + if ((type == STI_ARRAY) && (field == 1)) + { + WriteLog (lsWARNING, STObject) << "Encountered object with end of array marker"; + throw std::runtime_error ("Illegal terminator in object"); + } + if (!reachedEndOfObject) { // Figure out the field @@ -361,6 +367,12 @@ void STObject::add (Serializer& s, bool withSigningFields) const // insert them in sorted order const SerializedType* field = it.second; + // When we serialize an object inside another object, + // the type associated by rule with this field name + // must be OBJECT, or the object cannot be deserialized + assert ((field->getSType() != STI_OBJECT) || + (field->getFName().fieldType == STI_OBJECT)); + field->addFieldID (s); field->add (s); @@ -1233,6 +1245,12 @@ STArray* STArray::construct (SerializerIterator& sit, SField::ref field) if ((type == STI_ARRAY) && (field == 1)) break; + if ((type == STI_OBJECT) && (field == 1)) + { + WriteLog (lsWARNING, STObject) << "Encountered array with end of object marker"; + throw std::runtime_error ("Illegal terminator in array"); + } + SField::ref fn = SField::getField (type, field); if (fn.isInvalid ()) @@ -1241,6 +1259,12 @@ STArray* STArray::construct (SerializerIterator& sit, SField::ref field) throw std::runtime_error ("Unknown field"); } + if (fn.fieldType != STI_OBJECT) + { + WriteLog (lsTRACE, STObject) << "Array contains non-object"; + throw std::runtime_error ("Non-object in array"); + } + value.push_back (new STObject (fn)); value.rbegin ()->set (sit, 1); } diff --git a/src/ripple_data/protocol/SerializedTypes.cpp b/src/ripple_data/protocol/SerializedTypes.cpp index e44f227f0..eda4dacb9 100644 --- a/src/ripple_data/protocol/SerializedTypes.cpp +++ b/src/ripple_data/protocol/SerializedTypes.cpp @@ -353,6 +353,8 @@ STVector256* STVector256::construct (SerializerIterator& u, SField::ref name) void STVector256::add (Serializer& s) const { + assert (fName->isBinary ()); + assert (fName->fieldType == STI_VECTOR256); s.addVL (mValue.empty () ? nullptr : mValue[0].begin (), mValue.size () * (256 / 8)); } @@ -592,6 +594,8 @@ std::string STPathSet::getText () const void STPathSet::add (Serializer& s) const { + assert (fName->isBinary ()); + assert (fName->fieldType == STI_PATHSET); bool bFirst = true; BOOST_FOREACH (const STPath & spPath, value) diff --git a/src/ripple_data/protocol/SerializedTypes.h b/src/ripple_data/protocol/SerializedTypes.h index 6ebf7349f..57e8a522f 100644 --- a/src/ripple_data/protocol/SerializedTypes.h +++ b/src/ripple_data/protocol/SerializedTypes.h @@ -146,13 +146,14 @@ public: virtual void add (Serializer& s) const { - ; + assert (false); } virtual bool isEquivalent (const SerializedType& t) const; void addFieldID (Serializer& s) const { + assert (fName->isBinary ()); s.addFieldID (fName->fieldType, fName->fieldValue); } @@ -247,6 +248,8 @@ public: Json::Value getJson (int) const; void add (Serializer& s) const { + assert (fName->isBinary ()); + assert (fName->fieldType == STI_UINT8); s.add8 (value); } @@ -306,6 +309,8 @@ public: Json::Value getJson (int) const; void add (Serializer& s) const { + assert (fName->isBinary ()); + assert (fName->fieldType == STI_UINT16); s.add16 (value); } @@ -365,6 +370,8 @@ public: Json::Value getJson (int) const; void add (Serializer& s) const { + assert (fName->isBinary ()); + assert (fName->fieldType == STI_UINT32); s.add32 (value); } @@ -423,6 +430,8 @@ public: Json::Value getJson (int) const; void add (Serializer& s) const { + assert (fName->isBinary ()); + assert (fName->fieldType == STI_UINT64); s.add64 (value); } @@ -881,6 +890,8 @@ public: virtual std::string getText () const; void add (Serializer& s) const { + assert (fName->isBinary ()); + assert (fName->fieldType == STI_HASH128); s.add128 (value); } @@ -954,6 +965,8 @@ public: virtual std::string getText () const; void add (Serializer& s) const { + assert (fName->isBinary ()); + assert (fName->fieldType == STI_HASH160); s.add160 (value); } @@ -1027,6 +1040,8 @@ public: std::string getText () const; void add (Serializer& s) const { + assert (fName->isBinary ()); + assert (fName->fieldType == STI_HASH256); s.add256 (value); } @@ -1094,6 +1109,9 @@ public: virtual std::string getText () const; void add (Serializer& s) const { + assert (fName->isBinary ()); + assert ((fName->fieldType == STI_VL) || + (fName->fieldType == STI_ACCOUNT)); s.addVL (value); } From 828c2e3c7166ab917ce7002e884b602c4087796b Mon Sep 17 00:00:00 2001 From: sublimator Date: Wed, 25 Jun 2014 20:16:38 +0000 Subject: [PATCH 04/10] Restore checkpointed ledger under all paths in PathFind. --- src/ripple_app/paths/RippleCalc.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/ripple_app/paths/RippleCalc.cpp b/src/ripple_app/paths/RippleCalc.cpp index 24c17e9e7..6967c65aa 100644 --- a/src/ripple_app/paths/RippleCalc.cpp +++ b/src/ripple_app/paths/RippleCalc.cpp @@ -2819,6 +2819,13 @@ TER RippleCalc::rippleCalc ( } else { + // We must restore the activeLedger from lesCheckpoint in the case + // when iBest is -1 and just before the result is set to tesSUCCESS. + // There was an issue when not on the first increment and there was + // no best path, where we did not restore the ledger to the last + // checkpoint. + + activeLedger = lesCheckpoint.duplicate (); terResult = tesSUCCESS; } } From b9f1b0562555f2ee25aff1ad103ea545d8bb66d8 Mon Sep 17 00:00:00 2001 From: Tom Ritchford Date: Wed, 25 Jun 2014 20:19:16 +0000 Subject: [PATCH 05/10] Use swapWith to save CPU; edit comment. --- src/ripple_app/paths/RippleCalc.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/ripple_app/paths/RippleCalc.cpp b/src/ripple_app/paths/RippleCalc.cpp index 6967c65aa..f5264d3bc 100644 --- a/src/ripple_app/paths/RippleCalc.cpp +++ b/src/ripple_app/paths/RippleCalc.cpp @@ -2617,7 +2617,7 @@ TER RippleCalc::rippleCalc ( while (temUNCERTAIN == terResult) { int iBest = -1; - const LedgerEntrySet lesCheckpoint = activeLedger; + LedgerEntrySet lesCheckpoint = activeLedger; int iDry = 0; // True, if ever computed multi-quality. @@ -2821,11 +2821,8 @@ TER RippleCalc::rippleCalc ( { // We must restore the activeLedger from lesCheckpoint in the case // when iBest is -1 and just before the result is set to tesSUCCESS. - // There was an issue when not on the first increment and there was - // no best path, where we did not restore the ledger to the last - // checkpoint. - activeLedger = lesCheckpoint.duplicate (); + activeLedger.swapWith (lesCheckpoint); terResult = tesSUCCESS; } } From 9210efb0510d206c3fca76abd16bf7ac4d3c5294 Mon Sep 17 00:00:00 2001 From: Mark Travis Date: Mon, 30 Jun 2014 23:51:07 +0000 Subject: [PATCH 06/10] In JSON, output unprintable currency codes as hex --- src/ripple_data/protocol/STAmount.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/ripple_data/protocol/STAmount.cpp b/src/ripple_data/protocol/STAmount.cpp index c6dc58486..41610b126 100644 --- a/src/ripple_data/protocol/STAmount.cpp +++ b/src/ripple_data/protocol/STAmount.cpp @@ -223,6 +223,14 @@ std::string STAmount::createHumanCurrency (const uint160& uCurrency) { static uint160 const sIsoBits ("FFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFF"); + // Characters we are willing to include the ASCII representation + // of a three-letter currency code + static std::string legalASCIICurrencyCharacters = + "abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "0123456789" + "<>(){}[]|?!@#$%^&*"; + if (uCurrency.isZero ()) { return SYSTEM_CURRENCY_CODE; @@ -244,7 +252,8 @@ std::string STAmount::createHumanCurrency (const uint160& uCurrency) // Specifying the system currency code using ISO-style representation // is not allowed. - if (iso != SYSTEM_CURRENCY_CODE) + if ((iso != SYSTEM_CURRENCY_CODE) && + (iso.find_first_not_of (legalASCIICurrencyCharacters) == std::string::npos)) return iso; } From c4e9c49c10ca22ff6c6b65b9aca7ce61a0ea24c2 Mon Sep 17 00:00:00 2001 From: David Schwartz Date: Mon, 30 Jun 2014 16:53:23 -0700 Subject: [PATCH 07/10] Set version to 0.25.2-rc2 --- src/ripple_data/protocol/BuildInfo.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ripple_data/protocol/BuildInfo.cpp b/src/ripple_data/protocol/BuildInfo.cpp index e9841bee3..90352788b 100644 --- a/src/ripple_data/protocol/BuildInfo.cpp +++ b/src/ripple_data/protocol/BuildInfo.cpp @@ -31,7 +31,7 @@ char const* BuildInfo::getRawVersionString () // // The build version number (edit this for each release) // - "0.25.2-rc1" + "0.25.2-rc2" // // Must follow the format described here: // From 5714b42975055031883388148acb832f95d5d4d9 Mon Sep 17 00:00:00 2001 From: David Schwartz Date: Fri, 4 Jul 2014 00:47:40 +0000 Subject: [PATCH 08/10] Impose a local limit on path lengths --- src/ripple_app/transactors/Payment.cpp | 9 +++++++-- src/ripple_app/transactors/Payment.h | 3 +++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/ripple_app/transactors/Payment.cpp b/src/ripple_app/transactors/Payment.cpp index 311e07704..f4922746a 100644 --- a/src/ripple_app/transactors/Payment.cpp +++ b/src/ripple_app/transactors/Payment.cpp @@ -212,9 +212,14 @@ TER PaymentTransactor::doApply () try { bool const openLedger = is_bit_set (mParams, tapOPEN_LEDGER); - bool const tooManyPaths = spsPaths.size () > MaxPathSize; - terResult = openLedger && tooManyPaths + bool pathTooBig = spsPaths.size () > MaxPathSize; + + for (auto const& path : spsPaths) + if (path.size () > MaxPathLength) + pathTooBig = true; + + terResult = openLedger && pathTooBig ? telBAD_PATH_COUNT // Too many paths for proposed ledger. : RippleCalc::rippleCalc ( mEngine->view (), diff --git a/src/ripple_app/transactors/Payment.h b/src/ripple_app/transactors/Payment.h index 57502336e..2e935d4a3 100644 --- a/src/ripple_app/transactors/Payment.h +++ b/src/ripple_app/transactors/Payment.h @@ -37,6 +37,9 @@ class PaymentTransactor /* The largest number of paths we allow */ static std::size_t const MaxPathSize = 6; + /* The longest path we allow */ + static std::size_t const MaxPathLength = 8; + public: PaymentTransactor ( SerializedTransaction const& txn, From b2f19e8dc6c4a2c301b021e49a66f40854beaabd Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Mon, 7 Jul 2014 12:35:49 -0700 Subject: [PATCH 09/10] Find 'sabfd' paths This permits USD/GW1 to be bridged to USD/GW2 by BTC/GW3 or USD/GW1 to be bridged to BTC/GW2 by CNY/GW3. See RIPD-335. --- src/ripple_app/paths/Pathfinder.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/ripple_app/paths/Pathfinder.cpp b/src/ripple_app/paths/Pathfinder.cpp index 7d149a9c1..84feeee2e 100644 --- a/src/ripple_app/paths/Pathfinder.cpp +++ b/src/ripple_app/paths/Pathfinder.cpp @@ -914,6 +914,7 @@ void Pathfinder::initPathTable() list.push_back(CostedPath_t(6, makePath("safad"))); list.push_back(CostedPath_t(6, makePath("saxfd"))); // source -> gateway -> book to XRP -> book -> destination list.push_back(CostedPath_t(6, makePath("saxfad"))); + list.push_back(CostedPath_t(6, makePath("sabfd"))); // source -> gateway -> book -> book -> destination list.push_back(CostedPath_t(7, makePath("saaad"))); } @@ -927,6 +928,7 @@ void Pathfinder::initPathTable() list.push_back(CostedPath_t(5, makePath("saxfd"))); list.push_back(CostedPath_t(5, makePath("sxfad"))); list.push_back(CostedPath_t(6, makePath("saxfad"))); + list.push_back(CostedPath_t(6, makePath("sabfd"))); list.push_back(CostedPath_t(7, makePath("saafd"))); list.push_back(CostedPath_t(8, makePath("saafad"))); list.push_back(CostedPath_t(9, makePath("safaad"))); From ddf68d464d74e1c76a0cfd100a08bc8e65b91fec Mon Sep 17 00:00:00 2001 From: Mark Travis Date: Mon, 7 Jul 2014 11:46:15 -0700 Subject: [PATCH 10/10] Set version to 0.25.2 --- Builds/rpm/rippled.spec | 2 +- src/ripple_data/protocol/BuildInfo.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Builds/rpm/rippled.spec b/Builds/rpm/rippled.spec index 00afa5dda..424aa9438 100644 --- a/Builds/rpm/rippled.spec +++ b/Builds/rpm/rippled.spec @@ -1,5 +1,5 @@ Name: rippled -Version: 0.25.2-rc1 +Version: 0.25.2 Release: 1%{?dist} Summary: Ripple peer-to-peer network daemon diff --git a/src/ripple_data/protocol/BuildInfo.cpp b/src/ripple_data/protocol/BuildInfo.cpp index 90352788b..53fecbd8b 100644 --- a/src/ripple_data/protocol/BuildInfo.cpp +++ b/src/ripple_data/protocol/BuildInfo.cpp @@ -31,7 +31,7 @@ char const* BuildInfo::getRawVersionString () // // The build version number (edit this for each release) // - "0.25.2-rc2" + "0.25.2" // // Must follow the format described here: //