Reformatting using AStyle

This commit is contained in:
Vinnie Falco
2013-06-14 08:45:13 -07:00
parent 36bd8f7173
commit 521e812fc4
294 changed files with 54609 additions and 47598 deletions

View File

@@ -5,12 +5,12 @@ std::map<int, SField::ptr> SField::codeToField;
boost::mutex SField::mapMutex;
int SField::num = 0;
SField sfInvalid(-1), sfGeneric(0);
SField sfLedgerEntry(STI_LEDGERENTRY, 1, "LedgerEntry");
SField sfTransaction(STI_TRANSACTION, 1, "Transaction");
SField sfValidation(STI_VALIDATION, 1, "Validation");
SField sfHash(STI_HASH256, 257, "hash");
SField sfIndex(STI_HASH256, 258, "index");
SField sfInvalid (-1), sfGeneric (0);
SField sfLedgerEntry (STI_LEDGERENTRY, 1, "LedgerEntry");
SField sfTransaction (STI_TRANSACTION, 1, "Transaction");
SField sfValidation (STI_VALIDATION, 1, "Validation");
SField sfHash (STI_HASH256, 257, "hash");
SField sfIndex (STI_HASH256, 258, "index");
#define FIELD(name, type, index) SField sf##name(FIELD_CODE(STI_##type, index), STI_##type, index, #name);
#define TYPE(name, type, index)
@@ -18,50 +18,53 @@ SField sfIndex(STI_HASH256, 258, "index");
#undef FIELD
#undef TYPE
static int initFields()
static int initFields ()
{
sfTxnSignature.notSigningField();
sfTxnSignatures.notSigningField();
sfSignature.notSigningField();
sfTxnSignature.notSigningField ();
sfTxnSignatures.notSigningField ();
sfSignature.notSigningField ();
sfIndexes.setMeta(SField::sMD_Never);
sfPreviousTxnID.setMeta(SField::sMD_DeleteFinal);
sfPreviousTxnLgrSeq.setMeta(SField::sMD_DeleteFinal);
sfLedgerEntryType.setMeta(SField::sMD_Never);
sfRootIndex.setMeta(SField::sMD_Always);
sfIndexes.setMeta (SField::sMD_Never);
sfPreviousTxnID.setMeta (SField::sMD_DeleteFinal);
sfPreviousTxnLgrSeq.setMeta (SField::sMD_DeleteFinal);
sfLedgerEntryType.setMeta (SField::sMD_Never);
sfRootIndex.setMeta (SField::sMD_Always);
return 0;
return 0;
}
static const int f = initFields();
static const int f = initFields ();
SField::SField(SerializedTypeID tid, int fv) : fieldCode(FIELD_CODE(tid, fv)), fieldType(tid), fieldValue(fv),
fieldMeta(sMD_Default), fieldNum(++num), signingField(true)
{ // call with the map mutex
fieldName = lexical_cast_i(tid) + "/" + lexical_cast_i(fv);
codeToField[fieldCode] = this;
assert((fv != 1) || ((tid != STI_ARRAY) && (tid!=STI_OBJECT)));
SField::SField (SerializedTypeID tid, int fv) : fieldCode (FIELD_CODE (tid, fv)), fieldType (tid), fieldValue (fv),
fieldMeta (sMD_Default), fieldNum (++num), signingField (true)
{
// call with the map mutex
fieldName = lexical_cast_i (tid) + "/" + lexical_cast_i (fv);
codeToField[fieldCode] = this;
assert ((fv != 1) || ((tid != STI_ARRAY) && (tid != STI_OBJECT)));
}
SField::ref SField::getField(int code)
SField::ref SField::getField (int code)
{
int type = code >> 16;
int field = code % 0xffff;
int type = code >> 16;
int field = code % 0xffff;
if ((type <= 0) || (field <= 0))
return sfInvalid;
if ((type <= 0) || (field <= 0))
return sfInvalid;
boost::mutex::scoped_lock sl(mapMutex);
boost::mutex::scoped_lock sl (mapMutex);
std::map<int, SField::ptr>::iterator it = codeToField.find(code);
if (it != codeToField.end())
return *(it->second);
std::map<int, SField::ptr>::iterator it = codeToField.find (code);
if (field > 255) // don't dynamically extend types that have no binary encoding
return sfInvalid;
if (it != codeToField.end ())
return * (it->second);
switch (type)
{ // types we are willing to dynamically extend
if (field > 255) // don't dynamically extend types that have no binary encoding
return sfInvalid;
switch (type)
{
// types we are willing to dynamically extend
#define FIELD(name, type, index)
#define TYPE(name, type, index) case STI_##type:
@@ -69,56 +72,62 @@ SField::ref SField::getField(int code)
#undef FIELD
#undef TYPE
break;
default:
return sfInvalid;
}
break;
return *(new SField(static_cast<SerializedTypeID>(type), field));
default:
return sfInvalid;
}
return * (new SField (static_cast<SerializedTypeID> (type), field));
}
int SField::compare(SField::ref f1, SField::ref f2)
{ // -1 = f1 comes before f2, 0 = illegal combination, 1 = f1 comes after f2
if ((f1.fieldCode <= 0) || (f2.fieldCode <= 0))
return 0;
if (f1.fieldCode < f2.fieldCode)
return -1;
if (f2.fieldCode < f1.fieldCode)
return 1;
return 0;
}
std::string SField::getName() const
int SField::compare (SField::ref f1, SField::ref f2)
{
if (!fieldName.empty())
return fieldName;
if (fieldValue == 0)
return "";
return boost::lexical_cast<std::string>(static_cast<int>(fieldType)) + "/" +
boost::lexical_cast<std::string>(fieldValue);
// -1 = f1 comes before f2, 0 = illegal combination, 1 = f1 comes after f2
if ((f1.fieldCode <= 0) || (f2.fieldCode <= 0))
return 0;
if (f1.fieldCode < f2.fieldCode)
return -1;
if (f2.fieldCode < f1.fieldCode)
return 1;
return 0;
}
SField::ref SField::getField(const std::string& fieldName)
{ // OPTIMIZEME me with a map. CHECKME this is case sensitive
boost::mutex::scoped_lock sl(mapMutex);
typedef std::map<int, SField::ptr>::value_type int_sfref_pair;
BOOST_FOREACH(const int_sfref_pair& fieldPair, codeToField)
{
if (fieldPair.second->fieldName == fieldName)
return *(fieldPair.second);
}
return sfInvalid;
}
SField::~SField()
std::string SField::getName () const
{
boost::mutex::scoped_lock sl(mapMutex);
std::map<int, ptr>::iterator it = codeToField.find(fieldCode);
if ((it != codeToField.end()) && (it->second == this))
codeToField.erase(it);
if (!fieldName.empty ())
return fieldName;
if (fieldValue == 0)
return "";
return boost::lexical_cast<std::string> (static_cast<int> (fieldType)) + "/" +
boost::lexical_cast<std::string> (fieldValue);
}
SField::ref SField::getField (const std::string& fieldName)
{
// OPTIMIZEME me with a map. CHECKME this is case sensitive
boost::mutex::scoped_lock sl (mapMutex);
typedef std::map<int, SField::ptr>::value_type int_sfref_pair;
BOOST_FOREACH (const int_sfref_pair & fieldPair, codeToField)
{
if (fieldPair.second->fieldName == fieldName)
return * (fieldPair.second);
}
return sfInvalid;
}
SField::~SField ()
{
boost::mutex::scoped_lock sl (mapMutex);
std::map<int, ptr>::iterator it = codeToField.find (fieldCode);
if ((it != codeToField.end ()) && (it->second == this))
codeToField.erase (it);
}
// vim:ts=4

View File

@@ -6,10 +6,10 @@
enum SerializedTypeID
{
// special types
STI_UNKNOWN = -2,
STI_DONE = -1,
STI_NOTPRESENT = 0,
// special types
STI_UNKNOWN = -2,
STI_DONE = -1,
STI_NOTPRESENT = 0,
#define TYPE(name, field, value) STI_##field = value,
#define FIELD(name, field, value)
@@ -17,10 +17,10 @@ enum SerializedTypeID
#undef TYPE
#undef FIELD
// high level types
STI_TRANSACTION = 10001,
STI_LEDGERENTRY = 10002,
STI_VALIDATION = 10003,
// high level types
STI_TRANSACTION = 10001,
STI_LEDGERENTRY = 10002,
STI_VALIDATION = 10003,
};
/** Identifies fields.
@@ -32,112 +32,168 @@ enum SerializedTypeID
class SField
{
public:
typedef const SField& ref;
typedef SField const * ptr;
typedef const SField& ref;
typedef SField const* ptr;
static const int sMD_Never = 0x00;
static const int sMD_ChangeOrig = 0x01; // original value when it changes
static const int sMD_ChangeNew = 0x02; // new value when it changes
static const int sMD_DeleteFinal = 0x04; // final value when it is deleted
static const int sMD_Create = 0x08; // value when it's created
static const int sMD_Always = 0x10; // value when node containing it is affected at all
static const int sMD_Default = sMD_ChangeOrig | sMD_ChangeNew | sMD_DeleteFinal | sMD_Create;
static const int sMD_Never = 0x00;
static const int sMD_ChangeOrig = 0x01; // original value when it changes
static const int sMD_ChangeNew = 0x02; // new value when it changes
static const int sMD_DeleteFinal = 0x04; // final value when it is deleted
static const int sMD_Create = 0x08; // value when it's created
static const int sMD_Always = 0x10; // value when node containing it is affected at all
static const int sMD_Default = sMD_ChangeOrig | sMD_ChangeNew | sMD_DeleteFinal | sMD_Create;
public:
const int fieldCode; // (type<<16)|index
const SerializedTypeID fieldType; // STI_*
const int fieldValue; // Code number for protocol
std::string fieldName;
int fieldMeta;
int fieldNum;
bool signingField;
const int fieldCode; // (type<<16)|index
const SerializedTypeID fieldType; // STI_*
const int fieldValue; // Code number for protocol
std::string fieldName;
int fieldMeta;
int fieldNum;
bool signingField;
SField (int fc, SerializedTypeID tid, int fv, const char* fn)
SField (int fc, SerializedTypeID tid, int fv, const char* fn)
: fieldCode (fc)
, fieldType (tid)
, fieldValue (fv)
, fieldName (fn)
, fieldMeta (sMD_Default)
, signingField (true)
{
boost::mutex::scoped_lock sl(mapMutex);
{
boost::mutex::scoped_lock sl (mapMutex);
codeToField[fieldCode] = this;
fieldNum = ++num;
}
SField (SerializedTypeID tid, int fv, const char *fn)
fieldNum = ++num;
}
SField (SerializedTypeID tid, int fv, const char* fn)
: fieldCode (FIELD_CODE (tid, fv))
, fieldType (tid)
, fieldValue (fv)
, fieldName (fn)
, fieldMeta (sMD_Default)
, signingField (true)
{
boost::mutex::scoped_lock sl(mapMutex);
{
boost::mutex::scoped_lock sl (mapMutex);
codeToField[fieldCode] = this;
fieldNum = ++num;
}
explicit SField (int fc)
fieldNum = ++num;
}
explicit SField (int fc)
: fieldCode (fc)
, fieldType (STI_UNKNOWN)
, fieldValue (0)
, fieldMeta (sMD_Never)
, signingField (true)
{
boost::mutex::scoped_lock sl(mapMutex);
fieldNum = ++num;
}
{
boost::mutex::scoped_lock sl (mapMutex);
fieldNum = ++num;
}
~SField ();
~SField ();
static SField::ref getField (int fieldCode);
static SField::ref getField (const std::string& fieldName);
static SField::ref getField (int type, int value) { return getField(FIELD_CODE(type, value)); }
static SField::ref getField (SerializedTypeID type, int value) { return getField(FIELD_CODE(type, value)); }
static SField::ref getField (int fieldCode);
static SField::ref getField (const std::string& fieldName);
static SField::ref getField (int type, int value)
{
return getField (FIELD_CODE (type, value));
}
static SField::ref getField (SerializedTypeID type, int value)
{
return getField (FIELD_CODE (type, value));
}
std::string getName() const;
bool hasName() const { return !fieldName.empty(); }
std::string getName () const;
bool hasName () const
{
return !fieldName.empty ();
}
bool isGeneric() const { return fieldCode == 0; }
bool isInvalid() const { return fieldCode == -1; }
bool isUseful() const { return fieldCode > 0; }
bool isKnown() const { return fieldType != STI_UNKNOWN; }
bool isBinary() const { return fieldValue < 256; }
bool isGeneric () const
{
return fieldCode == 0;
}
bool isInvalid () const
{
return fieldCode == -1;
}
bool isUseful () const
{
return fieldCode > 0;
}
bool isKnown () const
{
return fieldType != STI_UNKNOWN;
}
bool isBinary () const
{
return fieldValue < 256;
}
// VFALCO NOTE What is a discardable field?
bool isDiscardable() const { return fieldValue > 256; }
bool isDiscardable () const
{
return fieldValue > 256;
}
int getCode() const { return fieldCode; }
int getNum() const { return fieldNum; }
static int getNumFields() { return num; }
int getCode () const
{
return fieldCode;
}
int getNum () const
{
return fieldNum;
}
static int getNumFields ()
{
return num;
}
bool isSigningField() const { return signingField; }
void notSigningField() { signingField = false; }
bool shouldMeta(int c) const { return (fieldMeta & c) != 0; }
void setMeta(int c) { fieldMeta = c; }
bool isSigningField () const
{
return signingField;
}
void notSigningField ()
{
signingField = false;
}
bool shouldMeta (int c) const
{
return (fieldMeta & c) != 0;
}
void setMeta (int c)
{
fieldMeta = c;
}
bool shouldInclude(bool withSigningField) const
{ return (fieldValue < 256) && (withSigningField || signingField); }
bool shouldInclude (bool withSigningField) const
{
return (fieldValue < 256) && (withSigningField || signingField);
}
bool operator== (const SField& f) const { return fieldCode == f.fieldCode; }
bool operator== (const SField& f) const
{
return fieldCode == f.fieldCode;
}
bool operator!= (const SField& f) const { return fieldCode != f.fieldCode; }
bool operator!= (const SField& f) const
{
return fieldCode != f.fieldCode;
}
static int compare(SField::ref f1, SField::ref f2);
static int compare (SField::ref f1, SField::ref f2);
// VFALCO TODO make these private
protected:
static std::map<int, ptr> codeToField;
static boost::mutex mapMutex;
static int num;
static std::map<int, ptr> codeToField;
static boost::mutex mapMutex;
static int num;
SField (SerializedTypeID id, int val);
SField (SerializedTypeID id, int val);
};
extern SField sfInvalid, sfGeneric, sfLedgerEntry, sfTransaction, sfValidation;

View File

@@ -3,137 +3,143 @@ 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 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()
void LEFInit ()
{
LedgerEntryFormat* lef;
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 (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 (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 (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 (GeneratorMap, ltGENERATOR_MAP)
<< SOElement (sfGenerator, SOE_REQUIRED)
;
DECLARE_LEF(Nickname, ltNICKNAME)
<< SOElement(sfAccount, SOE_REQUIRED)
<< SOElement(sfMinimumOffer, SOE_OPTIONAL)
;
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 (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 (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 (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 (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)
;
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)
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;
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)
LedgerEntryFormat* LedgerEntryFormat::getLgrFormat (int t)
{
std::map<int, LedgerEntryFormat*>::iterator it = byType.find((t));
if (it == byType.end())
return NULL;
return it->second;
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)
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;
std::map<std::string, LedgerEntryFormat*>::iterator it = byName.find ((t));
if (it == byName.end ())
return NULL;
return it->second;
}
// vim:ts=4

View File

@@ -4,79 +4,79 @@
// 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',
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',
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.
// 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,
lsfSell = 0x00020000, // True, offer was placed as a sell.
// ltOFFER
lsfPassive = 0x00010000,
lsfSell = 0x00020000, // True, offer was placed as a sell.
// ltRIPPLE_STATE
lsfLowReserve = 0x00010000, // True, if entry counts toward reserve.
lsfHighReserve = 0x00020000,
lsfLowAuth = 0x00040000,
lsfHighAuth = 0x00080000,
// 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;
std::string t_name;
LedgerEntryType t_type;
SOTemplate elements;
static std::map<int, LedgerEntryFormat*> byType;
static std::map<std::string, LedgerEntryFormat*> byName;
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;
}
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);
static LedgerEntryFormat* getLgrFormat (LedgerEntryType t);
static LedgerEntryFormat* getLgrFormat (const std::string& t);
static LedgerEntryFormat* getLgrFormat (int t);
};
#endif

View File

@@ -2,39 +2,42 @@
PackedMessage::PackedMessage (::google::protobuf::Message const& message, int type)
{
unsigned const messageBytes = message.ByteSize ();
unsigned const messageBytes = message.ByteSize ();
assert (messageBytes != 0);
mBuffer.resize (kHeaderBytes + messageBytes);
encodeHeader (messageBytes, type);
if (messageBytes != 0)
{
message.SerializeToArray (&mBuffer [PackedMessage::kHeaderBytes], messageBytes);
{
message.SerializeToArray (&mBuffer [PackedMessage::kHeaderBytes], messageBytes);
#ifdef DEBUG
// std::cerr << "PackedMessage: type=" << type << ", datalen=" << msg_size << std::endl;
// std::cerr << "PackedMessage: type=" << type << ", datalen=" << msg_size << std::endl;
#endif
}
}
}
bool PackedMessage::operator== (PackedMessage const& other) const
{
return mBuffer == other.mBuffer;
return mBuffer == other.mBuffer;
}
unsigned PackedMessage::getLength (std::vector <uint8_t> const& buf)
{
unsigned result;
if (buf.size() >= PackedMessage::kHeaderBytes)
if (buf.size () >= PackedMessage::kHeaderBytes)
{
result = buf [0];
result <<= 8; result |= buf [1];
result <<= 8; result |= buf [2];
result <<= 8; result |= buf [3];
result = buf [0];
result <<= 8;
result |= buf [1];
result <<= 8;
result |= buf [2];
result <<= 8;
result |= buf [3];
}
else
{
@@ -46,21 +49,22 @@ unsigned PackedMessage::getLength (std::vector <uint8_t> const& buf)
int PackedMessage::getType (std::vector<uint8_t> const& buf)
{
if(buf.size() < PackedMessage::kHeaderBytes)
return 0;
if (buf.size () < PackedMessage::kHeaderBytes)
return 0;
int ret = buf[4];
ret <<= 8; ret |= buf[5];
return ret;
int ret = buf[4];
ret <<= 8;
ret |= buf[5];
return ret;
}
void PackedMessage::encodeHeader (unsigned size, int type)
void PackedMessage::encodeHeader (unsigned size, int type)
{
assert(mBuffer.size() >= PackedMessage::kHeaderBytes);
mBuffer[0] = static_cast<boost::uint8_t>((size >> 24) & 0xFF);
mBuffer[1] = static_cast<boost::uint8_t>((size >> 16) & 0xFF);
mBuffer[2] = static_cast<boost::uint8_t>((size >> 8) & 0xFF);
mBuffer[3] = static_cast<boost::uint8_t>(size & 0xFF);
mBuffer[4] = static_cast<boost::uint8_t>((type >> 8) & 0xFF);
mBuffer[5] = static_cast<boost::uint8_t>(type & 0xFF);
assert (mBuffer.size () >= PackedMessage::kHeaderBytes);
mBuffer[0] = static_cast<boost::uint8_t> ((size >> 24) & 0xFF);
mBuffer[1] = static_cast<boost::uint8_t> ((size >> 16) & 0xFF);
mBuffer[2] = static_cast<boost::uint8_t> ((size >> 8) & 0xFF);
mBuffer[3] = static_cast<boost::uint8_t> (size & 0xFF);
mBuffer[4] = static_cast<boost::uint8_t> ((type >> 8) & 0xFF);
mBuffer[5] = static_cast<boost::uint8_t> (type & 0xFF);
}

View File

@@ -14,7 +14,7 @@ class PackedMessage : public boost::enable_shared_from_this <PackedMessage>
{
public:
typedef boost::shared_ptr< ::google::protobuf::Message > MessagePointer;
typedef boost::shared_ptr<PackedMessage> pointer;
typedef boost::shared_ptr<PackedMessage> pointer;
public:
/** Number of bytes in a message header.
@@ -26,27 +26,27 @@ public:
/** Retrieve the packed message data.
*/
// VFALCO TODO shouldn't this be const?
std::vector <uint8_t>& getBuffer()
std::vector <uint8_t>& getBuffer ()
{
return mBuffer;
}
/** Determine bytewise equality.
*/
bool operator == (PackedMessage const& other) const;
bool operator == (PackedMessage const& other) const;
/** Calculate the length of a packed message.
*/
static unsigned getLength (std::vector <uint8_t> const& buf);
static unsigned getLength (std::vector <uint8_t> const& buf);
/** Determine the type of a packed message.
*/
static int getType (std::vector <uint8_t> const& buf);
private:
// Encodes the size and type into a header at the beginning of buf
//
void encodeHeader (unsigned size, int type);
// Encodes the size and type into a header at the beginning of buf
//
void encodeHeader (unsigned size, int type);
std::vector <uint8_t> mBuffer;
};

