mirror of
https://github.com/XRPLF/rippled.git
synced 2025-12-06 17:27:55 +00:00
Move serialization and error code stuff into ripple_data
This commit is contained in:
@@ -10,7 +10,6 @@
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include "Config.h"
|
||||
#include "SerializedTypes.h"
|
||||
|
||||
SETUP_LOG (STAmount)
|
||||
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include "SerializedTypes.h"
|
||||
|
||||
// CAUTION: This is early code and is *NOT* ready for real use yet.
|
||||
|
||||
static void canonicalizeRound(bool isNative, uint64& value, int& offset, bool roundUp)
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
#include "ParseSection.h"
|
||||
#include "SerializedTypes.h"
|
||||
|
||||
#define ENABLE_INSECURE 0 // 1, to enable unnecessary features.
|
||||
|
||||
|
||||
@@ -39,6 +39,11 @@ DEFINE_INSTANCE(Ledger);
|
||||
|
||||
class SqliteStatement;
|
||||
|
||||
// VFALCO: TODO, figure out exactly how this thing works.
|
||||
// It seems like some ledger database is stored as a global, static in the
|
||||
// class. But then what is the meaning of a Ledger object? Is this
|
||||
// really two classes in one? StoreOfAllLedgers + SingleLedgerObject?
|
||||
//
|
||||
class Ledger : public boost::enable_shared_from_this<Ledger>, public IS_INSTANCE(Ledger)
|
||||
{ // The basic Ledger structure, can be opened, closed, or synching
|
||||
// VFALCO: TODO, eliminate the need for friends
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
#include "SerializedLedger.h"
|
||||
#include "TransactionMeta.h"
|
||||
#include "Ledger.h"
|
||||
#include "TransactionErr.h"
|
||||
|
||||
DEFINE_INSTANCE(LedgerEntrySetEntry);
|
||||
DEFINE_INSTANCE(LedgerEntrySet);
|
||||
|
||||
@@ -1,138 +0,0 @@
|
||||
|
||||
std::map<int, LedgerEntryFormat*> LedgerEntryFormat::byType;
|
||||
std::map<std::string, LedgerEntryFormat*> LedgerEntryFormat::byName;
|
||||
|
||||
#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
|
||||
|
||||
void LEFInit()
|
||||
{
|
||||
LedgerEntryFormat* lef;
|
||||
|
||||
DECLARE_LEF(AccountRoot, ltACCOUNT_ROOT)
|
||||
<< SOElement(sfAccount, SOE_REQUIRED)
|
||||
<< SOElement(sfSequence, SOE_REQUIRED)
|
||||
<< SOElement(sfBalance, SOE_REQUIRED)
|
||||
<< SOElement(sfOwnerCount, SOE_REQUIRED)
|
||||
<< SOElement(sfPreviousTxnID, SOE_REQUIRED)
|
||||
<< SOElement(sfPreviousTxnLgrSeq, SOE_REQUIRED)
|
||||
<< SOElement(sfRegularKey, SOE_OPTIONAL)
|
||||
<< SOElement(sfEmailHash, SOE_OPTIONAL)
|
||||
<< SOElement(sfWalletLocator, SOE_OPTIONAL)
|
||||
<< SOElement(sfWalletSize, SOE_OPTIONAL)
|
||||
<< SOElement(sfMessageKey, SOE_OPTIONAL)
|
||||
<< SOElement(sfTransferRate, SOE_OPTIONAL)
|
||||
<< SOElement(sfDomain, SOE_OPTIONAL)
|
||||
;
|
||||
|
||||
DECLARE_LEF(Contract, ltCONTRACT)
|
||||
<< 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_OPTIONAL)
|
||||
<< SOElement(sfFundCode, SOE_OPTIONAL)
|
||||
<< SOElement(sfRemoveCode, SOE_OPTIONAL)
|
||||
<< SOElement(sfExpireCode, SOE_OPTIONAL)
|
||||
;
|
||||
|
||||
DECLARE_LEF(DirectoryNode, ltDIR_NODE)
|
||||
<< SOElement(sfOwner, SOE_OPTIONAL) // for owner directories
|
||||
<< SOElement(sfTakerPaysCurrency, SOE_OPTIONAL) // for order book directories
|
||||
<< SOElement(sfTakerPaysIssuer, SOE_OPTIONAL) // for order book directories
|
||||
<< SOElement(sfTakerGetsCurrency, SOE_OPTIONAL) // for order book directories
|
||||
<< SOElement(sfTakerGetsIssuer, SOE_OPTIONAL) // for order book directories
|
||||
<< SOElement(sfExchangeRate, SOE_OPTIONAL) // for order book directories
|
||||
<< SOElement(sfIndexes, SOE_REQUIRED)
|
||||
<< SOElement(sfRootIndex, SOE_REQUIRED)
|
||||
<< SOElement(sfIndexNext, SOE_OPTIONAL)
|
||||
<< SOElement(sfIndexPrevious, SOE_OPTIONAL)
|
||||
;
|
||||
|
||||
DECLARE_LEF(GeneratorMap, ltGENERATOR_MAP)
|
||||
<< SOElement(sfGenerator, SOE_REQUIRED)
|
||||
;
|
||||
|
||||
DECLARE_LEF(Nickname, ltNICKNAME)
|
||||
<< 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(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(sfPreviousTxnID, SOE_REQUIRED)
|
||||
<< SOElement(sfPreviousTxnLgrSeq, SOE_REQUIRED)
|
||||
<< SOElement(sfLowNode, SOE_OPTIONAL)
|
||||
<< SOElement(sfLowQualityIn, SOE_OPTIONAL)
|
||||
<< SOElement(sfLowQualityOut, SOE_OPTIONAL)
|
||||
<< SOElement(sfHighNode, SOE_OPTIONAL)
|
||||
<< SOElement(sfHighQualityIn, SOE_OPTIONAL)
|
||||
<< SOElement(sfHighQualityOut, SOE_OPTIONAL)
|
||||
;
|
||||
|
||||
DECLARE_LEF(LedgerHashes, ltLEDGER_HASHES)
|
||||
<< SOElement(sfFirstLedgerSequence, SOE_OPTIONAL) // Remove if we do a ledger restart
|
||||
<< SOElement(sfLastLedgerSequence, SOE_OPTIONAL)
|
||||
<< SOElement(sfHashes, SOE_REQUIRED)
|
||||
;
|
||||
|
||||
DECLARE_LEF(EnabledFeatures, ltFEATURES)
|
||||
<< SOElement(sfFeatures, SOE_REQUIRED)
|
||||
;
|
||||
|
||||
DECLARE_LEF(FeeSettings, ltFEE_SETTINGS)
|
||||
<< SOElement(sfBaseFee, SOE_REQUIRED)
|
||||
<< SOElement(sfReferenceFeeUnits, SOE_REQUIRED)
|
||||
<< SOElement(sfReserveBase, SOE_REQUIRED)
|
||||
<< SOElement(sfReserveIncrement, SOE_REQUIRED)
|
||||
;
|
||||
}
|
||||
|
||||
LedgerEntryFormat* LedgerEntryFormat::getLgrFormat(LedgerEntryType t)
|
||||
{
|
||||
std::map<int, LedgerEntryFormat*>::iterator it = byType.find(static_cast<int>(t));
|
||||
if (it == byType.end())
|
||||
return NULL;
|
||||
return it->second;
|
||||
}
|
||||
|
||||
LedgerEntryFormat* LedgerEntryFormat::getLgrFormat(int t)
|
||||
{
|
||||
std::map<int, LedgerEntryFormat*>::iterator it = byType.find((t));
|
||||
if (it == byType.end())
|
||||
return NULL;
|
||||
return it->second;
|
||||
}
|
||||
|
||||
LedgerEntryFormat* LedgerEntryFormat::getLgrFormat(const std::string& t)
|
||||
{
|
||||
std::map<std::string, LedgerEntryFormat*>::iterator it = byName.find((t));
|
||||
if (it == byName.end())
|
||||
return NULL;
|
||||
return it->second;
|
||||
}
|
||||
|
||||
// vim:ts=4
|
||||
@@ -1,84 +0,0 @@
|
||||
#ifndef __LEDGERFORMATS__
|
||||
#define __LEDGERFORMATS__
|
||||
|
||||
#include "SerializedObject.h"
|
||||
|
||||
// Used as the type of a transaction or the type of a ledger entry.
|
||||
enum LedgerEntryType
|
||||
{
|
||||
ltINVALID = -1,
|
||||
ltACCOUNT_ROOT = 'a',
|
||||
ltDIR_NODE = 'd',
|
||||
ltGENERATOR_MAP = 'g',
|
||||
ltRIPPLE_STATE = 'r',
|
||||
ltNICKNAME = 'n',
|
||||
ltOFFER = 'o',
|
||||
ltCONTRACT = 'c',
|
||||
ltLEDGER_HASHES = 'h',
|
||||
ltFEATURES = 'f',
|
||||
ltFEE_SETTINGS = 's',
|
||||
};
|
||||
|
||||
// Used as a prefix for computing ledger indexes (keys).
|
||||
enum LedgerNameSpace
|
||||
{
|
||||
spaceAccount = 'a',
|
||||
spaceDirNode = 'd',
|
||||
spaceGenerator = 'g',
|
||||
spaceNickname = 'n',
|
||||
spaceRipple = 'r',
|
||||
spaceOffer = 'o', // Entry for an offer.
|
||||
spaceOwnerDir = 'O', // Directory of things owned by an account.
|
||||
spaceBookDir = 'B', // Directory of order books.
|
||||
spaceContract = 'c',
|
||||
spaceSkipList = 's',
|
||||
spaceFeature = 'f',
|
||||
spaceFee = 'e',
|
||||
};
|
||||
|
||||
enum LedgerSpecificFlags
|
||||
{
|
||||
// ltACCOUNT_ROOT
|
||||
lsfPasswordSpent = 0x00010000, // True, if password set fee is spent.
|
||||
lsfRequireDestTag = 0x00020000, // True, to require a DestinationTag for payments.
|
||||
lsfRequireAuth = 0x00040000, // True, to require a authorization to hold IOUs.
|
||||
lsfDisallowXRP = 0x00080000, // True, to disallow sending XRP.
|
||||
|
||||
// ltOFFER
|
||||
lsfPassive = 0x00010000,
|
||||
|
||||
// ltRIPPLE_STATE
|
||||
lsfLowReserve = 0x00010000, // True, if entry counts toward reserve.
|
||||
lsfHighReserve = 0x00020000,
|
||||
lsfLowAuth = 0x00040000,
|
||||
lsfHighAuth = 0x00080000,
|
||||
};
|
||||
|
||||
class LedgerEntryFormat
|
||||
{
|
||||
public:
|
||||
std::string t_name;
|
||||
LedgerEntryType t_type;
|
||||
SOTemplate elements;
|
||||
|
||||
static std::map<int, LedgerEntryFormat*> byType;
|
||||
static std::map<std::string, LedgerEntryFormat*> byName;
|
||||
|
||||
LedgerEntryFormat(const char *name, LedgerEntryType type) : t_name(name), t_type(type)
|
||||
{
|
||||
byName[name] = this;
|
||||
byType[type] = this;
|
||||
}
|
||||
LedgerEntryFormat& operator<<(const SOElement& el)
|
||||
{
|
||||
elements.push_back(el);
|
||||
return *this;
|
||||
}
|
||||
|
||||
static LedgerEntryFormat* getLgrFormat(LedgerEntryType t);
|
||||
static LedgerEntryFormat* getLgrFormat(const std::string& t);
|
||||
static LedgerEntryFormat* getLgrFormat(int t);
|
||||
};
|
||||
|
||||
#endif
|
||||
// vim:ts=4
|
||||
@@ -6,7 +6,6 @@
|
||||
#include "Application.h"
|
||||
#include "Pathfinder.h"
|
||||
#include "RippleCalc.h"
|
||||
#include "LedgerFormats.h"
|
||||
|
||||
SETUP_LOG (PFRequest)
|
||||
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/weak_ptr.hpp>
|
||||
|
||||
#include "SerializedTypes.h"
|
||||
#include "Pathfinder.h"
|
||||
|
||||
// A pathfinding request submitted by a client
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
#include "SerializedTypes.h"
|
||||
#include "RippleCalc.h"
|
||||
#include "OrderBookDB.h"
|
||||
#include "AccountItems.h"
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
|
||||
#include <boost/unordered_set.hpp>
|
||||
|
||||
#include "SerializedTypes.h"
|
||||
#include "Ledger.h"
|
||||
#include "NetworkOPs.h"
|
||||
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
#ifndef __SERIALIZEDLEDGER__
|
||||
#define __SERIALIZEDLEDGER__
|
||||
|
||||
#include "SerializedObject.h"
|
||||
#include "LedgerFormats.h"
|
||||
|
||||
DEFINE_INSTANCE(SerializedLedgerEntry);
|
||||
|
||||
// VFALCO: TODO, rename this to SerializedLedger
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,272 +0,0 @@
|
||||
#ifndef __SERIALIZEDOBJECT__
|
||||
#define __SERIALIZEDOBJECT__
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <boost/ptr_container/ptr_vector.hpp>
|
||||
|
||||
#include "SerializedTypes.h"
|
||||
|
||||
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<const SOElement*>& peek() const { return mTypes; }
|
||||
void push_back(const SOElement& r);
|
||||
int getIndex(SField::ref) const;
|
||||
|
||||
private:
|
||||
std::vector<const SOElement*> mTypes;
|
||||
std::vector<int> mIndex; // field num -> index
|
||||
};
|
||||
|
||||
class STObject : public SerializedType, private IS_INSTANCE(SerializedObject)
|
||||
{
|
||||
public:
|
||||
STObject() : mType(NULL) { ; }
|
||||
|
||||
STObject(SField::ref name) : SerializedType(name), mType(NULL) { ; }
|
||||
|
||||
STObject(const SOTemplate& type, SField::ref name) : SerializedType(name)
|
||||
{ set(type); }
|
||||
|
||||
STObject(const SOTemplate& type, SerializerIterator& sit, SField::ref name) : SerializedType(name)
|
||||
{ set(sit); setType(type); }
|
||||
|
||||
UPTR_T<STObject> oClone() const { return UPTR_T<STObject>(new STObject(*this)); }
|
||||
|
||||
static UPTR_T<STObject> parseJson(const Json::Value& value, SField::ref name = sfGeneric, int depth = 0);
|
||||
|
||||
virtual ~STObject() { ; }
|
||||
|
||||
static UPTR_T<SerializedType> deserialize(SerializerIterator& sit, SField::ref name);
|
||||
|
||||
bool setType(const SOTemplate& type);
|
||||
bool isValidForType();
|
||||
bool isFieldAllowed(SField::ref);
|
||||
bool isFree() const { return mType == NULL; }
|
||||
|
||||
void set(const SOTemplate&);
|
||||
bool set(SerializerIterator& u, int depth = 0);
|
||||
|
||||
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;
|
||||
Serializer getSerializer() const { Serializer s; add(s); return s; }
|
||||
std::string getFullText() const;
|
||||
std::string getText() const;
|
||||
virtual Json::Value getJson(int options) const;
|
||||
|
||||
int addObject(const SerializedType& t) { mData.push_back(t.clone().release()); return mData.size() - 1; }
|
||||
int giveObject(UPTR_T<SerializedType> t) { mData.push_back(t.release()); return mData.size() - 1; }
|
||||
int giveObject(SerializedType* t) { mData.push_back(t); return mData.size() - 1; }
|
||||
const boost::ptr_vector<SerializedType>& peekData() const { return mData; }
|
||||
boost::ptr_vector<SerializedType>& peekData() { return mData; }
|
||||
SerializedType& front() { return mData.front(); }
|
||||
const SerializedType& front() const { return mData.front(); }
|
||||
SerializedType& back() { return mData.back(); }
|
||||
const SerializedType& back() const { return mData.back(); }
|
||||
|
||||
int getCount() const { return mData.size(); }
|
||||
|
||||
bool setFlag(uint32);
|
||||
bool clearFlag(uint32);
|
||||
uint32 getFlags() const;
|
||||
|
||||
uint256 getHash(uint32 prefix) const;
|
||||
uint256 getSigningHash(uint32 prefix) const;
|
||||
|
||||
const SerializedType& peekAtIndex(int offset) const { return mData[offset]; }
|
||||
SerializedType& getIndex(int offset) { return mData[offset]; }
|
||||
const SerializedType* peekAtPIndex(int offset) const { return &(mData[offset]); }
|
||||
SerializedType* getPIndex(int offset) { return &(mData[offset]); }
|
||||
|
||||
int getFieldIndex(SField::ref field) const;
|
||||
SField::ref getFieldSType(int index) const;
|
||||
|
||||
const SerializedType& peekAtField(SField::ref field) const;
|
||||
SerializedType& getField(SField::ref field);
|
||||
const SerializedType* peekAtPField(SField::ref field) const;
|
||||
SerializedType* getPField(SField::ref field, bool createOkay = false);
|
||||
|
||||
// these throw if the field type doesn't match, or return default values if the
|
||||
// field is optional but not present
|
||||
std::string getFieldString(SField::ref field) const;
|
||||
unsigned char getFieldU8(SField::ref field) const;
|
||||
uint16 getFieldU16(SField::ref field) const;
|
||||
uint32 getFieldU32(SField::ref field) const;
|
||||
uint64 getFieldU64(SField::ref field) const;
|
||||
uint128 getFieldH128(SField::ref field) const;
|
||||
uint160 getFieldH160(SField::ref field) const;
|
||||
uint256 getFieldH256(SField::ref field) const;
|
||||
RippleAddress getFieldAccount(SField::ref field) const;
|
||||
uint160 getFieldAccount160(SField::ref field) const;
|
||||
std::vector<unsigned char> getFieldVL(SField::ref field) const;
|
||||
const STAmount& getFieldAmount(SField::ref field) const;
|
||||
const STPathSet& getFieldPathSet(SField::ref field) const;
|
||||
const STVector256& getFieldV256(SField::ref field) const;
|
||||
|
||||
void setFieldU8(SField::ref field, unsigned char);
|
||||
void setFieldU16(SField::ref field, uint16);
|
||||
void setFieldU32(SField::ref field, uint32);
|
||||
void setFieldU64(SField::ref field, uint64);
|
||||
void setFieldH128(SField::ref field, const uint128&);
|
||||
void setFieldH160(SField::ref field, const uint160&);
|
||||
void setFieldH256(SField::ref field, const uint256&);
|
||||
void setFieldVL(SField::ref field, const std::vector<unsigned char>&);
|
||||
void setFieldAccount(SField::ref field, const uint160&);
|
||||
void setFieldAccount(SField::ref field, const RippleAddress& addr)
|
||||
{ setFieldAccount(field, addr.getAccountID()); }
|
||||
void setFieldAmount(SField::ref field, const STAmount&);
|
||||
void setFieldPathSet(SField::ref field, const STPathSet&);
|
||||
void setFieldV256(SField::ref field, const STVector256& v);
|
||||
|
||||
STObject& peekFieldObject(SField::ref field);
|
||||
|
||||
bool isFieldPresent(SField::ref field) const;
|
||||
SerializedType* makeFieldPresent(SField::ref field);
|
||||
void makeFieldAbsent(SField::ref field);
|
||||
bool delField(SField::ref field);
|
||||
void delField(int index);
|
||||
|
||||
static UPTR_T<SerializedType> makeDefaultObject(SerializedTypeID id, SField::ref name);
|
||||
static UPTR_T<SerializedType> makeDeserializedObject(SerializedTypeID id, SField::ref name,
|
||||
SerializerIterator&, int depth);
|
||||
|
||||
static UPTR_T<SerializedType> makeNonPresentObject(SField::ref name)
|
||||
{ return makeDefaultObject(STI_NOTPRESENT, name); }
|
||||
static UPTR_T<SerializedType> makeDefaultObject(SField::ref name)
|
||||
{ return makeDefaultObject(name.fieldType, name); }
|
||||
|
||||
// field iterator stuff
|
||||
typedef boost::ptr_vector<SerializedType>::iterator iterator;
|
||||
typedef boost::ptr_vector<SerializedType>::const_iterator const_iterator;
|
||||
iterator begin() { return mData.begin(); }
|
||||
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); }
|
||||
|
||||
private:
|
||||
boost::ptr_vector<SerializedType> mData;
|
||||
const SOTemplate* mType;
|
||||
|
||||
STObject* duplicate() const { return new STObject(*this); }
|
||||
STObject(SField::ref name, boost::ptr_vector<SerializedType>& data) : SerializedType(name), mType(NULL)
|
||||
{ mData.swap(data); }
|
||||
};
|
||||
|
||||
// allow ptr_* collections of STObject's
|
||||
inline STObject* new_clone(const STObject& s) { return s.oClone().release(); }
|
||||
inline void delete_clone(const STObject* s) { boost::checked_delete(s); }
|
||||
|
||||
inline STObject::iterator range_begin(STObject& x) { return x.begin(); }
|
||||
inline STObject::iterator range_end(STObject &x) { return x.end(); }
|
||||
namespace boost
|
||||
{
|
||||
template<> struct range_mutable_iterator<STObject> { typedef STObject::iterator type; };
|
||||
template<> struct range_const_iterator<STObject> { typedef STObject::const_iterator type; };
|
||||
}
|
||||
|
||||
|
||||
|
||||
class STArray : public SerializedType, private IS_INSTANCE(SerializedArray)
|
||||
{
|
||||
public:
|
||||
typedef boost::ptr_vector<STObject> vector;
|
||||
typedef boost::ptr_vector<STObject>::iterator iterator;
|
||||
typedef boost::ptr_vector<STObject>::const_iterator const_iterator;
|
||||
typedef boost::ptr_vector<STObject>::reverse_iterator reverse_iterator;
|
||||
typedef boost::ptr_vector<STObject>::const_reverse_iterator const_reverse_iterator;
|
||||
typedef boost::ptr_vector<STObject>::size_type size_type;
|
||||
|
||||
public:
|
||||
STArray() { ; }
|
||||
STArray(int n) { value.reserve(n); }
|
||||
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) { ; }
|
||||
|
||||
static UPTR_T<SerializedType> deserialize(SerializerIterator& sit, SField::ref name)
|
||||
{ return UPTR_T<SerializedType>(construct(sit, name)); }
|
||||
|
||||
const vector& getValue() const { return value; }
|
||||
vector& getValue() { return value; }
|
||||
|
||||
// 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]; }
|
||||
iterator begin() { return value.begin(); }
|
||||
const_iterator begin() const { return value.begin(); }
|
||||
iterator end() { return value.end(); }
|
||||
const_iterator end() const { return value.end(); }
|
||||
size_type size() const { return value.size(); }
|
||||
reverse_iterator rbegin() { return value.rbegin(); }
|
||||
const_reverse_iterator rbegin() const { return value.rbegin(); }
|
||||
reverse_iterator rend() { return value.rend(); }
|
||||
const_reverse_iterator rend() const { return value.rend(); }
|
||||
iterator erase(iterator pos) { return value.erase(pos); }
|
||||
STObject& front() { return value.front(); }
|
||||
const STObject& front() const { return value.front(); }
|
||||
STObject& back() { return value.back(); }
|
||||
const STObject& back() const { return value.back(); }
|
||||
void pop_back() { value.pop_back(); }
|
||||
bool empty() const { return value.empty(); }
|
||||
void clear() { value.clear(); }
|
||||
void swap(STArray& a) { value.swap(a.value); }
|
||||
|
||||
virtual std::string getFullText() const;
|
||||
virtual std::string getText() const;
|
||||
virtual Json::Value getJson(int) const;
|
||||
virtual void add(Serializer& s) const;
|
||||
|
||||
void sort(bool (*compare)(const STObject& o1, const STObject& o2));
|
||||
|
||||
bool operator==(const STArray &s) { return value == s.value; }
|
||||
bool operator!=(const STArray &s) { return value != s.value; }
|
||||
|
||||
virtual SerializedTypeID getSType() const { return STI_ARRAY; }
|
||||
virtual bool isEquivalent(const SerializedType& t) const;
|
||||
virtual bool isDefault() const { return value.empty(); }
|
||||
|
||||
private:
|
||||
vector value;
|
||||
|
||||
STArray* duplicate() const { return new STArray(*this); }
|
||||
static STArray* construct(SerializerIterator&, SField::ref);
|
||||
};
|
||||
|
||||
inline STArray::iterator range_begin(STArray& x) { return x.begin(); }
|
||||
inline STArray::iterator range_end(STArray &x) { return x.end(); }
|
||||
namespace boost
|
||||
{
|
||||
template<> struct range_mutable_iterator<STArray> { typedef STArray::iterator type; };
|
||||
template<> struct range_const_iterator<STArray> { typedef STArray::const_iterator type; };
|
||||
}
|
||||
|
||||
#endif
|
||||
// vim:ts=4
|
||||
@@ -1,12 +1,7 @@
|
||||
#ifndef __SERIALIZEDTRANSACTION__
|
||||
#define __SERIALIZEDTRANSACTION__
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
#include "SerializedObject.h"
|
||||
#include "TransactionFormats.h"
|
||||
// VFALCO: TODO, eliminate these macros
|
||||
|
||||
#define TXN_SQL_NEW 'N'
|
||||
#define TXN_SQL_CONFLICT 'C'
|
||||
|
||||
@@ -1,553 +0,0 @@
|
||||
|
||||
SETUP_LOG (SerializedType)
|
||||
|
||||
const STAmount saZero(CURRENCY_ONE, ACCOUNT_ONE, 0);
|
||||
const STAmount saOne(CURRENCY_ONE, ACCOUNT_ONE, 1);
|
||||
|
||||
SerializedType& SerializedType::operator=(const SerializedType& t)
|
||||
{
|
||||
if ((t.fName != fName) && fName->isUseful() && t.fName->isUseful())
|
||||
{
|
||||
WriteLog ((t.getSType() == STI_AMOUNT) ? lsDEBUG : lsWARNING, SerializedType) // This is common for amounts
|
||||
<< "Caution: " << t.fName->getName() << " not replacing " << fName->getName();
|
||||
}
|
||||
if (!fName->isUseful()) fName = t.fName;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
void STPathSet::printDebug() {
|
||||
for (int i = 0; i < value.size(); i++) {
|
||||
std::cerr << i << ": ";
|
||||
for (int j = 0; j < value[i].mPath.size(); j++) {
|
||||
//STPathElement pe = value[i].mPath[j];
|
||||
RippleAddress nad;
|
||||
nad.setAccountID(value[i].mPath[j].mAccountID);
|
||||
std::cerr << " " << nad.humanAccountID();
|
||||
//std::cerr << " " << pe.mAccountID.GetHex();
|
||||
}
|
||||
std::cerr << std::endl;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void STPath::printDebug() {
|
||||
std::cerr << "STPath:" << std::endl;
|
||||
for(int i =0; i < mPath.size(); i++) {
|
||||
RippleAddress nad;
|
||||
nad.setAccountID(mPath[i].mAccountID);
|
||||
std::cerr << " " << i << ": " << nad.humanAccountID() << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
std::string SerializedType::getFullText() const
|
||||
{
|
||||
std::string ret;
|
||||
if (getSType() != STI_NOTPRESENT)
|
||||
{
|
||||
if(fName->hasName())
|
||||
{
|
||||
ret = fName->fieldName;
|
||||
ret += " = ";
|
||||
}
|
||||
ret += getText();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
STUInt8* STUInt8::construct(SerializerIterator& u, SField::ref name)
|
||||
{
|
||||
return new STUInt8(name, u.get8());
|
||||
}
|
||||
|
||||
std::string STUInt8::getText() const
|
||||
{
|
||||
if (getFName() == sfTransactionResult)
|
||||
{
|
||||
std::string token, human;
|
||||
if (transResultInfo(static_cast<TER>(value), token, human))
|
||||
return human;
|
||||
}
|
||||
return boost::lexical_cast<std::string>(value);
|
||||
}
|
||||
|
||||
Json::Value STUInt8::getJson(int) const
|
||||
{
|
||||
if (getFName() == sfTransactionResult)
|
||||
{
|
||||
std::string token, human;
|
||||
if (transResultInfo(static_cast<TER>(value), token, human))
|
||||
return token;
|
||||
else
|
||||
WriteLog (lsWARNING, SerializedType) << "Unknown result code in metadata: " << value;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
bool STUInt8::isEquivalent(const SerializedType& t) const
|
||||
{
|
||||
const STUInt8* v = dynamic_cast<const STUInt8*>(&t);
|
||||
return v && (value == v->value);
|
||||
}
|
||||
|
||||
STUInt16* STUInt16::construct(SerializerIterator& u, SField::ref name)
|
||||
{
|
||||
return new STUInt16(name, u.get16());
|
||||
}
|
||||
|
||||
std::string STUInt16::getText() const
|
||||
{
|
||||
if (getFName() == sfLedgerEntryType)
|
||||
{
|
||||
LedgerEntryFormat *f = LedgerEntryFormat::getLgrFormat(value);
|
||||
if (f != NULL)
|
||||
return f->t_name;
|
||||
}
|
||||
if (getFName() == sfTransactionType)
|
||||
{
|
||||
TransactionFormat *f = TransactionFormat::getTxnFormat(value);
|
||||
if (f != NULL)
|
||||
return f->t_name;
|
||||
}
|
||||
return boost::lexical_cast<std::string>(value);
|
||||
}
|
||||
|
||||
Json::Value STUInt16::getJson(int) const
|
||||
{
|
||||
if (getFName() == sfLedgerEntryType)
|
||||
{
|
||||
LedgerEntryFormat *f = LedgerEntryFormat::getLgrFormat(value);
|
||||
if (f != NULL)
|
||||
return f->t_name;
|
||||
}
|
||||
if (getFName() == sfTransactionType)
|
||||
{
|
||||
TransactionFormat *f = TransactionFormat::getTxnFormat(value);
|
||||
if (f != NULL)
|
||||
return f->t_name;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
bool STUInt16::isEquivalent(const SerializedType& t) const
|
||||
{
|
||||
const STUInt16* v = dynamic_cast<const STUInt16*>(&t);
|
||||
return v && (value == v->value);
|
||||
}
|
||||
|
||||
STUInt32* STUInt32::construct(SerializerIterator& u, SField::ref name)
|
||||
{
|
||||
return new STUInt32(name, u.get32());
|
||||
}
|
||||
|
||||
std::string STUInt32::getText() const
|
||||
{
|
||||
return boost::lexical_cast<std::string>(value);
|
||||
}
|
||||
|
||||
Json::Value STUInt32::getJson(int) const
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
bool STUInt32::isEquivalent(const SerializedType& t) const
|
||||
{
|
||||
const STUInt32* v = dynamic_cast<const STUInt32*>(&t);
|
||||
return v && (value == v->value);
|
||||
}
|
||||
|
||||
STUInt64* STUInt64::construct(SerializerIterator& u, SField::ref name)
|
||||
{
|
||||
return new STUInt64(name, u.get64());
|
||||
}
|
||||
|
||||
std::string STUInt64::getText() const
|
||||
{
|
||||
return boost::lexical_cast<std::string>(value);
|
||||
}
|
||||
|
||||
Json::Value STUInt64::getJson(int) const
|
||||
{
|
||||
return strHex(value);
|
||||
}
|
||||
|
||||
bool STUInt64::isEquivalent(const SerializedType& t) const
|
||||
{
|
||||
const STUInt64* v = dynamic_cast<const STUInt64*>(&t);
|
||||
return v && (value == v->value);
|
||||
}
|
||||
|
||||
STHash128* STHash128::construct(SerializerIterator& u, SField::ref name)
|
||||
{
|
||||
return new STHash128(name, u.get128());
|
||||
}
|
||||
|
||||
std::string STHash128::getText() const
|
||||
{
|
||||
return value.GetHex();
|
||||
}
|
||||
|
||||
bool STHash128::isEquivalent(const SerializedType& t) const
|
||||
{
|
||||
const STHash128* v = dynamic_cast<const STHash128*>(&t);
|
||||
return v && (value == v->value);
|
||||
}
|
||||
|
||||
STHash160* STHash160::construct(SerializerIterator& u, SField::ref name)
|
||||
{
|
||||
return new STHash160(name, u.get160());
|
||||
}
|
||||
|
||||
std::string STHash160::getText() const
|
||||
{
|
||||
return value.GetHex();
|
||||
}
|
||||
|
||||
bool STHash160::isEquivalent(const SerializedType& t) const
|
||||
{
|
||||
const STHash160* v = dynamic_cast<const STHash160*>(&t);
|
||||
return v && (value == v->value);
|
||||
}
|
||||
|
||||
STHash256* STHash256::construct(SerializerIterator& u, SField::ref name)
|
||||
{
|
||||
return new STHash256(name, u.get256());
|
||||
}
|
||||
|
||||
std::string STHash256::getText() const
|
||||
{
|
||||
return value.GetHex();
|
||||
}
|
||||
|
||||
bool STHash256::isEquivalent(const SerializedType& t) const
|
||||
{
|
||||
const STHash256* v = dynamic_cast<const STHash256*>(&t);
|
||||
return v && (value == v->value);
|
||||
}
|
||||
|
||||
STVariableLength::STVariableLength(SerializerIterator& st, SField::ref name) : SerializedType(name)
|
||||
{
|
||||
value = st.getVL();
|
||||
}
|
||||
|
||||
std::string STVariableLength::getText() const
|
||||
{
|
||||
return strHex(value);
|
||||
}
|
||||
|
||||
STVariableLength* STVariableLength::construct(SerializerIterator& u, SField::ref name)
|
||||
{
|
||||
return new STVariableLength(name, u.getVL());
|
||||
}
|
||||
|
||||
bool STVariableLength::isEquivalent(const SerializedType& t) const
|
||||
{
|
||||
const STVariableLength* v = dynamic_cast<const STVariableLength*>(&t);
|
||||
return v && (value == v->value);
|
||||
}
|
||||
|
||||
std::string STAccount::getText() const
|
||||
{
|
||||
uint160 u;
|
||||
RippleAddress a;
|
||||
|
||||
if (!getValueH160(u))
|
||||
return STVariableLength::getText();
|
||||
a.setAccountID(u);
|
||||
return a.humanAccountID();
|
||||
}
|
||||
|
||||
STAccount* STAccount::construct(SerializerIterator& u, SField::ref name)
|
||||
{
|
||||
return new STAccount(name, u.getVL());
|
||||
}
|
||||
|
||||
//
|
||||
// STVector256
|
||||
//
|
||||
|
||||
// Return a new object from a SerializerIterator.
|
||||
STVector256* STVector256::construct(SerializerIterator& u, SField::ref name)
|
||||
{
|
||||
std::vector<unsigned char> data = u.getVL();
|
||||
std::vector<unsigned char>::iterator begin = data.begin();
|
||||
|
||||
UPTR_T<STVector256> vec(new STVector256(name));
|
||||
|
||||
int count = data.size() / (256 / 8);
|
||||
vec->mValue.reserve(count);
|
||||
|
||||
unsigned int uStart = 0;
|
||||
for (unsigned int i = 0; i != count; i++)
|
||||
{
|
||||
unsigned int uEnd = uStart + (256 / 8);
|
||||
|
||||
// This next line could be optimized to construct a default uint256 in the vector and then copy into it
|
||||
vec->mValue.push_back(uint256(std::vector<unsigned char>(begin + uStart, begin + uEnd)));
|
||||
uStart = uEnd;
|
||||
}
|
||||
|
||||
return vec.release();
|
||||
}
|
||||
|
||||
void STVector256::add(Serializer& s) const
|
||||
{
|
||||
s.addVL(mValue.empty() ? NULL : mValue[0].begin(), mValue.size() * (256 / 8));
|
||||
}
|
||||
|
||||
bool STVector256::isEquivalent(const SerializedType& t) const
|
||||
{
|
||||
const STVector256* v = dynamic_cast<const STVector256*>(&t);
|
||||
return v && (mValue == v->mValue);
|
||||
}
|
||||
|
||||
bool STVector256::hasValue(const uint256& v) const
|
||||
{
|
||||
BOOST_FOREACH(const uint256& hash, mValue)
|
||||
{
|
||||
if (hash == v)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//
|
||||
// STAccount
|
||||
//
|
||||
|
||||
STAccount::STAccount(SField::ref n, const uint160& v) : STVariableLength(n)
|
||||
{
|
||||
peekValue().insert(peekValue().end(), v.begin(), v.end());
|
||||
}
|
||||
|
||||
bool STAccount::isValueH160() const
|
||||
{
|
||||
return peekValue().size() == (160 / 8);
|
||||
}
|
||||
|
||||
void STAccount::setValueH160(const uint160& v)
|
||||
{
|
||||
peekValue().clear();
|
||||
peekValue().insert(peekValue().end(), v.begin(), v.end());
|
||||
assert(peekValue().size() == (160/8));
|
||||
}
|
||||
|
||||
bool STAccount::getValueH160(uint160& v) const
|
||||
{
|
||||
if (!isValueH160()) return false;
|
||||
memcpy(v.begin(), &(peekValue().front()), (160/8));
|
||||
return true;
|
||||
}
|
||||
|
||||
RippleAddress STAccount::getValueNCA() const
|
||||
{
|
||||
RippleAddress a;
|
||||
uint160 v;
|
||||
if (getValueH160(v))
|
||||
a.setAccountID(v);
|
||||
return a;
|
||||
}
|
||||
|
||||
void STAccount::setValueNCA(const RippleAddress& nca)
|
||||
{
|
||||
setValueH160(nca.getAccountID());
|
||||
}
|
||||
|
||||
STPathSet* STPathSet::construct(SerializerIterator& s, SField::ref name)
|
||||
{
|
||||
std::vector<STPath> paths;
|
||||
std::vector<STPathElement> path;
|
||||
|
||||
do
|
||||
{
|
||||
int iType = s.get8();
|
||||
|
||||
if (iType == STPathElement::typeEnd || iType == STPathElement::typeBoundary)
|
||||
{
|
||||
if (path.empty())
|
||||
{
|
||||
WriteLog (lsINFO, SerializedType) << "STPathSet: Empty path.";
|
||||
|
||||
throw std::runtime_error("empty path");
|
||||
}
|
||||
|
||||
paths.push_back(path);
|
||||
path.clear();
|
||||
|
||||
if (iType == STPathElement::typeEnd)
|
||||
{
|
||||
return new STPathSet(name, paths);
|
||||
}
|
||||
}
|
||||
else if (iType & ~STPathElement::typeValidBits)
|
||||
{
|
||||
WriteLog (lsINFO, SerializedType) << "STPathSet: Bad path element: " << iType;
|
||||
|
||||
throw std::runtime_error("bad path element");
|
||||
}
|
||||
else
|
||||
{
|
||||
const bool bAccount = !!(iType & STPathElement::typeAccount);
|
||||
const bool bCurrency = !!(iType & STPathElement::typeCurrency);
|
||||
const bool bIssuer = !!(iType & STPathElement::typeIssuer);
|
||||
|
||||
uint160 uAccountID;
|
||||
uint160 uCurrency;
|
||||
uint160 uIssuerID;
|
||||
|
||||
if (bAccount)
|
||||
uAccountID = s.get160();
|
||||
|
||||
if (bCurrency)
|
||||
uCurrency = s.get160();
|
||||
|
||||
if (bIssuer)
|
||||
uIssuerID = s.get160();
|
||||
|
||||
path.push_back(STPathElement(uAccountID, uCurrency, uIssuerID, bCurrency));
|
||||
}
|
||||
} while(1);
|
||||
}
|
||||
|
||||
bool STPathSet::isEquivalent(const SerializedType& t) const
|
||||
{
|
||||
const STPathSet* v = dynamic_cast<const STPathSet*>(&t);
|
||||
return v && (value == v->value);
|
||||
}
|
||||
|
||||
bool STPath::hasSeen(const uint160 &uAccountId, const uint160& uCurrencyID, const uint160& uIssuerID)
|
||||
{
|
||||
for (int i = 0; i < mPath.size(); ++i)
|
||||
{
|
||||
const STPathElement& ele = getElement(i);
|
||||
if (ele.getAccountID() == uAccountId
|
||||
&& ele.getCurrency() == uCurrencyID
|
||||
&& ele.getIssuerID() == uIssuerID)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Json::Value STPath::getJson(int) const
|
||||
{
|
||||
Json::Value ret(Json::arrayValue);
|
||||
|
||||
BOOST_FOREACH(std::vector<STPathElement>::const_iterator::value_type it, mPath)
|
||||
{
|
||||
Json::Value elem(Json::objectValue);
|
||||
int iType = it.getNodeType();
|
||||
|
||||
elem["type"] = iType;
|
||||
elem["type_hex"] = strHex(iType);
|
||||
|
||||
if (iType & STPathElement::typeAccount)
|
||||
elem["account"] = RippleAddress::createHumanAccountID(it.getAccountID());
|
||||
|
||||
if (iType & STPathElement::typeCurrency)
|
||||
elem["currency"] = STAmount::createHumanCurrency(it.getCurrency());
|
||||
|
||||
if (iType & STPathElement::typeIssuer)
|
||||
elem["issuer"] = RippleAddress::createHumanAccountID(it.getIssuerID());
|
||||
|
||||
ret.append(elem);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
Json::Value STPathSet::getJson(int options) const
|
||||
{
|
||||
Json::Value ret(Json::arrayValue);
|
||||
|
||||
BOOST_FOREACH(std::vector<STPath>::const_iterator::value_type it, value)
|
||||
ret.append(it.getJson(options));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if 0
|
||||
std::string STPath::getText() const
|
||||
{
|
||||
std::string ret("[");
|
||||
bool first = true;
|
||||
|
||||
BOOST_FOREACH(const STPathElement& it, mPath)
|
||||
{
|
||||
if (!first) ret += ", ";
|
||||
switch (it.getNodeType())
|
||||
{
|
||||
case STPathElement::typeAccount:
|
||||
{
|
||||
ret += RippleAddress::createHumanAccountID(it.getNode());
|
||||
break;
|
||||
}
|
||||
|
||||
case STPathElement::typeOffer:
|
||||
{
|
||||
ret += "Offer(";
|
||||
ret += it.getNode().GetHex();
|
||||
ret += ")";
|
||||
break;
|
||||
}
|
||||
|
||||
default: throw std::runtime_error("Unknown path element");
|
||||
}
|
||||
first = false;
|
||||
}
|
||||
|
||||
return ret + "]";
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
std::string STPathSet::getText() const
|
||||
{
|
||||
std::string ret("{");
|
||||
bool firstPath = true;
|
||||
|
||||
BOOST_FOREACH(std::vector<STPath>::const_iterator::value_type it, value)
|
||||
{
|
||||
if (!firstPath)
|
||||
{
|
||||
ret += ", ";
|
||||
firstPath = false;
|
||||
}
|
||||
ret += it.getText();
|
||||
}
|
||||
return ret + "}";
|
||||
}
|
||||
#endif
|
||||
|
||||
void STPathSet::add(Serializer& s) const
|
||||
{
|
||||
bool bFirst = true;
|
||||
|
||||
BOOST_FOREACH(const STPath& spPath, value)
|
||||
{
|
||||
if (!bFirst)
|
||||
{
|
||||
s.add8(STPathElement::typeBoundary);
|
||||
}
|
||||
|
||||
BOOST_FOREACH(const STPathElement& speElement, spPath)
|
||||
{
|
||||
int iType = speElement.getNodeType();
|
||||
|
||||
s.add8(iType);
|
||||
|
||||
if (iType & STPathElement::typeAccount)
|
||||
s.add160(speElement.getAccountID());
|
||||
|
||||
if (iType & STPathElement::typeCurrency)
|
||||
s.add160(speElement.getCurrency());
|
||||
|
||||
if (iType & STPathElement::typeIssuer)
|
||||
s.add160(speElement.getIssuerID());
|
||||
}
|
||||
|
||||
bFirst = false;
|
||||
}
|
||||
s.add8(STPathElement::typeEnd);
|
||||
}
|
||||
// vim:ts=4
|
||||
@@ -1,885 +0,0 @@
|
||||
#ifndef __SERIALIZEDTYPES__
|
||||
#define __SERIALIZEDTYPES__
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
// CAUTION: Do not create a vector (or similar container) of any object derived from
|
||||
// SerializedType. Use Boost ptr_* containers. The copy assignment operator of
|
||||
// SerializedType has semantics that will cause contained types to change their names
|
||||
// when an object is deleted because copy assignment is used to "slide down" the
|
||||
// remaining types and this will not copy the field name. Changing the copy assignment
|
||||
// operator to copy the field name breaks the use of copy assignment just to copy values,
|
||||
// which is used in the transaction engine code.
|
||||
|
||||
enum PathFlags
|
||||
{
|
||||
PF_END = 0x00, // End of current path & path list.
|
||||
PF_BOUNDARY = 0xFF, // End of current path & new path follows.
|
||||
|
||||
PF_ACCOUNT = 0x01,
|
||||
PF_OFFER = 0x02,
|
||||
|
||||
PF_WANTED_CURRENCY = 0x10,
|
||||
PF_WANTED_ISSUER = 0x20,
|
||||
PF_REDEEM = 0x40,
|
||||
PF_ISSUE = 0x80,
|
||||
};
|
||||
|
||||
// VFALCO: TODO, make these non static or otherwise clean constants.
|
||||
static const uint160 u160_zero(0), u160_one(1);
|
||||
static inline const uint160& get_u160_zero() { return u160_zero; }
|
||||
static inline const uint160& get_u160_one() { return u160_one; }
|
||||
|
||||
// VFALCO: TODO, replace these with language constructs, gah!
|
||||
#define CURRENCY_XRP get_u160_zero()
|
||||
#define CURRENCY_ONE get_u160_one() // Used as a place holder.
|
||||
#define CURRENCY_BAD uint160(0x5852500000000000) // Do not allow XRP as an IOU currency.
|
||||
#define ACCOUNT_XRP get_u160_zero()
|
||||
#define ACCOUNT_ONE get_u160_one() // Used as a place holder.
|
||||
|
||||
class SerializedType
|
||||
{
|
||||
public:
|
||||
SerializedType() : fName(&sfGeneric) { ; }
|
||||
|
||||
explicit SerializedType (SField::ref n) : fName(&n) { assert(fName); }
|
||||
|
||||
virtual ~SerializedType() { }
|
||||
|
||||
static UPTR_T<SerializedType> deserialize(SField::ref name)
|
||||
{ return UPTR_T<SerializedType>(new SerializedType(name)); }
|
||||
|
||||
void setFName(SField::ref n) { fName = &n; assert(fName); }
|
||||
SField::ref getFName() const { return *fName; }
|
||||
std::string getName() const { return fName->fieldName; }
|
||||
|
||||
virtual SerializedTypeID getSType() const { return STI_NOTPRESENT; }
|
||||
UPTR_T<SerializedType> clone() const { return UPTR_T<SerializedType>(duplicate()); }
|
||||
|
||||
virtual std::string getFullText() const;
|
||||
virtual std::string getText() const // just the value
|
||||
{ return std::string(); }
|
||||
virtual Json::Value getJson(int /*options*/) const
|
||||
{ return getText(); }
|
||||
|
||||
virtual void add(Serializer& s) const { ; }
|
||||
|
||||
virtual bool isEquivalent(const SerializedType& t) const
|
||||
{ assert(getSType() == STI_NOTPRESENT); return t.getSType() == STI_NOTPRESENT; }
|
||||
|
||||
void addFieldID(Serializer& s) const { s.addFieldID(fName->fieldType, fName->fieldValue); }
|
||||
|
||||
SerializedType& operator=(const SerializedType& t);
|
||||
|
||||
bool operator==(const SerializedType& t) const
|
||||
{ return (getSType() == t.getSType()) && isEquivalent(t); }
|
||||
bool operator!=(const SerializedType& t) const
|
||||
{ return (getSType() != t.getSType()) || !isEquivalent(t); }
|
||||
|
||||
virtual bool isDefault() const { return true; }
|
||||
|
||||
protected:
|
||||
// VFALCO: TODO, make accessors for this
|
||||
SField::ptr fName;
|
||||
|
||||
private:
|
||||
virtual SerializedType* duplicate() const { return new SerializedType(*fName); }
|
||||
};
|
||||
|
||||
inline SerializedType* new_clone(const SerializedType& s) { return s.clone().release(); }
|
||||
inline void delete_clone(const SerializedType* s) { boost::checked_delete(s); }
|
||||
inline std::ostream& operator<<(std::ostream& out, const SerializedType& t) { return out << t.getFullText(); }
|
||||
|
||||
class STUInt8 : public SerializedType
|
||||
{
|
||||
public:
|
||||
|
||||
STUInt8(unsigned char v = 0) : value(v) { ; }
|
||||
STUInt8(SField::ref n, unsigned char v = 0) : SerializedType(n), value(v) { ; }
|
||||
static UPTR_T<SerializedType> deserialize(SerializerIterator& sit, SField::ref name)
|
||||
{ return UPTR_T<SerializedType>(construct(sit, name)); }
|
||||
|
||||
SerializedTypeID getSType() const { return STI_UINT8; }
|
||||
std::string getText() const;
|
||||
Json::Value getJson(int) const;
|
||||
void add(Serializer& s) const { s.add8(value); }
|
||||
|
||||
unsigned char getValue() const { return value; }
|
||||
void setValue(unsigned char v) { value = v; }
|
||||
|
||||
operator unsigned char() const { return value; }
|
||||
virtual bool isEquivalent(const SerializedType& t) const;
|
||||
virtual bool isDefault() const { return value == 0; }
|
||||
|
||||
private:
|
||||
unsigned char value;
|
||||
|
||||
STUInt8* duplicate() const { return new STUInt8(*this); }
|
||||
static STUInt8* construct(SerializerIterator&, SField::ref f);
|
||||
};
|
||||
|
||||
class STUInt16 : public SerializedType
|
||||
{
|
||||
public:
|
||||
|
||||
STUInt16(uint16 v = 0) : value(v) { ; }
|
||||
STUInt16(SField::ref n, uint16 v = 0) : SerializedType(n), value(v) { ; }
|
||||
static UPTR_T<SerializedType> deserialize(SerializerIterator& sit, SField::ref name)
|
||||
{ return UPTR_T<SerializedType>(construct(sit, name)); }
|
||||
|
||||
SerializedTypeID getSType() const { return STI_UINT16; }
|
||||
std::string getText() const;
|
||||
Json::Value getJson(int) const;
|
||||
void add(Serializer& s) const { s.add16(value); }
|
||||
|
||||
uint16 getValue() const { return value; }
|
||||
void setValue(uint16 v) { value=v; }
|
||||
|
||||
operator uint16() const { return value; }
|
||||
virtual bool isEquivalent(const SerializedType& t) const;
|
||||
virtual bool isDefault() const { return value == 0; }
|
||||
|
||||
private:
|
||||
uint16 value;
|
||||
|
||||
STUInt16* duplicate() const { return new STUInt16(*this); }
|
||||
static STUInt16* construct(SerializerIterator&, SField::ref name);
|
||||
};
|
||||
|
||||
class STUInt32 : public SerializedType
|
||||
{
|
||||
public:
|
||||
|
||||
STUInt32(uint32 v = 0) : value(v) { ; }
|
||||
STUInt32(SField::ref n, uint32 v = 0) : SerializedType(n), value(v) { ; }
|
||||
static UPTR_T<SerializedType> deserialize(SerializerIterator& sit, SField::ref name)
|
||||
{ return UPTR_T<SerializedType>(construct(sit, name)); }
|
||||
|
||||
SerializedTypeID getSType() const { return STI_UINT32; }
|
||||
std::string getText() const;
|
||||
Json::Value getJson(int) const;
|
||||
void add(Serializer& s) const { s.add32(value); }
|
||||
|
||||
uint32 getValue() const { return value; }
|
||||
void setValue(uint32 v) { value=v; }
|
||||
|
||||
operator uint32() const { return value; }
|
||||
virtual bool isEquivalent(const SerializedType& t) const;
|
||||
virtual bool isDefault() const { return value == 0; }
|
||||
|
||||
private:
|
||||
uint32 value;
|
||||
|
||||
STUInt32* duplicate() const { return new STUInt32(*this); }
|
||||
static STUInt32* construct(SerializerIterator&, SField::ref name);
|
||||
};
|
||||
|
||||
class STUInt64 : public SerializedType
|
||||
{
|
||||
public:
|
||||
|
||||
STUInt64(uint64 v = 0) : value(v) { ; }
|
||||
STUInt64(SField::ref n, uint64 v = 0) : SerializedType(n), value(v) { ; }
|
||||
static UPTR_T<SerializedType> deserialize(SerializerIterator& sit, SField::ref name)
|
||||
{ return UPTR_T<SerializedType>(construct(sit, name)); }
|
||||
|
||||
SerializedTypeID getSType() const { return STI_UINT64; }
|
||||
std::string getText() const;
|
||||
Json::Value getJson(int) const;
|
||||
void add(Serializer& s) const { s.add64(value); }
|
||||
|
||||
uint64 getValue() const { return value; }
|
||||
void setValue(uint64 v) { value=v; }
|
||||
|
||||
operator uint64() const { return value; }
|
||||
virtual bool isEquivalent(const SerializedType& t) const;
|
||||
virtual bool isDefault() const { return value == 0; }
|
||||
|
||||
private:
|
||||
uint64 value;
|
||||
|
||||
STUInt64* duplicate() const { return new STUInt64(*this); }
|
||||
static STUInt64* construct(SerializerIterator&, SField::ref name);
|
||||
};
|
||||
|
||||
// Internal form:
|
||||
// 1: If amount is zero, then value is zero and offset is -100
|
||||
// 2: Otherwise:
|
||||
// legal offset range is -96 to +80 inclusive
|
||||
// value range is 10^15 to (10^16 - 1) inclusive
|
||||
// amount = value * [10 ^ offset]
|
||||
|
||||
// Wire form:
|
||||
// High 8 bits are (offset+142), legal range is, 80 to 22 inclusive
|
||||
// Low 56 bits are value, legal range is 10^15 to (10^16 - 1) inclusive
|
||||
class STAmount : public SerializedType
|
||||
{
|
||||
public:
|
||||
static const int cMinOffset = -96, cMaxOffset = 80;
|
||||
static const uint64 cMinValue = 1000000000000000ull, cMaxValue = 9999999999999999ull;
|
||||
static const uint64 cMaxNative = 9000000000000000000ull;
|
||||
static const uint64 cNotNative = 0x8000000000000000ull;
|
||||
static const uint64 cPosNative = 0x4000000000000000ull;
|
||||
|
||||
static uint64 uRateOne;
|
||||
|
||||
STAmount(uint64 v = 0, bool isNeg = false) : mValue(v), mOffset(0), mIsNative(true), mIsNegative(isNeg)
|
||||
{ if (v == 0) mIsNegative = false; }
|
||||
|
||||
STAmount(SField::ref n, uint64 v = 0, bool isNeg = false)
|
||||
: SerializedType(n), mValue(v), mOffset(0), mIsNative(true), mIsNegative(isNeg)
|
||||
{ ; }
|
||||
|
||||
STAmount(SField::ref n, int64 v) : SerializedType(n), mOffset(0), mIsNative(true)
|
||||
{ set(v); }
|
||||
|
||||
STAmount(const uint160& uCurrencyID, const uint160& uIssuerID,
|
||||
uint64 uV = 0, int iOff = 0, bool bNegative = false)
|
||||
: mCurrency(uCurrencyID), mIssuer(uIssuerID), mValue(uV), mOffset(iOff), mIsNegative(bNegative)
|
||||
{ canonicalize(); }
|
||||
|
||||
STAmount(const uint160& uCurrencyID, const uint160& uIssuerID,
|
||||
uint32 uV, int iOff = 0, bool bNegative = false)
|
||||
: mCurrency(uCurrencyID), mIssuer(uIssuerID), mValue(uV), mOffset(iOff), mIsNegative(bNegative)
|
||||
{ canonicalize(); }
|
||||
|
||||
STAmount(SField::ref n, const uint160& currency, const uint160& issuer,
|
||||
uint64 v = 0, int off = 0, bool isNeg = false) :
|
||||
SerializedType(n), mCurrency(currency), mIssuer(issuer), mValue(v), mOffset(off), mIsNegative(isNeg)
|
||||
{ canonicalize(); }
|
||||
|
||||
STAmount(const uint160& uCurrencyID, const uint160& uIssuerID, int64 v, int iOff = 0)
|
||||
: mCurrency(uCurrencyID), mIssuer(uIssuerID), mOffset(iOff)
|
||||
{
|
||||
set(v);
|
||||
canonicalize();
|
||||
}
|
||||
|
||||
STAmount(SField::ref n, const uint160& currency, const uint160& issuer, int64 v, int off = 0)
|
||||
: SerializedType(n), mCurrency(currency), mIssuer(issuer), mOffset(off)
|
||||
{
|
||||
set(v);
|
||||
canonicalize();
|
||||
}
|
||||
|
||||
STAmount(const uint160& uCurrencyID, const uint160& uIssuerID, int v, int iOff = 0)
|
||||
: mCurrency(uCurrencyID), mIssuer(uIssuerID), mOffset(iOff)
|
||||
{
|
||||
set(v);
|
||||
canonicalize();
|
||||
}
|
||||
|
||||
STAmount(SField::ref n, const uint160& currency, const uint160& issuer, int v, int off = 0)
|
||||
: SerializedType(n), mCurrency(currency), mIssuer(issuer), mOffset(off)
|
||||
{
|
||||
set(v);
|
||||
canonicalize();
|
||||
}
|
||||
|
||||
STAmount(SField::ref, const Json::Value&);
|
||||
|
||||
static STAmount createFromInt64(SField::ref n, int64 v);
|
||||
|
||||
static UPTR_T<SerializedType> deserialize(SerializerIterator& sit, SField::ref name)
|
||||
{ return UPTR_T<SerializedType>(construct(sit, name)); }
|
||||
|
||||
bool bSetJson(const Json::Value& jvSource);
|
||||
|
||||
static STAmount saFromRate(uint64 uRate = 0)
|
||||
{ return STAmount(CURRENCY_ONE, ACCOUNT_ONE, uRate, -9, false); }
|
||||
|
||||
SerializedTypeID getSType() const { return STI_AMOUNT; }
|
||||
std::string getText() const;
|
||||
std::string getRaw() const;
|
||||
std::string getFullText() const;
|
||||
void add(Serializer& s) const;
|
||||
|
||||
int getExponent() const { return mOffset; }
|
||||
uint64 getMantissa() const { return mValue; }
|
||||
|
||||
// When the currency is XRP, the value in raw units. S=signed
|
||||
uint64 getNValue() const { if (!mIsNative) throw std::runtime_error("not native"); return mValue; }
|
||||
void setNValue(uint64 v) { if (!mIsNative) throw std::runtime_error("not native"); mValue = v; }
|
||||
int64 getSNValue() const;
|
||||
void setSNValue(int64);
|
||||
|
||||
std::string getHumanCurrency() const;
|
||||
|
||||
bool isNative() const { return mIsNative; }
|
||||
bool isZero() const { return mValue == 0; }
|
||||
bool isNonZero() const { return mValue != 0; }
|
||||
bool isNegative() const { return mIsNegative && !isZero(); }
|
||||
bool isPositive() const { return !mIsNegative && !isZero(); }
|
||||
bool isGEZero() const { return !mIsNegative; }
|
||||
operator bool() const { return !isZero(); }
|
||||
|
||||
void negate() { if (!isZero()) mIsNegative = !mIsNegative; }
|
||||
void zero() { mOffset = mIsNative ? 0 : -100; mValue = 0; mIsNegative = false; }
|
||||
|
||||
// Zero while copying currency and issuer.
|
||||
void zero(const STAmount& saTmpl)
|
||||
{ mCurrency = saTmpl.mCurrency; mIssuer = saTmpl.mIssuer; mIsNative = saTmpl.mIsNative; zero(); }
|
||||
void zero(const uint160& uCurrencyID, const uint160& uIssuerID)
|
||||
{ mCurrency = uCurrencyID; mIssuer = uIssuerID; mIsNative = !uCurrencyID; zero(); }
|
||||
|
||||
int compare(const STAmount&) const;
|
||||
|
||||
const uint160& getIssuer() const { return mIssuer; }
|
||||
STAmount* setIssuer(const uint160& uIssuer) { mIssuer = uIssuer; return this; }
|
||||
|
||||
const uint160& getCurrency() const { return mCurrency; }
|
||||
bool setValue(const std::string& sAmount);
|
||||
bool setFullValue(const std::string& sAmount, const std::string& sCurrency = "", const std::string& sIssuer = "");
|
||||
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;
|
||||
bool operator<(const STAmount&) const;
|
||||
bool operator>(const STAmount&) const;
|
||||
bool operator<=(const STAmount&) const;
|
||||
bool operator>=(const STAmount&) const;
|
||||
bool isComparable(const STAmount&) const;
|
||||
void throwComparable(const STAmount&) const;
|
||||
|
||||
// native currency only
|
||||
bool operator<(uint64) const;
|
||||
bool operator>(uint64) const;
|
||||
bool operator<=(uint64) const;
|
||||
bool operator>=(uint64) const;
|
||||
STAmount operator+(uint64) const;
|
||||
STAmount operator-(uint64) const;
|
||||
STAmount operator-(void) const;
|
||||
|
||||
STAmount& operator+=(const STAmount&);
|
||||
STAmount& operator-=(const STAmount&);
|
||||
STAmount& operator+=(uint64);
|
||||
STAmount& operator-=(uint64);
|
||||
STAmount& operator=(uint64);
|
||||
|
||||
operator double() const;
|
||||
|
||||
friend STAmount operator+(const STAmount& v1, const STAmount& v2);
|
||||
friend STAmount operator-(const STAmount& v1, const STAmount& v2);
|
||||
|
||||
static STAmount divide(const STAmount& v1, const STAmount& v2, const uint160& uCurrencyID, const uint160& uIssuerID);
|
||||
static STAmount divide(const STAmount& v1, const STAmount& v2, const STAmount& saUnit)
|
||||
{ return divide(v1, v2, saUnit.getCurrency(), saUnit.getIssuer()); }
|
||||
static STAmount divide(const STAmount& v1, const STAmount& v2)
|
||||
{ return divide(v1, v2, v1); }
|
||||
|
||||
static STAmount multiply(const STAmount& v1, const STAmount& v2, const uint160& uCurrencyID, const uint160& uIssuerID);
|
||||
static STAmount multiply(const STAmount& v1, const STAmount& v2, const STAmount& saUnit)
|
||||
{ return multiply(v1, v2, saUnit.getCurrency(), saUnit.getIssuer()); }
|
||||
static STAmount multiply(const STAmount& v1, const STAmount& v2)
|
||||
{ return multiply(v1, v2, v1); }
|
||||
|
||||
// Add, subtract, multiply, or divide rounding result in specified direction
|
||||
static STAmount addRound(const STAmount& v1, const STAmount& v2, bool roundUp);
|
||||
static STAmount subRound(const STAmount& v1, const STAmount& v2, bool roundUp);
|
||||
static STAmount mulRound(const STAmount& v1, const STAmount& v2,
|
||||
const uint160& currency, const uint160& issuer, bool roundUp);
|
||||
static STAmount divRound(const STAmount& v1, const STAmount& v2,
|
||||
const uint160& currency, const uint160& issuer, bool roundUp);
|
||||
|
||||
static STAmount mulRound(const STAmount& v1, const STAmount& v2, const STAmount& saUnit, bool roundUp)
|
||||
{ return mulRound(v1, v2, saUnit.getCurrency(), saUnit.getIssuer(), roundUp); }
|
||||
static STAmount mulRound(const STAmount& v1, const STAmount& v2, bool roundUp)
|
||||
{ return mulRound(v1, v2, v1.getCurrency(), v1.getIssuer(), roundUp); }
|
||||
static STAmount divRound(const STAmount& v1, const STAmount& v2, const STAmount& saUnit, bool roundUp)
|
||||
{ return divRound(v1, v2, saUnit.getCurrency(), saUnit.getIssuer(), roundUp); }
|
||||
static STAmount divRound(const STAmount& v1, const STAmount& v2, bool roundUp)
|
||||
{ return divRound(v1, v2, v1.getCurrency(), v1.getIssuer(), roundUp); }
|
||||
|
||||
// Someone is offering X for Y, what is the rate?
|
||||
// Rate: smaller is better, the taker wants the most out: in/out
|
||||
static uint64 getRate(const STAmount& offerOut, const STAmount& offerIn);
|
||||
static STAmount setRate(uint64 rate);
|
||||
|
||||
// Someone is offering X for Y, I try to pay Z, how much do I get?
|
||||
// And what's left of the offer? And how much do I actually pay?
|
||||
static bool applyOffer(
|
||||
const bool bSell,
|
||||
const uint32 uTakerPaysRate, const uint32 uOfferPaysRate,
|
||||
const STAmount& saOfferRate,
|
||||
const STAmount& saOfferFunds, const STAmount& saTakerFunds,
|
||||
const STAmount& saOfferPays, const STAmount& saOfferGets,
|
||||
const STAmount& saTakerPays, const STAmount& saTakerGets,
|
||||
STAmount& saTakerPaid, STAmount& saTakerGot,
|
||||
STAmount& saTakerIssuerFee, STAmount& saOfferIssuerFee);
|
||||
|
||||
// Someone is offering X for Y, I need Z, how much do I pay
|
||||
static STAmount getPay(const STAmount& offerOut, const STAmount& offerIn, const STAmount& needed);
|
||||
|
||||
static std::string createHumanCurrency(const uint160& uCurrency);
|
||||
static Json::Value createJsonCurrency(const uint160& uCurrency)
|
||||
// XXX Punted.
|
||||
{ return createHumanCurrency(uCurrency); }
|
||||
|
||||
static STAmount deserialize(SerializerIterator&);
|
||||
static bool currencyFromString(uint160& uDstCurrency, const std::string& sCurrency);
|
||||
static bool issuerFromString(uint160& uDstIssuer, const std::string& sIssuer);
|
||||
|
||||
Json::Value getJson(int) const;
|
||||
void setJson(Json::Value&) const;
|
||||
|
||||
STAmount getRound() const;
|
||||
void roundSelf();
|
||||
|
||||
private:
|
||||
uint160 mCurrency; // Compared by ==. Always update mIsNative.
|
||||
uint160 mIssuer; // Not compared by ==. 0 for XRP.
|
||||
|
||||
uint64 mValue;
|
||||
int mOffset;
|
||||
bool mIsNative; // Always !mCurrency. Native is XRP.
|
||||
bool mIsNegative;
|
||||
|
||||
void canonicalize();
|
||||
STAmount* duplicate() const { return new STAmount(*this); }
|
||||
static STAmount* construct(SerializerIterator&, SField::ref name);
|
||||
|
||||
STAmount(SField::ref name, const uint160& cur, const uint160& iss, uint64 val, int off, bool isNat, bool isNeg)
|
||||
: SerializedType(name), mCurrency(cur), mIssuer(iss), mValue(val), mOffset(off),
|
||||
mIsNative(isNat), mIsNegative(isNeg) { ; }
|
||||
|
||||
void set(int64 v)
|
||||
{
|
||||
if (v < 0)
|
||||
{
|
||||
mIsNegative = true;
|
||||
mValue = static_cast<uint64>(-v);
|
||||
}
|
||||
else
|
||||
{
|
||||
mIsNegative = false;
|
||||
mValue = static_cast<uint64>(v);
|
||||
}
|
||||
}
|
||||
|
||||
void set(int v)
|
||||
{
|
||||
if (v < 0)
|
||||
{
|
||||
mIsNegative = true;
|
||||
mValue = static_cast<uint64>(-v);
|
||||
}
|
||||
else
|
||||
{
|
||||
mIsNegative = false;
|
||||
mValue = static_cast<uint64>(v);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// VFALCO: TODO Make static member accessors for these in STAmount
|
||||
extern const STAmount saZero;
|
||||
extern const STAmount saOne;
|
||||
|
||||
class STHash128 : public SerializedType
|
||||
{
|
||||
public:
|
||||
STHash128(const uint128& v) : value(v) { ; }
|
||||
STHash128(SField::ref n, const uint128& v) : SerializedType(n), value(v) { ; }
|
||||
STHash128(SField::ref n, const char *v) : SerializedType(n) { value.SetHex(v); }
|
||||
STHash128(SField::ref n, const std::string &v) : SerializedType(n) { value.SetHex(v); }
|
||||
STHash128(SField::ref n) : SerializedType(n) { ; }
|
||||
STHash128() { ; }
|
||||
static UPTR_T<SerializedType> deserialize(SerializerIterator& sit, SField::ref name)
|
||||
{ return UPTR_T<SerializedType>(construct(sit, name)); }
|
||||
|
||||
SerializedTypeID getSType() const { return STI_HASH128; }
|
||||
virtual std::string getText() const;
|
||||
void add(Serializer& s) const { s.add128(value); }
|
||||
|
||||
const uint128& getValue() const { return value; }
|
||||
void setValue(const uint128& v) { value=v; }
|
||||
|
||||
operator uint128() const { return value; }
|
||||
virtual bool isEquivalent(const SerializedType& t) const;
|
||||
virtual bool isDefault() const { return value.isZero(); }
|
||||
|
||||
private:
|
||||
uint128 value;
|
||||
|
||||
STHash128* duplicate() const { return new STHash128(*this); }
|
||||
static STHash128* construct(SerializerIterator&, SField::ref name);
|
||||
};
|
||||
|
||||
class STHash160 : public SerializedType
|
||||
{
|
||||
public:
|
||||
STHash160(const uint160& v) : value(v) { ; }
|
||||
STHash160(SField::ref n, const uint160& v) : SerializedType(n), value(v) { ; }
|
||||
STHash160(SField::ref n, const char *v) : SerializedType(n) { value.SetHex(v); }
|
||||
STHash160(SField::ref n, const std::string &v) : SerializedType(n) { value.SetHex(v); }
|
||||
STHash160(SField::ref n) : SerializedType(n) { ; }
|
||||
STHash160() { ; }
|
||||
static UPTR_T<SerializedType> deserialize(SerializerIterator& sit, SField::ref name)
|
||||
{ return UPTR_T<SerializedType>(construct(sit, name)); }
|
||||
|
||||
SerializedTypeID getSType() const { return STI_HASH160; }
|
||||
virtual std::string getText() const;
|
||||
void add(Serializer& s) const { s.add160(value); }
|
||||
|
||||
const uint160& getValue() const { return value; }
|
||||
void setValue(const uint160& v) { value=v; }
|
||||
|
||||
operator uint160() const { return value; }
|
||||
virtual bool isEquivalent(const SerializedType& t) const;
|
||||
virtual bool isDefault() const { return value.isZero(); }
|
||||
|
||||
private:
|
||||
uint160 value;
|
||||
|
||||
STHash160* duplicate() const { return new STHash160(*this); }
|
||||
static STHash160* construct(SerializerIterator&, SField::ref name);
|
||||
};
|
||||
|
||||
class STHash256 : public SerializedType
|
||||
{
|
||||
public:
|
||||
STHash256(const uint256& v) : value(v) { ; }
|
||||
STHash256(SField::ref n, const uint256& v) : SerializedType(n), value(v) { ; }
|
||||
STHash256(SField::ref n, const char *v) : SerializedType(n) { value.SetHex(v); }
|
||||
STHash256(SField::ref n, const std::string &v) : SerializedType(n) { value.SetHex(v); }
|
||||
STHash256(SField::ref n) : SerializedType(n) { ; }
|
||||
STHash256() { ; }
|
||||
static UPTR_T<SerializedType> deserialize(SerializerIterator& sit, SField::ref name)
|
||||
{ return UPTR_T<SerializedType>(construct(sit, name)); }
|
||||
|
||||
SerializedTypeID getSType() const { return STI_HASH256; }
|
||||
std::string getText() const;
|
||||
void add(Serializer& s) const { s.add256(value); }
|
||||
|
||||
const uint256& getValue() const { return value; }
|
||||
void setValue(const uint256& v) { value=v; }
|
||||
|
||||
operator uint256() const { return value; }
|
||||
virtual bool isEquivalent(const SerializedType& t) const;
|
||||
virtual bool isDefault() const { return value.isZero(); }
|
||||
|
||||
private:
|
||||
uint256 value;
|
||||
|
||||
STHash256* duplicate() const { return new STHash256(*this); }
|
||||
static STHash256* construct(SerializerIterator&, SField::ref);
|
||||
};
|
||||
|
||||
// variable length byte string
|
||||
class STVariableLength : public SerializedType
|
||||
{
|
||||
public:
|
||||
STVariableLength(const std::vector<unsigned char>& v) : value(v) { ; }
|
||||
STVariableLength(SField::ref n, const std::vector<unsigned char>& v) : SerializedType(n), value(v) { ; }
|
||||
STVariableLength(SField::ref n) : SerializedType(n) { ; }
|
||||
STVariableLength(SerializerIterator&, SField::ref name = sfGeneric);
|
||||
STVariableLength() { ; }
|
||||
static UPTR_T<SerializedType> deserialize(SerializerIterator& sit, SField::ref name)
|
||||
{ return UPTR_T<SerializedType>(construct(sit, name)); }
|
||||
|
||||
virtual SerializedTypeID getSType() const { return STI_VL; }
|
||||
virtual std::string getText() const;
|
||||
void add(Serializer& s) const { s.addVL(value); }
|
||||
|
||||
const std::vector<unsigned char>& peekValue() const { return value; }
|
||||
std::vector<unsigned char>& peekValue() { return value; }
|
||||
std::vector<unsigned char> getValue() const { return value; }
|
||||
void setValue(const std::vector<unsigned char>& v) { value=v; }
|
||||
|
||||
operator std::vector<unsigned char>() const { return value; }
|
||||
virtual bool isEquivalent(const SerializedType& t) const;
|
||||
virtual bool isDefault() const { return value.empty(); }
|
||||
|
||||
private:
|
||||
std::vector<unsigned char> value;
|
||||
|
||||
virtual STVariableLength* duplicate() const { return new STVariableLength(*this); }
|
||||
static STVariableLength* construct(SerializerIterator&, SField::ref);
|
||||
};
|
||||
|
||||
class STAccount : public STVariableLength
|
||||
{
|
||||
public:
|
||||
STAccount(const std::vector<unsigned char>& v) : STVariableLength(v) { ; }
|
||||
STAccount(SField::ref n, const std::vector<unsigned char>& v) : STVariableLength(n, v) { ; }
|
||||
STAccount(SField::ref n, const uint160& v);
|
||||
STAccount(SField::ref n) : STVariableLength(n) { ; }
|
||||
STAccount() { ; }
|
||||
static UPTR_T<SerializedType> deserialize(SerializerIterator& sit, SField::ref name)
|
||||
{ return UPTR_T<SerializedType>(construct(sit, name)); }
|
||||
|
||||
SerializedTypeID getSType() const { return STI_ACCOUNT; }
|
||||
std::string getText() const;
|
||||
|
||||
RippleAddress getValueNCA() const;
|
||||
void setValueNCA(const RippleAddress& nca);
|
||||
|
||||
void setValueH160(const uint160& v);
|
||||
bool getValueH160(uint160&) const;
|
||||
bool isValueH160() const;
|
||||
|
||||
private:
|
||||
virtual STAccount* duplicate() const { return new STAccount(*this); }
|
||||
static STAccount* construct(SerializerIterator&, SField::ref);
|
||||
};
|
||||
|
||||
class STPathElement
|
||||
{
|
||||
private:
|
||||
// VFALCO: Remove these friend declarations
|
||||
friend class STPathSet;
|
||||
friend class STPath;
|
||||
friend class Pathfinder;
|
||||
|
||||
public:
|
||||
enum {
|
||||
typeEnd = 0x00,
|
||||
typeAccount = 0x01, // Rippling through an account (vs taking an offer).
|
||||
typeCurrency = 0x10, // Currency follows.
|
||||
typeIssuer = 0x20, // Issuer follows.
|
||||
typeBoundary = 0xFF, // Boundary between alternate paths.
|
||||
typeValidBits = (
|
||||
typeAccount
|
||||
| typeCurrency
|
||||
| typeIssuer
|
||||
), // Bits that may be non-zero.
|
||||
};
|
||||
|
||||
public:
|
||||
STPathElement(const uint160& uAccountID, const uint160& uCurrencyID, const uint160& uIssuerID,
|
||||
bool forceCurrency = false)
|
||||
: mAccountID(uAccountID), mCurrencyID(uCurrencyID), mIssuerID(uIssuerID)
|
||||
{
|
||||
mType =
|
||||
(uAccountID.isZero() ? 0 : STPathElement::typeAccount)
|
||||
| ((uCurrencyID.isZero() && !forceCurrency) ? 0 : STPathElement::typeCurrency)
|
||||
| (uIssuerID.isZero() ? 0 : STPathElement::typeIssuer);
|
||||
}
|
||||
|
||||
STPathElement(unsigned int uType, const uint160& uAccountID, const uint160& uCurrencyID, const uint160& uIssuerID)
|
||||
: mType(uType), mAccountID(uAccountID), mCurrencyID(uCurrencyID), mIssuerID(uIssuerID)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
int getNodeType() const { return mType; }
|
||||
bool isOffer() const { return mAccountID.isZero(); }
|
||||
bool isAccount() const { return !isOffer(); }
|
||||
|
||||
// Nodes are either an account ID or a offer prefix. Offer prefixs denote a class of offers.
|
||||
const uint160& getAccountID() const { return mAccountID; }
|
||||
const uint160& getCurrency() const { return mCurrencyID; }
|
||||
const uint160& getIssuerID() const { return mIssuerID; }
|
||||
|
||||
bool operator==(const STPathElement& t) const
|
||||
{
|
||||
return mType == t.mType && mAccountID == t.mAccountID && mCurrencyID == t.mCurrencyID &&
|
||||
mIssuerID == t.mIssuerID;
|
||||
}
|
||||
|
||||
private:
|
||||
unsigned int mType;
|
||||
uint160 mAccountID;
|
||||
uint160 mCurrencyID;
|
||||
uint160 mIssuerID;
|
||||
};
|
||||
|
||||
class STPath
|
||||
{
|
||||
public:
|
||||
STPath() { ; }
|
||||
STPath(const std::vector<STPathElement>& p) : mPath(p) { ; }
|
||||
|
||||
void printDebug();
|
||||
int size() const { return mPath.size(); }
|
||||
bool isEmpty() const { return mPath.empty(); }
|
||||
const STPathElement& getElement(int offset) const { return mPath[offset]; }
|
||||
const STPathElement& getElement(int offset) { return mPath[offset]; }
|
||||
void addElement(const STPathElement &e) { mPath.push_back(e); }
|
||||
void clear() { mPath.clear(); }
|
||||
bool hasSeen(const uint160 &uAccountId, const uint160& uCurrencyID, const uint160& uIssuerID);
|
||||
// std::string getText() const;
|
||||
Json::Value getJson(int) const;
|
||||
|
||||
// uint160 mCurrencyID;
|
||||
// uint160 mCurrentAccount; // what account is at the end of the path
|
||||
|
||||
std::vector<STPathElement>::iterator begin() { return mPath.begin(); }
|
||||
std::vector<STPathElement>::iterator end() { return mPath.end(); }
|
||||
std::vector<STPathElement>::const_iterator begin() const { return mPath.begin(); }
|
||||
std::vector<STPathElement>::const_iterator end() const { return mPath.end(); }
|
||||
|
||||
bool operator==(const STPath& t) const { return mPath == t.mPath; }
|
||||
|
||||
void setCanonical(const STPath& spExpanded);
|
||||
|
||||
private:
|
||||
friend class STPathSet;
|
||||
friend class Pathfinder;
|
||||
|
||||
std::vector<STPathElement> mPath;
|
||||
};
|
||||
|
||||
inline std::vector<STPathElement>::iterator range_begin(STPath & x)
|
||||
{
|
||||
return x.begin();
|
||||
}
|
||||
|
||||
inline std::vector<STPathElement>::iterator range_end(STPath & x)
|
||||
{
|
||||
return x.end();
|
||||
}
|
||||
|
||||
inline std::vector<STPathElement>::const_iterator range_begin(const STPath& x)
|
||||
{
|
||||
return x.begin();
|
||||
}
|
||||
|
||||
inline std::vector<STPathElement>::const_iterator range_end(const STPath& x)
|
||||
{
|
||||
return x.end();
|
||||
}
|
||||
|
||||
namespace boost
|
||||
{
|
||||
template<>
|
||||
struct range_mutable_iterator< STPath >
|
||||
{
|
||||
typedef std::vector<STPathElement>::iterator type;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct range_const_iterator< STPath >
|
||||
{
|
||||
typedef std::vector<STPathElement>::const_iterator type;
|
||||
};
|
||||
}
|
||||
|
||||
// A set of zero or more payment paths
|
||||
class STPathSet : public SerializedType
|
||||
{
|
||||
public:
|
||||
STPathSet () { ; }
|
||||
|
||||
explicit STPathSet(SField::ref n) : SerializedType(n) { ; }
|
||||
|
||||
explicit STPathSet(const std::vector<STPath>& v) : value(v) { ; }
|
||||
|
||||
STPathSet(SField::ref n, const std::vector<STPath>& v) : SerializedType(n), value(v) { ; }
|
||||
|
||||
static UPTR_T<SerializedType> deserialize(SerializerIterator& sit, SField::ref name)
|
||||
{
|
||||
return UPTR_T<SerializedType>(construct(sit, name));
|
||||
}
|
||||
|
||||
// std::string getText() const;
|
||||
void add(Serializer& s) const;
|
||||
virtual Json::Value getJson(int) const;
|
||||
|
||||
SerializedTypeID getSType() const { return STI_PATHSET; }
|
||||
int size() const { return value.size(); }
|
||||
const STPath& getPath(int off) const { return value[off]; }
|
||||
STPath& peekPath(int off) { return value[off]; }
|
||||
bool isEmpty() const { return value.empty(); }
|
||||
void clear() { value.clear(); }
|
||||
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();
|
||||
|
||||
std::vector<STPath>::iterator begin() { return value.begin(); }
|
||||
std::vector<STPath>::iterator end() { return value.end(); }
|
||||
std::vector<STPath>::const_iterator begin() const { return value.begin(); }
|
||||
std::vector<STPath>::const_iterator end() const { return value.end(); }
|
||||
|
||||
private:
|
||||
std::vector<STPath> value;
|
||||
|
||||
STPathSet* duplicate() const { return new STPathSet(*this); }
|
||||
static STPathSet* construct(SerializerIterator&, SField::ref);
|
||||
};
|
||||
|
||||
inline std::vector<STPath>::iterator range_begin(STPathSet & x)
|
||||
{
|
||||
return x.begin();
|
||||
}
|
||||
|
||||
inline std::vector<STPath>::iterator range_end(STPathSet & x)
|
||||
{
|
||||
return x.end();
|
||||
}
|
||||
|
||||
inline std::vector<STPath>::const_iterator range_begin(const STPathSet& x)
|
||||
{
|
||||
return x.begin();
|
||||
}
|
||||
|
||||
inline std::vector<STPath>::const_iterator range_end(const STPathSet& x)
|
||||
{
|
||||
return x.end();
|
||||
}
|
||||
|
||||
namespace boost
|
||||
{
|
||||
template<>
|
||||
struct range_mutable_iterator< STPathSet >
|
||||
{
|
||||
typedef std::vector<STPath>::iterator type;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct range_const_iterator< STPathSet >
|
||||
{
|
||||
typedef std::vector<STPath>::const_iterator type;
|
||||
};
|
||||
}
|
||||
|
||||
class STVector256 : public SerializedType
|
||||
{
|
||||
public:
|
||||
STVector256() { ; }
|
||||
STVector256(SField::ref n) : SerializedType(n) { ; }
|
||||
STVector256(SField::ref n, const std::vector<uint256>& v) : SerializedType(n), mValue(v) { ; }
|
||||
STVector256(const std::vector<uint256>& vector) : mValue(vector) { ; }
|
||||
|
||||
SerializedTypeID getSType() const { return STI_VECTOR256; }
|
||||
void add(Serializer& s) const;
|
||||
|
||||
static UPTR_T<SerializedType> deserialize(SerializerIterator& sit, SField::ref name)
|
||||
{ return UPTR_T<SerializedType>(construct(sit, name)); }
|
||||
|
||||
const std::vector<uint256>& peekValue() const { return mValue; }
|
||||
std::vector<uint256>& peekValue() { return mValue; }
|
||||
virtual bool isEquivalent(const SerializedType& t) const;
|
||||
virtual bool isDefault() const { return mValue.empty(); }
|
||||
|
||||
std::vector<uint256> getValue() const { return mValue; }
|
||||
int size() const { return mValue.size(); }
|
||||
bool isEmpty() const { return mValue.empty(); }
|
||||
|
||||
const uint256& at(int i) const { assert((i >= 0) && (i < size())); return mValue.at(i); }
|
||||
uint256& at(int i) { assert((i >= 0) && (i < size())); return mValue.at(i); }
|
||||
|
||||
void setValue(const STVector256& v) { mValue = v.mValue; }
|
||||
void setValue(const std::vector<uint256>& v) { mValue = v; }
|
||||
void addValue(const uint256& v) { mValue.push_back(v); }
|
||||
bool hasValue(const uint256& v) const;
|
||||
void sort() { std::sort(mValue.begin(), mValue.end()); }
|
||||
|
||||
Json::Value getJson(int) const;
|
||||
|
||||
private:
|
||||
std::vector<uint256> mValue;
|
||||
|
||||
STVector256* duplicate() const { return new STVector256(*this); }
|
||||
static STVector256* construct(SerializerIterator&, SField::ref);
|
||||
};
|
||||
|
||||
#endif
|
||||
// vim:ts=4
|
||||
@@ -1,8 +1,6 @@
|
||||
#ifndef __VALIDATION__
|
||||
#define __VALIDATION__
|
||||
|
||||
#include "SerializedObject.h"
|
||||
|
||||
DEFINE_INSTANCE(SerializedValidation);
|
||||
|
||||
class SerializedValidation : public STObject, private IS_INSTANCE(SerializedValidation)
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
|
||||
#include "SHAMap.h"
|
||||
#include "SerializedTransaction.h"
|
||||
#include "TransactionErr.h"
|
||||
|
||||
class Database;
|
||||
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
#include "SerializedTransaction.h"
|
||||
#include "SerializedLedger.h"
|
||||
#include "LedgerEntrySet.h"
|
||||
#include "TransactionErr.h"
|
||||
|
||||
|
||||
DEFINE_INSTANCE(TransactionEngine);
|
||||
|
||||
@@ -1,125 +0,0 @@
|
||||
|
||||
bool transResultInfo(TER terCode, std::string& strToken, std::string& strHuman)
|
||||
{
|
||||
static struct {
|
||||
TER terCode;
|
||||
const char* cpToken;
|
||||
const char* cpHuman;
|
||||
} transResultInfoA[] = {
|
||||
{ tecCLAIM, "tecCLAIM", "Fee claimed. Sequence used. No action." },
|
||||
{ tecDIR_FULL, "tecDIR_FULL", "Can not add entry to full directory." },
|
||||
{ tecFAILED_PROCESSING, "tecFAILED_PROCESSING", "Failed to correctly process transaction." },
|
||||
{ tecINSUF_RESERVE_LINE, "tecINSUF_RESERVE_LINE", "Insufficient reserve to add trust line." },
|
||||
{ tecINSUF_RESERVE_OFFER, "tecINSUF_RESERVE_OFFER", "Insufficient reserve to create offer." },
|
||||
{ tecNO_DST, "tecNO_DST", "Destination does not exist. Send XRP to create it." },
|
||||
{ tecNO_DST_INSUF_XRP, "tecNO_DST_INSUF_XRP", "Destination does not exist. Too little XRP sent to create it." },
|
||||
{ tecNO_LINE_INSUF_RESERVE, "tecNO_LINE_INSUF_RESERVE", "No such line. Too little reserve to create it." },
|
||||
{ tecNO_LINE_REDUNDANT, "tecNO_LINE_REDUNDANT", "Can't set non-existant line to default." },
|
||||
{ tecPATH_DRY, "tecPATH_DRY", "Path could not send partial amount." },
|
||||
{ tecPATH_PARTIAL, "tecPATH_PARTIAL", "Path could not send full amount." },
|
||||
|
||||
{ tecUNFUNDED, "tecUNFUNDED", "One of _ADD, _OFFER, or _SEND. Deprecated." },
|
||||
{ tecUNFUNDED_ADD, "tecUNFUNDED_ADD", "Insufficient XRP balance for WalletAdd." },
|
||||
{ tecUNFUNDED_OFFER, "tecUNFUNDED_OFFER", "Insufficient balance to fund created offer." },
|
||||
{ tecUNFUNDED_PAYMENT, "tecUNFUNDED_PAYMENT", "Insufficient XRP balance to send." },
|
||||
|
||||
{ tefFAILURE, "tefFAILURE", "Failed to apply." },
|
||||
{ tefALREADY, "tefALREADY", "The exact transaction was already in this ledger." },
|
||||
{ tefBAD_ADD_AUTH, "tefBAD_ADD_AUTH", "Not authorized to add account." },
|
||||
{ tefBAD_AUTH, "tefBAD_AUTH", "Transaction's public key is not authorized." },
|
||||
{ tefBAD_CLAIM_ID, "tefBAD_CLAIM_ID", "Malformed: Bad claim id." },
|
||||
{ tefBAD_GEN_AUTH, "tefBAD_GEN_AUTH", "Not authorized to claim generator." },
|
||||
{ tefBAD_LEDGER, "tefBAD_LEDGER", "Ledger in unexpected state." },
|
||||
{ tefCLAIMED, "tefCLAIMED", "Can not claim a previously claimed account." },
|
||||
{ tefCREATED, "tefCREATED", "Can't add an already created account." },
|
||||
{ tefDST_TAG_NEEDED, "tefDST_TAG_NEEDED", "Destination tag required." },
|
||||
{ tefEXCEPTION, "tefEXCEPTION", "Unexpected program state." },
|
||||
{ tefGEN_IN_USE, "tefGEN_IN_USE", "Generator already in use." },
|
||||
{ tefINTERNAL, "tefINTERNAL", "Internal error." },
|
||||
{ tefNO_AUTH_REQUIRED, "tefNO_AUTH_REQUIRED", "Auth is not required." },
|
||||
{ tefPAST_SEQ, "tefPAST_SEQ", "This sequence number has already past." },
|
||||
{ tefWRONG_PRIOR, "tefWRONG_PRIOR", "This previous transaction does not match." },
|
||||
|
||||
{ telLOCAL_ERROR, "telLOCAL_ERROR", "Local failure." },
|
||||
{ telBAD_DOMAIN, "telBAD_DOMAIN", "Domain too long." },
|
||||
{ telBAD_PATH_COUNT, "telBAD_PATH_COUNT", "Malformed: Too many paths." },
|
||||
{ telBAD_PUBLIC_KEY, "telBAD_PUBLIC_KEY", "Public key too long." },
|
||||
{ telFAILED_PROCESSING, "telFAILED_PROCESSING", "Failed to correctly process transaction." },
|
||||
{ telINSUF_FEE_P, "telINSUF_FEE_P", "Fee insufficient." },
|
||||
{ telNO_DST_PARTIAL, "telNO_DST_PARTIAL", "Partial payment to create account not allowed." },
|
||||
|
||||
{ temMALFORMED, "temMALFORMED", "Malformed transaction." },
|
||||
{ temBAD_AMOUNT, "temBAD_AMOUNT", "Can only send positive amounts." },
|
||||
{ temBAD_AUTH_MASTER, "temBAD_AUTH_MASTER", "Auth for unclaimed account needs correct master key." },
|
||||
{ temBAD_CURRENCY, "temBAD_CURRENCY", "Malformed: Bad currency." },
|
||||
{ temBAD_FEE, "temBAD_FEE", "Invalid fee, negative or not XRP." },
|
||||
{ temBAD_EXPIRATION, "temBAD_EXPIRATION", "Malformed: Bad expiration." },
|
||||
{ temBAD_ISSUER, "temBAD_ISSUER", "Malformed: Bad issuer." },
|
||||
{ temBAD_LIMIT, "temBAD_LIMIT", "Limits must be non-negative." },
|
||||
{ temBAD_OFFER, "temBAD_OFFER", "Malformed: Bad offer." },
|
||||
{ temBAD_PATH, "temBAD_PATH", "Malformed: Bad path." },
|
||||
{ temBAD_PATH_LOOP, "temBAD_PATH_LOOP", "Malformed: Loop in path." },
|
||||
{ temBAD_PUBLISH, "temBAD_PUBLISH", "Malformed: Bad publish." },
|
||||
{ temBAD_SIGNATURE, "temBAD_SIGNATURE", "Malformed: Bad signature." },
|
||||
{ temBAD_SRC_ACCOUNT, "temBAD_SRC_ACCOUNT", "Malformed: Bad source account." },
|
||||
{ temBAD_TRANSFER_RATE, "temBAD_TRANSFER_RATE", "Malformed: Transfer rate must be >= 1.0" },
|
||||
{ temBAD_SEQUENCE, "temBAD_SEQUENCE", "Malformed: Sequence is not in the past." },
|
||||
{ temBAD_SEND_XRP_LIMIT, "temBAD_SEND_XRP_LIMIT", "Malformed: Limit quality is not allowed for XRP to XRP." },
|
||||
{ temBAD_SEND_XRP_MAX, "temBAD_SEND_XRP_MAX", "Malformed: Send max is not allowed for XRP to XRP." },
|
||||
{ temBAD_SEND_XRP_NO_DIRECT, "temBAD_SEND_XRP_NO_DIRECT", "Malformed: No Ripple direct is not allowed for XRP to XRP." },
|
||||
{ temBAD_SEND_XRP_PARTIAL, "temBAD_SEND_XRP_PARTIAL", "Malformed: Partial payment is not allowed for XRP to XRP." },
|
||||
{ temBAD_SEND_XRP_PATHS, "temBAD_SEND_XRP_PATHS", "Malformed: Paths are not allowed for XRP to XRP." },
|
||||
{ temDST_IS_SRC, "temDST_IS_SRC", "Destination may not be source." },
|
||||
{ temDST_NEEDED, "temDST_NEEDED", "Destination not specified." },
|
||||
{ temINVALID, "temINVALID", "The transaction is ill-formed." },
|
||||
{ temINVALID_FLAG, "temINVALID_FLAG", "The transaction has an invalid flag." },
|
||||
{ temREDUNDANT, "temREDUNDANT", "Sends same currency to self." },
|
||||
{ temREDUNDANT_SEND_MAX, "temREDUNDANT_SEND_MAX", "Send max is redundant." },
|
||||
{ temRIPPLE_EMPTY, "temRIPPLE_EMPTY", "PathSet with no paths." },
|
||||
{ temUNCERTAIN, "temUNCERTAIN", "In process of determining result. Never returned." },
|
||||
{ temUNKNOWN, "temUNKNOWN", "The transactions requires logic not implemented yet." },
|
||||
|
||||
{ terRETRY, "terRETRY", "Retry transaction." },
|
||||
{ terFUNDS_SPENT, "terFUNDS_SPENT", "Can't set password, password set funds already spent." },
|
||||
{ terINSUF_FEE_B, "terINSUF_FEE_B", "Account balance can't pay fee." },
|
||||
{ terLAST, "terLAST", "Process last." },
|
||||
{ terNO_ACCOUNT, "terNO_ACCOUNT", "The source account does not exist." },
|
||||
{ terNO_AUTH, "terNO_AUTH", "Not authorized to hold IOUs." },
|
||||
{ terNO_LINE, "terNO_LINE", "No such line." },
|
||||
{ terPRE_SEQ, "terPRE_SEQ", "Missing/inapplicable prior transaction." },
|
||||
{ terOWNERS, "terOWNERS", "Non-zero owner count." },
|
||||
|
||||
{ tesSUCCESS, "tesSUCCESS", "The transaction was applied." },
|
||||
};
|
||||
|
||||
int iIndex = NUMBER(transResultInfoA);
|
||||
|
||||
while (iIndex-- && transResultInfoA[iIndex].terCode != terCode)
|
||||
;
|
||||
|
||||
if (iIndex >= 0)
|
||||
{
|
||||
strToken = transResultInfoA[iIndex].cpToken;
|
||||
strHuman = transResultInfoA[iIndex].cpHuman;
|
||||
}
|
||||
|
||||
return iIndex >= 0;
|
||||
}
|
||||
|
||||
std::string transToken(TER terCode)
|
||||
{
|
||||
std::string strToken;
|
||||
std::string strHuman;
|
||||
|
||||
return transResultInfo(terCode, strToken, strHuman) ? strToken : "-";
|
||||
}
|
||||
|
||||
std::string transHuman(TER terCode)
|
||||
{
|
||||
std::string strToken;
|
||||
std::string strHuman;
|
||||
|
||||
return transResultInfo(terCode, strToken, strHuman) ? strHuman : "-";
|
||||
}
|
||||
|
||||
// vim:ts=4
|
||||
@@ -1,154 +0,0 @@
|
||||
#ifndef _TRANSACTION_ERR_
|
||||
#define _TRANSACTION_ERR_
|
||||
|
||||
#include <string>
|
||||
|
||||
enum TER // aka TransactionEngineResult
|
||||
{
|
||||
// Note: Range is stable. Exact numbers are currently unstable. Use tokens.
|
||||
|
||||
// -399 .. -300: L Local error (transaction fee inadequate, exceeds local limit)
|
||||
// Only valid during non-consensus processing.
|
||||
// Implications:
|
||||
// - Not forwarded
|
||||
// - No fee check
|
||||
telLOCAL_ERROR = -399,
|
||||
telBAD_DOMAIN,
|
||||
telBAD_PATH_COUNT,
|
||||
telBAD_PUBLIC_KEY,
|
||||
telFAILED_PROCESSING,
|
||||
telINSUF_FEE_P,
|
||||
telNO_DST_PARTIAL,
|
||||
|
||||
// -299 .. -200: M Malformed (bad signature)
|
||||
// Causes:
|
||||
// - Transaction corrupt.
|
||||
// Implications:
|
||||
// - Not applied
|
||||
// - Not forwarded
|
||||
// - Reject
|
||||
// - Can not succeed in any imagined ledger.
|
||||
temMALFORMED = -299,
|
||||
temBAD_AMOUNT,
|
||||
temBAD_AUTH_MASTER,
|
||||
temBAD_CURRENCY,
|
||||
temBAD_FEE,
|
||||
temBAD_EXPIRATION,
|
||||
temBAD_ISSUER,
|
||||
temBAD_LIMIT,
|
||||
temBAD_OFFER,
|
||||
temBAD_PATH,
|
||||
temBAD_PATH_LOOP,
|
||||
temBAD_PUBLISH,
|
||||
temBAD_TRANSFER_RATE,
|
||||
temBAD_SEND_XRP_LIMIT,
|
||||
temBAD_SEND_XRP_MAX,
|
||||
temBAD_SEND_XRP_NO_DIRECT,
|
||||
temBAD_SEND_XRP_PARTIAL,
|
||||
temBAD_SEND_XRP_PATHS,
|
||||
temBAD_SIGNATURE,
|
||||
temBAD_SRC_ACCOUNT,
|
||||
temBAD_SEQUENCE,
|
||||
temDST_IS_SRC,
|
||||
temDST_NEEDED,
|
||||
temINVALID,
|
||||
temINVALID_FLAG,
|
||||
temREDUNDANT,
|
||||
temREDUNDANT_SEND_MAX,
|
||||
temRIPPLE_EMPTY,
|
||||
temUNCERTAIN, // An intermediate result used internally, should never be returned.
|
||||
temUNKNOWN,
|
||||
|
||||
// -199 .. -100: F Failure (sequence number previously used)
|
||||
// Causes:
|
||||
// - Transaction cannot succeed because of ledger state.
|
||||
// - Unexpected ledger state.
|
||||
// - C++ exception.
|
||||
// Implications:
|
||||
// - Not applied
|
||||
// - Not forwarded
|
||||
// - Could succeed in an imagined ledger.
|
||||
tefFAILURE = -199,
|
||||
tefALREADY,
|
||||
tefBAD_ADD_AUTH,
|
||||
tefBAD_AUTH,
|
||||
tefBAD_CLAIM_ID,
|
||||
tefBAD_GEN_AUTH,
|
||||
tefBAD_LEDGER,
|
||||
tefCLAIMED,
|
||||
tefCREATED,
|
||||
tefDST_TAG_NEEDED,
|
||||
tefEXCEPTION,
|
||||
tefGEN_IN_USE,
|
||||
tefINTERNAL,
|
||||
tefNO_AUTH_REQUIRED, // Can't set auth if auth is not required.
|
||||
tefPAST_SEQ,
|
||||
tefWRONG_PRIOR,
|
||||
|
||||
// -99 .. -1: R Retry (sequence too high, no funds for txn fee, originating account non-existent)
|
||||
// Causes:
|
||||
// - Prior application of another, possibly non-existant, another transaction could allow this transaction to succeed.
|
||||
// Implications:
|
||||
// - Not applied
|
||||
// - Not forwarded
|
||||
// - Might succeed later
|
||||
// - Hold
|
||||
// - Makes hole in sequence which jams transactions.
|
||||
terRETRY = -99,
|
||||
terFUNDS_SPENT, // This is a free transaction, therefore don't burden network.
|
||||
terINSUF_FEE_B, // Can't pay fee, therefore don't burden network.
|
||||
terNO_ACCOUNT, // Can't pay fee, therefore don't burden network.
|
||||
terNO_AUTH, // Not authorized to hold IOUs.
|
||||
terNO_LINE, // Internal flag.
|
||||
terOWNERS, // Can't succeed with non-zero owner count.
|
||||
terPRE_SEQ, // Can't pay fee, no point in forwarding, therefore don't burden network.
|
||||
terLAST, // Process after all other transactions
|
||||
|
||||
// 0: S Success (success)
|
||||
// Causes:
|
||||
// - Success.
|
||||
// Implications:
|
||||
// - Applied
|
||||
// - Forwarded
|
||||
tesSUCCESS = 0,
|
||||
|
||||
// 100 .. 129 C Claim fee only (ripple transaction with no good paths, pay to non-existent account, no path)
|
||||
// Causes:
|
||||
// - Success, but does not achieve optimal result.
|
||||
// - Invalid transaction or no effect, but claim fee to use the sequence number.
|
||||
// Implications:
|
||||
// - Applied
|
||||
// - Forwarded
|
||||
// Only allowed as a return code of appliedTransaction when !tapRetry. Otherwise, treated as terRETRY.
|
||||
//
|
||||
// DO NOT CHANGE THESE NUMBERS: They appear in ledger meta data.
|
||||
tecCLAIM = 100,
|
||||
tecPATH_PARTIAL = 101,
|
||||
tecUNFUNDED_ADD = 102,
|
||||
tecUNFUNDED_OFFER = 103,
|
||||
tecUNFUNDED_PAYMENT = 104,
|
||||
tecFAILED_PROCESSING = 105,
|
||||
tecDIR_FULL = 121,
|
||||
tecINSUF_RESERVE_LINE = 122,
|
||||
tecINSUF_RESERVE_OFFER = 123,
|
||||
tecNO_DST = 124,
|
||||
tecNO_DST_INSUF_XRP = 125,
|
||||
tecNO_LINE_INSUF_RESERVE = 126,
|
||||
tecNO_LINE_REDUNDANT = 127,
|
||||
tecPATH_DRY = 128,
|
||||
tecUNFUNDED = 129, // Deprecated, old ambiguous unfunded.
|
||||
};
|
||||
|
||||
#define isTelLocal(x) ((x) >= telLOCAL_ERROR && (x) < temMALFORMED)
|
||||
#define isTemMalformed(x) ((x) >= temMALFORMED && (x) < tefFAILURE)
|
||||
#define isTefFailure(x) ((x) >= tefFAILURE && (x) < terRETRY)
|
||||
#define isTerRetry(x) ((x) >= terRETRY && (x) < tesSUCCESS)
|
||||
#define isTesSuccess(x) ((x) == tesSUCCESS)
|
||||
#define isTecClaim(x) ((x) >= tecCLAIM)
|
||||
|
||||
bool transResultInfo(TER terCode, std::string& strToken, std::string& strHuman);
|
||||
std::string transToken(TER terCode);
|
||||
std::string transHuman(TER terCode);
|
||||
|
||||
#endif
|
||||
// vim:ts=4
|
||||
@@ -1,112 +0,0 @@
|
||||
|
||||
std::map<int, TransactionFormat*> TransactionFormat::byType;
|
||||
std::map<std::string, TransactionFormat*> TransactionFormat::byName;
|
||||
|
||||
#define TF_BASE \
|
||||
<< SOElement(sfTransactionType, SOE_REQUIRED) \
|
||||
<< SOElement(sfFlags, SOE_OPTIONAL) \
|
||||
<< SOElement(sfSourceTag, SOE_OPTIONAL) \
|
||||
<< SOElement(sfAccount, SOE_REQUIRED) \
|
||||
<< SOElement(sfSequence, SOE_REQUIRED) \
|
||||
<< SOElement(sfPreviousTxnID, SOE_OPTIONAL) \
|
||||
<< SOElement(sfFee, SOE_REQUIRED) \
|
||||
<< SOElement(sfOperationLimit, SOE_OPTIONAL) \
|
||||
<< SOElement(sfSigningPubKey, SOE_REQUIRED) \
|
||||
<< SOElement(sfTxnSignature, SOE_OPTIONAL)
|
||||
|
||||
#define DECLARE_TF(name, type) tf = new TransactionFormat(#name, type); (*tf) TF_BASE
|
||||
|
||||
void TFInit()
|
||||
{
|
||||
TransactionFormat* tf;
|
||||
|
||||
DECLARE_TF(AccountSet, ttACCOUNT_SET)
|
||||
<< SOElement(sfEmailHash, SOE_OPTIONAL)
|
||||
<< SOElement(sfWalletLocator, SOE_OPTIONAL)
|
||||
<< SOElement(sfWalletSize, SOE_OPTIONAL)
|
||||
<< SOElement(sfMessageKey, SOE_OPTIONAL)
|
||||
<< SOElement(sfDomain, SOE_OPTIONAL)
|
||||
<< SOElement(sfTransferRate, SOE_OPTIONAL)
|
||||
;
|
||||
|
||||
DECLARE_TF(TrustSet, ttTRUST_SET)
|
||||
<< SOElement(sfLimitAmount, SOE_OPTIONAL)
|
||||
<< SOElement(sfQualityIn, SOE_OPTIONAL)
|
||||
<< SOElement(sfQualityOut, SOE_OPTIONAL)
|
||||
;
|
||||
|
||||
DECLARE_TF(OfferCreate, ttOFFER_CREATE)
|
||||
<< SOElement(sfTakerPays, SOE_REQUIRED)
|
||||
<< SOElement(sfTakerGets, SOE_REQUIRED)
|
||||
<< SOElement(sfExpiration, SOE_OPTIONAL)
|
||||
;
|
||||
|
||||
DECLARE_TF(OfferCancel, ttOFFER_CANCEL)
|
||||
<< SOElement(sfOfferSequence, SOE_REQUIRED)
|
||||
;
|
||||
|
||||
DECLARE_TF(SetRegularKey, ttREGULAR_KEY_SET)
|
||||
<< SOElement(sfRegularKey, SOE_REQUIRED)
|
||||
;
|
||||
|
||||
DECLARE_TF(Payment, ttPAYMENT)
|
||||
<< SOElement(sfDestination, SOE_REQUIRED)
|
||||
<< SOElement(sfAmount, SOE_REQUIRED)
|
||||
<< SOElement(sfSendMax, SOE_OPTIONAL)
|
||||
<< SOElement(sfPaths, SOE_DEFAULT)
|
||||
<< SOElement(sfInvoiceID, SOE_OPTIONAL)
|
||||
<< SOElement(sfDestinationTag, SOE_OPTIONAL)
|
||||
;
|
||||
|
||||
DECLARE_TF(Contract, ttCONTRACT)
|
||||
<< SOElement(sfExpiration, SOE_REQUIRED)
|
||||
<< SOElement(sfBondAmount, SOE_REQUIRED)
|
||||
<< SOElement(sfStampEscrow, SOE_REQUIRED)
|
||||
<< SOElement(sfRippleEscrow, SOE_REQUIRED)
|
||||
<< SOElement(sfCreateCode, SOE_OPTIONAL)
|
||||
<< SOElement(sfFundCode, SOE_OPTIONAL)
|
||||
<< SOElement(sfRemoveCode, SOE_OPTIONAL)
|
||||
<< SOElement(sfExpireCode, SOE_OPTIONAL)
|
||||
;
|
||||
|
||||
DECLARE_TF(RemoveContract, ttCONTRACT_REMOVE)
|
||||
<< SOElement(sfTarget, SOE_REQUIRED)
|
||||
;
|
||||
|
||||
DECLARE_TF(EnableFeature, ttFEATURE)
|
||||
<< SOElement(sfFeature, SOE_REQUIRED)
|
||||
;
|
||||
|
||||
DECLARE_TF(SetFee, ttFEE)
|
||||
<< SOElement(sfBaseFee, SOE_REQUIRED)
|
||||
<< SOElement(sfReferenceFeeUnits, SOE_REQUIRED)
|
||||
<< SOElement(sfReserveBase, SOE_REQUIRED)
|
||||
<< SOElement(sfReserveIncrement, SOE_REQUIRED)
|
||||
;
|
||||
}
|
||||
|
||||
TransactionFormat* TransactionFormat::getTxnFormat(TransactionType t)
|
||||
{
|
||||
std::map<int, TransactionFormat*>::iterator it = byType.find(static_cast<int>(t));
|
||||
if (it == byType.end())
|
||||
return NULL;
|
||||
return it->second;
|
||||
}
|
||||
|
||||
TransactionFormat* TransactionFormat::getTxnFormat(int t)
|
||||
{
|
||||
std::map<int, TransactionFormat*>::iterator it = byType.find((t));
|
||||
if (it == byType.end())
|
||||
return NULL;
|
||||
return it->second;
|
||||
}
|
||||
|
||||
TransactionFormat* TransactionFormat::getTxnFormat(const std::string& t)
|
||||
{
|
||||
std::map<std::string, TransactionFormat*>::iterator it = byName.find((t));
|
||||
if (it == byName.end())
|
||||
return NULL;
|
||||
return it->second;
|
||||
}
|
||||
|
||||
// vim:ts=4
|
||||
@@ -1,91 +0,0 @@
|
||||
#ifndef __TRANSACTIONFORMATS__
|
||||
#define __TRANSACTIONFORMATS__
|
||||
|
||||
#include "SerializedObject.h"
|
||||
#include "LedgerFormats.h"
|
||||
|
||||
enum TransactionType
|
||||
{
|
||||
ttINVALID = -1,
|
||||
|
||||
ttPAYMENT = 0,
|
||||
ttCLAIM = 1, // open
|
||||
ttWALLET_ADD = 2,
|
||||
ttACCOUNT_SET = 3,
|
||||
ttPASSWORD_FUND = 4, // open
|
||||
ttREGULAR_KEY_SET = 5,
|
||||
ttNICKNAME_SET = 6, // open
|
||||
ttOFFER_CREATE = 7,
|
||||
ttOFFER_CANCEL = 8,
|
||||
ttCONTRACT = 9,
|
||||
ttCONTRACT_REMOVE = 10, // can we use the same msg as offer cancel
|
||||
|
||||
ttTRUST_SET = 20,
|
||||
|
||||
ttFEATURE = 100,
|
||||
ttFEE = 101,
|
||||
};
|
||||
|
||||
class TransactionFormat
|
||||
{
|
||||
public:
|
||||
std::string t_name;
|
||||
TransactionType t_type;
|
||||
SOTemplate elements;
|
||||
|
||||
static std::map<int, TransactionFormat*> byType;
|
||||
static std::map<std::string, TransactionFormat*> byName;
|
||||
|
||||
TransactionFormat(const char *name, TransactionType type) : t_name(name), t_type(type)
|
||||
{
|
||||
byName[name] = this;
|
||||
byType[type] = this;
|
||||
}
|
||||
TransactionFormat& operator<<(const SOElement& el)
|
||||
{
|
||||
elements.push_back(el);
|
||||
return *this;
|
||||
}
|
||||
|
||||
static TransactionFormat* getTxnFormat(TransactionType t);
|
||||
static TransactionFormat* getTxnFormat(const std::string& t);
|
||||
static TransactionFormat* getTxnFormat(int t);
|
||||
};
|
||||
|
||||
const int TransactionMinLen = 32;
|
||||
const int TransactionMaxLen = 1048576;
|
||||
|
||||
//
|
||||
// Transaction flags.
|
||||
//
|
||||
|
||||
// AccountSet flags:
|
||||
const uint32 tfRequireDestTag = 0x00010000;
|
||||
const uint32 tfOptionalDestTag = 0x00020000;
|
||||
const uint32 tfRequireAuth = 0x00040000;
|
||||
const uint32 tfOptionalAuth = 0x00080000;
|
||||
const uint32 tfDisallowXRP = 0x00100000;
|
||||
const uint32 tfAllowXRP = 0x00200000;
|
||||
const uint32 tfAccountSetMask = ~(tfRequireDestTag|tfOptionalDestTag
|
||||
|tfRequireAuth|tfOptionalAuth
|
||||
|tfDisallowXRP|tfAllowXRP);
|
||||
|
||||
// OfferCreate flags:
|
||||
const uint32 tfPassive = 0x00010000;
|
||||
const uint32 tfImmediateOrCancel = 0x00020000;
|
||||
const uint32 tfFillOrKill = 0x00040000;
|
||||
const uint32 tfSell = 0x00080000;
|
||||
const uint32 tfOfferCreateMask = ~(tfPassive|tfImmediateOrCancel|tfFillOrKill|tfSell);
|
||||
|
||||
// Payment flags:
|
||||
const uint32 tfNoRippleDirect = 0x00010000;
|
||||
const uint32 tfPartialPayment = 0x00020000;
|
||||
const uint32 tfLimitQuality = 0x00040000;
|
||||
const uint32 tfPaymentMask = ~(tfPartialPayment|tfLimitQuality|tfNoRippleDirect);
|
||||
|
||||
// TrustSet flags:
|
||||
const uint32 tfSetfAuth = 0x00010000;
|
||||
const uint32 tfTrustSetMask = ~(tfSetfAuth);
|
||||
|
||||
#endif
|
||||
// vim:ts=4
|
||||
@@ -6,10 +6,7 @@
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/ptr_container/ptr_vector.hpp>
|
||||
|
||||
#include "SerializedTypes.h"
|
||||
#include "SerializedObject.h"
|
||||
#include "SerializedLedger.h"
|
||||
#include "TransactionErr.h"
|
||||
|
||||
class TransactionMetaSet
|
||||
{
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
#ifndef __TRANSACTOR__
|
||||
#define __TRANSACTOR__
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
#include "SerializedTransaction.h"
|
||||
#include "TransactionErr.h"
|
||||
#include "TransactionEngine.h"
|
||||
|
||||
class Transactor
|
||||
|
||||
Reference in New Issue
Block a user