From 6d8ee90a8d72929a93078fe8884246658af10923 Mon Sep 17 00:00:00 2001 From: Vinnie Falco Date: Fri, 7 Jun 2013 14:39:35 -0700 Subject: [PATCH] Split up ripple_SerializedObject.h --- .../ripple_data/protocol/ripple_FieldNames.h | 9 +- .../protocol/ripple_SerializedObject.cpp | 16 -- .../protocol/ripple_SerializedObject.h | 44 ++---- .../ripple_SerializedObjectTemplate.cpp | 42 +++++ .../ripple_SerializedObjectTemplate.h | 71 +++++++++ modules/ripple_data/ripple_data.cpp | 1 + modules/ripple_data/ripple_data.h | 1 + newcoin.vcxproj | 7 + newcoin.vcxproj.filters | 6 + src/cpp/ripple/SerializedValidation.cpp | 147 ++++++++++-------- src/cpp/ripple/SerializedValidation.h | 28 ++-- src/cpp/ripple/main.cpp | 4 +- 12 files changed, 237 insertions(+), 139 deletions(-) create mode 100644 modules/ripple_data/protocol/ripple_SerializedObjectTemplate.cpp create mode 100644 modules/ripple_data/protocol/ripple_SerializedObjectTemplate.h diff --git a/modules/ripple_data/protocol/ripple_FieldNames.h b/modules/ripple_data/protocol/ripple_FieldNames.h index 1aa40879eb..2f1d771bb8 100644 --- a/modules/ripple_data/protocol/ripple_FieldNames.h +++ b/modules/ripple_data/protocol/ripple_FieldNames.h @@ -23,14 +23,7 @@ enum SerializedTypeID STI_VALIDATION = 10003, }; -enum SOE_Flags -{ - SOE_INVALID = -1, - SOE_REQUIRED = 0, // required - SOE_OPTIONAL = 1, // optional, may be present with default value - SOE_DEFAULT = 2, // optional, if present, must not have default value -}; - +// VFALCO: TODO, rename this to NamedField class SField { public: diff --git a/modules/ripple_data/protocol/ripple_SerializedObject.cpp b/modules/ripple_data/protocol/ripple_SerializedObject.cpp index 77d1e3e657..db5c984233 100644 --- a/modules/ripple_data/protocol/ripple_SerializedObject.cpp +++ b/modules/ripple_data/protocol/ripple_SerializedObject.cpp @@ -117,22 +117,6 @@ UPTR_T STObject::makeDeserializedObject(SerializedTypeID id, SFi } } -void SOTemplate::push_back(const SOElement &r) -{ - if (mIndex.empty()) - mIndex.resize(SField::getNumFields() + 1, -1); - assert(r.e_field.getNum() < mIndex.size()); - assert(getIndex(r.e_field) == -1); - mIndex[r.e_field.getNum()] = mTypes.size(); - mTypes.push_back(new SOElement(r)); -} - -int SOTemplate::getIndex(SField::ref f) const -{ - assert(f.getNum() < mIndex.size()); - return mIndex[f.getNum()]; -} - void STObject::set(const SOTemplate& type) { mData.clear(); diff --git a/modules/ripple_data/protocol/ripple_SerializedObject.h b/modules/ripple_data/protocol/ripple_SerializedObject.h index c29c31251e..2f517c147a 100644 --- a/modules/ripple_data/protocol/ripple_SerializedObject.h +++ b/modules/ripple_data/protocol/ripple_SerializedObject.h @@ -4,41 +4,17 @@ DEFINE_INSTANCE(SerializedObject); DEFINE_INSTANCE(SerializedArray); -// Serializable object/array types - -class SOElement -{ // An element in the description of a serialized object -public: - SField::ref e_field; - const SOE_Flags flags; - - SOElement(SField::ref fi, SOE_Flags fl) : e_field(fi), flags(fl) { ; } -}; - -class SOTemplate -{ -public: - SOTemplate() { ; } - const std::vector& peek() const { return mTypes; } - void push_back(const SOElement& r); - int getIndex(SField::ref) const; - -private: - std::vector mTypes; - std::vector mIndex; // field num -> index -}; - class STObject : public SerializedType, private IS_INSTANCE(SerializedObject) { public: STObject() : mType(NULL) { ; } - STObject(SField::ref name) : SerializedType(name), mType(NULL) { ; } + explicit STObject(SField::ref name) : SerializedType(name), mType(NULL) { ; } - STObject(const SOTemplate& type, SField::ref name) : SerializedType(name) + STObject (const SOTemplate& type, SField::ref name) : SerializedType(name) { set(type); } - STObject(const SOTemplate& type, SerializerIterator& sit, SField::ref name) : SerializedType(name) + STObject (const SOTemplate& type, SerializerIterator& sit, SField::ref name) : SerializedType(name) { set(sit); setType(type); } UPTR_T oClone() const { return UPTR_T(new STObject(*this)); } @@ -184,7 +160,7 @@ namespace boost template<> struct range_const_iterator { typedef STObject::const_iterator type; }; } - +//------------------------------------------------------------------------------ class STArray : public SerializedType, private IS_INSTANCE(SerializedArray) { @@ -197,12 +173,12 @@ public: typedef boost::ptr_vector::size_type size_type; public: - STArray() { ; } - STArray(int n) { value.reserve(n); } - STArray(SField::ref f) : SerializedType(f) { ; } + STArray () { ; } + explicit STArray(int n) { value.reserve(n); } + explicit STArray(SField::ref f) : SerializedType(f) { ; } STArray(SField::ref f, int n) : SerializedType(f) { value.reserve(n); } STArray(SField::ref f, const vector& v) : SerializedType(f), value(v) { ; } - STArray(vector& v) : value(v) { ; } + explicit STArray(vector& v) : value(v) { ; } static UPTR_T deserialize(SerializerIterator& sit, SField::ref name) { return UPTR_T(construct(sit, name)); } @@ -210,7 +186,9 @@ public: const vector& getValue() const { return value; } vector& getValue() { return value; } - // vector-like functions + // VFALCO: NOTE as long as we're married to boost why not use boost::iterator_facade? + // + // vector-like functions void push_back(const STObject& object) { value.push_back(object.oClone().release()); } STObject& operator[](int j) { return value[j]; } const STObject& operator[](int j) const { return value[j]; } diff --git a/modules/ripple_data/protocol/ripple_SerializedObjectTemplate.cpp b/modules/ripple_data/protocol/ripple_SerializedObjectTemplate.cpp new file mode 100644 index 0000000000..3f316efc7d --- /dev/null +++ b/modules/ripple_data/protocol/ripple_SerializedObjectTemplate.cpp @@ -0,0 +1,42 @@ + +SOTemplate::SOTemplate () +{ +} + +void SOTemplate::push_back (SOElement const& r) +{ + // Ensure there is the enough space in the index mapping + // table for all possible fields. + // + if (mIndex.empty()) + { + // Unmapped indices will be set to -1 + // + mIndex.resize (SField::getNumFields() + 1, -1); + } + + // Make sure the field's index is in range + // + assert (r.e_field.getNum() < mIndex.size()); + + // Make sure that this field hasn't already been assigned + // + assert(getIndex(r.e_field) == -1); + + // Add the field to the index mapping table + // + mIndex [r.e_field.getNum ()] = mTypes.size(); + + // Append the new element. + // + mTypes.push_back (new SOElement (r)); +} + +int SOTemplate::getIndex (SField::ref f) const +{ + // The mapping table should be large enough for any possible field + // + assert (f.getNum() < mIndex.size()); + + return mIndex[f.getNum()]; +} diff --git a/modules/ripple_data/protocol/ripple_SerializedObjectTemplate.h b/modules/ripple_data/protocol/ripple_SerializedObjectTemplate.h new file mode 100644 index 0000000000..a977e76b6a --- /dev/null +++ b/modules/ripple_data/protocol/ripple_SerializedObjectTemplate.h @@ -0,0 +1,71 @@ +#ifndef RIPPLE_SERIALIZEDOBJECTTEMPLATE_H +#define RIPPLE_SERIALIZEDOBJECTTEMPLATE_H + +//------------------------------------------------------------------------------ + +/** Flags for elements in a SerializedObjectTemplate. +*/ +// VFALCO: NOTE, these don't look like bit-flags... +enum SOE_Flags +{ + SOE_INVALID = -1, + SOE_REQUIRED = 0, // required + SOE_OPTIONAL = 1, // optional, may be present with default value + SOE_DEFAULT = 2, // optional, if present, must not have default value +}; + +//------------------------------------------------------------------------------ + +/** An element in a SerializedObjectTemplate. +*/ +class SOElement +{ +public: + SField::ref const e_field; + SOE_Flags const flags; + + SOElement (SField::ref fieldName, SOE_Flags flags) + : e_field (fieldName) + , flags (flags) + { + } +}; + +//------------------------------------------------------------------------------ + +/** Defines the fields and their attributes within a SerializedObject. + + Each subclass of SerializedObject will provide its own template + describing the available fields and their metadata attributes. +*/ +class SOTemplate +{ +public: + /** Create an empty template. + + After creating the template, call @ref push_back with the + desired fields. + + @see push_back + */ + SOTemplate (); + + std::vector const& peek() const + { + return mTypes; + } + + /** Add an element to the template. + */ + void push_back (SOElement const& r); + + /** Retrieve the position of a named field. + */ + int getIndex (SField::ref) const; + +private: + std::vector mTypes; + std::vector mIndex; // field num -> index +}; + +#endif diff --git a/modules/ripple_data/ripple_data.cpp b/modules/ripple_data/ripple_data.cpp index 51dafb76ae..36efc50a12 100644 --- a/modules/ripple_data/ripple_data.cpp +++ b/modules/ripple_data/ripple_data.cpp @@ -82,6 +82,7 @@ #include "protocol/ripple_RippleAddress.cpp" #include "protocol/ripple_SerializedTypes.cpp" #include "protocol/ripple_Serializer.cpp" +#include "protocol/ripple_SerializedObjectTemplate.cpp" #include "protocol/ripple_SerializedObject.cpp" #include "protocol/ripple_TER.cpp" #include "protocol/ripple_TransactionFormat.cpp" diff --git a/modules/ripple_data/ripple_data.h b/modules/ripple_data/ripple_data.h index 2d8a5a38d0..85cd862702 100644 --- a/modules/ripple_data/ripple_data.h +++ b/modules/ripple_data/ripple_data.h @@ -72,6 +72,7 @@ #include "protocol/ripple_Serializer.h" // needs CKey #include "protocol/ripple_TER.h" #include "protocol/ripple_SerializedTypes.h" // needs Serializer, TER +#include "protocol/ripple_SerializedObjectTemplate.h" #include "protocol/ripple_SerializedObject.h" #include "protocol/ripple_LedgerFormat.h" // needs SOTemplate from SerializedObject #include "protocol/ripple_TransactionFormat.h" diff --git a/newcoin.vcxproj b/newcoin.vcxproj index 190b15b75e..696ff93656 100644 --- a/newcoin.vcxproj +++ b/newcoin.vcxproj @@ -315,6 +315,12 @@ true true + + true + true + true + true + true true @@ -1311,6 +1317,7 @@ + diff --git a/newcoin.vcxproj.filters b/newcoin.vcxproj.filters index bfb5b952e4..1cd8913c6b 100644 --- a/newcoin.vcxproj.filters +++ b/newcoin.vcxproj.filters @@ -816,6 +816,9 @@ 1. Modules\ripple_main\refactored + + 1. Modules\ripple_data\protocol + @@ -1520,6 +1523,9 @@ 1. Modules\ripple_main\refactored + + 1. Modules\ripple_data\protocol + diff --git a/src/cpp/ripple/SerializedValidation.cpp b/src/cpp/ripple/SerializedValidation.cpp index 43b48ada9d..9cf2614ecb 100644 --- a/src/cpp/ripple/SerializedValidation.cpp +++ b/src/cpp/ripple/SerializedValidation.cpp @@ -1,128 +1,139 @@ DECLARE_INSTANCE(SerializedValidation); -SOTemplate sValidationFormat; - -void SVFInit() +SerializedValidation::SerializedValidation (SerializerIterator& sit, bool checkSignature) + : STObject (getFormat (), sit, sfValidation) + , mTrusted (false) { - sValidationFormat.push_back(SOElement(sfFlags, SOE_REQUIRED)); - sValidationFormat.push_back(SOElement(sfLedgerHash, SOE_REQUIRED)); - 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(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)); -}; - -const uint32 SerializedValidation::sFullFlag = 0x1; - -SerializedValidation::SerializedValidation(SerializerIterator& sit, bool checkSignature) - : STObject(sValidationFormat, sit, sfValidation), mTrusted(false) -{ - mNodeID = RippleAddress::createNodePublic(getFieldVL(sfSigningPubKey)).getNodeID(); - assert(mNodeID.isNonZero()); - if (checkSignature && !isValid()) - { - Log(lsTRACE) << "Invalid validation " << getJson(0); - throw std::runtime_error("Invalid validation"); - } + mNodeID = RippleAddress::createNodePublic(getFieldVL(sfSigningPubKey)).getNodeID(); + assert(mNodeID.isNonZero()); + if (checkSignature && !isValid()) + { + Log(lsTRACE) << "Invalid validation " << getJson(0); + throw std::runtime_error("Invalid validation"); + } } -SerializedValidation::SerializedValidation(const uint256& ledgerHash, uint32 signTime, - const RippleAddress& raPub, bool isFull) - : STObject(sValidationFormat, sfValidation), mTrusted(false) +SerializedValidation::SerializedValidation ( + const uint256& ledgerHash, uint32 signTime, + const RippleAddress& raPub, bool isFull) + : STObject (getFormat (), sfValidation) + , mTrusted (false) { // Does not sign - setFieldH256(sfLedgerHash, ledgerHash); - setFieldU32(sfSigningTime, signTime); + setFieldH256(sfLedgerHash, ledgerHash); + setFieldU32(sfSigningTime, signTime); - setFieldVL(sfSigningPubKey, raPub.getNodePublic()); - mNodeID = raPub.getNodeID(); - assert(mNodeID.isNonZero()); + setFieldVL(sfSigningPubKey, raPub.getNodePublic()); + mNodeID = raPub.getNodeID(); + assert(mNodeID.isNonZero()); - if (!isFull) - setFlag(sFullFlag); + if (!isFull) + setFlag(sFullFlag); } void SerializedValidation::sign(const RippleAddress& raPriv) { - uint256 signingHash; - sign(signingHash, raPriv); + uint256 signingHash; + sign(signingHash, raPriv); } void SerializedValidation::sign(uint256& signingHash, const RippleAddress& raPriv) { - signingHash = getSigningHash(); - std::vector signature; - raPriv.signNodePrivate(signingHash, signature); - setFieldVL(sfSignature, signature); + signingHash = getSigningHash(); + std::vector signature; + raPriv.signNodePrivate(signingHash, signature); + setFieldVL(sfSignature, signature); } uint256 SerializedValidation::getSigningHash() const { - return STObject::getSigningHash(theConfig.SIGN_VALIDATION); + return STObject::getSigningHash(theConfig.SIGN_VALIDATION); } uint256 SerializedValidation::getLedgerHash() const { - return getFieldH256(sfLedgerHash); + return getFieldH256(sfLedgerHash); } uint32 SerializedValidation::getSignTime() const { - return getFieldU32(sfSigningTime); + return getFieldU32(sfSigningTime); } uint32 SerializedValidation::getFlags() const { - return getFieldU32(sfFlags); + return getFieldU32(sfFlags); } bool SerializedValidation::isValid() const { - return isValid(getSigningHash()); + return isValid(getSigningHash()); } bool SerializedValidation::isValid(const uint256& signingHash) const { - try - { - RippleAddress raPublicKey = RippleAddress::createNodePublic(getFieldVL(sfSigningPubKey)); - return raPublicKey.isValid() && raPublicKey.verifyNodePublic(signingHash, getFieldVL(sfSignature)); - } - catch (...) - { - Log(lsINFO) << "exception validating validation"; - return false; - } + try + { + RippleAddress raPublicKey = RippleAddress::createNodePublic(getFieldVL(sfSigningPubKey)); + return raPublicKey.isValid() && raPublicKey.verifyNodePublic(signingHash, getFieldVL(sfSignature)); + } + catch (...) + { + Log(lsINFO) << "exception validating validation"; + return false; + } } RippleAddress SerializedValidation::getSignerPublic() const { - RippleAddress a; - a.setNodePublic(getFieldVL(sfSigningPubKey)); - return a; + RippleAddress a; + a.setNodePublic(getFieldVL(sfSigningPubKey)); + return a; } bool SerializedValidation::isFull() const { - return (getFlags() & sFullFlag) != 0; + return (getFlags() & sFullFlag) != 0; } std::vector SerializedValidation::getSignature() const { - return getFieldVL(sfSignature); + return getFieldVL(sfSignature); } std::vector SerializedValidation::getSigned() const { - Serializer s; - add(s); - return s.peekData(); + Serializer s; + add(s); + return s.peekData(); +} + +SOTemplate const& SerializedValidation::getFormat () +{ + struct FormatHolder + { + SOTemplate format; + + FormatHolder () + { + format.push_back (SOElement (sfFlags, SOE_REQUIRED)); + format.push_back (SOElement (sfLedgerHash, SOE_REQUIRED)); + format.push_back (SOElement (sfLedgerSequence, SOE_OPTIONAL)); + format.push_back (SOElement (sfCloseTime, SOE_OPTIONAL)); + format.push_back (SOElement (sfLoadFee, SOE_OPTIONAL)); + format.push_back (SOElement (sfFeatures, SOE_OPTIONAL)); + format.push_back (SOElement (sfBaseFee, SOE_OPTIONAL)); + format.push_back (SOElement (sfReserveBase, SOE_OPTIONAL)); + format.push_back (SOElement (sfReserveIncrement,SOE_OPTIONAL)); + format.push_back (SOElement (sfSigningTime, SOE_REQUIRED)); + format.push_back (SOElement (sfSigningPubKey, SOE_REQUIRED)); + format.push_back (SOElement (sfSignature, SOE_OPTIONAL)); + } + }; + + static FormatHolder holder; + + return holder.format; } // vim:ts=4 diff --git a/src/cpp/ripple/SerializedValidation.h b/src/cpp/ripple/SerializedValidation.h index 108761c938..4955b9a620 100644 --- a/src/cpp/ripple/SerializedValidation.h +++ b/src/cpp/ripple/SerializedValidation.h @@ -1,21 +1,23 @@ -#ifndef __VALIDATION__ -#define __VALIDATION__ +#ifndef RIPPLE_SERIALIZEDVALIDATION_H +#define RIPPLE_SERIALIZEDVALIDATION_H -DEFINE_INSTANCE(SerializedValidation); +DEFINE_INSTANCE (SerializedValidation); -class SerializedValidation : public STObject, private IS_INSTANCE(SerializedValidation) +class SerializedValidation + : public STObject + , private IS_INSTANCE (SerializedValidation) { public: typedef boost::shared_ptr pointer; typedef const boost::shared_ptr& ref; - static const uint32 sFullFlag; + static const uint32 sFullFlag = 0x1; - // These throw if the object is not valid - SerializedValidation(SerializerIterator& sit, bool checkSignature = true); + // These throw if the object is not valid + SerializedValidation (SerializerIterator& sit, bool checkSignature = true); // Does not sign the validation - SerializedValidation(const uint256& ledgerHash, uint32 signTime, const RippleAddress& raPub, bool isFull); + SerializedValidation (const uint256& ledgerHash, uint32 signTime, const RippleAddress& raPub, bool isFull); uint256 getLedgerHash() const; uint32 getSignTime() const; @@ -36,15 +38,17 @@ public: // The validation this replaced const uint256& getPreviousHash() { return mPreviousHash; } - bool isPreviousHash(const uint256& h) { return mPreviousHash == h; } + bool isPreviousHash(const uint256& h) const { return mPreviousHash == h; } void setPreviousHash(const uint256& h) { mPreviousHash = h; } private: - uint256 mPreviousHash; + static SOTemplate const& getFormat (); + + void setNode (); + + uint256 mPreviousHash; uint160 mNodeID; bool mTrusted; - - void setNode(); }; #endif diff --git a/src/cpp/ripple/main.cpp b/src/cpp/ripple/main.cpp index 086a054c3f..7b1b328727 100644 --- a/src/cpp/ripple/main.cpp +++ b/src/cpp/ripple/main.cpp @@ -12,9 +12,9 @@ namespace po = boost::program_options; +// VFALCO: TODO make these singletons that initialize statically extern void TFInit(); extern void LEFInit(); -extern void SVFInit(); using namespace std; using namespace boost::unit_test; @@ -213,9 +213,9 @@ int main(int argc, char* argv[]) InstanceType::multiThread(); + // VFALCO: TODO make these singletons that initialize statically TFInit(); LEFInit(); - SVFInit(); if (vm.count("unittest")) {