File diff suppressed because it is too large Load Diff

View File

@@ -8,180 +8,194 @@
class RippleAddress : public CBase58Data
{
private:
typedef enum {
VER_NONE = 1,
VER_NODE_PUBLIC = 28,
VER_NODE_PRIVATE = 32,
VER_ACCOUNT_ID = 0,
VER_ACCOUNT_PUBLIC = 35,
VER_ACCOUNT_PRIVATE = 34,
VER_FAMILY_GENERATOR = 41,
VER_FAMILY_SEED = 33,
} VersionEncoding;
typedef enum
{
VER_NONE = 1,
VER_NODE_PUBLIC = 28,
VER_NODE_PRIVATE = 32,
VER_ACCOUNT_ID = 0,
VER_ACCOUNT_PUBLIC = 35,
VER_ACCOUNT_PRIVATE = 34,
VER_FAMILY_GENERATOR = 41,
VER_FAMILY_SEED = 33,
} VersionEncoding;
bool mIsValid;
bool mIsValid;
public:
RippleAddress();
RippleAddress ();
// For public and private key, checks if they are legal.
bool isValid() const { return mIsValid; }
// For public and private key, checks if they are legal.
bool isValid () const
{
return mIsValid;
}
void clear();
bool isSet() const;
void clear ();
bool isSet () const;
std::string humanAddressType() const;
std::string humanAddressType () const;
//
// Node Public - Also used for Validators
//
uint160 getNodeID() const;
Blob const& getNodePublic() const;
//
// Node Public - Also used for Validators
//
uint160 getNodeID () const;
Blob const& getNodePublic () const;
std::string humanNodePublic() const;
std::string humanNodePublic () const;
bool setNodePublic(const std::string& strPublic);
void setNodePublic(Blob const& vPublic);
bool verifyNodePublic(uint256 const& hash, Blob const& vchSig) const;
bool verifyNodePublic(uint256 const& hash, const std::string& strSig) const;
bool setNodePublic (const std::string& strPublic);
void setNodePublic (Blob const& vPublic);
bool verifyNodePublic (uint256 const& hash, Blob const& vchSig) const;
bool verifyNodePublic (uint256 const& hash, const std::string& strSig) const;
static RippleAddress createNodePublic(const RippleAddress& naSeed);
static RippleAddress createNodePublic(Blob const& vPublic);
static RippleAddress createNodePublic(const std::string& strPublic);
static RippleAddress createNodePublic (const RippleAddress& naSeed);
static RippleAddress createNodePublic (Blob const& vPublic);
static RippleAddress createNodePublic (const std::string& strPublic);
//
// Node Private
//
Blob const& getNodePrivateData() const;
uint256 getNodePrivate() const;
//
// Node Private
//
Blob const& getNodePrivateData () const;
uint256 getNodePrivate () const;
std::string humanNodePrivate() const;
std::string humanNodePrivate () const;
bool setNodePrivate(const std::string& strPrivate);
void setNodePrivate(Blob const& vPrivate);
void setNodePrivate(uint256 hash256);
void signNodePrivate(uint256 const& hash, Blob& vchSig) const;
bool setNodePrivate (const std::string& strPrivate);
void setNodePrivate (Blob const& vPrivate);
void setNodePrivate (uint256 hash256);
void signNodePrivate (uint256 const& hash, Blob& vchSig) const;
static RippleAddress createNodePrivate(const RippleAddress& naSeed);
static RippleAddress createNodePrivate (const RippleAddress& naSeed);
//
// Accounts IDs
//
uint160 getAccountID() const;
//
// Accounts IDs
//
uint160 getAccountID () const;
std::string humanAccountID() const;
std::string humanAccountID () const;
bool setAccountID(const std::string& strAccountID, const char* pAlphabet=Base58::getCurrentAlphabet ());
void setAccountID(const uint160& hash160In);
bool setAccountID (const std::string& strAccountID, const char* pAlphabet = Base58::getCurrentAlphabet ());
void setAccountID (const uint160& hash160In);
static RippleAddress createAccountID(const std::string& strAccountID)
{ RippleAddress na; na.setAccountID(strAccountID); return na; }
static RippleAddress createAccountID (const std::string& strAccountID)
{
RippleAddress na;
na.setAccountID (strAccountID);
return na;
}
static RippleAddress createAccountID(const uint160& uiAccountID);
static RippleAddress createAccountID (const uint160& uiAccountID);
static std::string createHumanAccountID(const uint160& uiAccountID)
{ return createAccountID(uiAccountID).humanAccountID(); }
static std::string createHumanAccountID (const uint160& uiAccountID)
{
return createAccountID (uiAccountID).humanAccountID ();
}
static std::string createHumanAccountID(Blob const& vPrivate)
{ return createAccountPrivate(vPrivate).humanAccountID(); }
static std::string createHumanAccountID (Blob const& vPrivate)
{
return createAccountPrivate (vPrivate).humanAccountID ();
}
//
// Accounts Public
//
Blob const& getAccountPublic() const;
//
// Accounts Public
//
Blob const& getAccountPublic () const;
std::string humanAccountPublic() const;
std::string humanAccountPublic () const;
bool setAccountPublic(const std::string& strPublic);
void setAccountPublic(Blob const& vPublic);
void setAccountPublic(const RippleAddress& generator, int seq);
bool setAccountPublic (const std::string& strPublic);
void setAccountPublic (Blob const& vPublic);
void setAccountPublic (const RippleAddress& generator, int seq);
bool accountPublicVerify(uint256 const& uHash, Blob const& vucSig) const;
bool accountPublicVerify (uint256 const& uHash, Blob const& vucSig) const;
static RippleAddress createAccountPublic(Blob const& vPublic)
{
RippleAddress naNew;
static RippleAddress createAccountPublic (Blob const& vPublic)
{
RippleAddress naNew;
naNew.setAccountPublic(vPublic);
naNew.setAccountPublic (vPublic);
return naNew;
}
return naNew;
}
static std::string createHumanAccountPublic(Blob const& vPublic) {
return createAccountPublic(vPublic).humanAccountPublic();
}
static std::string createHumanAccountPublic (Blob const& vPublic)
{
return createAccountPublic (vPublic).humanAccountPublic ();
}
// Create a deterministic public key from a public generator.
static RippleAddress createAccountPublic(const RippleAddress& naGenerator, int iSeq);
// Create a deterministic public key from a public generator.
static RippleAddress createAccountPublic (const RippleAddress& naGenerator, int iSeq);
//
// Accounts Private
//
uint256 getAccountPrivate() const;
//
// Accounts Private
//
uint256 getAccountPrivate () const;
std::string humanAccountPrivate() const;
std::string humanAccountPrivate () const;
bool setAccountPrivate(const std::string& strPrivate);
void setAccountPrivate(Blob const& vPrivate);
void setAccountPrivate(uint256 hash256);
void setAccountPrivate(const RippleAddress& naGenerator, const RippleAddress& naSeed, int seq);
bool setAccountPrivate (const std::string& strPrivate);
void setAccountPrivate (Blob const& vPrivate);
void setAccountPrivate (uint256 hash256);
void setAccountPrivate (const RippleAddress& naGenerator, const RippleAddress& naSeed, int seq);
bool accountPrivateSign(uint256 const& uHash, Blob& vucSig) const;
// bool accountPrivateVerify(uint256 const& uHash, Blob const& vucSig) const;
bool accountPrivateSign (uint256 const& uHash, Blob& vucSig) const;
// bool accountPrivateVerify(uint256 const& uHash, Blob const& vucSig) const;
// Encrypt a message.
Blob accountPrivateEncrypt(const RippleAddress& naPublicTo, Blob const& vucPlainText) const;
// Encrypt a message.
Blob accountPrivateEncrypt (const RippleAddress& naPublicTo, Blob const& vucPlainText) const;
// Decrypt a message.
Blob accountPrivateDecrypt(const RippleAddress& naPublicFrom, Blob const& vucCipherText) const;
// Decrypt a message.
Blob accountPrivateDecrypt (const RippleAddress& naPublicFrom, Blob const& vucCipherText) const;
static RippleAddress createAccountPrivate(const RippleAddress& naGenerator, const RippleAddress& naSeed, int iSeq);
static RippleAddress createAccountPrivate (const RippleAddress& naGenerator, const RippleAddress& naSeed, int iSeq);
static RippleAddress createAccountPrivate(Blob const& vPrivate)
{
RippleAddress naNew;
static RippleAddress createAccountPrivate (Blob const& vPrivate)
{
RippleAddress naNew;
naNew.setAccountPrivate(vPrivate);
naNew.setAccountPrivate (vPrivate);
return naNew;
}
return naNew;
}
static std::string createHumanAccountPrivate(Blob const& vPrivate) {
return createAccountPrivate(vPrivate).humanAccountPrivate();
}
static std::string createHumanAccountPrivate (Blob const& vPrivate)
{
return createAccountPrivate (vPrivate).humanAccountPrivate ();
}
//
// Generators
// Use to generate a master or regular family.
//
BIGNUM* getGeneratorBN() const; // DEPRECATED
Blob const& getGenerator() const;
//
// Generators
// Use to generate a master or regular family.
//
BIGNUM* getGeneratorBN () const; // DEPRECATED
Blob const& getGenerator () const;
std::string humanGenerator() const;
std::string humanGenerator () const;
bool setGenerator(const std::string& strGenerator);
void setGenerator(Blob const& vPublic);
// void setGenerator(const RippleAddress& seed);
bool setGenerator (const std::string& strGenerator);
void setGenerator (Blob const& vPublic);
// void setGenerator(const RippleAddress& seed);
// Create generator for making public deterministic keys.
static RippleAddress createGeneratorPublic(const RippleAddress& naSeed);
// Create generator for making public deterministic keys.
static RippleAddress createGeneratorPublic (const RippleAddress& naSeed);
//
// Seeds
// Clients must disallow reconizable entries from being seeds.
uint128 getSeed() const;
//
// Seeds
// Clients must disallow reconizable entries from being seeds.
uint128 getSeed () const;
std::string humanSeed() const;
std::string humanSeed1751() const;
std::string humanSeed () const;
std::string humanSeed1751 () const;
bool setSeed(const std::string& strSeed);
int setSeed1751(const std::string& strHuman1751);
bool setSeedGeneric(const std::string& strText);
void setSeed(uint128 hash128);
void setSeedRandom();
bool setSeed (const std::string& strSeed);
int setSeed1751 (const std::string& strHuman1751);
bool setSeedGeneric (const std::string& strText);
void setSeed (uint128 hash128);
void setSeedRandom ();
static RippleAddress createSeedRandom();
static RippleAddress createSeedGeneric(const std::string& strText);
static RippleAddress createSeedRandom ();
static RippleAddress createSeedGeneric (const std::string& strText);
};
#endif

View File

@@ -33,9 +33,9 @@ public:
// the point of call, i.e. "User-agent:" SYSTEM_NAME
// It will be necessary to rewrite some of them to use string streams.
//
#define SYSTEM_NAME "ripple"
#define SYSTEM_CURRENCY_CODE "XRP"
#define SYSTEM_CURRENCY_PRECISION 6
#define SYSTEM_CURRENCY_CODE_RIPPLE "XRR"
#define SYSTEM_NAME "ripple"
#define SYSTEM_CURRENCY_CODE "XRP"
#define SYSTEM_CURRENCY_PRECISION 6
#define SYSTEM_CURRENCY_CODE_RIPPLE "XRR"
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -1,324 +1,348 @@
// CAUTION: This is early code and is *NOT* ready for real use yet.
static void canonicalizeRound(bool isNative, uint64& value, int& offset, bool roundUp)
static void canonicalizeRound (bool isNative, uint64& value, int& offset, bool roundUp)
{
if (!roundUp) // canonicalize already rounds down
return;
if (!roundUp) // canonicalize already rounds down
return;
WriteLog (lsTRACE, STAmount) << "canonicalize< " << value << ":" << offset << (roundUp ? " up" : " down");
if (isNative)
{
if (offset < 0)
{
int loops = 0;
while (offset < -1)
{
value /= 10;
++offset;
++loops;
}
value += (loops >= 2) ? 9 : 10; // add before last divide
value /= 10;
++offset;
}
}
else if (value > STAmount::cMaxValue)
{
while (value > (10 * STAmount::cMaxValue))
{
value /= 10;
++offset;
}
value += 9; // add before last divide
value /= 10;
++offset;
}
WriteLog (lsTRACE, STAmount) << "canonicalize> " << value << ":" << offset << (roundUp ? " up" : " down");
WriteLog (lsTRACE, STAmount) << "canonicalize< " << value << ":" << offset << (roundUp ? " up" : " down");
if (isNative)
{
if (offset < 0)
{
int loops = 0;
while (offset < -1)
{
value /= 10;
++offset;
++loops;
}
value += (loops >= 2) ? 9 : 10; // add before last divide
value /= 10;
++offset;
}
}
else if (value > STAmount::cMaxValue)
{
while (value > (10 * STAmount::cMaxValue))
{
value /= 10;
++offset;
}
value += 9; // add before last divide
value /= 10;
++offset;
}
WriteLog (lsTRACE, STAmount) << "canonicalize> " << value << ":" << offset << (roundUp ? " up" : " down");
}
STAmount STAmount::addRound(const STAmount& v1, const STAmount& v2, bool roundUp)
STAmount STAmount::addRound (const STAmount& v1, const STAmount& v2, bool roundUp)
{
v1.throwComparable(v2);
v1.throwComparable (v2);
if (v2.mValue == 0)
return v1;
if (v2.mValue == 0)
return v1;
if (v1.mValue == 0)
return STAmount(v1.getFName(), v1.mCurrency, v1.mIssuer, v2.mValue, v2.mOffset, v2.mIsNegative);
if (v1.mValue == 0)
return STAmount (v1.getFName (), v1.mCurrency, v1.mIssuer, v2.mValue, v2.mOffset, v2.mIsNegative);
if (v1.mIsNative)
return STAmount(v1.getFName(), v1.getSNValue() + v2.getSNValue());
if (v1.mIsNative)
return STAmount (v1.getFName (), v1.getSNValue () + v2.getSNValue ());
int ov1 = v1.mOffset, ov2 = v2.mOffset;
int64 vv1 = static_cast<int64>(v1.mValue), vv2 = static_cast<uint64>(v2.mValue);
if (v1.mIsNegative)
vv1 = -vv1;
if (v2.mIsNegative)
vv2 = -vv2;
int ov1 = v1.mOffset, ov2 = v2.mOffset;
int64 vv1 = static_cast<int64> (v1.mValue), vv2 = static_cast<uint64> (v2.mValue);
if (ov1 < ov2)
{
while (ov1 < (ov2 - 1))
{
vv1 /= 10;
++ov1;
}
if (roundUp)
vv1 += 9;
vv1 /= 10;
++ov1;
}
if (v1.mIsNegative)
vv1 = -vv1;
if (ov2 < ov1)
{
while (ov2 < (ov1 - 1))
{
vv2 /= 10;
++ov2;
}
if (roundUp)
vv2 += 9;
vv2 /= 10;
++ov2;
}
if (v2.mIsNegative)
vv2 = -vv2;
int64 fv = vv1 + vv2;
if ((fv >= -10) && (fv <= 10))
return STAmount(v1.getFName(), v1.mCurrency, v1.mIssuer);
else if (fv >= 0)
{
uint64 v = static_cast<uint64>(fv);
canonicalizeRound(false, v, ov1, roundUp);
return STAmount(v1.getFName(), v1.mCurrency, v1.mIssuer, v, ov1, false);
}
else
{
uint64 v = static_cast<uint64>(-fv);
canonicalizeRound(false, v, ov1, !roundUp);
return STAmount(v1.getFName(), v1.mCurrency, v1.mIssuer, v, ov1, true);
}
if (ov1 < ov2)
{
while (ov1 < (ov2 - 1))
{
vv1 /= 10;
++ov1;
}
if (roundUp)
vv1 += 9;
vv1 /= 10;
++ov1;
}
if (ov2 < ov1)
{
while (ov2 < (ov1 - 1))
{
vv2 /= 10;
++ov2;
}
if (roundUp)
vv2 += 9;
vv2 /= 10;
++ov2;
}
int64 fv = vv1 + vv2;
if ((fv >= -10) && (fv <= 10))
return STAmount (v1.getFName (), v1.mCurrency, v1.mIssuer);
else if (fv >= 0)
{
uint64 v = static_cast<uint64> (fv);
canonicalizeRound (false, v, ov1, roundUp);
return STAmount (v1.getFName (), v1.mCurrency, v1.mIssuer, v, ov1, false);
}
else
{
uint64 v = static_cast<uint64> (-fv);
canonicalizeRound (false, v, ov1, !roundUp);
return STAmount (v1.getFName (), v1.mCurrency, v1.mIssuer, v, ov1, true);
}
}
STAmount STAmount::subRound(const STAmount& v1, const STAmount& v2, bool roundUp)
STAmount STAmount::subRound (const STAmount& v1, const STAmount& v2, bool roundUp)
{
v1.throwComparable(v2);
v1.throwComparable (v2);
if (v2.mValue == 0)
return v1;
if (v2.mValue == 0)
return v1;
if (v1.mValue == 0)
return STAmount(v1.getFName(), v1.mCurrency, v1.mIssuer, v2.mValue, v2.mOffset, !v2.mIsNegative);
if (v1.mValue == 0)
return STAmount (v1.getFName (), v1.mCurrency, v1.mIssuer, v2.mValue, v2.mOffset, !v2.mIsNegative);
if (v1.mIsNative)
return STAmount(v1.getFName(), v1.getSNValue() - v2.getSNValue());
if (v1.mIsNative)
return STAmount (v1.getFName (), v1.getSNValue () - v2.getSNValue ());
int ov1 = v1.mOffset, ov2 = v2.mOffset;
int64 vv1 = static_cast<int64>(v1.mValue), vv2 = static_cast<uint64>(v2.mValue);
int ov1 = v1.mOffset, ov2 = v2.mOffset;
int64 vv1 = static_cast<int64> (v1.mValue), vv2 = static_cast<uint64> (v2.mValue);
if (v1.mIsNegative)
vv1 = -vv1;
if (v1.mIsNegative)
vv1 = -vv1;
if (!v2.mIsNegative)
vv2 = -vv2;
if (!v2.mIsNegative)
vv2 = -vv2;
if (ov1 < ov2)
{
while (ov1 < (ov2 - 1))
{
vv1 /= 10;
++ov1;
}
if (roundUp)
vv1 += 9;
vv1 /= 10;
++ov1;
}
if (ov1 < ov2)
{
while (ov1 < (ov2 - 1))
{
vv1 /= 10;
++ov1;
}
if (ov2 < ov1)
{
while (ov2 < (ov1 - 1))
{
vv2 /= 10;
++ov2;
}
if (roundUp)
vv2 += 9;
vv2 /= 10;
++ov2;
}
if (roundUp)
vv1 += 9;
int64 fv = vv1 + vv2;
if ((fv >= -10) && (fv <= 10))
return STAmount(v1.getFName(), v1.mCurrency, v1.mIssuer);
else if (fv >= 0)
{
uint64 v = static_cast<uint64>(fv);
canonicalizeRound(false, v, ov1, roundUp);
return STAmount(v1.getFName(), v1.mCurrency, v1.mIssuer, v, ov1, false);
}
else
{
uint64 v = static_cast<uint64>(-fv);
canonicalizeRound(false, v, ov1, !roundUp);
return STAmount(v1.getFName(), v1.mCurrency, v1.mIssuer, v, ov1, true);
}
vv1 /= 10;
++ov1;
}
if (ov2 < ov1)
{
while (ov2 < (ov1 - 1))
{
vv2 /= 10;
++ov2;
}
if (roundUp)
vv2 += 9;
vv2 /= 10;
++ov2;
}
int64 fv = vv1 + vv2;
if ((fv >= -10) && (fv <= 10))
return STAmount (v1.getFName (), v1.mCurrency, v1.mIssuer);
else if (fv >= 0)
{
uint64 v = static_cast<uint64> (fv);
canonicalizeRound (false, v, ov1, roundUp);
return STAmount (v1.getFName (), v1.mCurrency, v1.mIssuer, v, ov1, false);
}
else
{
uint64 v = static_cast<uint64> (-fv);
canonicalizeRound (false, v, ov1, !roundUp);
return STAmount (v1.getFName (), v1.mCurrency, v1.mIssuer, v, ov1, true);
}
}
STAmount STAmount::mulRound(const STAmount& v1, const STAmount& v2,
const uint160& uCurrencyID, const uint160& uIssuerID, bool roundUp)
STAmount STAmount::mulRound (const STAmount& v1, const STAmount& v2,
const uint160& uCurrencyID, const uint160& uIssuerID, bool roundUp)
{
if (v1.isZero() || v2.isZero())
return STAmount(uCurrencyID, uIssuerID);
if (v1.isZero () || v2.isZero ())
return STAmount (uCurrencyID, uIssuerID);
if (v1.mIsNative && v2.mIsNative && uCurrencyID.isZero())
{
uint64 minV = (v1.getSNValue() < v2.getSNValue()) ? v1.getSNValue() : v2.getSNValue();
uint64 maxV = (v1.getSNValue() < v2.getSNValue()) ? v2.getSNValue() : v1.getSNValue();
if (minV > 3000000000ull) // sqrt(cMaxNative)
throw std::runtime_error("Native value overflow");
if (((maxV >> 32) * minV) > 2095475792ull) // cMaxNative / 2^32
throw std::runtime_error("Native value overflow");
return STAmount(v1.getFName(), minV * maxV);
}
if (v1.mIsNative && v2.mIsNative && uCurrencyID.isZero ())
{
uint64 minV = (v1.getSNValue () < v2.getSNValue ()) ? v1.getSNValue () : v2.getSNValue ();
uint64 maxV = (v1.getSNValue () < v2.getSNValue ()) ? v2.getSNValue () : v1.getSNValue ();
uint64 value1 = v1.mValue, value2 = v2.mValue;
int offset1 = v1.mOffset, offset2 = v2.mOffset;
if (minV > 3000000000ull) // sqrt(cMaxNative)
throw std::runtime_error ("Native value overflow");
if (v1.mIsNative)
{
while (value1 < STAmount::cMinValue)
{
value1 *= 10;
--offset1;
}
}
if (((maxV >> 32) * minV) > 2095475792ull) // cMaxNative / 2^32
throw std::runtime_error ("Native value overflow");
if (v2.mIsNative)
{
while (value2 < STAmount::cMinValue)
{
value2 *= 10;
--offset2;
}
}
return STAmount (v1.getFName (), minV * maxV);
}
bool resultNegative = v1.mIsNegative != v2.mIsNegative;
// Compute (numerator * denominator) / 10^14 with rounding
// 10^16 <= result <= 10^18
CBigNum v;
if ((BN_add_word64(&v, value1) != 1) || (BN_mul_word64(&v, value2) != 1))
throw std::runtime_error("internal bn error");
uint64 value1 = v1.mValue, value2 = v2.mValue;
int offset1 = v1.mOffset, offset2 = v2.mOffset;
if (resultNegative != roundUp) // rounding down is automatic when we divide
BN_add_word64(&v, tenTo14m1);
if (v1.mIsNative)
{
while (value1 < STAmount::cMinValue)
{
value1 *= 10;
--offset1;
}
}
if (BN_div_word64(&v, tenTo14) == ((uint64) -1))
throw std::runtime_error("internal bn error");
if (v2.mIsNative)
{
while (value2 < STAmount::cMinValue)
{
value2 *= 10;
--offset2;
}
}
// 10^16 <= product <= 10^18
assert(BN_num_bytes(&v) <= 64);
bool resultNegative = v1.mIsNegative != v2.mIsNegative;
// Compute (numerator * denominator) / 10^14 with rounding
// 10^16 <= result <= 10^18
CBigNum v;
uint64 amount = v.getuint64();
int offset = offset1 + offset2 + 14;
canonicalizeRound(uCurrencyID.isZero(), amount, offset, resultNegative != roundUp);
return STAmount(uCurrencyID, uIssuerID, amount, offset, resultNegative);
if ((BN_add_word64 (&v, value1) != 1) || (BN_mul_word64 (&v, value2) != 1))
throw std::runtime_error ("internal bn error");
if (resultNegative != roundUp) // rounding down is automatic when we divide
BN_add_word64 (&v, tenTo14m1);
if (BN_div_word64 (&v, tenTo14) == ((uint64) - 1))
throw std::runtime_error ("internal bn error");
// 10^16 <= product <= 10^18
assert (BN_num_bytes (&v) <= 64);
uint64 amount = v.getuint64 ();
int offset = offset1 + offset2 + 14;
canonicalizeRound (uCurrencyID.isZero (), amount, offset, resultNegative != roundUp);
return STAmount (uCurrencyID, uIssuerID, amount, offset, resultNegative);
}
STAmount STAmount::divRound(const STAmount& num, const STAmount& den,
const uint160& uCurrencyID, const uint160& uIssuerID, bool roundUp)
STAmount STAmount::divRound (const STAmount& num, const STAmount& den,
const uint160& uCurrencyID, const uint160& uIssuerID, bool roundUp)
{
if (den.isZero())
throw std::runtime_error("division by zero");
if (num.isZero())
return STAmount(uCurrencyID, uIssuerID);
if (den.isZero ())
throw std::runtime_error ("division by zero");
uint64 numVal = num.mValue, denVal = den.mValue;
int numOffset = num.mOffset, denOffset = den.mOffset;
if (num.isZero ())
return STAmount (uCurrencyID, uIssuerID);
if (num.mIsNative)
while (numVal < STAmount::cMinValue)
{ // Need to bring into range
numVal *= 10;
--numOffset;
}
uint64 numVal = num.mValue, denVal = den.mValue;
int numOffset = num.mOffset, denOffset = den.mOffset;
if (den.mIsNative)
while (denVal < STAmount::cMinValue)
{
denVal *= 10;
--denOffset;
}
if (num.mIsNative)
while (numVal < STAmount::cMinValue)
{
// Need to bring into range
numVal *= 10;
--numOffset;
}
bool resultNegative = num.mIsNegative != den.mIsNegative;
// Compute (numerator * 10^17) / denominator
CBigNum v;
if ((BN_add_word64(&v, numVal) != 1) || (BN_mul_word64(&v, tenTo17) != 1))
throw std::runtime_error("internal bn error");
if (den.mIsNative)
while (denVal < STAmount::cMinValue)
{
denVal *= 10;
--denOffset;
}
if (resultNegative != roundUp) // Rounding down is automatic when we divide
BN_add_word64(&v, denVal - 1);
bool resultNegative = num.mIsNegative != den.mIsNegative;
// Compute (numerator * 10^17) / denominator
CBigNum v;
if (BN_div_word64(&v, denVal) == ((uint64) -1))
throw std::runtime_error("internal bn error");
if ((BN_add_word64 (&v, numVal) != 1) || (BN_mul_word64 (&v, tenTo17) != 1))
throw std::runtime_error ("internal bn error");
// 10^16 <= quotient <= 10^18
assert(BN_num_bytes(&v) <= 64);
if (resultNegative != roundUp) // Rounding down is automatic when we divide
BN_add_word64 (&v, denVal - 1);
uint64 amount = v.getuint64();
int offset = numOffset - denOffset - 17;
canonicalizeRound(uCurrencyID.isZero(), amount, offset, resultNegative != roundUp);
return STAmount(uCurrencyID, uIssuerID, amount, offset, resultNegative);
if (BN_div_word64 (&v, denVal) == ((uint64) - 1))
throw std::runtime_error ("internal bn error");
// 10^16 <= quotient <= 10^18
assert (BN_num_bytes (&v) <= 64);
uint64 amount = v.getuint64 ();
int offset = numOffset - denOffset - 17;
canonicalizeRound (uCurrencyID.isZero (), amount, offset, resultNegative != roundUp);
return STAmount (uCurrencyID, uIssuerID, amount, offset, resultNegative);
}
BOOST_AUTO_TEST_SUITE(amountRound)
BOOST_AUTO_TEST_SUITE (amountRound)
BOOST_AUTO_TEST_CASE( amountRound_test )
BOOST_AUTO_TEST_CASE ( amountRound_test )
{
uint64 value = 25000000000000000ull;
int offset = -14;
canonicalizeRound(false, value, offset, true);
uint64 value = 25000000000000000ull;
int offset = -14;
canonicalizeRound (false, value, offset, true);
STAmount one(CURRENCY_ONE, ACCOUNT_ONE, 1);
STAmount two(CURRENCY_ONE, ACCOUNT_ONE, 2);
STAmount three(CURRENCY_ONE, ACCOUNT_ONE, 3);
STAmount one (CURRENCY_ONE, ACCOUNT_ONE, 1);
STAmount two (CURRENCY_ONE, ACCOUNT_ONE, 2);
STAmount three (CURRENCY_ONE, ACCOUNT_ONE, 3);
STAmount oneThird1 = STAmount::divRound(one, three, CURRENCY_ONE, ACCOUNT_ONE, false);
STAmount oneThird2 = STAmount::divide(one, three, CURRENCY_ONE, ACCOUNT_ONE);
STAmount oneThird3 = STAmount::divRound(one, three, CURRENCY_ONE, ACCOUNT_ONE, true);
WriteLog (lsINFO, STAmount) << oneThird1;
WriteLog (lsINFO, STAmount) << oneThird2;
WriteLog (lsINFO, STAmount) << oneThird3;
STAmount oneThird1 = STAmount::divRound (one, three, CURRENCY_ONE, ACCOUNT_ONE, false);
STAmount oneThird2 = STAmount::divide (one, three, CURRENCY_ONE, ACCOUNT_ONE);
STAmount oneThird3 = STAmount::divRound (one, three, CURRENCY_ONE, ACCOUNT_ONE, true);
WriteLog (lsINFO, STAmount) << oneThird1;
WriteLog (lsINFO, STAmount) << oneThird2;
WriteLog (lsINFO, STAmount) << oneThird3;
STAmount twoThird1 = STAmount::divRound(two, three, CURRENCY_ONE, ACCOUNT_ONE, false);
STAmount twoThird2 = STAmount::divide(two, three, CURRENCY_ONE, ACCOUNT_ONE);
STAmount twoThird3 = STAmount::divRound(two, three, CURRENCY_ONE, ACCOUNT_ONE, true);
WriteLog (lsINFO, STAmount) << twoThird1;
WriteLog (lsINFO, STAmount) << twoThird2;
WriteLog (lsINFO, STAmount) << twoThird3;
STAmount twoThird1 = STAmount::divRound (two, three, CURRENCY_ONE, ACCOUNT_ONE, false);
STAmount twoThird2 = STAmount::divide (two, three, CURRENCY_ONE, ACCOUNT_ONE);
STAmount twoThird3 = STAmount::divRound (two, three, CURRENCY_ONE, ACCOUNT_ONE, true);
WriteLog (lsINFO, STAmount) << twoThird1;
WriteLog (lsINFO, STAmount) << twoThird2;
WriteLog (lsINFO, STAmount) << twoThird3;
STAmount oneA = STAmount::mulRound(oneThird1, three, CURRENCY_ONE, ACCOUNT_ONE, false);
STAmount oneB = STAmount::multiply(oneThird2, three, CURRENCY_ONE, ACCOUNT_ONE);
STAmount oneC = STAmount::mulRound(oneThird3, three, CURRENCY_ONE, ACCOUNT_ONE, true);
WriteLog (lsINFO, STAmount) << oneA;
WriteLog (lsINFO, STAmount) << oneB;
WriteLog (lsINFO, STAmount) << oneC;
STAmount oneA = STAmount::mulRound (oneThird1, three, CURRENCY_ONE, ACCOUNT_ONE, false);
STAmount oneB = STAmount::multiply (oneThird2, three, CURRENCY_ONE, ACCOUNT_ONE);
STAmount oneC = STAmount::mulRound (oneThird3, three, CURRENCY_ONE, ACCOUNT_ONE, true);
WriteLog (lsINFO, STAmount) << oneA;
WriteLog (lsINFO, STAmount) << oneB;
WriteLog (lsINFO, STAmount) << oneC;
STAmount fourThirdsA = STAmount::addRound(twoThird2, twoThird2, false);
STAmount fourThirdsB = twoThird2 + twoThird2;
STAmount fourThirdsC = STAmount::addRound(twoThird2, twoThird2, true);
WriteLog (lsINFO, STAmount) << fourThirdsA;
WriteLog (lsINFO, STAmount) << fourThirdsB;
WriteLog (lsINFO, STAmount) << fourThirdsC;
STAmount fourThirdsA = STAmount::addRound (twoThird2, twoThird2, false);
STAmount fourThirdsB = twoThird2 + twoThird2;
STAmount fourThirdsC = STAmount::addRound (twoThird2, twoThird2, true);
WriteLog (lsINFO, STAmount) << fourThirdsA;
WriteLog (lsINFO, STAmount) << fourThirdsB;
WriteLog (lsINFO, STAmount) << fourThirdsC;
STAmount dripTest1 = STAmount::mulRound(twoThird2, two, uint160(), uint160(), false);
STAmount dripTest2 = STAmount::multiply(twoThird2, two, uint160(), uint160());
STAmount dripTest3 = STAmount::mulRound(twoThird2, two, uint160(), uint160(), true);
WriteLog (lsINFO, STAmount) << dripTest1;
WriteLog (lsINFO, STAmount) << dripTest2;
WriteLog (lsINFO, STAmount) << dripTest3;
STAmount dripTest1 = STAmount::mulRound (twoThird2, two, uint160 (), uint160 (), false);
STAmount dripTest2 = STAmount::multiply (twoThird2, two, uint160 (), uint160 ());
STAmount dripTest3 = STAmount::mulRound (twoThird2, two, uint160 (), uint160 (), true);
WriteLog (lsINFO, STAmount) << dripTest1;
WriteLog (lsINFO, STAmount) << dripTest2;
WriteLog (lsINFO, STAmount) << dripTest3;
}
BOOST_AUTO_TEST_SUITE_END()
BOOST_AUTO_TEST_SUITE_END ()
// vim:ts=4

View File

@@ -10,169 +10,169 @@
This is done to reduce the average size of the messages.
*/
// types (common)
TYPE(Int16, UINT16, 1)
TYPE(Int32, UINT32, 2)
TYPE(Int64, UINT64, 3)
TYPE(Hash128, HASH128, 4)
TYPE(Hash256, HASH256, 5)
TYPE(Amount, AMOUNT, 6)
TYPE(VariableLength, VL, 7)
TYPE(Account, ACCOUNT, 8)
// 9-13 are reserved
TYPE(Object, OBJECT, 14)
TYPE(Array, ARRAY, 15)
// types (common)
TYPE (Int16, UINT16, 1)
TYPE (Int32, UINT32, 2)
TYPE (Int64, UINT64, 3)
TYPE (Hash128, HASH128, 4)
TYPE (Hash256, HASH256, 5)
TYPE (Amount, AMOUNT, 6)
TYPE (VariableLength, VL, 7)
TYPE (Account, ACCOUNT, 8)
// 9-13 are reserved
TYPE (Object, OBJECT, 14)
TYPE (Array, ARRAY, 15)
// types (uncommon)
TYPE(Int8, UINT8, 16)
TYPE(Hash160, HASH160, 17)
TYPE(PathSet, PATHSET, 18)
TYPE(Vector256, VECTOR256, 19)
// types (uncommon)
TYPE (Int8, UINT8, 16)
TYPE (Hash160, HASH160, 17)
TYPE (PathSet, PATHSET, 18)
TYPE (Vector256, VECTOR256, 19)
// 8-bit integers
FIELD(CloseResolution, UINT8, 1)
FIELD(TemplateEntryType, UINT8, 2)
FIELD(TransactionResult, UINT8, 3)
// 8-bit integers
FIELD (CloseResolution, UINT8, 1)
FIELD (TemplateEntryType, UINT8, 2)
FIELD (TransactionResult, UINT8, 3)
// 16-bit integers
FIELD(LedgerEntryType, UINT16, 1)
FIELD(TransactionType, UINT16, 2)
// 16-bit integers
FIELD (LedgerEntryType, UINT16, 1)
FIELD (TransactionType, UINT16, 2)
// 32-bit integers (common)
FIELD(Flags, UINT32, 2)
FIELD(SourceTag, UINT32, 3)
FIELD(Sequence, UINT32, 4)
FIELD(PreviousTxnLgrSeq, UINT32, 5)
FIELD(LedgerSequence, UINT32, 6)
FIELD(CloseTime, UINT32, 7)
FIELD(ParentCloseTime, UINT32, 8)
FIELD(SigningTime, UINT32, 9)
FIELD(Expiration, UINT32, 10)
FIELD(TransferRate, UINT32, 11)
FIELD(WalletSize, UINT32, 12)
FIELD(OwnerCount, UINT32, 13)
FIELD(DestinationTag, UINT32, 14)
// 32-bit integers (common)
FIELD (Flags, UINT32, 2)
FIELD (SourceTag, UINT32, 3)
FIELD (Sequence, UINT32, 4)
FIELD (PreviousTxnLgrSeq, UINT32, 5)
FIELD (LedgerSequence, UINT32, 6)
FIELD (CloseTime, UINT32, 7)
FIELD (ParentCloseTime, UINT32, 8)
FIELD (SigningTime, UINT32, 9)
FIELD (Expiration, UINT32, 10)
FIELD (TransferRate, UINT32, 11)
FIELD (WalletSize, UINT32, 12)
FIELD (OwnerCount, UINT32, 13)
FIELD (DestinationTag, UINT32, 14)
// 32-bit integers (uncommon)
FIELD(HighQualityIn, UINT32, 16)
FIELD(HighQualityOut, UINT32, 17)
FIELD(LowQualityIn, UINT32, 18)
FIELD(LowQualityOut, UINT32, 19)
FIELD(QualityIn, UINT32, 20)
FIELD(QualityOut, UINT32, 21)
FIELD(StampEscrow, UINT32, 22)
FIELD(BondAmount, UINT32, 23)
FIELD(LoadFee, UINT32, 24)
FIELD(OfferSequence, UINT32, 25)
FIELD(FirstLedgerSequence, UINT32, 26) // Deprecated: do not use
FIELD(LastLedgerSequence, UINT32, 27)
FIELD(TransactionIndex, UINT32, 28)
FIELD(OperationLimit, UINT32, 29)
FIELD(ReferenceFeeUnits, UINT32, 30)
FIELD(ReserveBase, UINT32, 31)
FIELD(ReserveIncrement, UINT32, 32)
// 32-bit integers (uncommon)
FIELD (HighQualityIn, UINT32, 16)
FIELD (HighQualityOut, UINT32, 17)
FIELD (LowQualityIn, UINT32, 18)
FIELD (LowQualityOut, UINT32, 19)
FIELD (QualityIn, UINT32, 20)
FIELD (QualityOut, UINT32, 21)
FIELD (StampEscrow, UINT32, 22)
FIELD (BondAmount, UINT32, 23)
FIELD (LoadFee, UINT32, 24)
FIELD (OfferSequence, UINT32, 25)
FIELD (FirstLedgerSequence, UINT32, 26) // Deprecated: do not use
FIELD (LastLedgerSequence, UINT32, 27)
FIELD (TransactionIndex, UINT32, 28)
FIELD (OperationLimit, UINT32, 29)
FIELD (ReferenceFeeUnits, UINT32, 30)
FIELD (ReserveBase, UINT32, 31)
FIELD (ReserveIncrement, UINT32, 32)
// 64-bit integers
FIELD(IndexNext, UINT64, 1)
FIELD(IndexPrevious, UINT64, 2)
FIELD(BookNode, UINT64, 3)
FIELD(OwnerNode, UINT64, 4)
FIELD(BaseFee, UINT64, 5)
FIELD(ExchangeRate, UINT64, 6)
FIELD(LowNode, UINT64, 7)
FIELD(HighNode, UINT64, 8)
// 64-bit integers
FIELD (IndexNext, UINT64, 1)
FIELD (IndexPrevious, UINT64, 2)
FIELD (BookNode, UINT64, 3)
FIELD (OwnerNode, UINT64, 4)
FIELD (BaseFee, UINT64, 5)
FIELD (ExchangeRate, UINT64, 6)
FIELD (LowNode, UINT64, 7)
FIELD (HighNode, UINT64, 8)
// 128-bit
FIELD(EmailHash, HASH128, 1)
// 128-bit
FIELD (EmailHash, HASH128, 1)
// 256-bit (common)
FIELD(LedgerHash, HASH256, 1)
FIELD(ParentHash, HASH256, 2)
FIELD(TransactionHash, HASH256, 3)
FIELD(AccountHash, HASH256, 4)
FIELD(PreviousTxnID, HASH256, 5)
FIELD(LedgerIndex, HASH256, 6)
FIELD(WalletLocator, HASH256, 7)
FIELD(RootIndex, HASH256, 8)
// 256-bit (common)
FIELD (LedgerHash, HASH256, 1)
FIELD (ParentHash, HASH256, 2)
FIELD (TransactionHash, HASH256, 3)
FIELD (AccountHash, HASH256, 4)
FIELD (PreviousTxnID, HASH256, 5)
FIELD (LedgerIndex, HASH256, 6)
FIELD (WalletLocator, HASH256, 7)
FIELD (RootIndex, HASH256, 8)
// 256-bit (uncommon)
FIELD(BookDirectory, HASH256, 16)
FIELD(InvoiceID, HASH256, 17)
FIELD(Nickname, HASH256, 18)
FIELD(Feature, HASH256, 19)
// 256-bit (uncommon)
FIELD (BookDirectory, HASH256, 16)
FIELD (InvoiceID, HASH256, 17)
FIELD (Nickname, HASH256, 18)
FIELD (Feature, HASH256, 19)
// 160-bit (common)
FIELD(TakerPaysCurrency, HASH160, 1)
FIELD(TakerPaysIssuer, HASH160, 2)
FIELD(TakerGetsCurrency, HASH160, 3)
FIELD(TakerGetsIssuer, HASH160, 4)
// 160-bit (common)
FIELD (TakerPaysCurrency, HASH160, 1)
FIELD (TakerPaysIssuer, HASH160, 2)
FIELD (TakerGetsCurrency, HASH160, 3)
FIELD (TakerGetsIssuer, HASH160, 4)
// currency amount (common)
FIELD(Amount, AMOUNT, 1)
FIELD(Balance, AMOUNT, 2)
FIELD(LimitAmount, AMOUNT, 3)
FIELD(TakerPays, AMOUNT, 4)
FIELD(TakerGets, AMOUNT, 5)
FIELD(LowLimit, AMOUNT, 6)
FIELD(HighLimit, AMOUNT, 7)
FIELD(Fee, AMOUNT, 8)
FIELD(SendMax, AMOUNT, 9)
// currency amount (common)
FIELD (Amount, AMOUNT, 1)
FIELD (Balance, AMOUNT, 2)
FIELD (LimitAmount, AMOUNT, 3)
FIELD (TakerPays, AMOUNT, 4)
FIELD (TakerGets, AMOUNT, 5)
FIELD (LowLimit, AMOUNT, 6)
FIELD (HighLimit, AMOUNT, 7)
FIELD (Fee, AMOUNT, 8)
FIELD (SendMax, AMOUNT, 9)
// currency amount (uncommon)
FIELD(MinimumOffer, AMOUNT, 16)
FIELD(RippleEscrow, AMOUNT, 17)
// currency amount (uncommon)
FIELD (MinimumOffer, AMOUNT, 16)
FIELD (RippleEscrow, AMOUNT, 17)
// variable length
FIELD(PublicKey, VL, 1)
FIELD(MessageKey, VL, 2)
FIELD(SigningPubKey, VL, 3)
FIELD(TxnSignature, VL, 4)
FIELD(Generator, VL, 5)
FIELD(Signature, VL, 6)
FIELD(Domain, VL, 7)
FIELD(FundCode, VL, 8)
FIELD(RemoveCode, VL, 9)
FIELD(ExpireCode, VL, 10)
FIELD(CreateCode, VL, 11)
// variable length
FIELD (PublicKey, VL, 1)
FIELD (MessageKey, VL, 2)
FIELD (SigningPubKey, VL, 3)
FIELD (TxnSignature, VL, 4)
FIELD (Generator, VL, 5)
FIELD (Signature, VL, 6)
FIELD (Domain, VL, 7)
FIELD (FundCode, VL, 8)
FIELD (RemoveCode, VL, 9)
FIELD (ExpireCode, VL, 10)
FIELD (CreateCode, VL, 11)
// account
FIELD(Account, ACCOUNT, 1)
FIELD(Owner, ACCOUNT, 2)
FIELD(Destination, ACCOUNT, 3)
FIELD(Issuer, ACCOUNT, 4)
FIELD(Target, ACCOUNT, 7)
FIELD(RegularKey, ACCOUNT, 8)
// account
FIELD (Account, ACCOUNT, 1)
FIELD (Owner, ACCOUNT, 2)
FIELD (Destination, ACCOUNT, 3)
FIELD (Issuer, ACCOUNT, 4)
FIELD (Target, ACCOUNT, 7)
FIELD (RegularKey, ACCOUNT, 8)
// path set
FIELD(Paths, PATHSET, 1)
// path set
FIELD (Paths, PATHSET, 1)
// vector of 256-bit
FIELD(Indexes, VECTOR256, 1)
FIELD(Hashes, VECTOR256, 2)
FIELD(Features, VECTOR256, 3)
// vector of 256-bit
FIELD (Indexes, VECTOR256, 1)
FIELD (Hashes, VECTOR256, 2)
FIELD (Features, VECTOR256, 3)
// inner object
// OBJECT/1 is reserved for end of object
FIELD(TransactionMetaData, OBJECT, 2)
FIELD(CreatedNode, OBJECT, 3)
FIELD(DeletedNode, OBJECT, 4)
FIELD(ModifiedNode, OBJECT, 5)
FIELD(PreviousFields, OBJECT, 6)
FIELD(FinalFields, OBJECT, 7)
FIELD(NewFields, OBJECT, 8)
FIELD(TemplateEntry, OBJECT, 9)
// inner object
// OBJECT/1 is reserved for end of object
FIELD (TransactionMetaData, OBJECT, 2)
FIELD (CreatedNode, OBJECT, 3)
FIELD (DeletedNode, OBJECT, 4)
FIELD (ModifiedNode, OBJECT, 5)
FIELD (PreviousFields, OBJECT, 6)
FIELD (FinalFields, OBJECT, 7)
FIELD (NewFields, OBJECT, 8)
FIELD (TemplateEntry, OBJECT, 9)
// array of objects
// ARRAY/1 is reserved for end of array
FIELD(SigningAccounts, ARRAY, 2)
FIELD(TxnSignatures, ARRAY, 3)
FIELD(Signatures, ARRAY, 4)
FIELD(Template, ARRAY, 5)
FIELD(Necessary, ARRAY, 6)
FIELD(Sufficient, ARRAY, 7)
FIELD(AffectedNodes, ARRAY, 8)
// array of objects
// ARRAY/1 is reserved for end of array
FIELD (SigningAccounts, ARRAY, 2)
FIELD (TxnSignatures, ARRAY, 3)
FIELD (Signatures, ARRAY, 4)
FIELD (Template, ARRAY, 5)
FIELD (Necessary, ARRAY, 6)
FIELD (Sufficient, ARRAY, 7)
FIELD (AffectedNodes, ARRAY, 8)
// vim:ts=4

File diff suppressed because it is too large Load Diff

View File

@@ -1,256 +1,488 @@
#ifndef RIPPLE_SERIALIZEDOBJECT_H
#define RIPPLE_SERIALIZEDOBJECT_H
DEFINE_INSTANCE(SerializedObject);
DEFINE_INSTANCE(SerializedArray);
DEFINE_INSTANCE (SerializedObject);
DEFINE_INSTANCE (SerializedArray);
class STObject : public SerializedType, private IS_INSTANCE(SerializedObject)
class STObject : public SerializedType, private IS_INSTANCE (SerializedObject)
{
public:
STObject() : mType(NULL) { ; }
STObject () : mType (NULL)
{
;
}
explicit STObject(SField::ref name) : SerializedType(name), mType(NULL) { ; }
explicit STObject (SField::ref name) : SerializedType (name), mType (NULL)
{
;
}
STObject (const SOTemplate& type, SField::ref name) : SerializedType(name)
{ set(type); }
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); }
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)); }
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);
static UPTR_T<STObject> parseJson (const Json::Value & value, SField::ref name = sfGeneric, int depth = 0);
virtual ~STObject() { ; }
virtual ~STObject ()
{
;
}
static UPTR_T<SerializedType> deserialize(SerializerIterator& sit, SField::ref name);
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; }
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);
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 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
virtual void add (Serializer & s) const
{
add (s, true); // just inner elements
}
void add(Serializer& s, bool withSignature) const;
void add (Serializer & s, bool withSignature) const;
// VFALCO NOTE does this return an expensive copy of an object with a dynamic buffer?
// VFALCO TODO Remove this function and fix the few callers.
Serializer getSerializer() const { Serializer s; add(s); return s; }
Serializer getSerializer () const
{
Serializer s;
add (s);
return s;
}
std::string getFullText() const;
std::string getText() const;
virtual Json::Value getJson(int options) const;
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 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(); }
int getCount () const
{
return mData.size ();
}
bool setFlag(uint32);
bool clearFlag(uint32);
uint32 getFlags() const;
bool setFlag (uint32);
bool clearFlag (uint32);
uint32 getFlags () const;
uint256 getHash(uint32 prefix) const;
uint256 getSigningHash(uint32 prefix) 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]); }
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;
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);
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;
Blob 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;
// 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;
Blob 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, uint256 const& );
void setFieldVL(SField::ref field, Blob const&);
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);
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, uint256 const& );
void setFieldVL (SField::ref field, Blob const&);
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);
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);
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> makeDefaultObject (SerializedTypeID id, SField::ref name);
// VFALCO TODO remove the 'depth' parameter
static UPTR_T<SerializedType> makeDeserializedObject (
SerializedTypeID id,
SField::ref name,
SerializerIterator &,
SerializerIterator&,
int depth);
static UPTR_T<SerializedType> makeNonPresentObject (SField::ref name)
{
return makeDefaultObject(STI_NOTPRESENT, name);
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);
{
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(); }
// 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 hasMatchingEntry (const SerializedType&);
bool operator==(const STObject& o) const;
bool operator!=(const STObject& o) const { return ! (*this == o); }
bool operator== (const STObject & o) const;
bool operator!= (const STObject & o) const
{
return ! (*this == o);
}
private:
boost::ptr_vector<SerializedType> mData;
const SOTemplate* mType;
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); }
STObject* duplicate () const
{
return new STObject (*this);
}
STObject (SField::ref name, boost::ptr_vector<SerializedType>& data) : SerializedType (name), mType (NULL)
{
mData.swap (data);
}
};
//------------------------------------------------------------------------------
inline STObject::iterator range_begin(STObject& x) { return x.begin(); }
inline STObject::iterator range_end(STObject &x) { return x.end(); }
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; };
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)
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;
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 () { ; }
explicit STArray(int n) { value.reserve(n); }
explicit STArray(SField::ref f) : SerializedType(f) { ; }
STArray(SField::ref f, int n) : SerializedType(f) { value.reserve(n); }
STArray(SField::ref f, const vector& v) : SerializedType(f), value(v) { ; }
explicit STArray(vector& v) : value(v) { ; }
STArray ()
{
;
}
explicit STArray (int n)
{
value.reserve (n);
}
explicit STArray (SField::ref f) : SerializedType (f)
{
;
}
STArray (SField::ref f, int n) : SerializedType (f)
{
value.reserve (n);
}
STArray (SField::ref f, const vector & v) : SerializedType (f), value (v)
{
;
}
explicit STArray (vector & v) : value (v)
{
;
}
static UPTR_T<SerializedType> deserialize(SerializerIterator& sit, SField::ref name)
{ return UPTR_T<SerializedType>(construct(sit, name)); }
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; }
const vector& getValue () const
{
return value;
}
vector& getValue ()
{
return value;
}
// VFALCO NOTE as long as we're married to boost why not use boost::iterator_facade?
//
// vector-like functions
void push_back(const STObject& object) { value.push_back(object.oClone().release()); }
STObject& operator[](int j) { return value[j]; }
const STObject& operator[](int j) const { return value[j]; }
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); }
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;
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));
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; }
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(); }
virtual SerializedTypeID getSType () const
{
return STI_ARRAY;
}
virtual bool isEquivalent (const SerializedType & t) const;
virtual bool isDefault () const
{
return value.empty ();
}
private:
vector value;
vector value;
STArray* duplicate() const { return new STArray(*this); }
static STArray* construct(SerializerIterator&, SField::ref);
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(); }
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; };
template<> struct range_mutable_iterator<STArray>
{
typedef STArray::iterator type;
};
template<> struct range_const_iterator<STArray>
{
typedef STArray::const_iterator type;
};
}
#endif

View File

@@ -8,24 +8,24 @@ void SOTemplate::push_back (SOElement const& r)
// Ensure there is the enough space in the index mapping
// table for all possible fields.
//
if (mIndex.empty())
if (mIndex.empty ())
{
// Unmapped indices will be set to -1
//
mIndex.resize (SField::getNumFields() + 1, -1);
mIndex.resize (SField::getNumFields () + 1, -1);
}
// Make sure the field's index is in range
//
assert (r.e_field.getNum() < mIndex.size());
assert (r.e_field.getNum () < mIndex.size ());
// Make sure that this field hasn't already been assigned
//
assert(getIndex(r.e_field) == -1);
assert (getIndex (r.e_field) == -1);
// Add the field to the index mapping table
//
mIndex [r.e_field.getNum ()] = mTypes.size();
mIndex [r.e_field.getNum ()] = mTypes.size ();
// Append the new element.
//
@@ -36,7 +36,7 @@ int SOTemplate::getIndex (SField::ref f) const
{
// The mapping table should be large enough for any possible field
//
assert (f.getNum() < mIndex.size());
assert (f.getNum () < mIndex.size ());
return mIndex[f.getNum()];
return mIndex[f.getNum ()];
}

View File

@@ -8,10 +8,10 @@
// VFALCO NOTE these don't look like bit-flags...
enum SOE_Flags
{
SOE_INVALID = -1,
SOE_REQUIRED = 0, // required
SOE_OPTIONAL = 1, // optional, may be present with default value
SOE_DEFAULT = 2, // optional, if present, must not have default value
SOE_INVALID = -1,
SOE_REQUIRED = 0, // required
SOE_OPTIONAL = 1, // optional, may be present with default value
SOE_DEFAULT = 2, // optional, if present, must not have default value
};
//------------------------------------------------------------------------------
@@ -21,10 +21,10 @@ enum SOE_Flags
class SOElement
{
public:
SField::ref const e_field;
SOE_Flags const flags;
SField::ref const e_field;
SOE_Flags const flags;
SOElement (SField::ref fieldName, SOE_Flags flags)
SOElement (SField::ref fieldName, SOE_Flags flags)
: e_field (fieldName)
, flags (flags)
{
@@ -48,12 +48,12 @@ public:
@see push_back
*/
SOTemplate ();
SOTemplate ();
// VFALCO NOTE Why do we even bother with the 'private' keyword if
// this function is present?
//
std::vector <SOElement const*> const& peek() const
std::vector <SOElement const*> const& peek () const
{
return mTypes;
}
@@ -61,15 +61,15 @@ public:
/** Add an element to the template.
*/
void push_back (SOElement const& r);
/** Retrieve the position of a named field.
*/
int getIndex (SField::ref) const;
private:
std::vector <SOElement const*> mTypes;
std::vector <SOElement const*> mTypes;
std::vector <int> mIndex; // field num -> index
std::vector <int> mIndex; // field num -> index
};
#endif

View File

@@ -1,265 +1,291 @@
SETUP_LOG (SerializedType)
const STAmount saZero(CURRENCY_ONE, ACCOUNT_ONE, 0);
const STAmount saOne(CURRENCY_ONE, ACCOUNT_ONE, 1);
const STAmount saZero (CURRENCY_ONE, ACCOUNT_ONE, 0);
const STAmount saOne (CURRENCY_ONE, ACCOUNT_ONE, 1);
SerializedType& SerializedType::operator=(const SerializedType& t)
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();
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 ();
}
std::cerr << std::endl;
}
if (!fName->isUseful ()) fName = t.fName;
return *this;
}
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
void STPathSet::printDebug ()
{
std::string ret;
if (getSType() != STI_NOTPRESENT)
{
if(fName->hasName())
{
ret = fName->fieldName;
ret += " = ";
}
ret += getText();
}
return ret;
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;
}
}
STUInt8* STUInt8::construct(SerializerIterator& u, SField::ref name)
void STPath::printDebug ()
{
return new STUInt8(name, u.get8());
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 STUInt8::getText() const
std::string SerializedType::getFullText () 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);
std::string ret;
if (getSType () != STI_NOTPRESENT)
{
if (fName->hasName ())
{
ret = fName->fieldName;
ret += " = ";
}
ret += getText ();
}
return ret;
}
Json::Value STUInt8::getJson(int) const
STUInt8* STUInt8::construct (SerializerIterator& u, SField::ref name)
{
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;
return new STUInt8 (name, u.get8 ());
}
bool STUInt8::isEquivalent(const SerializedType& t) const
std::string STUInt8::getText () const
{
const STUInt8* v = dynamic_cast<const STUInt8*>(&t);
return v && (value == v->value);
if (getFName () == sfTransactionResult)
{
std::string token, human;
if (transResultInfo (static_cast<TER> (value), token, human))
return human;
}
return boost::lexical_cast<std::string> (value);
}
STUInt16* STUInt16::construct(SerializerIterator& u, SField::ref name)
Json::Value STUInt8::getJson (int) const
{
return new STUInt16(name, u.get16());
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;
}
std::string STUInt16::getText() const
bool STUInt8::isEquivalent (const SerializedType& t) 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);
const STUInt8* v = dynamic_cast<const STUInt8*> (&t);
return v && (value == v->value);
}
Json::Value STUInt16::getJson(int) const
STUInt16* STUInt16::construct (SerializerIterator& u, SField::ref name)
{
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;
return new STUInt16 (name, u.get16 ());
}
bool STUInt16::isEquivalent(const SerializedType& t) const
std::string STUInt16::getText () const
{
const STUInt16* v = dynamic_cast<const STUInt16*>(&t);
return v && (value == v->value);
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);
}
STUInt32* STUInt32::construct(SerializerIterator& u, SField::ref name)
{
return new STUInt32(name, u.get32());
}
std::string STUInt32::getText() const
Json::Value STUInt16::getJson (int) const
{
return boost::lexical_cast<std::string>(value);
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;
}
Json::Value STUInt32::getJson(int) const
bool STUInt16::isEquivalent (const SerializedType& t) const
{
return value;
const STUInt16* v = dynamic_cast<const STUInt16*> (&t);
return v && (value == v->value);
}
bool STUInt32::isEquivalent(const SerializedType& t) const
STUInt32* STUInt32::construct (SerializerIterator& u, SField::ref name)
{
const STUInt32* v = dynamic_cast<const STUInt32*>(&t);
return v && (value == v->value);
return new STUInt32 (name, u.get32 ());
}
STUInt64* STUInt64::construct(SerializerIterator& u, SField::ref name)
std::string STUInt32::getText () const
{
return new STUInt64(name, u.get64());
return boost::lexical_cast<std::string> (value);
}
std::string STUInt64::getText() const
Json::Value STUInt32::getJson (int) const
{
return boost::lexical_cast<std::string>(value);
return value;
}
Json::Value STUInt64::getJson(int) const
bool STUInt32::isEquivalent (const SerializedType& t) const
{
return strHex(value);
const STUInt32* v = dynamic_cast<const STUInt32*> (&t);
return v && (value == v->value);
}
bool STUInt64::isEquivalent(const SerializedType& t) const
STUInt64* STUInt64::construct (SerializerIterator& u, SField::ref name)
{
const STUInt64* v = dynamic_cast<const STUInt64*>(&t);
return v && (value == v->value);
return new STUInt64 (name, u.get64 ());
}
STHash128* STHash128::construct(SerializerIterator& u, SField::ref name)
std::string STUInt64::getText () const
{
return new STHash128(name, u.get128());
return boost::lexical_cast<std::string> (value);
}
std::string STHash128::getText() const
Json::Value STUInt64::getJson (int) const
{
return value.GetHex();
return strHex (value);
}
bool STHash128::isEquivalent(const SerializedType& t) const
bool STUInt64::isEquivalent (const SerializedType& t) const
{
const STHash128* v = dynamic_cast<const STHash128*>(&t);
return v && (value == v->value);
const STUInt64* v = dynamic_cast<const STUInt64*> (&t);
return v && (value == v->value);
}
STHash160* STHash160::construct(SerializerIterator& u, SField::ref name)
STHash128* STHash128::construct (SerializerIterator& u, SField::ref name)
{
return new STHash160(name, u.get160());
return new STHash128 (name, u.get128 ());
}
std::string STHash160::getText() const
std::string STHash128::getText () const
{
return value.GetHex();
return value.GetHex ();
}
bool STHash160::isEquivalent(const SerializedType& t) const
bool STHash128::isEquivalent (const SerializedType& t) const
{
const STHash160* v = dynamic_cast<const STHash160*>(&t);
return v && (value == v->value);
const STHash128* v = dynamic_cast<const STHash128*> (&t);
return v && (value == v->value);
}
STHash256* STHash256::construct(SerializerIterator& u, SField::ref name)
STHash160* STHash160::construct (SerializerIterator& u, SField::ref name)
{
return new STHash256(name, u.get256());
return new STHash160 (name, u.get160 ());
}
std::string STHash256::getText() const
std::string STHash160::getText () const
{
return value.GetHex();
return value.GetHex ();
}
bool STHash256::isEquivalent(const SerializedType& t) const
bool STHash160::isEquivalent (const SerializedType& t) const
{
const STHash256* v = dynamic_cast<const STHash256*>(&t);
return v && (value == v->value);
const STHash160* v = dynamic_cast<const STHash160*> (&t);
return v && (value == v->value);
}
STVariableLength::STVariableLength(SerializerIterator& st, SField::ref name) : SerializedType(name)
STHash256* STHash256::construct (SerializerIterator& u, SField::ref name)
{
value = st.getVL();
return new STHash256 (name, u.get256 ());
}
std::string STVariableLength::getText() const
std::string STHash256::getText () const
{
return strHex(value);
return value.GetHex ();
}
STVariableLength* STVariableLength::construct(SerializerIterator& u, SField::ref name)
bool STHash256::isEquivalent (const SerializedType& t) const
{
return new STVariableLength(name, u.getVL());
const STHash256* v = dynamic_cast<const STHash256*> (&t);
return v && (value == v->value);
}
bool STVariableLength::isEquivalent(const SerializedType& t) const
STVariableLength::STVariableLength (SerializerIterator& st, SField::ref name) : SerializedType (name)
{
const STVariableLength* v = dynamic_cast<const STVariableLength*>(&t);
return v && (value == v->value);
value = st.getVL ();
}
std::string STAccount::getText() const
std::string STVariableLength::getText () const
{
uint160 u;
RippleAddress a;
if (!getValueH160(u))
return STVariableLength::getText();
a.setAccountID(u);
return a.humanAccountID();
return strHex (value);
}
STAccount* STAccount::construct(SerializerIterator& u, SField::ref name)
STVariableLength* STVariableLength::construct (SerializerIterator& u, SField::ref name)
{
return new STAccount(name, u.getVL());
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 ());
}
//
@@ -267,287 +293,298 @@ STAccount* STAccount::construct(SerializerIterator& u, SField::ref name)
//
// Return a new object from a SerializerIterator.
STVector256* STVector256::construct(SerializerIterator& u, SField::ref name)
STVector256* STVector256::construct (SerializerIterator& u, SField::ref name)
{
Blob data = u.getVL();
Blob ::iterator begin = data.begin();
Blob data = u.getVL ();
Blob ::iterator begin = data.begin ();
UPTR_T<STVector256> vec(new STVector256(name));
UPTR_T<STVector256> vec (new STVector256 (name));
int count = data.size() / (256 / 8);
vec->mValue.reserve(count);
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);
unsigned int uStart = 0;
// This next line could be optimized to construct a default uint256 in the vector and then copy into it
vec->mValue.push_back(uint256(Blob (begin + uStart, begin + uEnd)));
uStart = uEnd;
}
for (unsigned int i = 0; i != count; i++)
{
unsigned int uEnd = uStart + (256 / 8);
return vec.release();
// This next line could be optimized to construct a default uint256 in the vector and then copy into it
vec->mValue.push_back (uint256 (Blob (begin + uStart, begin + uEnd)));
uStart = uEnd;
}
return vec.release ();
}
void STVector256::add(Serializer& s) const
void STVector256::add (Serializer& s) const
{
s.addVL(mValue.empty() ? NULL : mValue[0].begin(), mValue.size() * (256 / 8));
s.addVL (mValue.empty () ? NULL : mValue[0].begin (), mValue.size () * (256 / 8));
}
bool STVector256::isEquivalent(const SerializedType& t) const
bool STVector256::isEquivalent (const SerializedType& t) const
{
const STVector256* v = dynamic_cast<const STVector256*>(&t);
return v && (mValue == v->mValue);
const STVector256* v = dynamic_cast<const STVector256*> (&t);
return v && (mValue == v->mValue);
}
bool STVector256::hasValue(uint256 const& v) const
bool STVector256::hasValue (uint256 const& v) const
{
BOOST_FOREACH(uint256 const& hash, mValue)
{
if (hash == v)
return true;
}
BOOST_FOREACH (uint256 const & hash, mValue)
{
if (hash == v)
return true;
}
return false;
return false;
}
//
// STAccount
//
STAccount::STAccount(SField::ref n, const uint160& v) : STVariableLength(n)
STAccount::STAccount (SField::ref n, const uint160& v) : STVariableLength (n)
{
peekValue().insert(peekValue().end(), v.begin(), v.end());
peekValue ().insert (peekValue ().end (), v.begin (), v.end ());
}
bool STAccount::isValueH160() const
bool STAccount::isValueH160 () const
{
return peekValue().size() == (160 / 8);
return peekValue ().size () == (160 / 8);
}
void STAccount::setValueH160(const uint160& v)
void STAccount::setValueH160 (const uint160& v)
{
peekValue().clear();
peekValue().insert(peekValue().end(), v.begin(), v.end());
assert(peekValue().size() == (160/8));
peekValue ().clear ();
peekValue ().insert (peekValue ().end (), v.begin (), v.end ());
assert (peekValue ().size () == (160 / 8));
}
bool STAccount::getValueH160(uint160& v) const
bool STAccount::getValueH160 (uint160& v) const
{
if (!isValueH160()) return false;
memcpy(v.begin(), &(peekValue().front()), (160/8));
return true;
if (!isValueH160 ()) return false;
memcpy (v.begin (), & (peekValue ().front ()), (160 / 8));
return true;
}
RippleAddress STAccount::getValueNCA() const
RippleAddress STAccount::getValueNCA () const
{
RippleAddress a;
uint160 v;
if (getValueH160(v))
a.setAccountID(v);
return a;
RippleAddress a;
uint160 v;
if (getValueH160 (v))
a.setAccountID (v);
return a;
}
void STAccount::setValueNCA(const RippleAddress& nca)
void STAccount::setValueNCA (const RippleAddress& nca)
{
setValueH160(nca.getAccountID());
setValueH160 (nca.getAccountID ());
}
STPathSet* STPathSet::construct(SerializerIterator& s, SField::ref name)
STPathSet* STPathSet::construct (SerializerIterator& s, SField::ref name)
{
std::vector<STPath> paths;
std::vector<STPathElement> path;
std::vector<STPath> paths;
std::vector<STPathElement> path;
do
{
int iType = s.get8();
do
{
int iType = s.get8 ();
if (iType == STPathElement::typeEnd || iType == STPathElement::typeBoundary)
{
if (path.empty())
{
WriteLog (lsINFO, SerializedType) << "STPathSet: Empty path.";
if (iType == STPathElement::typeEnd || iType == STPathElement::typeBoundary)
{
if (path.empty ())
{
WriteLog (lsINFO, SerializedType) << "STPathSet: Empty path.";
throw std::runtime_error("empty path");
}
throw std::runtime_error ("empty path");
}
paths.push_back(path);
path.clear();
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;
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);
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;
uint160 uAccountID;
uint160 uCurrency;
uint160 uIssuerID;
if (bAccount)
uAccountID = s.get160();
if (bAccount)
uAccountID = s.get160 ();
if (bCurrency)
uCurrency = s.get160();
if (bCurrency)
uCurrency = s.get160 ();
if (bIssuer)
uIssuerID = s.get160();
if (bIssuer)
uIssuerID = s.get160 ();
path.push_back(STPathElement(uAccountID, uCurrency, uIssuerID, bCurrency));
}
} while(1);
path.push_back (STPathElement (uAccountID, uCurrency, uIssuerID, bCurrency));
}
}
while (1);
}
bool STPathSet::isEquivalent(const SerializedType& t) const
bool STPathSet::isEquivalent (const SerializedType& t) const
{
const STPathSet* v = dynamic_cast<const STPathSet*>(&t);
return v && (value == v->value);
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)
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;
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 STPath::getJson (int) const
{
Json::Value ret(Json::arrayValue);
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();
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);
elem["type"] = iType;
elem["type_hex"] = strHex (iType);
if (iType & STPathElement::typeAccount)
elem["account"] = RippleAddress::createHumanAccountID(it.getAccountID());
if (iType & STPathElement::typeAccount)
elem["account"] = RippleAddress::createHumanAccountID (it.getAccountID ());
if (iType & STPathElement::typeCurrency)
elem["currency"] = STAmount::createHumanCurrency(it.getCurrency());
if (iType & STPathElement::typeCurrency)
elem["currency"] = STAmount::createHumanCurrency (it.getCurrency ());
if (iType & STPathElement::typeIssuer)
elem["issuer"] = RippleAddress::createHumanAccountID(it.getIssuerID());
if (iType & STPathElement::typeIssuer)
elem["issuer"] = RippleAddress::createHumanAccountID (it.getIssuerID ());
ret.append(elem);
}
ret.append (elem);
}
return ret;
return ret;
}
Json::Value STPathSet::getJson(int options) const
Json::Value STPathSet::getJson (int options) const
{
Json::Value ret(Json::arrayValue);
Json::Value ret (Json::arrayValue);
BOOST_FOREACH(std::vector<STPath>::const_iterator::value_type it, value)
ret.append(it.getJson(options));
BOOST_FOREACH (std::vector<STPath>::const_iterator::value_type it, value)
ret.append (it.getJson (options));
return ret;
return ret;
}
#if 0
std::string STPath::getText() const
std::string STPath::getText () const
{
std::string ret("[");
bool first = true;
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;
}
BOOST_FOREACH (const STPathElement & it, mPath)
{
if (!first) ret += ", ";
case STPathElement::typeOffer:
{
ret += "Offer(";
ret += it.getNode().GetHex();
ret += ")";
break;
}
switch (it.getNodeType ())
{
case STPathElement::typeAccount:
{
ret += RippleAddress::createHumanAccountID (it.getNode ());
break;
}
default: throw std::runtime_error("Unknown path element");
}
first = false;
}
case STPathElement::typeOffer:
{
ret += "Offer(";
ret += it.getNode ().GetHex ();
ret += ")";
break;
}
return ret + "]";
default:
throw std::runtime_error ("Unknown path element");
}
first = false;
}
return ret + "]";
}
#endif
#if 0
std::string STPathSet::getText() const
std::string STPathSet::getText () const
{
std::string ret("{");
bool firstPath = true;
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 + "}";
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
void STPathSet::add (Serializer& s) const
{
bool bFirst = true;
bool bFirst = true;
BOOST_FOREACH(const STPath& spPath, value)
{
if (!bFirst)
{
s.add8(STPathElement::typeBoundary);
}
BOOST_FOREACH (const STPath & spPath, value)
{
if (!bFirst)
{
s.add8 (STPathElement::typeBoundary);
}
BOOST_FOREACH(const STPathElement& speElement, spPath)
{
int iType = speElement.getNodeType();
BOOST_FOREACH (const STPathElement & speElement, spPath)
{
int iType = speElement.getNodeType ();
s.add8(iType);
s.add8 (iType);
if (iType & STPathElement::typeAccount)
s.add160(speElement.getAccountID());
if (iType & STPathElement::typeAccount)
s.add160 (speElement.getAccountID ());
if (iType & STPathElement::typeCurrency)
s.add160(speElement.getCurrency());
if (iType & STPathElement::typeCurrency)
s.add160 (speElement.getCurrency ());
if (iType & STPathElement::typeIssuer)
s.add160(speElement.getIssuerID());
}
if (iType & STPathElement::typeIssuer)
s.add160 (speElement.getIssuerID ());
}
bFirst = false;
}
s.add8(STPathElement::typeEnd);
bFirst = false;
}
s.add8 (STPathElement::typeEnd);
}
// vim:ts=4

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -6,155 +6,270 @@ class CKey; // forward declaration
class Serializer
{
public:
typedef boost::shared_ptr<Serializer> pointer;
typedef boost::shared_ptr<Serializer> pointer;
protected:
Blob mData;
Blob mData;
public:
Serializer(int n = 256) { mData.reserve(n); }
Serializer(Blob const& data) : mData(data) { ; }
Serializer(const std::string& data) : mData(data.data(), (data.data()) + data.size()) { ; }
Serializer(Blob ::iterator begin, Blob ::iterator end) :
mData(begin, end) { ; }
Serializer(Blob ::const_iterator begin, Blob ::const_iterator end) :
mData(begin, end) { ; }
Serializer (int n = 256)
{
mData.reserve (n);
}
Serializer (Blob const& data) : mData (data)
{
;
}
Serializer (const std::string& data) : mData (data.data (), (data.data ()) + data.size ())
{
;
}
Serializer (Blob ::iterator begin, Blob ::iterator end) :
mData (begin, end)
{
;
}
Serializer (Blob ::const_iterator begin, Blob ::const_iterator end) :
mData (begin, end)
{
;
}
// assemble functions
int add8(unsigned char byte);
int add16(uint16);
int add32(uint32); // ledger indexes, account sequence, timestamps
int add64(uint64); // native currency amounts
int add128(const uint128&); // private key generators
int add160(const uint160&); // account names, hankos
int add256(uint256 const& ); // transaction and ledger hashes
int addRaw(Blob const& vector);
int addRaw(const void *ptr, int len);
int addRaw(const Serializer& s);
int addZeros(size_t uBytes);
// assemble functions
int add8 (unsigned char byte);
int add16 (uint16);
int add32 (uint32); // ledger indexes, account sequence, timestamps
int add64 (uint64); // native currency amounts
int add128 (const uint128&); // private key generators
int add160 (const uint160&); // account names, hankos
int add256 (uint256 const& ); // transaction and ledger hashes
int addRaw (Blob const& vector);
int addRaw (const void* ptr, int len);
int addRaw (const Serializer& s);
int addZeros (size_t uBytes);
int addVL(Blob const& vector);
int addVL(const std::string& string);
int addVL(const void *ptr, int len);
int addVL (Blob const& vector);
int addVL (const std::string& string);
int addVL (const void* ptr, int len);
// disassemble functions
bool get8(int&, int offset) const;
bool get8(unsigned char&, int offset) const;
bool get16(uint16&, int offset) const;
bool get32(uint32&, int offset) const;
bool get64(uint64&, int offset) const;
bool get128(uint128&, int offset) const;
bool get160(uint160&, int offset) const;
bool get256(uint256&, int offset) const;
uint256 get256(int offset) const;
bool getRaw(Blob&, int offset, int length) const;
Blob getRaw(int offset, int length) const;
// disassemble functions
bool get8 (int&, int offset) const;
bool get8 (unsigned char&, int offset) const;
bool get16 (uint16&, int offset) const;
bool get32 (uint32&, int offset) const;
bool get64 (uint64&, int offset) const;
bool get128 (uint128&, int offset) const;
bool get160 (uint160&, int offset) const;
bool get256 (uint256&, int offset) const;
uint256 get256 (int offset) const;
bool getRaw (Blob&, int offset, int length) const;
Blob getRaw (int offset, int length) const;
bool getVL(Blob& objectVL, int offset, int& length) const;
bool getVLLength(int& length, int offset) const;
bool getVL (Blob& objectVL, int offset, int& length) const;
bool getVLLength (int& length, int offset) const;
bool getFieldID(int& type, int& name, int offset) const;
int addFieldID(int type, int name);
int addFieldID(SerializedTypeID type, int name) { return addFieldID(static_cast<int>(type), name); }
bool getFieldID (int& type, int& name, int offset) const;
int addFieldID (int type, int name);
int addFieldID (SerializedTypeID type, int name)
{
return addFieldID (static_cast<int> (type), name);
}
// normal hash functions
uint160 getRIPEMD160(int size=-1) const;
uint256 getSHA256(int size=-1) const;
uint256 getSHA512Half(int size=-1) const;
static uint256 getSHA512Half(Blob const& data, int size=-1);
static uint256 getSHA512Half(const unsigned char *data, int len);
static uint256 getSHA512Half(const std::string& strData);
// normal hash functions
uint160 getRIPEMD160 (int size = -1) const;
uint256 getSHA256 (int size = -1) const;
uint256 getSHA512Half (int size = -1) const;
static uint256 getSHA512Half (Blob const& data, int size = -1);
static uint256 getSHA512Half (const unsigned char* data, int len);
static uint256 getSHA512Half (const std::string& strData);
// prefix hash functions
static uint256 getPrefixHash(uint32 prefix, const unsigned char *data, int len);
uint256 getPrefixHash(uint32 prefix) const
{ return getPrefixHash(prefix, &(mData.front()), mData.size()); }
static uint256 getPrefixHash(uint32 prefix, Blob const& data)
{ return getPrefixHash(prefix, &(data.front()), data.size()); }
static uint256 getPrefixHash(uint32 prefix, const std::string& strData)
{ return getPrefixHash(prefix, reinterpret_cast<const unsigned char *>(strData.data()), strData.size()); }
// prefix hash functions
static uint256 getPrefixHash (uint32 prefix, const unsigned char* data, int len);
uint256 getPrefixHash (uint32 prefix) const
{
return getPrefixHash (prefix, & (mData.front ()), mData.size ());
}
static uint256 getPrefixHash (uint32 prefix, Blob const& data)
{
return getPrefixHash (prefix, & (data.front ()), data.size ());
}
static uint256 getPrefixHash (uint32 prefix, const std::string& strData)
{
return getPrefixHash (prefix, reinterpret_cast<const unsigned char*> (strData.data ()), strData.size ());
}
// totality functions
Blob const& peekData() const { return mData; }
Blob getData() const { return mData; }
Blob& modData() { return mData; }
int getCapacity() const { return mData.capacity(); }
int getDataLength() const { return mData.size(); }
const void* getDataPtr() const { return &mData.front(); }
void* getDataPtr() { return &mData.front(); }
int getLength() const { return mData.size(); }
std::string getString() const { return std::string(static_cast<const char *>(getDataPtr()), size()); }
void secureErase() { memset(&(mData.front()), 0, mData.size()); erase(); }
void erase() { mData.clear(); }
int removeLastByte();
bool chop(int num);
// totality functions
Blob const& peekData () const
{
return mData;
}
Blob getData () const
{
return mData;
}
Blob& modData ()
{
return mData;
}
int getCapacity () const
{
return mData.capacity ();
}
int getDataLength () const
{
return mData.size ();
}
const void* getDataPtr () const
{
return &mData.front ();
}
void* getDataPtr ()
{
return &mData.front ();
}
int getLength () const
{
return mData.size ();
}
std::string getString () const
{
return std::string (static_cast<const char*> (getDataPtr ()), size ());
}
void secureErase ()
{
memset (& (mData.front ()), 0, mData.size ());
erase ();
}
void erase ()
{
mData.clear ();
}
int removeLastByte ();
bool chop (int num);
// vector-like functions
Blob ::iterator begin() { return mData.begin(); }
Blob ::iterator end() { return mData.end(); }
Blob ::const_iterator begin() const { return mData.begin(); }
Blob ::const_iterator end() const { return mData.end(); }
Blob ::size_type size() const { return mData.size(); }
void reserve(size_t n) { mData.reserve(n); }
void resize(size_t n) { mData.resize(n); }
size_t capacity() const { return mData.capacity(); }
// vector-like functions
Blob ::iterator begin ()
{
return mData.begin ();
}
Blob ::iterator end ()
{
return mData.end ();
}
Blob ::const_iterator begin () const
{
return mData.begin ();
}
Blob ::const_iterator end () const
{
return mData.end ();
}
Blob ::size_type size () const
{
return mData.size ();
}
void reserve (size_t n)
{
mData.reserve (n);
}
void resize (size_t n)
{
mData.resize (n);
}
size_t capacity () const
{
return mData.capacity ();
}
bool operator==(Blob const& v) { return v == mData; }
bool operator!=(Blob const& v) { return v != mData; }
bool operator==(const Serializer& v) { return v.mData == mData; }
bool operator!=(const Serializer& v) { return v.mData != mData; }
bool operator== (Blob const& v)
{
return v == mData;
}
bool operator!= (Blob const& v)
{
return v != mData;
}
bool operator== (const Serializer& v)
{
return v.mData == mData;
}
bool operator!= (const Serializer& v)
{
return v.mData != mData;
}
// signature functions
bool checkSignature(int pubkeyOffset, int signatureOffset) const;
bool checkSignature(Blob const& signature, CKey& rkey) const;
bool makeSignature(Blob& signature, CKey& rkey) const;
bool addSignature(CKey& rkey);
// signature functions
bool checkSignature (int pubkeyOffset, int signatureOffset) const;
bool checkSignature (Blob const& signature, CKey& rkey) const;
bool makeSignature (Blob& signature, CKey& rkey) const;
bool addSignature (CKey& rkey);
// low-level VL length encode/decode functions
static Blob encodeVL(int length);
static int lengthVL(int length) { return length + encodeLengthLength(length); }
static int encodeLengthLength(int length); // length to encode length
static int decodeLengthLength(int b1);
static int decodeVLLength(int b1);
static int decodeVLLength(int b1, int b2);
static int decodeVLLength(int b1, int b2, int b3);
// low-level VL length encode/decode functions
static Blob encodeVL (int length);
static int lengthVL (int length)
{
return length + encodeLengthLength (length);
}
static int encodeLengthLength (int length); // length to encode length
static int decodeLengthLength (int b1);
static int decodeVLLength (int b1);
static int decodeVLLength (int b1, int b2);
static int decodeVLLength (int b1, int b2, int b3);
static void TestSerializer();
static void TestSerializer ();
};
class SerializerIterator
{
protected:
const Serializer& mSerializer;
int mPos;
const Serializer& mSerializer;
int mPos;
public:
// Reference is not const because we don't want to bind to a temporary
SerializerIterator(Serializer& s) : mSerializer(s), mPos(0) { ; }
// Reference is not const because we don't want to bind to a temporary
SerializerIterator (Serializer& s) : mSerializer (s), mPos (0)
{
;
}
const Serializer& operator*(void) { return mSerializer; }
void reset(void) { mPos = 0; }
void setPos(int p) { mPos = p; }
const Serializer& operator* (void)
{
return mSerializer;
}
void reset (void)
{
mPos = 0;
}
void setPos (int p)
{
mPos = p;
}
int getPos(void) { return mPos; }
bool empty() { return mPos == mSerializer.getLength(); }
int getBytesLeft();
int getPos (void)
{
return mPos;
}
bool empty ()
{
return mPos == mSerializer.getLength ();
}
int getBytesLeft ();
// get functions throw on error
unsigned char get8();
uint16 get16();
uint32 get32();
uint64 get64();
uint128 get128();
uint160 get160();
uint256 get256();
// get functions throw on error
unsigned char get8 ();
uint16 get16 ();
uint32 get32 ();
uint64 get64 ();
uint128 get128 ();
uint160 get160 ();
uint256 get256 ();
void getFieldID(int& type, int& field);
void getFieldID (int& type, int& field);
Blob getRaw(int iLength);
Blob getRaw (int iLength);
Blob getVL();
Blob getVL ();
};
#endif

View File

@@ -1,125 +1,127 @@
bool transResultInfo(TER terCode, std::string& strToken, std::string& strHuman)
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." },
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." },
{ 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." },
{ 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." },
{ 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." },
{ 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." },
{ 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." },
};
{ tesSUCCESS, "tesSUCCESS", "The transaction was applied." },
};
int iIndex = NUMBER(transResultInfoA);
int iIndex = NUMBER (transResultInfoA);
while (iIndex-- && transResultInfoA[iIndex].terCode != terCode)
;
while (iIndex-- && transResultInfoA[iIndex].terCode != terCode)
;
if (iIndex >= 0)
{
strToken = transResultInfoA[iIndex].cpToken;
strHuman = transResultInfoA[iIndex].cpHuman;
}
if (iIndex >= 0)
{
strToken = transResultInfoA[iIndex].cpToken;
strHuman = transResultInfoA[iIndex].cpHuman;
}
return iIndex >= 0;
return iIndex >= 0;
}
std::string transToken(TER terCode)
std::string transToken (TER terCode)
{
std::string strToken;
std::string strHuman;
std::string strToken;
std::string strHuman;
return transResultInfo(terCode, strToken, strHuman) ? strToken : "-";
return transResultInfo (terCode, strToken, strHuman) ? strToken : "-";
}
std::string transHuman(TER terCode)
std::string transHuman (TER terCode)
{
std::string strToken;
std::string strHuman;
std::string strToken;
std::string strHuman;
return transResultInfo(terCode, strToken, strHuman) ? strHuman : "-";
return transResultInfo (terCode, strToken, strHuman) ? strHuman : "-";
}
// vim:ts=4

View File

@@ -7,149 +7,149 @@
//
// VFALCO TODO consider renaming TER to TxErr or TxResult for clarity.
//
enum TER // aka TransactionEngineResult
enum TER // aka TransactionEngineResult
{
// Note: Range is stable. Exact numbers are currently unstable. Use tokens.
// 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, // VFALCO TODO should read "telBAD_DOMAIN = -398," etc...
telBAD_PATH_COUNT,
telBAD_PUBLIC_KEY,
telFAILED_PROCESSING,
telINSUF_FEE_P,
telNO_DST_PARTIAL,
// -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, // VFALCO TODO should read "telBAD_DOMAIN = -398," etc...
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,
// -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,
// -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
// -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,
// 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.
// 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.
};
// VFALCO TODO change these to normal functions.
#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)
#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)
// VFALCO TODO group these into a shell class along with the defines above.
extern bool transResultInfo (TER terCode, std::string& strToken, std::string& strHuman);

View File

@@ -4,111 +4,117 @@ std::map<int, TransactionFormat*> TransactionFormat::byType;
std::map<std::string, TransactionFormat*> TransactionFormat::byName;
// VFALCO TODO surely we can think of a better way than to use macros??
#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 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()
void TFInit ()
{
TransactionFormat* tf;
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 (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 (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 (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 (OfferCancel, ttOFFER_CANCEL)
<< SOElement (sfOfferSequence, SOE_REQUIRED)
;
DECLARE_TF(SetRegularKey, ttREGULAR_KEY_SET)
<< SOElement(sfRegularKey, 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 (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 (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 (RemoveContract, ttCONTRACT_REMOVE)
<< SOElement (sfTarget, SOE_REQUIRED)
;
DECLARE_TF(EnableFeature, ttFEATURE)
<< SOElement(sfFeature, 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)
;
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)
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;
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)
TransactionFormat* TransactionFormat::getTxnFormat (int t)
{
std::map<int, TransactionFormat*>::iterator it = byType.find((t));
if (it == byType.end())
return NULL;
return it->second;
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)
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;
std::map<std::string, TransactionFormat*>::iterator it = byName.find ((t));
if (it == byName.end ())
return NULL;
return it->second;
}
// vim:ts=4
// vim:ts=4

View File

@@ -3,86 +3,86 @@
enum TransactionType
{
ttINVALID = -1,
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
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,
ttTRUST_SET = 20,
ttFEATURE = 100,
ttFEE = 101,
ttFEATURE = 100,
ttFEE = 101,
};
class TransactionFormat
{
public:
std::string t_name;
TransactionType t_type;
SOTemplate elements;
std::string t_name;
TransactionType t_type;
SOTemplate elements;
static std::map<int, TransactionFormat*> byType;
static std::map<std::string, TransactionFormat*> byName;
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)
TransactionFormat (const char* name, TransactionType type) : t_name (name), t_type (type)
{
byName[name] = this;
byType[type] = this;
byName[name] = this;
byType[type] = this;
}
TransactionFormat& operator<<(const SOElement& el)
TransactionFormat& operator<< (const SOElement& el)
{
elements.push_back(el);
return *this;
elements.push_back (el);
return *this;
}
static TransactionFormat* getTxnFormat(TransactionType t);
static TransactionFormat* getTxnFormat(const std::string& t);
static TransactionFormat* getTxnFormat(int t);
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;
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);
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);
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);
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);
const uint32 tfSetfAuth = 0x00010000;
const uint32 tfTrustSetMask = ~ (tfSetfAuth);
#endif
// vim:ts=4