Merge branch 'master' of github.com:jedmccaleb/NewCoin into works

This commit is contained in:
Arthur Britto
2012-10-01 12:18:03 -07:00
28 changed files with 1321 additions and 1063 deletions

View File

@@ -299,7 +299,7 @@ void STAmount::add(Serializer& s) const
}
}
STAmount::STAmount(const char* name, int64 value) : SerializedType(name), mOffset(0), mIsNative(true)
STAmount::STAmount(SField::ref name, int64 value) : SerializedType(name), mOffset(0), mIsNative(true)
{
if (value >= 0)
{
@@ -325,13 +325,14 @@ void STAmount::setValue(const STAmount &a)
uint64 STAmount::toUInt64() const
{ // makes them sort easily
if (mValue == 0) return 0x4000000000000000ull;
if (mValue == 0)
return 0x4000000000000000ull;
if (mIsNegative)
return mValue | (static_cast<uint64>(mOffset + 97) << (64 - 10));
return mValue | (static_cast<uint64>(mOffset + 256 + 97) << (64 - 10));
}
STAmount* STAmount::construct(SerializerIterator& sit, const char *name)
STAmount* STAmount::construct(SerializerIterator& sit, SField::ref name)
{
uint64 value = sit.get64();
@@ -351,8 +352,6 @@ STAmount* STAmount::construct(SerializerIterator& sit, const char *name)
int offset = static_cast<int>(value >> (64 - 10)); // 10 bits for the offset, sign and "not native" flag
value &= ~(1023ull << (64-10));
STAmount* sapResult;
if (value)
{
bool isNegative = (offset & 256) == 0;
@@ -360,17 +359,12 @@ STAmount* STAmount::construct(SerializerIterator& sit, const char *name)
if ((value < cMinValue) || (value > cMaxValue) || (offset < cMinOffset) || (offset > cMaxOffset))
throw std::runtime_error("invalid currency value");
sapResult = new STAmount(name, uCurrencyID, uIssuerID, value, offset, isNegative);
}
else
{
if (offset != 512)
throw std::runtime_error("invalid currency value");
sapResult = new STAmount(name, uCurrencyID, uIssuerID);
return new STAmount(name, uCurrencyID, uIssuerID, value, offset, isNegative);
}
return sapResult;
if (offset != 512)
throw std::runtime_error("invalid currency value");
return new STAmount(name, uCurrencyID, uIssuerID);
}
int64 STAmount::getSNValue() const
@@ -520,7 +514,7 @@ STAmount& STAmount::operator-=(const STAmount& a)
STAmount STAmount::operator-(void) const
{
if (mValue == 0) return *this;
return STAmount(name, mCurrency, mIssuer, mValue, mOffset, mIsNative, !mIsNegative);
return STAmount(getFName(), mCurrency, mIssuer, mValue, mOffset, mIsNative, !mIsNegative);
}
STAmount& STAmount::operator=(uint64 v)
@@ -573,12 +567,12 @@ bool STAmount::operator>=(uint64 v) const
STAmount STAmount::operator+(uint64 v) const
{
return STAmount(name, getSNValue() + static_cast<int64>(v));
return STAmount(getFName(), getSNValue() + static_cast<int64>(v));
}
STAmount STAmount::operator-(uint64 v) const
{
return STAmount(name, getSNValue() - static_cast<int64>(v));
return STAmount(getFName(), getSNValue() - static_cast<int64>(v));
}
STAmount::operator double() const
@@ -596,7 +590,7 @@ STAmount operator+(const STAmount& v1, const STAmount& v2)
v1.throwComparable(v2);
if (v1.mIsNative)
return STAmount(v1.name, v1.getSNValue() + v2.getSNValue());
return STAmount(v1.getFName(), v1.getSNValue() + v2.getSNValue());
int ov1 = v1.mOffset, ov2 = v2.mOffset;
@@ -618,9 +612,9 @@ STAmount operator+(const STAmount& v1, const STAmount& v2)
int64 fv = vv1 + vv2;
if (fv >= 0)
return STAmount(v1.name, v1.mCurrency, v1.mIssuer, fv, ov1, false);
return STAmount(v1.getFName(), v1.mCurrency, v1.mIssuer, fv, ov1, false);
else
return STAmount(v1.name, v1.mCurrency, v1.mIssuer, -fv, ov1, true);
return STAmount(v1.getFName(), v1.mCurrency, v1.mIssuer, -fv, ov1, true);
}
STAmount operator-(const STAmount& v1, const STAmount& v2)
@@ -629,7 +623,7 @@ STAmount operator-(const STAmount& v1, const STAmount& v2)
v1.throwComparable(v2);
if (v2.mIsNative)
return STAmount(v1.name, v1.getSNValue() - v2.getSNValue());
return STAmount(v1.fName, v1.getSNValue() - v2.getSNValue());
int ov1 = v1.mOffset, ov2 = v2.mOffset;
int64 vv1 = static_cast<int64>(v1.mValue), vv2 = static_cast<int64>(v2.mValue);
@@ -650,9 +644,9 @@ STAmount operator-(const STAmount& v1, const STAmount& v2)
int64 fv = vv1 - vv2;
if (fv >= 0)
return STAmount(v1.name, v1.mCurrency, v1.mIssuer, fv, ov1, false);
return STAmount(v1.getFName(), v1.mCurrency, v1.mIssuer, fv, ov1, false);
else
return STAmount(v1.name, v1.mCurrency, v1.mIssuer, -fv, ov1, true);
return STAmount(v1.getFName(), v1.mCurrency, v1.mIssuer, -fv, ov1, true);
}
STAmount STAmount::divide(const STAmount& num, const STAmount& den, const uint160& uCurrencyID, const uint160& uIssuerID)
@@ -704,7 +698,7 @@ STAmount STAmount::multiply(const STAmount& v1, const STAmount& v2, const uint16
return STAmount(uCurrencyID, uIssuerID);
if (v1.mIsNative && v2.mIsNative) // FIXME: overflow
return STAmount(v1.name, v1.getSNValue() * v2.getSNValue());
return STAmount(v1.getFName(), v1.getSNValue() * v2.getSNValue());
uint64 value1 = v1.mValue, value2 = v2.mValue;
int offset1 = v1.mOffset, offset2 = v2.mOffset;
@@ -883,19 +877,15 @@ uint64 STAmount::convertToDisplayAmount(const STAmount& internalAmount, uint64 t
return muldiv(internalAmount.getNValue(), totalInit, totalNow);
}
STAmount STAmount::convertToInternalAmount(uint64 displayAmount, uint64 totalNow, uint64 totalInit,
const char *name)
STAmount STAmount::convertToInternalAmount(uint64 displayAmount, uint64 totalNow, uint64 totalInit, SField::ref name)
{ // Convert a display/request currency amount to an internal amount
return STAmount(name, muldiv(displayAmount, totalNow, totalInit));
}
STAmount STAmount::deserialize(SerializerIterator& it)
{
STAmount *s = construct(it);
std::auto_ptr<STAmount> s(dynamic_cast<STAmount*>(construct(it, sfGeneric)));
STAmount ret(*s);
delete s;
return ret;
}

View File

@@ -1,13 +1,97 @@
#include "FieldNames.h"
#define FIELD(name, type, index) { sf##name, #name, STI_##type, index },
#include <map>
#include <boost/thread/mutex.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/foreach.hpp>
// These must stay at the top of this file
std::map<int, SField::ptr> SField::codeToField;
boost::mutex SField::mapMutex;
SField sfInvalid(-1), sfGeneric(0);
SField sfLedgerEntry(FIELD_CODE(STI_LEDGERENTRY, 1), STI_LEDGERENTRY, 1, "LedgerEntry");
SField sfTransaction(FIELD_CODE(STI_TRANSACTION, 1), STI_TRANSACTION, 1, "Transaction");
SField sfValidation(FIELD_CODE(STI_VALIDATION, 1), STI_VALIDATION, 1, "Validation");
#define FIELD(name, type, index) SField sf##name(FIELD_CODE(STI_##type, index), STI_##type, index, #name);
#define TYPE(name, type, index)
FieldName FieldNames[]=
{
#include "SerializeProto.h"
};
#undef FIELD
#undef TYPE
SField::ref SField::getField(int code)
{
int type = code >> 16;
int field = code % 0xffff;
if ((type <= 0) || (type >= 256) || (field <= 0) || (field >= 256))
return sfInvalid;
boost::mutex::scoped_lock sl(mapMutex);
std::map<int, SField::ptr>::iterator it = codeToField.find(code);
if (it != codeToField.end())
return *(it->second);
switch (type)
{ // types we are willing to dynamically extend
#define FIELD(name, type, index)
#define TYPE(name, type, index) case STI_##type:
#include "SerializeProto.h"
#undef FIELD
#undef TYPE
break;
default:
return sfInvalid;
}
return *(new SField(code, static_cast<SerializedTypeID>(type), field, NULL));
}
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;
}
SField::ref SField::getField(int type, int value)
{
return getField(FIELD_CODE(type, value));
}
std::string SField::getName() const
{
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::pair<const int, SField::ptr> int_sfref_pair;
BOOST_FOREACH(const int_sfref_pair& fieldPair, codeToField)
{
if (fieldPair.second->fieldName == fieldName)
return *(fieldPair.second);
}
return sfInvalid;
}

View File

@@ -1,16 +1,85 @@
#ifndef __FIELDNAMES__
#define __FIELDNAMES__
#include "SerializedTypes.h"
#include "SerializedObject.h"
#include <string>
struct FieldName
#include <boost/thread/mutex.hpp>
#define FIELD_CODE(type, index) ((static_cast<int>(type) << 16) | index)
enum SerializedTypeID
{
SOE_Field field;
const char *fieldName;
SerializedTypeID fieldType;
int fieldValue;
int fieldID;
// special types
STI_UNKNOWN = -2,
STI_DONE = -1,
STI_NOTPRESENT = 0,
#define TYPE(name, field, value) STI_##field = value,
#define FIELD(name, field, value)
#include "SerializeProto.h"
#undef TYPE
#undef FIELD
// high level types
STI_TRANSACTION = 10001,
STI_LEDGERENTRY = 10002,
STI_VALIDATION = 10003,
};
enum SOE_Flags
{
SOE_END = -1, // marks end of object
SOE_REQUIRED = 0, // required
SOE_OPTIONAL = 1, // optional
};
class SField
{
public:
typedef const SField& ref;
typedef SField const * ptr;
protected:
static std::map<int, ptr> codeToField;
static boost::mutex mapMutex;
public:
const int fieldCode; // (type<<16)|index
const SerializedTypeID fieldType; // STI_*
const int fieldValue; // Code number for protocol
std::string fieldName;
SField(int fc, SerializedTypeID tid, int fv, const char* fn) :
fieldCode(fc), fieldType(tid), fieldValue(fv), fieldName(fn)
{ codeToField[fc] = this; }
SField(int fc) : fieldCode(fc), fieldType(STI_UNKNOWN), fieldValue(0) { ; }
static SField::ref getField(int fieldCode);
static SField::ref getField(int fieldType, int fieldValue);
static SField::ref getField(const std::string& fieldName);
static SField::ref getField(SerializedTypeID type, int value) { return getField(FIELD_CODE(type, value)); }
std::string getName() const;
bool hasName() const { return !fieldName.empty(); }
bool isGeneric() const { return fieldCode == 0; }
bool isInvalid() const { return fieldCode == -1; }
bool isKnown() const { return fieldType != STI_UNKNOWN; }
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);
};
extern SField sfInvalid, sfGeneric, sfLedgerEntry, sfTransaction, sfValidation;
#define FIELD(name, type, index) extern SField sf##name;
#define TYPE(name, type, index)
#include "SerializeProto.h"
#undef FIELD
#undef TYPE
#endif

View File

@@ -977,21 +977,23 @@ void LedgerConsensus::applyTransaction(TransactionEngine& engine, const Serializ
{
#endif
TER result = engine.applyTransaction(*txn, parms);
if (result > 0)
if (isTerRetry(result))
{
Log(lsINFO) << " retry";
assert(!ledger->hasTransaction(txn->getTransactionID()));
failedTransactions.push_back(txn);
}
else if (result == 0)
else if (isTepSuccess(result)) // FIXME: Need to do partial success
{
Log(lsTRACE) << " success";
assert(ledger->hasTransaction(txn->getTransactionID()));
}
else
else if (isTemMalformed(result) || isTefFailure(result))
{
Log(lsINFO) << " hard fail";
}
else
assert(false);
#ifndef TRUST_NETWORK
}
catch (...)

View File

@@ -876,7 +876,7 @@ uint32 LedgerEntrySet::rippleTransferRate(const uint160& uIssuerID)
}
// XXX Might not need this, might store in nodes on calc reverse.
uint32 LedgerEntrySet::rippleQualityIn(const uint160& uToAccountID, const uint160& uFromAccountID, const uint160& uCurrencyID, const SOE_Field sfLow, const SOE_Field sfHigh)
uint32 LedgerEntrySet::rippleQualityIn(const uint160& uToAccountID, const uint160& uFromAccountID, const uint160& uCurrencyID, SField::ref sfLow, SField::ref sfHigh)
{
uint32 uQuality = QUALITY_ONE;
SLE::pointer sleRippleState;
@@ -891,7 +891,7 @@ uint32 LedgerEntrySet::rippleQualityIn(const uint160& uToAccountID, const uint16
if (sleRippleState)
{
SOE_Field sfField = uToAccountID < uFromAccountID ? sfLow: sfHigh;
SField::ref sfField = uToAccountID < uFromAccountID ? sfLow: sfHigh;
uQuality = sleRippleState->getIFieldPresent(sfField)
? sleRippleState->getIFieldU32(sfField)

View File

@@ -104,7 +104,8 @@ public:
uint32 rippleTransferRate(const uint160& uIssuerID);
STAmount rippleOwed(const uint160& uToAccountID, const uint160& uFromAccountID, const uint160& uCurrencyID);
STAmount rippleLimit(const uint160& uToAccountID, const uint160& uFromAccountID, const uint160& uCurrencyID);
uint32 rippleQualityIn(const uint160& uToAccountID, const uint160& uFromAccountID, const uint160& uCurrencyID, const SOE_Field sfLow=sfLowQualityIn, const SOE_Field sfHigh=sfHighQualityIn);
uint32 rippleQualityIn(const uint160& uToAccountID, const uint160& uFromAccountID, const uint160& uCurrencyID,
SField::ref sfLow = sfLowQualityIn, SField::ref sfHigh = sfHighQualityIn);
uint32 rippleQualityOut(const uint160& uToAccountID, const uint160& uFromAccountID, const uint160& uCurrencyID)
{ return rippleQualityIn(uToAccountID, uFromAccountID, uCurrencyID, sfLowQualityOut, sfHighQualityOut); }

View File

@@ -1,98 +1,103 @@
#include "LedgerFormats.h"
#define S_FIELD(x) sf##x, #x
#define LEF_BASE \
{ sfLedgerIndex, SOE_OPTIONAL }, \
{ sfLedgerEntryType, SOE_REQUIRED }, \
{ sfFlags, SOE_REQUIRED },
LedgerEntryFormat LedgerFormats[]=
{
{ "AccountRoot", ltACCOUNT_ROOT, {
{ S_FIELD(Flags), STI_UINT32, SOE_FLAGS, 0 },
{ S_FIELD(Account), STI_ACCOUNT, SOE_REQUIRED, 0 },
{ S_FIELD(Sequence), STI_UINT32, SOE_REQUIRED, 0 },
{ S_FIELD(Balance), STI_AMOUNT, SOE_REQUIRED, 0 },
{ S_FIELD(LastTxnID), STI_HASH256, SOE_REQUIRED, 0 },
{ S_FIELD(LastTxnSeq), STI_UINT32, SOE_REQUIRED, 0 },
{ S_FIELD(AuthorizedKey), STI_ACCOUNT, SOE_IFFLAG, 1 },
{ S_FIELD(EmailHash), STI_HASH128, SOE_IFFLAG, 2 },
{ S_FIELD(WalletLocator), STI_HASH256, SOE_IFFLAG, 4 },
{ S_FIELD(MessageKey), STI_VL, SOE_IFFLAG, 8 },
{ S_FIELD(TransferRate), STI_UINT32, SOE_IFFLAG, 16 },
{ S_FIELD(Domain), STI_VL, SOE_IFFLAG, 32 },
{ S_FIELD(PublishHash), STI_HASH256, SOE_IFFLAG, 64 },
{ S_FIELD(PublishSize), STI_UINT32, SOE_IFFLAG, 128 },
{ sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 } }
{ "AccountRoot", ltACCOUNT_ROOT, { LEF_BASE
{ sfAccount, SOE_REQUIRED },
{ sfSequence, SOE_REQUIRED },
{ sfBalance, SOE_REQUIRED },
{ sfLastTxnID, SOE_REQUIRED },
{ sfLastTxnSeq, SOE_REQUIRED },
{ sfAuthorizedKey, SOE_OPTIONAL },
{ sfEmailHash, SOE_OPTIONAL },
{ sfWalletLocator, SOE_OPTIONAL },
{ sfMessageKey, SOE_OPTIONAL },
{ sfTransferRate, SOE_OPTIONAL },
{ sfDomain, SOE_OPTIONAL },
{ sfPublishHash, SOE_OPTIONAL },
{ sfPublishSize, SOE_OPTIONAL },
{ sfInvalid, SOE_END } }
},
{ "Contract", ltCONTRACT, {
{ S_FIELD(Flags), STI_UINT32, SOE_FLAGS, 0 },
{ S_FIELD(Account), STI_ACCOUNT, SOE_REQUIRED, 0 },
{ S_FIELD(Balance), STI_AMOUNT, SOE_REQUIRED, 0 },
{ S_FIELD(LastTxnID), STI_HASH256, SOE_REQUIRED, 0 },
{ S_FIELD(LastTxnSeq), STI_UINT32, SOE_REQUIRED, 0 },
{ S_FIELD(Issuer), STI_ACCOUNT, SOE_REQUIRED, 0 },
{ S_FIELD(Owner), STI_ACCOUNT, SOE_REQUIRED, 0 },
{ S_FIELD(Expiration), STI_UINT32, SOE_REQUIRED, 0 },
{ S_FIELD(BondAmount), STI_UINT32, SOE_REQUIRED, 0 },
{ S_FIELD(CreateCode), STI_VL, SOE_REQUIRED, 0 },
{ S_FIELD(FundCode), STI_VL, SOE_REQUIRED, 0 },
{ S_FIELD(RemoveCode), STI_VL, SOE_REQUIRED, 0 },
{ S_FIELD(ExpireCode), STI_VL, SOE_REQUIRED, 0 },
{ sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 } }
{ "Contract", ltCONTRACT, { LEF_BASE
{ sfLedgerEntryType,SOE_REQUIRED },
{ sfFlags, SOE_REQUIRED },
{ sfAccount, SOE_REQUIRED },
{ sfBalance, SOE_REQUIRED },
{ sfLastTxnID, SOE_REQUIRED },
{ sfLastTxnSeq, SOE_REQUIRED },
{ sfIssuer, SOE_REQUIRED },
{ sfOwner, SOE_REQUIRED },
{ sfExpiration, SOE_REQUIRED },
{ sfBondAmount, SOE_REQUIRED },
{ sfCreateCode, SOE_REQUIRED },
{ sfFundCode, SOE_REQUIRED },
{ sfRemoveCode, SOE_REQUIRED },
{ sfExpireCode, SOE_REQUIRED },
{ sfInvalid, SOE_END } }
},
{ "DirectoryNode", ltDIR_NODE, {
{ S_FIELD(Flags), STI_UINT32, SOE_FLAGS, 0 },
{ S_FIELD(Indexes), STI_VECTOR256, SOE_REQUIRED, 0 },
{ S_FIELD(IndexNext), STI_UINT64, SOE_IFFLAG, 1 },
{ S_FIELD(IndexPrevious), STI_UINT64, SOE_IFFLAG, 2 },
{ sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 } }
{ "DirectoryNode", ltDIR_NODE, { LEF_BASE
{ sfLedgerEntryType,SOE_REQUIRED },
{ sfFlags, SOE_REQUIRED },
{ sfIndexes, SOE_REQUIRED },
{ sfIndexNext, SOE_OPTIONAL },
{ sfIndexPrevious, SOE_OPTIONAL },
{ sfInvalid, SOE_END } }
},
{ "GeneratorMap", ltGENERATOR_MAP, {
{ S_FIELD(Flags), STI_UINT32, SOE_FLAGS, 0 },
{ S_FIELD(Generator), STI_VL, SOE_REQUIRED, 0 },
{ sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 } }
{ "GeneratorMap", ltGENERATOR_MAP, { LEF_BASE
{ sfGenerator, SOE_REQUIRED },
{ sfInvalid, SOE_END } }
},
{ "Nickname", ltNICKNAME, {
{ S_FIELD(Flags), STI_UINT32, SOE_FLAGS, 0 },
{ S_FIELD(Account), STI_ACCOUNT, SOE_REQUIRED, 0 },
{ S_FIELD(MinimumOffer), STI_AMOUNT, SOE_IFFLAG, 1 },
{ sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 } }
{ "Nickname", ltNICKNAME, { LEF_BASE
{ sfAccount, SOE_REQUIRED },
{ sfMinimumOffer, SOE_OPTIONAL },
{ sfInvalid, SOE_END } }
},
{ "Offer", ltOFFER, {
{ S_FIELD(Flags), STI_UINT32, SOE_FLAGS, 0 },
{ S_FIELD(Account), STI_ACCOUNT, SOE_REQUIRED, 0 },
{ S_FIELD(Sequence), STI_UINT32, SOE_REQUIRED, 0 },
{ S_FIELD(TakerPays), STI_AMOUNT, SOE_REQUIRED, 0 },
{ S_FIELD(TakerGets), STI_AMOUNT, SOE_REQUIRED, 0 },
{ S_FIELD(BookDirectory), STI_HASH256, SOE_REQUIRED, 0 },
{ S_FIELD(BookNode), STI_UINT64, SOE_REQUIRED, 0 },
{ S_FIELD(OwnerNode), STI_UINT64, SOE_REQUIRED, 0 },
{ S_FIELD(LastTxnID), STI_HASH256, SOE_REQUIRED, 0 },
{ S_FIELD(LastTxnSeq), STI_UINT32, SOE_REQUIRED, 0 },
{ S_FIELD(Expiration), STI_UINT32, SOE_IFFLAG, 1 },
{ sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 } }
{ "Offer", ltOFFER, { LEF_BASE
{ sfAccount, SOE_REQUIRED },
{ sfSequence, SOE_REQUIRED },
{ sfTakerPays, SOE_REQUIRED },
{ sfTakerGets, SOE_REQUIRED },
{ sfBookDirectory, SOE_REQUIRED },
{ sfBookNode, SOE_REQUIRED },
{ sfOwnerNode, SOE_REQUIRED },
{ sfLastTxnID, SOE_REQUIRED },
{ sfLastTxnSeq, SOE_REQUIRED },
{ sfExpiration, SOE_OPTIONAL },
{ sfInvalid, SOE_END } }
},
{ "RippleState", ltRIPPLE_STATE, {
{ S_FIELD(Flags), STI_UINT32, SOE_FLAGS, 0 },
{ S_FIELD(Balance), STI_AMOUNT, SOE_REQUIRED, 0 },
{ S_FIELD(LowLimit), STI_AMOUNT, SOE_REQUIRED, 0 },
{ S_FIELD(HighLimit), STI_AMOUNT, SOE_REQUIRED, 0 },
{ S_FIELD(LastTxnID), STI_HASH256, SOE_REQUIRED, 0 },
{ S_FIELD(LastTxnSeq), STI_UINT32, SOE_REQUIRED, 0 },
{ S_FIELD(LowQualityIn), STI_UINT32, SOE_IFFLAG, 1 },
{ S_FIELD(LowQualityOut), STI_UINT32, SOE_IFFLAG, 2 },
{ S_FIELD(HighQualityIn), STI_UINT32, SOE_IFFLAG, 4 },
{ S_FIELD(HighQualityOut), STI_UINT32, SOE_IFFLAG, 8 },
{ sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 } }
{ "RippleState", ltRIPPLE_STATE, { LEF_BASE
{ sfBalance, SOE_REQUIRED },
{ sfLowLimit, SOE_REQUIRED },
{ sfHighLimit, SOE_REQUIRED },
{ sfLastTxnID, SOE_REQUIRED },
{ sfLastTxnSeq, SOE_REQUIRED },
{ sfLowQualityIn, SOE_OPTIONAL },
{ sfLowQualityOut, SOE_OPTIONAL },
{ sfHighQualityIn, SOE_OPTIONAL },
{ sfHighQualityOut, SOE_OPTIONAL },
{ sfInvalid, SOE_END } }
},
{ NULL, ltINVALID }
};
LedgerEntryFormat* getLgrFormat(LedgerEntryType t)
{
return getLgrFormat(static_cast<int>(t));
}
LedgerEntryFormat* getLgrFormat(int t)
{
LedgerEntryFormat* f = LedgerFormats;
while (f->t_name != NULL)
{
if (f->t_type == t) return f;
if (f->t_type == t)
return f;
++f;
}
return NULL;

View File

@@ -41,12 +41,13 @@ enum LedgerSpecificFlags
struct LedgerEntryFormat
{
const char *t_name;
LedgerEntryType t_type;
SOElement elements[20];
const char * t_name;
LedgerEntryType t_type;
SOElement elements[24];
};
extern LedgerEntryFormat LedgerFormats[];
extern LedgerEntryFormat* getLgrFormat(LedgerEntryType t);
extern LedgerEntryFormat* getLgrFormat(int t);
#endif
// vim:ts=4

View File

@@ -83,17 +83,18 @@ uint32 NetworkOPs::getCurrentLedgerID()
Transaction::pointer NetworkOPs::submitTransaction(const Transaction::pointer& tpTrans)
{
Serializer s;
tpTrans->getSTransaction()->add(s);
std::vector<unsigned char> vucTransaction = s.getData();
SerializerIterator sit(s);
Transaction::pointer tpTransNew = Transaction::sharedTransaction(s.getData(), true);
assert(tpTransNew);
assert(tpTransNew->getSTransaction()->isEquivalent(*tpTrans->getSTransaction()));
if(!tpTransNew->getSTransaction()->isEquivalent(*tpTrans->getSTransaction()))
{
Log(lsFATAL) << "Transaction reconstruction failure";
Log(lsFATAL) << tpTransNew->getSTransaction()->getJson(0);
Log(lsFATAL) << tpTrans->getSTransaction()->getJson(0);
assert(false);
}
(void) NetworkOPs::processTransaction(tpTransNew);

View File

@@ -1777,17 +1777,17 @@ Json::Value RPCServer::doSend(const Json::Value& params)
// Destination exists, ordinary send.
STPathSet spsPaths;
/*
uint160 srcCurrencyID;
bool ret_b;
ret_b = false;
STAmount::currencyFromString(srcCurrencyID, sSrcCurrency);
bool ret_b;
ret_b = false;
Pathfinder pf(naSrcAccountID, naDstAccountID, srcCurrencyID, saDstAmount);
ret_b = pf.findPaths(5, 1, spsPaths);
// TODO: Nope; the above can't be right
*/
if (!saSrcAmountMax.isNative() || !saDstAmount.isNative())
{
STAmount::currencyFromString(srcCurrencyID, sSrcCurrency);
Pathfinder pf(naSrcAccountID, naDstAccountID, srcCurrencyID, saDstAmount);
ret_b = pf.findPaths(5, 1, spsPaths);
}
trans = Transaction::sharedPayment(
naAccountPublic, naAccountPrivate,
naSrcAccountID,

View File

@@ -2,11 +2,11 @@
// appropriate #define statements.
// types (common)
TYPE("Int32", UINT32, 1)
TYPE("Int64", UINT64, 2)
TYPE("Hash128", HASH128, 3)
TYPE("Hash256", HASH256, 4)
// 5 is reserved
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)
@@ -16,28 +16,32 @@
// types (uncommon)
TYPE("Int8", UINT8, 16)
TYPE("Int16", UINT16, 17)
TYPE("Hash160", HASH160, 18)
TYPE("PathSet", PATHSET, 19)
TYPE("Vector256", VECTOR256, 20)
TYPE("Hash160", HASH160, 17)
TYPE("PathSet", PATHSET, 18)
TYPE("Vector256", VECTOR256, 19)
// 8-bit integers
FIELD(CloseResolution, UINT8, 1)
// 16-bit integers
FIELD(LedgerEntryType, UINT16, 1)
FIELD(TransactionType, UINT16, 2)
// 32-bit integers (common)
FIELD(Flags, UINT32, 1)
FIELD(SourceTag, UINT32, 2)
FIELD(Sequence, UINT32, 3)
FIELD(LastTxnSeq, UINT32, 4)
FIELD(LedgerSequence, UINT32, 5)
FIELD(CloseTime, UINT32, 6)
FIELD(ParentCloseTime, UINT32, 7)
FIELD(SigningTime, UINT32, 8)
FIELD(Expiration, UINT32, 9)
FIELD(TransferRate, UINT32, 10)
FIELD(PublishSize, UINT32, 11)
FIELD(ObjectType, UINT32, 1)
FIELD(Flags, UINT32, 2)
FIELD(SourceTag, UINT32, 3)
FIELD(Sequence, UINT32, 4)
FIELD(LastTxnSeq, 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(PublishSize, UINT32, 12)
// 32-bit integers (uncommon)
FIELD(HighQualityIn, UINT32, 16)
@@ -59,7 +63,7 @@
FIELD(BaseFee, UINT64, 5)
// 128-bit
FIELD(EmailHash, HASH128, 2)
FIELD(EmailHash, HASH128, 1)
// 256-bit (common)
FIELD(LedgerHash, HASH256, 1)
@@ -67,8 +71,9 @@
FIELD(TransactionHash, HASH256, 3)
FIELD(AccountHash, HASH256, 4)
FIELD(LastTxnID, HASH256, 5)
FIELD(WalletLocator, HASH256, 6)
FIELD(PublishHash, HASH256, 7)
FIELD(LedgerIndex, HASH256, 6)
FIELD(WalletLocator, HASH256, 7)
FIELD(PublishHash, HASH256, 8)
// 256-bit (uncommon)
FIELD(BookDirectory, HASH256, 16)
@@ -83,6 +88,7 @@
FIELD(TakerGets, AMOUNT, 5)
FIELD(LowLimit, AMOUNT, 6)
FIELD(HighLimit, AMOUNT, 7)
FIELD(Fee, AMOUNT, 8)
FIELD(SendMax, AMOUNT, 9)
// current amount (uncommon)
@@ -92,14 +98,15 @@
// variable length
FIELD(PublicKey, VL, 1)
FIELD(MessageKey, VL, 2)
FIELD(SigningKey, VL, 3)
FIELD(Signature, VL, 4)
FIELD(SigningPubKey, VL, 3)
FIELD(TxnSignature, VL, 4)
FIELD(Generator, VL, 5)
FIELD(Domain, VL, 6)
FIELD(FundCode, VL, 7)
FIELD(RemoveCode, VL, 8)
FIELD(ExpireCode, VL, 9)
FIELD(CreateCode, VL, 10)
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)
@@ -119,9 +126,9 @@
// inner object
// OBJECT/1 is reserved for end of object
FIELD(MiddleTransaction, OBJECT, 2)
FIELD(InnerTransaction, OBJECT, 3)
// array of objects
// ARRAY/1 is reserved for end of array
FIELD(SigningAccounts, ARRAY, 2)
FIELD(TxnSignatures, ARRAY, 3)
FIELD(Signatures, ARRAY, 4)

View File

@@ -6,35 +6,43 @@
#include "Log.h"
SerializedLedgerEntry::SerializedLedgerEntry(SerializerIterator& sit, const uint256& index)
: SerializedType("LedgerEntry"), mIndex(index)
: STObject(sfLedgerEntry), mIndex(index)
{
uint16 type = sit.get16();
set(sit);
uint16 type = getValueFieldU16(sfLedgerEntryType);
mFormat = getLgrFormat(static_cast<LedgerEntryType>(type));
if (mFormat == NULL) throw std::runtime_error("invalid ledger entry type");
if (mFormat == NULL)
throw std::runtime_error("invalid ledger entry type");
mType = mFormat->t_type;
mVersion.setValue(type);
mObject = STObject(mFormat->elements, sit);
if (!setType(mFormat->elements))
throw std::runtime_error("ledger entry not valid for type");
}
SerializedLedgerEntry::SerializedLedgerEntry(const Serializer& s, const uint256& index)
: SerializedType("LedgerEntry"), mIndex(index)
: STObject(sfLedgerEntry), mIndex(index)
{
SerializerIterator sit(s);
set(sit);
uint16 type = sit.get16();
uint16 type = getValueFieldU16(sfLedgerEntryType);
mFormat = getLgrFormat(static_cast<LedgerEntryType>(type));
if (mFormat == NULL) throw std::runtime_error("invalid ledger entry type");
if (mFormat == NULL)
throw std::runtime_error("invalid ledger entry type");
mType = mFormat->t_type;
mVersion.setValue(type);
mObject.set(mFormat->elements, sit);
if (!setType(mFormat->elements))
{
Log(lsWARNING) << "Ledger entry not valid for type " << mFormat->t_name;
Log(lsWARNING) << getJson(0);
throw std::runtime_error("ledger entry not valid for type");
}
}
SerializedLedgerEntry::SerializedLedgerEntry(LedgerEntryType type) : SerializedType("LedgerEntry"), mType(type)
SerializedLedgerEntry::SerializedLedgerEntry(LedgerEntryType type) : STObject(sfLedgerEntry), mType(type)
{
mFormat = getLgrFormat(type);
if (mFormat == NULL) throw std::runtime_error("invalid ledger entry type");
mVersion.setValue(static_cast<uint16>(mFormat->t_type));
mObject.set(mFormat->elements);
set(mFormat->elements);
setValueFieldU16(sfLedgerEntryType, static_cast<uint16>(mFormat->t_type));
}
std::string SerializedLedgerEntry::getFullText() const
@@ -44,76 +52,64 @@ std::string SerializedLedgerEntry::getFullText() const
ret += "\" = { ";
ret += mFormat->t_name;
ret += ", ";
ret += mObject.getFullText();
ret += STObject::getFullText();
ret += "}";
return ret;
}
std::string SerializedLedgerEntry::getText() const
{
return str(boost::format("{ %s, %s, %s }")
return str(boost::format("{ %s, %s }")
% mIndex.GetHex()
% mVersion.getText()
% mObject.getText());
% STObject::getText());
}
Json::Value SerializedLedgerEntry::getJson(int options) const
{
Json::Value ret(mObject.getJson(options));
Json::Value ret(STObject::getJson(options));
ret["type"] = mFormat->t_name;
ret["index"] = mIndex.GetHex();
ret["version"] = std::string(1, mVersion);
return ret;
}
bool SerializedLedgerEntry::isEquivalent(const SerializedType& t) const
{ // locators are not compared
const SerializedLedgerEntry* v = dynamic_cast<const SerializedLedgerEntry*>(&t);
if (!v) return false;
if (mType != v->mType) return false;
if (mObject != v->mObject) return false;
return true;
}
bool SerializedLedgerEntry::isThreadedType()
{
return getIFieldIndex(sfLastTxnID) != -1;
return getFieldIndex(sfLastTxnID) != -1;
}
bool SerializedLedgerEntry::isThreaded()
{
return getIFieldPresent(sfLastTxnID);
return isFieldPresent(sfLastTxnID);
}
uint256 SerializedLedgerEntry::getThreadedTransaction()
{
return getIFieldH256(sfLastTxnID);
return getValueFieldH256(sfLastTxnID);
}
uint32 SerializedLedgerEntry::getThreadedLedger()
{
return getIFieldU32(sfLastTxnSeq);
return getValueFieldU32(sfLastTxnSeq);
}
bool SerializedLedgerEntry::thread(const uint256& txID, uint32 ledgerSeq, uint256& prevTxID, uint32& prevLedgerID)
{
uint256 oldPrevTxID = getIFieldH256(sfLastTxnID);
uint256 oldPrevTxID = getValueFieldH256(sfLastTxnID);
Log(lsTRACE) << "Thread Tx:" << txID << " prev:" << oldPrevTxID;
if (oldPrevTxID == txID)
return false;
prevTxID = oldPrevTxID;
prevLedgerID = getIFieldU32(sfLastTxnSeq);
prevLedgerID = getValueFieldU32(sfLastTxnSeq);
assert(prevTxID != txID);
setIFieldH256(sfLastTxnID, txID);
setIFieldU32(sfLastTxnSeq, ledgerSeq);
setValueFieldH256(sfLastTxnID, txID);
setValueFieldU32(sfLastTxnSeq, ledgerSeq);
return true;
}
bool SerializedLedgerEntry::hasOneOwner()
{
return (mType != ltACCOUNT_ROOT) && (getIFieldIndex(sfAccount) != -1);
return (mType != ltACCOUNT_ROOT) && (getFieldIndex(sfAccount) != -1);
}
bool SerializedLedgerEntry::hasTwoOwners()
@@ -123,7 +119,7 @@ bool SerializedLedgerEntry::hasTwoOwners()
NewcoinAddress SerializedLedgerEntry::getOwner()
{
return getIValueFieldAccount(sfAccount);
return getValueFieldAccount(sfAccount);
}
NewcoinAddress SerializedLedgerEntry::getFirstOwner()
@@ -141,30 +137,24 @@ std::vector<uint256> SerializedLedgerEntry::getOwners()
std::vector<uint256> owners;
uint160 account;
for (int i = 0, fields = getIFieldCount(); i < fields; ++i)
for (int i = 0, fields = getCount(); i < fields; ++i)
{
switch (getIFieldSType(i))
SField::ref fc = getFieldSType(i);
if ((fc == sfAccount) || (fc == sfOwner))
{
case sfAccount:
{
const STAccount* entry = dynamic_cast<const STAccount *>(mObject.peekAtPIndex(i));
if ((entry != NULL) && entry->getValueH160(account))
owners.push_back(Ledger::getAccountRootIndex(account));
}
break;
case sfLowLimit:
case sfHighLimit:
{
const STAmount* entry = dynamic_cast<const STAmount *>(mObject.peekAtPIndex(i));
if ((entry != NULL))
owners.push_back(Ledger::getAccountRootIndex(entry->getIssuer()));
}
break;
default:
nothing();
break;
const STAccount* entry = dynamic_cast<const STAccount *>(peekAtPIndex(i));
if ((entry != NULL) && entry->getValueH160(account))
owners.push_back(Ledger::getAccountRootIndex(account));
}
if ((fc == sfLowLimit) || (fc == sfHighLimit))
{
const STAmount* entry = dynamic_cast<const STAmount *>(peekAtPIndex(i));
if ((entry != NULL))
{
uint160 issuer = entry->getIssuer();
if (issuer.isNonZero())
owners.push_back(Ledger::getAccountRootIndex(issuer));
}
}
}

View File

@@ -5,7 +5,7 @@
#include "LedgerFormats.h"
#include "NewcoinAddress.h"
class SerializedLedgerEntry : public SerializedType
class SerializedLedgerEntry : public STObject
{
public:
typedef boost::shared_ptr<SerializedLedgerEntry> pointer;
@@ -14,8 +14,6 @@ public:
protected:
uint256 mIndex;
LedgerEntryType mType;
STUInt16 mVersion;
STObject mObject;
const LedgerEntryFormat* mFormat;
SerializedLedgerEntry* duplicate() const { return new SerializedLedgerEntry(*this); }
@@ -25,45 +23,18 @@ public:
SerializedLedgerEntry(SerializerIterator& sit, const uint256& index);
SerializedLedgerEntry(LedgerEntryType type);
int getLength() const { return mVersion.getLength() + mObject.getLength(); }
SerializedTypeID getSType() const { return STI_LEDGERENTRY; }
std::string getFullText() const;
std::string getText() const;
Json::Value getJson(int options) const;
void add(Serializer& s) const { mVersion.add(s); mObject.add(s); }
virtual bool isEquivalent(const SerializedType& t) const;
bool setFlag(uint32 uSet) { return mObject.setFlag(uSet); }
bool clearFlag(uint32 uClear) { return mObject.clearFlag(uClear); }
uint32 getFlags() const { return mObject.getFlags(); }
const uint256& getIndex() const { return mIndex; }
void setIndex(const uint256& i) { mIndex = i; }
const uint256& getIndex() const { return mIndex; }
void setIndex(const uint256& i) { mIndex = i; }
LedgerEntryType getType() const { return mType; }
uint16 getVersion() const { return mVersion.getValue(); }
uint16 getVersion() const { return getValueFieldU16(sfLedgerEntryType); }
const LedgerEntryFormat* getFormat() { return mFormat; }
int getIFieldIndex(SOE_Field field) const { return mObject.getFieldIndex(field); }
int getIFieldCount() const { return mObject.getCount(); }
const SerializedType& peekIField(SOE_Field field) const { return mObject.peekAtField(field); }
SerializedType& getIField(SOE_Field field) { return mObject.getField(field); }
SOE_Field getIFieldSType(int index) { return mObject.getFieldSType(index); }
std::string getIFieldString(SOE_Field field) const { return mObject.getFieldString(field); }
unsigned char getIFieldU8(SOE_Field field) const { return mObject.getValueFieldU8(field); }
uint16 getIFieldU16(SOE_Field field) const { return mObject.getValueFieldU16(field); }
uint32 getIFieldU32(SOE_Field field) const { return mObject.getValueFieldU32(field); }
uint64 getIFieldU64(SOE_Field field) const { return mObject.getValueFieldU64(field); }
uint128 getIFieldH128(SOE_Field field) const { return mObject.getValueFieldH128(field); }
uint160 getIFieldH160(SOE_Field field) const { return mObject.getValueFieldH160(field); }
uint256 getIFieldH256(SOE_Field field) const { return mObject.getValueFieldH256(field); }
std::vector<unsigned char> getIFieldVL(SOE_Field field) const { return mObject.getValueFieldVL(field); }
std::vector<TaggedListItem> getIFieldTL(SOE_Field field) const { return mObject.getValueFieldTL(field); }
NewcoinAddress getIValueFieldAccount(SOE_Field field) const { return mObject.getValueFieldAccount(field); }
STAmount getIValueFieldAmount(SOE_Field field) const { return mObject.getValueFieldAmount(field); }
STVector256 getIFieldV256(SOE_Field field) { return mObject.getValueFieldV256(field); }
bool isThreadedType(); // is this a ledger entry that can be threaded
bool isThreaded(); // is this ledger entry actually threaded
bool hasOneOwner(); // This node has one other node that owns it (like nickname)
@@ -76,28 +47,49 @@ public:
bool thread(const uint256& txID, uint32 ledgerSeq, uint256& prevTxID, uint32& prevLedgerID);
std::vector<uint256> getOwners(); // nodes notified if this node is deleted
void setIFieldU8(SOE_Field field, unsigned char v) { return mObject.setValueFieldU8(field, v); }
void setIFieldU16(SOE_Field field, uint16 v) { return mObject.setValueFieldU16(field, v); }
void setIFieldU32(SOE_Field field, uint32 v) { return mObject.setValueFieldU32(field, v); }
void setIFieldU64(SOE_Field field, uint64 v) { return mObject.setValueFieldU64(field, v); }
void setIFieldH128(SOE_Field field, const uint128& v) { return mObject.setValueFieldH128(field, v); }
void setIFieldH160(SOE_Field field, const uint160& v) { return mObject.setValueFieldH160(field, v); }
void setIFieldH256(SOE_Field field, const uint256& v) { return mObject.setValueFieldH256(field, v); }
void setIFieldVL(SOE_Field field, const std::vector<unsigned char>& v)
{ return mObject.setValueFieldVL(field, v); }
void setIFieldTL(SOE_Field field, const std::vector<TaggedListItem>& v)
{ return mObject.setValueFieldTL(field, v); }
void setIFieldAccount(SOE_Field field, const uint160& account)
{ return mObject.setValueFieldAccount(field, account); }
void setIFieldAccount(SOE_Field field, const NewcoinAddress& account)
{ return mObject.setValueFieldAccount(field, account); }
void setIFieldAmount(SOE_Field field, const STAmount& amount)
{ return mObject.setValueFieldAmount(field, amount); }
void setIFieldV256(SOE_Field field, const STVector256& v) { return mObject.setValueFieldV256(field, v); }
// CAUTION: All these functions are now obsolete and will be removed after
// the new serialization code is merged.
int getIFieldIndex(SField::ref field) const { return getFieldIndex(field); }
int getIFieldCount() const { return getCount(); }
const SerializedType& peekIField(SField::ref field) const { return peekAtField(field); }
SerializedType& getIField(SField::ref field) { return getField(field); }
SField::ref getIFieldSType(int index) { return getFieldSType(index); }
std::string getIFieldString(SField::ref field) const { return getFieldString(field); }
unsigned char getIFieldU8(SField::ref field) const { return getValueFieldU8(field); }
uint16 getIFieldU16(SField::ref field) const { return getValueFieldU16(field); }
uint32 getIFieldU32(SField::ref field) const { return getValueFieldU32(field); }
uint64 getIFieldU64(SField::ref field) const { return getValueFieldU64(field); }
uint128 getIFieldH128(SField::ref field) const { return getValueFieldH128(field); }
uint160 getIFieldH160(SField::ref field) const { return getValueFieldH160(field); }
uint256 getIFieldH256(SField::ref field) const { return getValueFieldH256(field); }
std::vector<unsigned char> getIFieldVL(SField::ref field) const { return getValueFieldVL(field); }
std::vector<TaggedListItem> getIFieldTL(SField::ref field) const { return getValueFieldTL(field); }
NewcoinAddress getIValueFieldAccount(SField::ref field) const { return getValueFieldAccount(field); }
STAmount getIValueFieldAmount(SField::ref field) const { return getValueFieldAmount(field); }
STVector256 getIFieldV256(SField::ref field) { return getValueFieldV256(field); }
void setIFieldU8(SField::ref field, unsigned char v) { return setValueFieldU8(field, v); }
void setIFieldU16(SField::ref field, uint16 v) { return setValueFieldU16(field, v); }
void setIFieldU32(SField::ref field, uint32 v) { return setValueFieldU32(field, v); }
void setIFieldU64(SField::ref field, uint64 v) { return setValueFieldU64(field, v); }
void setIFieldH128(SField::ref field, const uint128& v) { return setValueFieldH128(field, v); }
void setIFieldH160(SField::ref field, const uint160& v) { return setValueFieldH160(field, v); }
void setIFieldH256(SField::ref field, const uint256& v) { return setValueFieldH256(field, v); }
void setIFieldVL(SField::ref field, const std::vector<unsigned char>& v)
{ return setValueFieldVL(field, v); }
void setIFieldTL(SField::ref field, const std::vector<TaggedListItem>& v)
{ return setValueFieldTL(field, v); }
void setIFieldAccount(SField::ref field, const uint160& account)
{ return setValueFieldAccount(field, account); }
void setIFieldAccount(SField::ref field, const NewcoinAddress& account)
{ return setValueFieldAccount(field, account); }
void setIFieldAmount(SField::ref field, const STAmount& amount)
{ return setValueFieldAmount(field, amount); }
void setIFieldV256(SField::ref field, const STVector256& v) { return setValueFieldV256(field, v); }
bool getIFieldPresent(SField::ref field) const { return isFieldPresent(field); }
void makeIFieldPresent(SField::ref field) { makeFieldPresent(field); }
void makeIFieldAbsent(SField::ref field) { return makeFieldAbsent(field); }
// CAUTION: All the above functions are obsolete
bool getIFieldPresent(SOE_Field field) const { return mObject.isFieldPresent(field); }
void makeIFieldPresent(SOE_Field field) { mObject.makeFieldPresent(field); }
void makeIFieldAbsent(SOE_Field field) { return mObject.makeFieldAbsent(field); }
};
typedef SerializedLedgerEntry SLE;

View File

@@ -3,13 +3,16 @@
#include <boost/foreach.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/bind.hpp>
#include "../json/writer.h"
#include "Log.h"
std::auto_ptr<SerializedType> STObject::makeDefaultObject(SerializedTypeID id, const char *name)
std::auto_ptr<SerializedType> STObject::makeDefaultObject(SerializedTypeID id, SField::ref name)
{
assert((id == STI_NOTPRESENT) || (id == name.fieldType));
switch(id)
{
case STI_NOTPRESENT:
@@ -48,13 +51,19 @@ std::auto_ptr<SerializedType> STObject::makeDefaultObject(SerializedTypeID id, c
case STI_PATHSET:
return std::auto_ptr<SerializedType>(new STPathSet(name));
case STI_OBJECT:
return std::auto_ptr<SerializedType>(new STObject(name));
case STI_ARRAY:
return std::auto_ptr<SerializedType>(new STArray(name));
default:
throw std::runtime_error("Unknown object type");
}
}
std::auto_ptr<SerializedType> STObject::makeDeserializedObject(SerializedTypeID id, const char *name,
SerializerIterator& sit)
std::auto_ptr<SerializedType> STObject::makeDeserializedObject(SerializedTypeID id, SField::ref name,
SerializerIterator& sit, int depth)
{
switch(id)
{
@@ -94,89 +103,128 @@ std::auto_ptr<SerializedType> STObject::makeDeserializedObject(SerializedTypeID
case STI_PATHSET:
return STPathSet::deserialize(sit, name);
case STI_ARRAY:
return STArray::deserialize(sit, name);
case STI_OBJECT:
return STObject::deserialize(sit, name);
default:
throw std::runtime_error("Unknown object type");
}
}
void STObject::set(const SOElement* elem)
void STObject::set(SOElement::ptr elem)
{
mData.empty();
mType.empty();
mFlagIdx = -1;
while (elem->e_id != STI_DONE)
while (elem->flags != SOE_END)
{
if (elem->e_type == SOE_FLAGS) mFlagIdx = mType.size();
mType.push_back(elem);
if (elem->e_type == SOE_IFFLAG)
giveObject(makeDefaultObject(STI_NOTPRESENT, elem->e_name));
if (elem->flags == SOE_OPTIONAL)
giveObject(makeNonPresentObject(elem->e_field));
else
giveObject(makeDefaultObject(elem->e_id, elem->e_name));
giveObject(makeDefaultObject(elem->e_field));
++elem;
}
}
STObject::STObject(const SOElement* elem, const char *name) : SerializedType(name)
bool STObject::setType(SOElement::ptrList t)
{
set(elem);
}
boost::ptr_vector<SerializedType> newData;
bool valid = true;
void STObject::set(const SOElement* elem, SerializerIterator& sit)
{
mData.empty();
mType.empty();
mFlagIdx = -1;
int flags = -1;
while (elem->e_id != STI_DONE)
while (t->flags != SOE_END)
{
mType.push_back(elem);
bool done = false;
if (elem->e_type == SOE_IFFLAG)
{
assert(flags >= 0);
if ((flags&elem->e_flags) == 0)
bool match = false;
for (boost::ptr_vector<SerializedType>::iterator it = mData.begin(); it != mData.end(); ++it)
if (it->getFName() == t->e_field)
{
done = true;
giveObject(makeDefaultObject(STI_NOTPRESENT, elem->e_name));
match = true;
newData.push_back(mData.release(it).release());
break;
}
}
else if (elem->e_type == SOE_IFNFLAG)
if (!match)
{
assert(flags >= 0);
if ((flags&elem->e_flags) != 0)
if (t->flags != SOE_OPTIONAL)
{
done = true;
giveObject(makeDefaultObject(elem->e_id, elem->e_name));
Log(lsTRACE) << "setType !valid missing";
valid = false;
}
newData.push_back(makeNonPresentObject(t->e_field));
}
else if (elem->e_type == SOE_FLAGS)
{
assert(elem->e_id == STI_UINT32);
flags = sit.get32();
mFlagIdx = giveObject(new STUInt32(elem->e_name, flags));
done = true;
}
if (!done)
giveObject(makeDeserializedObject(elem->e_id, elem->e_name, sit));
elem++;
mType.push_back(t++);
}
if (mData.size() != 0)
{
Log(lsTRACE) << "setType !valid leftover";
valid = false;
}
mData.swap(newData);
return valid;
}
STObject::STObject(const SOElement* elem, SerializerIterator& sit, const char *name)
: SerializedType(name), mFlagIdx(-1)
bool STObject::isValidForType()
{
set(elem, sit);
boost::ptr_vector<SerializedType>::iterator it = mData.begin();
BOOST_FOREACH(SOElement::ptr elem, mType)
{
if (it == mData.end())
return false;
if (elem->e_field != it->getFName())
return false;
++it;
}
return true;
}
bool STObject::isFieldAllowed(SField::ref field)
{
BOOST_FOREACH(SOElement::ptr elem, mType)
{ // are any required elemnents missing
if (elem->e_field == field)
return true;
}
return false;
}
bool STObject::set(SerializerIterator& sit, int depth)
{ // return true = terminated with end-of-object
mData.empty();
while (!sit.empty())
{
int type, field;
sit.getFieldID(type, field);
if ((type == STI_OBJECT) && (field == 1)) // end of object indicator
return true;
SField::ref fn = SField::getField(type, field);
if (fn.isInvalid())
throw std::runtime_error("Unknown field");
giveObject(makeDeserializedObject(fn.fieldType, fn, sit, depth + 1));
}
return false;
}
std::auto_ptr<SerializedType> STObject::deserialize(SerializerIterator& sit, SField::ref name)
{
STObject *o;
std::auto_ptr<SerializedType> object(o = new STObject(name));
o->set(sit, 1);
return object;
}
std::string STObject::getFullText() const
{
std::string ret;
bool first = true;
if (name != NULL)
if (fName->hasName())
{
ret = name;
ret = fName->getName();
ret += " = {";
}
else ret = "{";
@@ -193,18 +241,33 @@ std::string STObject::getFullText() const
return ret;
}
int STObject::getLength() const
void STObject::add(Serializer& s, bool withSigningFields) const
{
int ret = 0;
BOOST_FOREACH(const SerializedType& it, mData)
ret += it.getLength();
return ret;
}
std::map<int, const SerializedType*> fields;
void STObject::add(Serializer& s) const
{
BOOST_FOREACH(const SerializedType& it, mData)
it.add(s);
{ // pick out the fields and sort them
if (it.getSType() != STI_NOTPRESENT)
{
SField::ref fName = it.getFName();
if (withSigningFields || ((fName != sfTxnSignature) && (fName != sfTxnSignatures)))
fields.insert(std::make_pair(it.getFName().fieldCode, &it));
}
}
typedef std::pair<const int, const SerializedType*> field_iterator;
BOOST_FOREACH(field_iterator& it, fields)
{ // insert them in sorted order
const SerializedType* field = it.second;
field->addFieldID(s);
field->add(s);
if (dynamic_cast<const STArray*>(field) != NULL)
s.addFieldID(STI_ARRAY, 1);
else if (dynamic_cast<const STObject*>(field) != NULL)
s.addFieldID(STI_OBJECT, 1);
}
}
std::string STObject::getText() const
@@ -227,7 +290,8 @@ std::string STObject::getText() const
bool STObject::isEquivalent(const SerializedType& t) const
{
const STObject* v = dynamic_cast<const STObject*>(&t);
if (!v) return false;
if (!v)
return false;
boost::ptr_vector<SerializedType>::const_iterator it1 = mData.begin(), end1 = mData.end();
boost::ptr_vector<SerializedType>::const_iterator it2 = v->mData.begin(), end2 = v->mData.end();
while ((it1 != end1) && (it2 != end2))
@@ -240,15 +304,35 @@ bool STObject::isEquivalent(const SerializedType& t) const
return (it1 == end1) && (it2 == end2);
}
int STObject::getFieldIndex(SOE_Field field) const
uint256 STObject::getHash(uint32 prefix) const
{
Serializer s;
s.add32(prefix);
add(s, true);
return s.getSHA512Half();
}
uint256 STObject::getSigningHash(uint32 prefix) const
{
Serializer s;
s.add32(prefix);
add(s, false);
return s.getSHA512Half();
}
int STObject::getFieldIndex(SField::ref field) const
{
int i = 0;
for (std::vector<const SOElement*>::const_iterator it = mType.begin(), end = mType.end(); it != end; ++it, ++i)
if ((*it)->e_field == field) return i;
BOOST_FOREACH(const SerializedType& elem, mData)
{
if (elem.getFName() == field)
return i;
++i;
}
return -1;
}
const SerializedType& STObject::peekAtField(SOE_Field field) const
const SerializedType& STObject::peekAtField(SField::ref field) const
{
int index = getFieldIndex(field);
if (index == -1)
@@ -256,7 +340,7 @@ const SerializedType& STObject::peekAtField(SOE_Field field) const
return peekAtIndex(index);
}
SerializedType& STObject::getField(SOE_Field field)
SerializedType& STObject::getField(SField::ref field)
{
int index = getFieldIndex(field);
if (index == -1)
@@ -264,12 +348,12 @@ SerializedType& STObject::getField(SOE_Field field)
return getIndex(index);
}
SOE_Field STObject::getFieldSType(int index) const
SField::ref STObject::getFieldSType(int index) const
{
return mType[index]->e_field;
return mData[index].getFName();
}
const SerializedType* STObject::peekAtPField(SOE_Field field) const
const SerializedType* STObject::peekAtPField(SField::ref field) const
{
int index = getFieldIndex(field);
if (index == -1)
@@ -277,7 +361,7 @@ const SerializedType* STObject::peekAtPField(SOE_Field field) const
return peekAtPIndex(index);
}
SerializedType* STObject::getPField(SOE_Field field)
SerializedType* STObject::getPField(SField::ref field)
{
int index = getFieldIndex(field);
if (index == -1)
@@ -285,7 +369,7 @@ SerializedType* STObject::getPField(SOE_Field field)
return getPIndex(index);
}
bool STObject::isFieldPresent(SOE_Field field) const
bool STObject::isFieldPresent(SField::ref field) const
{
int index = getFieldIndex(field);
if (index == -1)
@@ -295,76 +379,78 @@ bool STObject::isFieldPresent(SOE_Field field) const
bool STObject::setFlag(uint32 f)
{
if (mFlagIdx < 0) return false;
STUInt32* t = dynamic_cast<STUInt32*>(getPIndex(mFlagIdx));
assert(t);
STUInt32* t = dynamic_cast<STUInt32*>(getPField(sfFlags));
if (!t)
return false;
t->setValue(t->getValue() | f);
return true;
}
bool STObject::clearFlag(uint32 f)
{
if (mFlagIdx < 0) return false;
STUInt32* t = dynamic_cast<STUInt32*>(getPIndex(mFlagIdx));
assert(t);
STUInt32* t = dynamic_cast<STUInt32*>(getPField(sfFlags));
if (!t)
return false;
t->setValue(t->getValue() & ~f);
return true;
}
uint32 STObject::getFlags(void) const
{
if (mFlagIdx < 0) return 0;
const STUInt32* t = dynamic_cast<const STUInt32*>(peekAtPIndex(mFlagIdx));
assert(t);
const STUInt32* t = dynamic_cast<const STUInt32*>(peekAtPField(sfFlags));
if (!t)
return 0;
return t->getValue();
}
SerializedType* STObject::makeFieldPresent(SOE_Field field)
SerializedType* STObject::makeFieldPresent(SField::ref field)
{
int index = getFieldIndex(field);
if (index == -1)
throw std::runtime_error("Field not found");
if ((mType[index]->e_type != SOE_IFFLAG) && (mType[index]->e_type != SOE_IFNFLAG))
throw std::runtime_error("field is not optional");
SerializedType* f = getPIndex(index);
if (f->getSType() != STI_NOTPRESENT) return f;
mData.replace(index, makeDefaultObject(mType[index]->e_id, mType[index]->e_name));
f = getPIndex(index);
if (mType[index]->e_type == SOE_IFFLAG)
setFlag(mType[index]->e_flags);
else if (mType[index]->e_type == SOE_IFNFLAG)
clearFlag(mType[index]->e_flags);
return f;
if (f->getSType() != STI_NOTPRESENT)
return f;
mData.replace(index, makeDefaultObject(f->getFName()));
return getPIndex(index);
}
void STObject::makeFieldAbsent(SOE_Field field)
void STObject::makeFieldAbsent(SField::ref field)
{
int index = getFieldIndex(field);
if (index == -1)
throw std::runtime_error("Field not found");
if ((mType[index]->e_type != SOE_IFFLAG) && (mType[index]->e_type != SOE_IFNFLAG))
throw std::runtime_error("field is not optional");
if (peekAtIndex(index).getSType() == STI_NOTPRESENT) return;
mData.replace(index, new SerializedType(mType[index]->e_name));
const SerializedType& f = peekAtIndex(index);
if (f.getSType() == STI_NOTPRESENT)
return;
if (mType[index]->e_type == SOE_IFFLAG)
clearFlag(mType[index]->e_flags);
else if (mType[index]->e_type == SOE_IFNFLAG)
setFlag(mType[index]->e_flags);
mData.replace(index, makeDefaultObject(f.getFName()));
}
std::string STObject::getFieldString(SOE_Field field) const
bool STObject::delField(SField::ref field)
{
int index = getFieldIndex(field);
if (index == -1)
return false;
delField(index);
return true;
}
void STObject::delField(int index)
{
mData.erase(mData.begin() + index);
}
std::string STObject::getFieldString(SField::ref field) const
{
const SerializedType* rf = peekAtPField(field);
if (!rf) throw std::runtime_error("Field not found");
return rf->getText();
}
unsigned char STObject::getValueFieldU8(SOE_Field field) const
unsigned char STObject::getValueFieldU8(SField::ref field) const
{
const SerializedType* rf = peekAtPField(field);
if (!rf) throw std::runtime_error("Field not found");
@@ -375,7 +461,7 @@ unsigned char STObject::getValueFieldU8(SOE_Field field) const
return cf->getValue();
}
uint16 STObject::getValueFieldU16(SOE_Field field) const
uint16 STObject::getValueFieldU16(SField::ref field) const
{
const SerializedType* rf = peekAtPField(field);
if (!rf) throw std::runtime_error("Field not found");
@@ -386,7 +472,7 @@ uint16 STObject::getValueFieldU16(SOE_Field field) const
return cf->getValue();
}
uint32 STObject::getValueFieldU32(SOE_Field field) const
uint32 STObject::getValueFieldU32(SField::ref field) const
{
const SerializedType* rf = peekAtPField(field);
if (!rf) throw std::runtime_error("Field not found");
@@ -397,7 +483,7 @@ uint32 STObject::getValueFieldU32(SOE_Field field) const
return cf->getValue();
}
uint64 STObject::getValueFieldU64(SOE_Field field) const
uint64 STObject::getValueFieldU64(SField::ref field) const
{
const SerializedType* rf = peekAtPField(field);
if (!rf) throw std::runtime_error("Field not found");
@@ -408,7 +494,7 @@ uint64 STObject::getValueFieldU64(SOE_Field field) const
return cf->getValue();
}
uint128 STObject::getValueFieldH128(SOE_Field field) const
uint128 STObject::getValueFieldH128(SField::ref field) const
{
const SerializedType* rf = peekAtPField(field);
if (!rf) throw std::runtime_error("Field not found");
@@ -419,7 +505,7 @@ uint128 STObject::getValueFieldH128(SOE_Field field) const
return cf->getValue();
}
uint160 STObject::getValueFieldH160(SOE_Field field) const
uint160 STObject::getValueFieldH160(SField::ref field) const
{
const SerializedType* rf = peekAtPField(field);
if (!rf) throw std::runtime_error("Field not found");
@@ -430,7 +516,7 @@ uint160 STObject::getValueFieldH160(SOE_Field field) const
return cf->getValue();
}
uint256 STObject::getValueFieldH256(SOE_Field field) const
uint256 STObject::getValueFieldH256(SField::ref field) const
{
const SerializedType* rf = peekAtPField(field);
if (!rf) throw std::runtime_error("Field not found");
@@ -441,7 +527,7 @@ uint256 STObject::getValueFieldH256(SOE_Field field) const
return cf->getValue();
}
NewcoinAddress STObject::getValueFieldAccount(SOE_Field field) const
NewcoinAddress STObject::getValueFieldAccount(SField::ref field) const
{
const SerializedType* rf = peekAtPField(field);
if (!rf)
@@ -459,7 +545,7 @@ NewcoinAddress STObject::getValueFieldAccount(SOE_Field field) const
return cf->getValueNCA();
}
std::vector<unsigned char> STObject::getValueFieldVL(SOE_Field field) const
std::vector<unsigned char> STObject::getValueFieldVL(SField::ref field) const
{
const SerializedType* rf = peekAtPField(field);
if (!rf) throw std::runtime_error("Field not found");
@@ -470,7 +556,7 @@ std::vector<unsigned char> STObject::getValueFieldVL(SOE_Field field) const
return cf->getValue();
}
STAmount STObject::getValueFieldAmount(SOE_Field field) const
STAmount STObject::getValueFieldAmount(SField::ref field) const
{
const SerializedType* rf = peekAtPField(field);
if (!rf) throw std::runtime_error("Field not found");
@@ -481,7 +567,7 @@ STAmount STObject::getValueFieldAmount(SOE_Field field) const
return *cf;
}
STPathSet STObject::getValueFieldPathSet(SOE_Field field) const
STPathSet STObject::getValueFieldPathSet(SField::ref field) const
{
const SerializedType* rf = peekAtPField(field);
if (!rf) throw std::runtime_error("Field not found");
@@ -492,7 +578,7 @@ STPathSet STObject::getValueFieldPathSet(SOE_Field field) const
return *cf;
}
STVector256 STObject::getValueFieldV256(SOE_Field field) const
STVector256 STObject::getValueFieldV256(SField::ref field) const
{
const SerializedType* rf = peekAtPField(field);
if (!rf) throw std::runtime_error("Field not found");
@@ -503,7 +589,7 @@ STVector256 STObject::getValueFieldV256(SOE_Field field) const
return *cf;
}
void STObject::setValueFieldU8(SOE_Field field, unsigned char v)
void STObject::setValueFieldU8(SField::ref field, unsigned char v)
{
SerializedType* rf = getPField(field);
if (!rf) throw std::runtime_error("Field not found");
@@ -513,7 +599,7 @@ void STObject::setValueFieldU8(SOE_Field field, unsigned char v)
cf->setValue(v);
}
void STObject::setValueFieldU16(SOE_Field field, uint16 v)
void STObject::setValueFieldU16(SField::ref field, uint16 v)
{
SerializedType* rf = getPField(field);
if (!rf) throw std::runtime_error("Field not found");
@@ -523,7 +609,7 @@ void STObject::setValueFieldU16(SOE_Field field, uint16 v)
cf->setValue(v);
}
void STObject::setValueFieldU32(SOE_Field field, uint32 v)
void STObject::setValueFieldU32(SField::ref field, uint32 v)
{
SerializedType* rf = getPField(field);
if (!rf) throw std::runtime_error("Field not found");
@@ -533,7 +619,7 @@ void STObject::setValueFieldU32(SOE_Field field, uint32 v)
cf->setValue(v);
}
void STObject::setValueFieldU64(SOE_Field field, uint64 v)
void STObject::setValueFieldU64(SField::ref field, uint64 v)
{
SerializedType* rf = getPField(field);
if (!rf) throw std::runtime_error("Field not found");
@@ -543,7 +629,7 @@ void STObject::setValueFieldU64(SOE_Field field, uint64 v)
cf->setValue(v);
}
void STObject::setValueFieldH128(SOE_Field field, const uint128& v)
void STObject::setValueFieldH128(SField::ref field, const uint128& v)
{
SerializedType* rf = getPField(field);
if (!rf) throw std::runtime_error("Field not found");
@@ -553,7 +639,7 @@ void STObject::setValueFieldH128(SOE_Field field, const uint128& v)
cf->setValue(v);
}
void STObject::setValueFieldH160(SOE_Field field, const uint160& v)
void STObject::setValueFieldH160(SField::ref field, const uint160& v)
{
SerializedType* rf = getPField(field);
if (!rf) throw std::runtime_error("Field not found");
@@ -563,7 +649,7 @@ void STObject::setValueFieldH160(SOE_Field field, const uint160& v)
cf->setValue(v);
}
void STObject::setValueFieldH256(SOE_Field field, const uint256& v)
void STObject::setValueFieldH256(SField::ref field, const uint256& v)
{
SerializedType* rf = getPField(field);
if (!rf) throw std::runtime_error("Field not found");
@@ -573,7 +659,7 @@ void STObject::setValueFieldH256(SOE_Field field, const uint256& v)
cf->setValue(v);
}
void STObject::setValueFieldV256(SOE_Field field, const STVector256& v)
void STObject::setValueFieldV256(SField::ref field, const STVector256& v)
{
SerializedType* rf = getPField(field);
if (!rf) throw std::runtime_error("Field not found");
@@ -583,7 +669,7 @@ void STObject::setValueFieldV256(SOE_Field field, const STVector256& v)
cf->setValue(v);
}
void STObject::setValueFieldAccount(SOE_Field field, const uint160& v)
void STObject::setValueFieldAccount(SField::ref field, const uint160& v)
{
SerializedType* rf = getPField(field);
if (!rf) throw std::runtime_error("Field not found");
@@ -593,7 +679,7 @@ void STObject::setValueFieldAccount(SOE_Field field, const uint160& v)
cf->setValueH160(v);
}
void STObject::setValueFieldVL(SOE_Field field, const std::vector<unsigned char>& v)
void STObject::setValueFieldVL(SField::ref field, const std::vector<unsigned char>& v)
{
SerializedType* rf = getPField(field);
if (!rf) throw std::runtime_error("Field not found");
@@ -603,7 +689,7 @@ void STObject::setValueFieldVL(SOE_Field field, const std::vector<unsigned char>
cf->setValue(v);
}
void STObject::setValueFieldAmount(SOE_Field field, const STAmount &v)
void STObject::setValueFieldAmount(SField::ref field, const STAmount &v)
{
SerializedType* rf = getPField(field);
if (!rf) throw std::runtime_error("Field not found");
@@ -613,7 +699,7 @@ void STObject::setValueFieldAmount(SOE_Field field, const STAmount &v)
(*cf) = v;
}
void STObject::setValueFieldPathSet(SOE_Field field, const STPathSet &v)
void STObject::setValueFieldPathSet(SField::ref field, const STPathSet &v)
{
SerializedType* rf = getPField(field);
if (!rf) throw std::runtime_error("Field not found");
@@ -631,9 +717,10 @@ Json::Value STObject::getJson(int options) const
{
if (it.getSType() != STI_NOTPRESENT)
{
if (it.getName() == NULL)
if (!it.getFName().hasName())
ret[boost::lexical_cast<std::string>(index)] = it.getJson(options);
else ret[it.getName()] = it.getJson(options);
else
ret[it.getName()] = it.getJson(options);
}
}
return ret;
@@ -649,6 +736,185 @@ Json::Value STVector256::getJson(int options) const
return ret;
}
std::string STArray::getFullText() const
{
return "WRITEME";
}
std::string STArray::getText() const
{
return "WRITEME";
}
Json::Value STArray::getJson(int) const
{
return Json::Value("WRITEME");
}
void STArray::add(Serializer& s) const
{
BOOST_FOREACH(const STObject& object, value)
{
object.addFieldID(s);
object.add(s);
s.addFieldID(STI_OBJECT, 1);
}
}
bool STArray::isEquivalent(const SerializedType& t) const
{
const STArray* v = dynamic_cast<const STArray*>(&t);
if (!v)
return false;
return value == v->value;
}
STArray* STArray::construct(SerializerIterator& sit, SField::ref field)
{
vector value;
while (!sit.empty())
{
int type, field;
sit.getFieldID(type, field);
if ((type == STI_ARRAY) && (field == 1))
break;
SField::ref fn = SField::getField(type, field);
if (fn.isInvalid())
throw std::runtime_error("Unknown field");
value.push_back(STObject(fn));
value.rbegin()->set(sit, 1);
}
return new STArray(field, value);
}
std::auto_ptr<STObject> STObject::parseJson(const Json::Value& object, SField::ref name, int depth)
{
if (!object.isObject())
throw std::runtime_error("Value is not an object");
boost::ptr_vector<SerializedType> data;
Json::Value::Members members(object.getMemberNames());
for (Json::Value::Members::iterator it = members.begin(), end = members.end(); it != end; ++it)
{
const std::string& name = *it;
const Json::Value& value = object[name];
SField::ref field = SField::getField(name);
if (field == sfInvalid)
throw std::runtime_error("Unknown field: " + name);
switch (field.fieldType)
{
case STI_UINT8:
if (value.isString())
data.push_back(new STUInt8(field, boost::lexical_cast<unsigned char>(value.asString())));
else if (value.isInt())
data.push_back(new STUInt8(field, boost::lexical_cast<unsigned char>(value.asInt())));
else if (value.isUInt())
data.push_back(new STUInt8(field, boost::lexical_cast<unsigned char>(value.asUInt())));
else
throw std::runtime_error("Incorrect type");
break;
case STI_UINT16:
if (value.isString())
{
std::string strValue = value.asString();
if (!strValue.empty() && (strValue[0]<'0' || strValue[0]>'9'))
{
if (field == sfTransactionType)
{
// WRITEME
}
else if (field == sfLedgerEntryType)
{
// WRITEME
}
else
throw std::runtime_error("Invalid field data");
}
data.push_back(new STUInt16(field, boost::lexical_cast<uint16>(strValue)));
}
else if (value.isInt())
data.push_back(new STUInt16(field, boost::lexical_cast<uint16>(value.asInt())));
else if (value.isUInt())
data.push_back(new STUInt16(field, boost::lexical_cast<uint16>(value.asUInt())));
else
throw std::runtime_error("Incorrect type");
break;
case STI_UINT32:
if (value.isString())
data.push_back(new STUInt32(field, boost::lexical_cast<uint32>(value.asString())));
else if (value.isInt())
data.push_back(new STUInt32(field, boost::lexical_cast<uint32>(value.asInt())));
else if (value.isUInt())
data.push_back(new STUInt32(field, boost::lexical_cast<uint32>(value.asUInt())));
else
throw std::runtime_error("Incorrect type");
break;
case STI_UINT64:
if (value.isString())
data.push_back(new STUInt64(field, boost::lexical_cast<uint64>(value.asString())));
else if (value.isInt())
data.push_back(new STUInt64(field, boost::lexical_cast<uint64>(value.asInt())));
else if (value.isUInt())
data.push_back(new STUInt64(field, boost::lexical_cast<uint64>(value.asUInt())));
else
throw std::runtime_error("Incorrect type");
break;
case STI_HASH128:
// WRITEME
case STI_HASH160:
// WRITEME
case STI_HASH256:
// WRITEME
case STI_VL:
// WRITEME
case STI_AMOUNT:
// WRITEME
case STI_VECTOR256:
// WRITEME
case STI_PATHSET:
// WRITEME
case STI_OBJECT:
case STI_ACCOUNT:
case STI_TRANSACTION:
case STI_LEDGERENTRY:
case STI_VALIDATION:
if (!value.isObject())
throw std::runtime_error("Inner value is not an object");
if (depth > 64)
throw std::runtime_error("Json nest depth exceeded");
data.push_back(parseJson(value, field, depth + 1));
break;
case STI_ARRAY:
// WRITEME
default:
throw std::runtime_error("Invalid field type");
}
}
return std::auto_ptr<STObject>(new STObject(name, data));
}
#if 0
static SOElement testSOElements[2][16] =
{ // field, name, id, type, flags
{
@@ -708,4 +974,6 @@ void STObject::unitTest()
}
#endif
// vim:ts=4

View File

@@ -9,62 +9,56 @@
#include "SerializedTypes.h"
enum SOE_Type
{
SOE_NEVER = -1, // never occurs (marks end of object)
SOE_REQUIRED = 0, // required
SOE_FLAGS = 1, // flags field
SOE_IFFLAG = 2, // present if flag set
SOE_IFNFLAG = 3 // present if flag not set
};
// Serializable object/array types
enum SOE_Field
{
sfInvalid = -1,
sfGeneric = 0,
#define FIELD(name, type, index) sf##name,
#define TYPE(name, type, index)
#include "SerializeProto.h"
#undef FIELD
#undef TYPE
// test fields
sfTest1, sfTest2, sfTest3, sfTest4
};
struct SOElement
class SOElement
{ // An element in the description of a serialized object
SOE_Field e_field;
const char *e_name;
SerializedTypeID e_id;
SOE_Type e_type;
int e_flags;
public:
typedef SOElement const * ptr; // used to point to one element
typedef SOElement const * ptrList; // used to point to a terminated list of elements
SField::ref e_field;
const SOE_Flags flags;
};
class STObject : public SerializedType
{
protected:
int mFlagIdx; // the offset to the flags object, -1 if none
boost::ptr_vector<SerializedType> mData;
std::vector<const SOElement*> mType;
std::vector<SOElement::ptr> mType;
STObject* duplicate() const { return new STObject(*this); }
STObject(SField::ref name, boost::ptr_vector<SerializedType>& data) : SerializedType(name) { mData.swap(data); }
public:
STObject(const char *n = NULL) : SerializedType(n), mFlagIdx(-1) { ; }
STObject(const SOElement *t, const char *n = NULL);
STObject(const SOElement *t, SerializerIterator& u, const char *n = NULL);
STObject() { ; }
STObject(SField::ref name) : SerializedType(name) { ; }
STObject(SOElement::ptrList type, SField::ref name) : SerializedType(name)
{ set(type); }
STObject(SOElement::ptrList type, SerializerIterator& sit, SField::ref name) : SerializedType(name)
{ set(sit); setType(type); }
static std::auto_ptr<STObject> parseJson(const Json::Value& value, SField::ref name, int depth = 0);
virtual ~STObject() { ; }
void set(const SOElement* t);
void set(const SOElement* t, SerializerIterator& u);
static std::auto_ptr<SerializedType> deserialize(SerializerIterator& sit, SField::ref name);
bool setType(SOElement::ptrList);
bool isValidForType();
bool isFieldAllowed(SField::ref);
void set(SOElement::ptrList);
bool set(SerializerIterator& u, int depth = 0);
int getLength() const;
virtual SerializedTypeID getSType() const { return STI_OBJECT; }
virtual bool isEquivalent(const SerializedType& t) const;
void add(Serializer& s) const;
virtual void add(Serializer& s) const { add(s, true); } // just inner elements
void add(Serializer& s, bool withSignature) const;
Serializer getSerializer() const { Serializer s; add(s); return s; }
std::string getFullText() const;
std::string getText() const;
@@ -82,64 +76,132 @@ public:
bool clearFlag(uint32);
uint32 getFlags() const;
uint256 getHash(uint32 prefix) const;
uint256 getSigningHash(uint32 prefix) const;
const SerializedType& peekAtIndex(int offset) const { return mData[offset]; }
SerializedType& getIndex(int offset) { return mData[offset]; }
const SerializedType* peekAtPIndex(int offset) const { return &(mData[offset]); }
SerializedType* getPIndex(int offset) { return &(mData[offset]); }
int getFieldIndex(SOE_Field field) const;
SOE_Field getFieldSType(int index) const;
int getFieldIndex(SField::ref field) const;
SField::ref getFieldSType(int index) const;
const SerializedType& peekAtField(SOE_Field field) const;
SerializedType& getField(SOE_Field field);
const SerializedType* peekAtPField(SOE_Field field) const;
SerializedType* getPField(SOE_Field field);
const SOElement* getFieldType(SOE_Field field) 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);
// these throw if the field type doesn't match, or return default values if the
// field is optional but not present
std::string getFieldString(SOE_Field field) const;
unsigned char getValueFieldU8(SOE_Field field) const;
uint16 getValueFieldU16(SOE_Field field) const;
uint32 getValueFieldU32(SOE_Field field) const;
uint64 getValueFieldU64(SOE_Field field) const;
uint128 getValueFieldH128(SOE_Field field) const;
uint160 getValueFieldH160(SOE_Field field) const;
uint256 getValueFieldH256(SOE_Field field) const;
NewcoinAddress getValueFieldAccount(SOE_Field field) const;
std::vector<unsigned char> getValueFieldVL(SOE_Field field) const;
std::vector<TaggedListItem> getValueFieldTL(SOE_Field field) const;
STAmount getValueFieldAmount(SOE_Field field) const;
STPathSet getValueFieldPathSet(SOE_Field field) const;
STVector256 getValueFieldV256(SOE_Field field) const;
std::string getFieldString(SField::ref field) const;
unsigned char getValueFieldU8(SField::ref field) const;
uint16 getValueFieldU16(SField::ref field) const;
uint32 getValueFieldU32(SField::ref field) const;
uint64 getValueFieldU64(SField::ref field) const;
uint128 getValueFieldH128(SField::ref field) const;
uint160 getValueFieldH160(SField::ref field) const;
uint256 getValueFieldH256(SField::ref field) const;
NewcoinAddress getValueFieldAccount(SField::ref field) const;
std::vector<unsigned char> getValueFieldVL(SField::ref field) const;
std::vector<TaggedListItem> getValueFieldTL(SField::ref field) const;
STAmount getValueFieldAmount(SField::ref field) const;
STPathSet getValueFieldPathSet(SField::ref field) const;
STVector256 getValueFieldV256(SField::ref field) const;
void setValueFieldU8(SOE_Field field, unsigned char);
void setValueFieldU16(SOE_Field field, uint16);
void setValueFieldU32(SOE_Field field, uint32);
void setValueFieldU64(SOE_Field field, uint64);
void setValueFieldH128(SOE_Field field, const uint128&);
void setValueFieldH160(SOE_Field field, const uint160&);
void setValueFieldH256(SOE_Field field, const uint256&);
void setValueFieldVL(SOE_Field field, const std::vector<unsigned char>&);
void setValueFieldTL(SOE_Field field, const std::vector<TaggedListItem>&);
void setValueFieldAccount(SOE_Field field, const uint160&);
void setValueFieldAccount(SOE_Field field, const NewcoinAddress& addr)
void setValueFieldU8(SField::ref field, unsigned char);
void setValueFieldU16(SField::ref field, uint16);
void setValueFieldU32(SField::ref field, uint32);
void setValueFieldU64(SField::ref field, uint64);
void setValueFieldH128(SField::ref field, const uint128&);
void setValueFieldH160(SField::ref field, const uint160&);
void setValueFieldH256(SField::ref field, const uint256&);
void setValueFieldVL(SField::ref field, const std::vector<unsigned char>&);
void setValueFieldTL(SField::ref field, const std::vector<TaggedListItem>&);
void setValueFieldAccount(SField::ref field, const uint160&);
void setValueFieldAccount(SField::ref field, const NewcoinAddress& addr)
{ setValueFieldAccount(field, addr.getAccountID()); }
void setValueFieldAmount(SOE_Field field, const STAmount&);
void setValueFieldPathSet(SOE_Field field, const STPathSet&);
void setValueFieldV256(SOE_Field field, const STVector256& v);
void setValueFieldAmount(SField::ref field, const STAmount&);
void setValueFieldPathSet(SField::ref field, const STPathSet&);
void setValueFieldV256(SField::ref field, const STVector256& v);
bool isFieldPresent(SOE_Field field) const;
SerializedType* makeFieldPresent(SOE_Field field);
void makeFieldAbsent(SOE_Field field);
bool isFieldPresent(SField::ref field) const;
SerializedType* makeFieldPresent(SField::ref field);
void makeFieldAbsent(SField::ref field);
bool delField(SField::ref field);
void delField(int index);
static std::auto_ptr<SerializedType> makeDefaultObject(SerializedTypeID id, const char *name);
static std::auto_ptr<SerializedType> makeDeserializedObject(SerializedTypeID id, const char *name,
SerializerIterator&);
static std::auto_ptr<SerializedType> makeDefaultObject(SerializedTypeID id, SField::ref name);
static std::auto_ptr<SerializedType> makeDeserializedObject(SerializedTypeID id, SField::ref name,
SerializerIterator&, int depth);
static std::auto_ptr<SerializedType> makeNonPresentObject(SField::ref name)
{ return makeDefaultObject(STI_NOTPRESENT, name); }
static std::auto_ptr<SerializedType> makeDefaultObject(SField::ref name)
{ return makeDefaultObject(name.fieldType, name); }
static void unitTest();
};
class STArray : public SerializedType
{
public:
typedef std::vector<STObject> vector;
typedef std::vector<STObject>::iterator iterator;
typedef std::vector<STObject>::const_iterator const_iterator;
typedef std::vector<STObject>::reverse_iterator reverse_iterator;
typedef std::vector<STObject>::const_reverse_iterator const_reverse_iterator;
typedef std::vector<STObject>::size_type size_type;
protected:
vector value;
STArray* duplicate() const { return new STArray(*this); }
static STArray* construct(SerializerIterator&, SField::ref);
public:
STArray() { ; }
STArray(SField::ref f) : SerializedType(f) { ; }
STArray(SField::ref f, const vector& v) : SerializedType(f), value(v) { ; }
STArray(vector& v) : value(v) { ; }
static std::auto_ptr<SerializedType> deserialize(SerializerIterator& sit, SField::ref name)
{ return std::auto_ptr<SerializedType>(construct(sit, name)); }
const vector& getValue() const { return value; }
vector& getValue() { return value; }
// vector-like functions
void push_back(const STObject& object) { value.push_back(object); }
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); }
void pop_back() { value.pop_back(); }
bool empty() const { return value.empty(); }
void clear() { value.clear(); }
virtual std::string getFullText() const;
virtual std::string getText() const;
virtual Json::Value getJson(int) const;
virtual void add(Serializer& s) const;
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;
};
#endif
// vim:ts=4

View File

@@ -7,21 +7,16 @@
#include "Log.h"
#include "HashPrefixes.h"
SerializedTransaction::SerializedTransaction(TransactionType type) : mType(type)
SerializedTransaction::SerializedTransaction(TransactionType type) : STObject(sfTransaction), mType(type)
{
mFormat = getTxnFormat(type);
if (mFormat == NULL) throw std::runtime_error("invalid transaction type");
mMiddleTxn.giveObject(new STVariableLength("SigningPubKey"));
mMiddleTxn.giveObject(new STAccount("SourceAccount"));
mMiddleTxn.giveObject(new STUInt32("Sequence"));
mMiddleTxn.giveObject(new STUInt16("Type", static_cast<uint16>(type)));
mMiddleTxn.giveObject(new STAmount("Fee"));
mInnerTxn = STObject(mFormat->elements, "InnerTransaction");
if (mFormat == NULL)
throw std::runtime_error("invalid transaction type");
set(mFormat->elements);
setValueFieldU16(sfTransactionType, mFormat->t_type);
}
SerializedTransaction::SerializedTransaction(SerializerIterator& sit)
SerializedTransaction::SerializedTransaction(SerializerIterator& sit) : STObject(sfTransaction)
{
int length = sit.getBytesLeft();
if ((length < TransactionMinLen) || (length > TransactionMaxLen))
@@ -30,32 +25,17 @@ SerializedTransaction::SerializedTransaction(SerializerIterator& sit)
throw std::runtime_error("Transaction length invalid");
}
mSignature.setValue(sit.getVL());
set(sit);
mType = static_cast<TransactionType>(getValueFieldU16(sfTransactionType));
mMiddleTxn.giveObject(new STVariableLength("SigningPubKey", sit.getVL()));
STAccount sa("SourceAccount", sit.getVL());
mSourceAccount = sa.getValueNCA();
mMiddleTxn.giveObject(new STAccount(sa));
mMiddleTxn.giveObject(new STUInt32("Sequence", sit.get32()));
mType = static_cast<TransactionType>(sit.get16());
mMiddleTxn.giveObject(new STUInt16("Type", static_cast<uint16>(mType)));
mFormat = getTxnFormat(mType);
if (!mFormat)
throw std::runtime_error("invalid transaction type");
if (!setType(mFormat->elements))
{
Log(lsERROR) << "Transaction has invalid type";
throw std::runtime_error("Transaction has invalid type");
assert(false);
throw std::runtime_error("transaction not valid");
}
mMiddleTxn.giveObject(STAmount::deserialize(sit, "Fee"));
mInnerTxn = STObject(mFormat->elements, sit, "InnerTransaction");
}
int SerializedTransaction::getLength() const
{
return mSignature.getLength() + mMiddleTxn.getLength() + mInnerTxn.getLength();
}
std::string SerializedTransaction::getFullText() const
@@ -63,29 +43,21 @@ std::string SerializedTransaction::getFullText() const
std::string ret = "\"";
ret += getTransactionID().GetHex();
ret += "\" = {";
ret += mSignature.getFullText();
ret += mMiddleTxn.getFullText();
ret += mInnerTxn.getFullText();
ret += STObject::getFullText();
ret += "}";
return ret;
}
std::string SerializedTransaction::getText() const
{
std::string ret = "{";
ret += mSignature.getText();
ret += mMiddleTxn.getText();
ret += mInnerTxn.getText();
ret += "}";
return ret;
return STObject::getText();
}
std::vector<NewcoinAddress> SerializedTransaction::getAffectedAccounts() const
{
std::vector<NewcoinAddress> accounts;
accounts.push_back(mSourceAccount);
BOOST_FOREACH(const SerializedType& it, mInnerTxn.peekData())
BOOST_FOREACH(const SerializedType& it, peekData())
{
const STAccount* sa = dynamic_cast<const STAccount*>(&it);
if (sa != NULL)
@@ -108,197 +80,70 @@ std::vector<NewcoinAddress> SerializedTransaction::getAffectedAccounts() const
return accounts;
}
void SerializedTransaction::add(Serializer& s) const
{
mSignature.add(s);
mMiddleTxn.add(s);
mInnerTxn.add(s);
}
bool SerializedTransaction::isEquivalent(const SerializedType& t) const
{ // Signatures are not compared
const SerializedTransaction* v = dynamic_cast<const SerializedTransaction*>(&t);
if (!v) return false;
if (mType != v->mType) return false;
if (mMiddleTxn != v->mMiddleTxn) return false;
if (mInnerTxn != v->mInnerTxn) return false;
return true;
}
uint256 SerializedTransaction::getSigningHash() const
{
Serializer s;
s.add32(sHP_TransactionSign);
mMiddleTxn.add(s);
mInnerTxn.add(s);
return s.getSHA512Half();
return STObject::getSigningHash(sHP_TransactionSign);
}
uint256 SerializedTransaction::getTransactionID() const
{ // perhaps we should cache this
Serializer s;
s.add32(sHP_TransactionID);
mSignature.add(s);
mMiddleTxn.add(s);
mInnerTxn.add(s);
return s.getSHA512Half();
return getHash(sHP_TransactionID);
}
std::vector<unsigned char> SerializedTransaction::getSignature() const
{
return mSignature.getValue();
try
{
return getValueFieldVL(sfTxnSignature);
}
catch (...)
{
return std::vector<unsigned char>();
}
}
const std::vector<unsigned char>& SerializedTransaction::peekSignature() const
void SerializedTransaction::sign(const NewcoinAddress& naAccountPrivate)
{
return mSignature.peekValue();
}
bool SerializedTransaction::sign(const NewcoinAddress& naAccountPrivate)
{
return naAccountPrivate.accountPrivateSign(getSigningHash(), mSignature.peekValue());
std::vector<unsigned char> signature;
naAccountPrivate.accountPrivateSign(getSigningHash(), signature);
setValueFieldVL(sfTxnSignature, signature);
}
bool SerializedTransaction::checkSign(const NewcoinAddress& naAccountPublic) const
{
return naAccountPublic.accountPublicVerify(getSigningHash(), mSignature.getValue());
try
{
return naAccountPublic.accountPublicVerify(getSigningHash(), getValueFieldVL(sfTxnSignature));
}
catch (...)
{
return false;
}
}
void SerializedTransaction::setSignature(const std::vector<unsigned char>& sig)
void SerializedTransaction::setSigningPubKey(const NewcoinAddress& naSignPubKey)
{
mSignature.setValue(sig);
setValueFieldVL(sfSigningPubKey, naSignPubKey.getAccountPublic());
}
STAmount SerializedTransaction::getTransactionFee() const
void SerializedTransaction::setSourceAccount(const NewcoinAddress& naSource)
{
const STAmount* v = dynamic_cast<const STAmount*>(mMiddleTxn.peekAtPIndex(TransactionIFee));
if (!v) throw std::runtime_error("corrupt transaction");
return *v;
setValueFieldAccount(sfAccount, naSource);
}
void SerializedTransaction::setTransactionFee(const STAmount& fee)
{
STAmount* v = dynamic_cast<STAmount*>(mMiddleTxn.getPIndex(TransactionIFee));
if (!v) throw std::runtime_error("corrupt transaction");
v->setValue(fee);
}
uint32 SerializedTransaction::getSequence() const
{
const STUInt32* v = dynamic_cast<const STUInt32*>(mMiddleTxn.peekAtPIndex(TransactionISequence));
if (!v) throw std::runtime_error("corrupt transaction");
return v->getValue();
}
void SerializedTransaction::setSequence(uint32 seq)
{
STUInt32* v = dynamic_cast<STUInt32*>(mMiddleTxn.getPIndex(TransactionISequence));
if (!v) throw std::runtime_error("corrupt transaction");
v->setValue(seq);
}
std::vector<unsigned char> SerializedTransaction::getSigningPubKey() const
{
const STVariableLength* v =
dynamic_cast<const STVariableLength*>(mMiddleTxn.peekAtPIndex(TransactionISigningPubKey));
if (!v) throw std::runtime_error("corrupt transaction");
return v->getValue();
}
const std::vector<unsigned char>& SerializedTransaction::peekSigningPubKey() const
{
const STVariableLength* v=
dynamic_cast<const STVariableLength*>(mMiddleTxn.peekAtPIndex(TransactionISigningPubKey));
if (!v) throw std::runtime_error("corrupt transaction");
return v->peekValue();
}
std::vector<unsigned char>& SerializedTransaction::peekSigningPubKey()
{
STVariableLength* v = dynamic_cast<STVariableLength*>(mMiddleTxn.getPIndex(TransactionISigningPubKey));
if (!v) throw std::runtime_error("corrupt transaction");
return v->peekValue();
}
const NewcoinAddress& SerializedTransaction::setSigningPubKey(const NewcoinAddress& naSignPubKey)
{
mSignPubKey = naSignPubKey;
STVariableLength* v = dynamic_cast<STVariableLength*>(mMiddleTxn.getPIndex(TransactionISigningPubKey));
if (!v) throw std::runtime_error("corrupt transaction");
v->setValue(mSignPubKey.getAccountPublic());
return mSignPubKey;
}
const NewcoinAddress& SerializedTransaction::setSourceAccount(const NewcoinAddress& naSource)
{
mSourceAccount = naSource;
STAccount* v = dynamic_cast<STAccount*>(mMiddleTxn.getPIndex(TransactionISourceID));
if (!v) throw std::runtime_error("corrupt transaction");
v->setValueNCA(mSourceAccount);
return mSourceAccount;
}
uint160 SerializedTransaction::getITFieldAccount(SOE_Field field) const
uint160 SerializedTransaction::getITFieldAccount(SField::ref field) const
{
uint160 r;
const SerializedType* st = mInnerTxn.peekAtPField(field);
if (!st) return r;
const STAccount* ac = dynamic_cast<const STAccount*>(st);
if (!ac) return r;
ac->getValueH160(r);
const STAccount* ac = dynamic_cast<const STAccount*>(peekAtPField(field));
if (ac)
ac->getValueH160(r);
return r;
}
int SerializedTransaction::getITFieldIndex(SOE_Field field) const
{
return mInnerTxn.getFieldIndex(field);
}
int SerializedTransaction::getITFieldCount() const
{
return mInnerTxn.getCount();
}
bool SerializedTransaction::getITFieldPresent(SOE_Field field) const
{
return mInnerTxn.isFieldPresent(field);
}
const SerializedType& SerializedTransaction::peekITField(SOE_Field field) const
{
return mInnerTxn.peekAtField(field);
}
SerializedType& SerializedTransaction::getITField(SOE_Field field)
{
return mInnerTxn.getField(field);
}
void SerializedTransaction::makeITFieldPresent(SOE_Field field)
{
mInnerTxn.makeFieldPresent(field);
}
void SerializedTransaction::makeITFieldAbsent(SOE_Field field)
{
return mInnerTxn.makeFieldAbsent(field);
}
Json::Value SerializedTransaction::getJson(int options) const
{
Json::Value ret = Json::objectValue;
Json::Value ret = STObject::getJson(0);
ret["id"] = getTransactionID().GetHex();
ret["signature"] = mSignature.getText();
Json::Value middle = mMiddleTxn.getJson(options);
middle["type"] = mFormat->t_name;
ret["middle"] = middle;
ret["inner"] = mInnerTxn.getJson(options);
return ret;
}

View File

@@ -17,17 +17,13 @@
#define TXN_SQL_INCLUDED 'I'
#define TXN_SQL_UNKNOWN 'U'
class SerializedTransaction : public SerializedType
class SerializedTransaction : public STObject
{
public:
typedef boost::shared_ptr<SerializedTransaction> pointer;
protected:
NewcoinAddress mSignPubKey;
NewcoinAddress mSourceAccount;
TransactionType mType;
STVariableLength mSignature;
STObject mMiddleTxn, mInnerTxn;
const TransactionFormat* mFormat;
SerializedTransaction* duplicate() const { return new SerializedTransaction(*this); }
@@ -37,84 +33,72 @@ public:
SerializedTransaction(TransactionType type);
// STObject functions
int getLength() const;
SerializedTypeID getSType() const { return STI_TRANSACTION; }
std::string getFullText() const;
std::string getText() const;
void add(Serializer& s) const;
virtual bool isEquivalent(const SerializedType& t) const;
// outer transaction functions / signature functions
std::vector<unsigned char> getSignature() const;
const std::vector<unsigned char>& peekSignature() const;
void setSignature(const std::vector<unsigned char>& s);
void setSignature(const std::vector<unsigned char>& s) { setValueFieldVL(sfTxnSignature, s); }
uint256 getSigningHash() const;
TransactionType getTxnType() const { return mType; }
STAmount getTransactionFee() const;
void setTransactionFee(const STAmount& fee);
TransactionType getTxnType() const { return mType; }
STAmount getTransactionFee() const { return getValueFieldAmount(sfFee); }
void setTransactionFee(const STAmount& fee) { setValueFieldAmount(sfFee, fee); }
const NewcoinAddress& getSourceAccount() const { return mSourceAccount; }
std::vector<unsigned char> getSigningPubKey() const;
const std::vector<unsigned char>& peekSigningPubKey() const;
std::vector<unsigned char>& peekSigningPubKey();
const NewcoinAddress& setSigningPubKey(const NewcoinAddress& naSignPubKey);
const NewcoinAddress& setSourceAccount(const NewcoinAddress& naSource);
NewcoinAddress getSourceAccount() const { return getValueFieldAccount(sfAccount); }
std::vector<unsigned char> getSigningPubKey() const { return getValueFieldVL(sfSigningPubKey); }
void setSigningPubKey(const NewcoinAddress& naSignPubKey);
void setSourceAccount(const NewcoinAddress& naSource);
std::string getTransactionType() const { return mFormat->t_name; }
// inner transaction functions
uint32 getFlags() const { return mInnerTxn.getFlags(); }
void setFlag(uint32 v) { mInnerTxn.setFlag(v); }
void clearFlag(uint32 v) { mInnerTxn.clearFlag(v); }
uint32 getSequence() const { return getValueFieldU32(sfSequence); }
void setSequence(uint32 seq) { return setValueFieldU32(sfSequence, seq); }
uint32 getSequence() const;
void setSequence(uint32);
// inner transaction field functions (OBSOLETE - use STObject functions)
int getITFieldIndex(SField::ref field) const { return getFieldIndex(field); }
const SerializedType& peekITField(SField::ref field) const { return peekAtField(field); }
SerializedType& getITField(SField::ref field) { return getField(field); }
// inner transaction field functions
int getITFieldIndex(SOE_Field field) const;
int getITFieldCount() const;
const SerializedType& peekITField(SOE_Field field) const;
SerializedType& getITField(SOE_Field field);
// inner transaction field value functions (OBSOLETE - use STObject functions)
std::string getITFieldString(SField::ref field) const { return getFieldString(field); }
unsigned char getITFieldU8(SField::ref field) const { return getValueFieldU8(field); }
uint16 getITFieldU16(SField::ref field) const { return getValueFieldU16(field); }
uint32 getITFieldU32(SField::ref field) const { return getValueFieldU32(field); }
uint64 getITFieldU64(SField::ref field) const { return getValueFieldU64(field); }
uint128 getITFieldH128(SField::ref field) const { return getValueFieldH128(field); }
uint160 getITFieldH160(SField::ref field) const { return getValueFieldH160(field); }
uint160 getITFieldAccount(SField::ref field) const;
uint256 getITFieldH256(SField::ref field) const { return getValueFieldH256(field); }
std::vector<unsigned char> getITFieldVL(SField::ref field) const { return getValueFieldVL(field); }
std::vector<TaggedListItem> getITFieldTL(SField::ref field) const { return getValueFieldTL(field); }
STAmount getITFieldAmount(SField::ref field) const { return getValueFieldAmount(field); }
STPathSet getITFieldPathSet(SField::ref field) const { return getValueFieldPathSet(field); }
// inner transaction field value functions
std::string getITFieldString(SOE_Field field) const { return mInnerTxn.getFieldString(field); }
unsigned char getITFieldU8(SOE_Field field) const { return mInnerTxn.getValueFieldU8(field); }
uint16 getITFieldU16(SOE_Field field) const { return mInnerTxn.getValueFieldU16(field); }
uint32 getITFieldU32(SOE_Field field) const { return mInnerTxn.getValueFieldU32(field); }
uint64 getITFieldU64(SOE_Field field) const { return mInnerTxn.getValueFieldU64(field); }
uint128 getITFieldH128(SOE_Field field) const { return mInnerTxn.getValueFieldH128(field); }
uint160 getITFieldH160(SOE_Field field) const { return mInnerTxn.getValueFieldH160(field); }
uint160 getITFieldAccount(SOE_Field field) const;
uint256 getITFieldH256(SOE_Field field) const { return mInnerTxn.getValueFieldH256(field); }
std::vector<unsigned char> getITFieldVL(SOE_Field field) const { return mInnerTxn.getValueFieldVL(field); }
std::vector<TaggedListItem> getITFieldTL(SOE_Field field) const { return mInnerTxn.getValueFieldTL(field); }
STAmount getITFieldAmount(SOE_Field field) const { return mInnerTxn.getValueFieldAmount(field); }
STPathSet getITFieldPathSet(SOE_Field field) const { return mInnerTxn.getValueFieldPathSet(field); }
void setITFieldU8(SField::ref field, unsigned char v) { return setValueFieldU8(field, v); }
void setITFieldU16(SField::ref field, uint16 v) { return setValueFieldU16(field, v); }
void setITFieldU32(SField::ref field, uint32 v) { return setValueFieldU32(field, v); }
void setITFieldU64(SField::ref field, uint32 v) { return setValueFieldU64(field, v); }
void setITFieldH128(SField::ref field, const uint128& v) { return setValueFieldH128(field, v); }
void setITFieldH160(SField::ref field, const uint160& v) { return setValueFieldH160(field, v); }
void setITFieldH256(SField::ref field, const uint256& v) { return setValueFieldH256(field, v); }
void setITFieldVL(SField::ref field, const std::vector<unsigned char>& v)
{ return setValueFieldVL(field, v); }
void setITFieldTL(SField::ref field, const std::vector<TaggedListItem>& v)
{ return setValueFieldTL(field, v); }
void setITFieldAccount(SField::ref field, const uint160& v)
{ return setValueFieldAccount(field, v); }
void setITFieldAccount(SField::ref field, const NewcoinAddress& v)
{ return setValueFieldAccount(field, v); }
void setITFieldAmount(SField::ref field, const STAmount& v)
{ return setValueFieldAmount(field, v); }
void setITFieldPathSet(SField::ref field, const STPathSet& v)
{ return setValueFieldPathSet(field, v); }
void setITFieldU8(SOE_Field field, unsigned char v) { return mInnerTxn.setValueFieldU8(field, v); }
void setITFieldU16(SOE_Field field, uint16 v) { return mInnerTxn.setValueFieldU16(field, v); }
void setITFieldU32(SOE_Field field, uint32 v) { return mInnerTxn.setValueFieldU32(field, v); }
void setITFieldU64(SOE_Field field, uint32 v) { return mInnerTxn.setValueFieldU64(field, v); }
void setITFieldH128(SOE_Field field, const uint128& v) { return mInnerTxn.setValueFieldH128(field, v); }
void setITFieldH160(SOE_Field field, const uint160& v) { return mInnerTxn.setValueFieldH160(field, v); }
void setITFieldH256(SOE_Field field, const uint256& v) { return mInnerTxn.setValueFieldH256(field, v); }
void setITFieldVL(SOE_Field field, const std::vector<unsigned char>& v)
{ return mInnerTxn.setValueFieldVL(field, v); }
void setITFieldTL(SOE_Field field, const std::vector<TaggedListItem>& v)
{ return mInnerTxn.setValueFieldTL(field, v); }
void setITFieldAccount(SOE_Field field, const uint160& v)
{ return mInnerTxn.setValueFieldAccount(field, v); }
void setITFieldAccount(SOE_Field field, const NewcoinAddress& v)
{ return mInnerTxn.setValueFieldAccount(field, v); }
void setITFieldAmount(SOE_Field field, const STAmount& v)
{ return mInnerTxn.setValueFieldAmount(field, v); }
void setITFieldPathSet(SOE_Field field, const STPathSet& v)
{ return mInnerTxn.setValueFieldPathSet(field, v); }
// optional field functions
bool getITFieldPresent(SOE_Field field) const;
void makeITFieldPresent(SOE_Field field);
void makeITFieldAbsent(SOE_Field field);
// optional field functions (OBSOLETE - use STObject functions)
bool getITFieldPresent(SField::ref field) const { return isFieldPresent(field); }
void makeITFieldPresent(SField::ref field) { makeFieldPresent(field); }
void makeITFieldAbsent(SField::ref field) { makeFieldAbsent(field); }
std::vector<NewcoinAddress> getAffectedAccounts() const;
@@ -122,7 +106,7 @@ public:
virtual Json::Value getJson(int options) const;
bool sign(const NewcoinAddress& naAccountPrivate);
void sign(const NewcoinAddress& naAccountPrivate);
bool checkSign(const NewcoinAddress& naAccountPublic) const;
// SQL Functions

View File

@@ -5,6 +5,8 @@
#include "SerializedTypes.h"
#include "SerializedObject.h"
#include "TransactionFormats.h"
#include "LedgerFormats.h"
#include "FieldNames.h"
#include "Log.h"
#include "NewcoinAddress.h"
#include "utils.h"
@@ -17,9 +19,9 @@ std::string SerializedType::getFullText() const
std::string ret;
if (getSType() != STI_NOTPRESENT)
{
if(name != NULL)
if(fName->hasName())
{
ret = name;
ret = fName->fieldName;
ret += " = ";
}
ret += getText();
@@ -27,7 +29,7 @@ std::string SerializedType::getFullText() const
return ret;
}
STUInt8* STUInt8::construct(SerializerIterator& u, const char *name)
STUInt8* STUInt8::construct(SerializerIterator& u, SField::ref name)
{
return new STUInt8(name, u.get8());
}
@@ -43,13 +45,25 @@ bool STUInt8::isEquivalent(const SerializedType& t) const
return v && (value == v->value);
}
STUInt16* STUInt16::construct(SerializerIterator& u, const char *name)
STUInt16* STUInt16::construct(SerializerIterator& u, SField::ref name)
{
return new STUInt16(name, u.get16());
}
std::string STUInt16::getText() const
{
if (getFName() == sfLedgerEntryType)
{
LedgerEntryFormat *f = getLgrFormat(value);
if (f != NULL)
return f->t_name;
}
if (getFName() == sfTransactionType)
{
TransactionFormat *f = getTxnFormat(value);
if (f != NULL)
return f->t_name;
}
return boost::lexical_cast<std::string>(value);
}
@@ -59,7 +73,7 @@ bool STUInt16::isEquivalent(const SerializedType& t) const
return v && (value == v->value);
}
STUInt32* STUInt32::construct(SerializerIterator& u, const char *name)
STUInt32* STUInt32::construct(SerializerIterator& u, SField::ref name)
{
return new STUInt32(name, u.get32());
}
@@ -75,7 +89,7 @@ bool STUInt32::isEquivalent(const SerializedType& t) const
return v && (value == v->value);
}
STUInt64* STUInt64::construct(SerializerIterator& u, const char *name)
STUInt64* STUInt64::construct(SerializerIterator& u, SField::ref name)
{
return new STUInt64(name, u.get64());
}
@@ -91,7 +105,7 @@ bool STUInt64::isEquivalent(const SerializedType& t) const
return v && (value == v->value);
}
STHash128* STHash128::construct(SerializerIterator& u, const char *name)
STHash128* STHash128::construct(SerializerIterator& u, SField::ref name)
{
return new STHash128(name, u.get128());
}
@@ -107,7 +121,7 @@ bool STHash128::isEquivalent(const SerializedType& t) const
return v && (value == v->value);
}
STHash160* STHash160::construct(SerializerIterator& u, const char *name)
STHash160* STHash160::construct(SerializerIterator& u, SField::ref name)
{
return new STHash160(name, u.get160());
}
@@ -123,7 +137,7 @@ bool STHash160::isEquivalent(const SerializedType& t) const
return v && (value == v->value);
}
STHash256* STHash256::construct(SerializerIterator& u, const char *name)
STHash256* STHash256::construct(SerializerIterator& u, SField::ref name)
{
return new STHash256(name, u.get256());
}
@@ -139,7 +153,7 @@ bool STHash256::isEquivalent(const SerializedType& t) const
return v && (value == v->value);
}
STVariableLength::STVariableLength(SerializerIterator& st, const char *name) : SerializedType(name)
STVariableLength::STVariableLength(SerializerIterator& st, SField::ref name) : SerializedType(name)
{
value = st.getVL();
}
@@ -149,16 +163,11 @@ std::string STVariableLength::getText() const
return strHex(value);
}
STVariableLength* STVariableLength::construct(SerializerIterator& u, const char *name)
STVariableLength* STVariableLength::construct(SerializerIterator& u, SField::ref name)
{
return new STVariableLength(name, u.getVL());
}
int STVariableLength::getLength() const
{
return Serializer::encodeLengthLength(value.size()) + value.size();
}
bool STVariableLength::isEquivalent(const SerializedType& t) const
{
const STVariableLength* v = dynamic_cast<const STVariableLength*>(&t);
@@ -176,7 +185,7 @@ std::string STAccount::getText() const
return a.humanAccountID();
}
STAccount* STAccount::construct(SerializerIterator& u, const char *name)
STAccount* STAccount::construct(SerializerIterator& u, SField::ref name)
{
return new STAccount(name, u.getVL());
}
@@ -186,7 +195,7 @@ STAccount* STAccount::construct(SerializerIterator& u, const char *name)
//
// Return a new object from a SerializerIterator.
STVector256* STVector256::construct(SerializerIterator& u, const char *name)
STVector256* STVector256::construct(SerializerIterator& u, SField::ref name)
{
std::vector<unsigned char> data = u.getVL();
std::vector<uint256> value;
@@ -255,7 +264,7 @@ void STAccount::setValueNCA(const NewcoinAddress& nca)
setValueH160(nca.getAccountID());
}
STPathSet* STPathSet::construct(SerializerIterator& s, const char *name)
STPathSet* STPathSet::construct(SerializerIterator& s, SField::ref name)
{
std::vector<STPath> paths;
std::vector<STPathElement> path;
@@ -342,18 +351,6 @@ int STPath::getSerializeSize() const
return iBytes;
}
int STPathSet::getLength() const
{
int iBytes = 0;
BOOST_FOREACH(const STPath& spPath, value)
{
iBytes += spPath.getSerializeSize();
}
return iBytes ? iBytes : 1;
}
Json::Value STPath::getJson(int) const
{
Json::Value ret(Json::arrayValue);

View File

@@ -8,28 +8,13 @@
#include "uint256.h"
#include "Serializer.h"
#include "FieldNames.h"
enum SerializedTypeID
{
// special types
STI_DONE = -1,
STI_NOTPRESENT = 0,
#define TYPE(name, field, value) STI_##field = value,
#define FIELD(name, field, value)
#include "SerializeProto.h"
#undef TYPE
#undef FIELD
// high level types
STI_TRANSACTION = 100001,
STI_LEDGERENTRY = 100002
};
enum PathFlags
{
PF_END = 0x00, // End of current path & path list.
PF_BOUNDRY = 0xFF, // End of current path & new path follows.
PF_BOUNDARY = 0xFF, // End of current path & new path follows.
PF_ACCOUNT = 0x01,
PF_OFFER = 0x02,
@@ -48,24 +33,25 @@ enum PathFlags
class SerializedType
{
protected:
const char* name;
SField::ptr fName;
virtual SerializedType* duplicate() const { return new SerializedType(name); }
virtual SerializedType* duplicate() const { return new SerializedType(*fName); }
SerializedType(SField::ptr n) : fName(n) { assert(fName); }
public:
SerializedType() : name(NULL) { ; }
SerializedType(const char* n) : name(n) { ; }
SerializedType(const SerializedType& n) : name(n.name) { ; }
SerializedType() : fName(&sfGeneric) { ; }
SerializedType(SField::ref n) : fName(&n) { assert(fName); }
SerializedType(const SerializedType& n) : fName(n.fName) { ; }
virtual ~SerializedType() { ; }
static std::auto_ptr<SerializedType> deserialize(const char* name)
static std::auto_ptr<SerializedType> deserialize(SField::ref name)
{ return std::auto_ptr<SerializedType>(new SerializedType(name)); }
void setName(const char* n) { name=n; }
const char *getName() const { return name; }
void setFName(SField::ref n) { fName = &n; assert(fName); }
SField::ref getFName() const { return *fName; }
std::string getName() const { return fName->fieldName; }
virtual int getLength() const { return 0; }
virtual SerializedTypeID getSType() const { return STI_NOTPRESENT; }
std::auto_ptr<SerializedType> clone() const { return std::auto_ptr<SerializedType>(duplicate()); }
@@ -75,13 +61,15 @@ public:
virtual Json::Value getJson(int) const
{ return getText(); }
virtual void add(Serializer& s) const { return; }
virtual void add(Serializer& s) const { ; }
virtual bool isEquivalent(const SerializedType& t) const
{ assert(getSType() == STI_NOTPRESENT); return t.getSType() == STI_NOTPRESENT; }
void addFieldID(Serializer& s) const { s.addFieldID(fName->fieldType, fName->fieldValue); }
SerializedType& operator=(const SerializedType& t)
{ name = (name == NULL) ? t.name : name; return *this; }
{ if (!fName->fieldCode) fName = t.fName; return *this; }
bool operator==(const SerializedType& t) const
{ return (getSType() == t.getSType()) && isEquivalent(t); }
bool operator!=(const SerializedType& t) const
@@ -97,23 +85,22 @@ class STUInt8 : public SerializedType
protected:
unsigned char value;
STUInt8* duplicate() const { return new STUInt8(name, value); }
static STUInt8* construct(SerializerIterator&, const char* name = NULL);
STUInt8* duplicate() const { return new STUInt8(*this); }
static STUInt8* construct(SerializerIterator&, SField::ref f);
public:
STUInt8(unsigned char v=0) : value(v) { ; }
STUInt8(const char* n, unsigned char v=0) : SerializedType(n), value(v) { ; }
static std::auto_ptr<SerializedType> deserialize(SerializerIterator& sit, const char* name)
STUInt8(unsigned char v = 0) : value(v) { ; }
STUInt8(SField::ref n, unsigned char v = 0) : SerializedType(n), value(v) { ; }
static std::auto_ptr<SerializedType> deserialize(SerializerIterator& sit, SField::ref name)
{ return std::auto_ptr<SerializedType>(construct(sit, name)); }
int getLength() const { return 1; }
SerializedTypeID getSType() const { return STI_UINT8; }
std::string getText() const;
void add(Serializer& s) const { s.add8(value); }
unsigned char getValue() const { return value; }
void setValue(unsigned char v) { value=v; }
void setValue(unsigned char v) { value = v; }
operator unsigned char() const { return value; }
virtual bool isEquivalent(const SerializedType& t) const;
@@ -124,17 +111,16 @@ class STUInt16 : public SerializedType
protected:
uint16 value;
STUInt16* duplicate() const { return new STUInt16(name, value); }
static STUInt16* construct(SerializerIterator&, const char* name = NULL);
STUInt16* duplicate() const { return new STUInt16(*this); }
static STUInt16* construct(SerializerIterator&, SField::ref name);
public:
STUInt16(uint16 v=0) : value(v) { ; }
STUInt16(const char* n, uint16 v=0) : SerializedType(n), value(v) { ; }
static std::auto_ptr<SerializedType> deserialize(SerializerIterator& sit, const char* name)
STUInt16(uint16 v = 0) : value(v) { ; }
STUInt16(SField::ref n, uint16 v = 0) : SerializedType(n), value(v) { ; }
static std::auto_ptr<SerializedType> deserialize(SerializerIterator& sit, SField::ref name)
{ return std::auto_ptr<SerializedType>(construct(sit, name)); }
int getLength() const { return 2; }
SerializedTypeID getSType() const { return STI_UINT16; }
std::string getText() const;
void add(Serializer& s) const { s.add16(value); }
@@ -151,17 +137,16 @@ class STUInt32 : public SerializedType
protected:
uint32 value;
STUInt32* duplicate() const { return new STUInt32(name, value); }
static STUInt32* construct(SerializerIterator&, const char* name = NULL);
STUInt32* duplicate() const { return new STUInt32(*this); }
static STUInt32* construct(SerializerIterator&, SField::ref name);
public:
STUInt32(uint32 v=0) : value(v) { ; }
STUInt32(const char* n, uint32 v=0) : SerializedType(n), value(v) { ; }
static std::auto_ptr<SerializedType> deserialize(SerializerIterator& sit, const char* name)
STUInt32(uint32 v = 0) : value(v) { ; }
STUInt32(SField::ref n, uint32 v = 0) : SerializedType(n), value(v) { ; }
static std::auto_ptr<SerializedType> deserialize(SerializerIterator& sit, SField::ref name)
{ return std::auto_ptr<SerializedType>(construct(sit, name)); }
int getLength() const { return 4; }
SerializedTypeID getSType() const { return STI_UINT32; }
std::string getText() const;
void add(Serializer& s) const { s.add32(value); }
@@ -178,17 +163,16 @@ class STUInt64 : public SerializedType
protected:
uint64 value;
STUInt64* duplicate() const { return new STUInt64(name, value); }
static STUInt64* construct(SerializerIterator&, const char* name = NULL);
STUInt64* duplicate() const { return new STUInt64(*this); }
static STUInt64* construct(SerializerIterator&, SField::ref name);
public:
STUInt64(uint64 v=0) : value(v) { ; }
STUInt64(const char* n, uint64 v=0) : SerializedType(n), value(v) { ; }
static std::auto_ptr<SerializedType> deserialize(SerializerIterator& sit, const char* name)
STUInt64(uint64 v = 0) : value(v) { ; }
STUInt64(SField::ref n, uint64 v = 0) : SerializedType(n), value(v) { ; }
static std::auto_ptr<SerializedType> deserialize(SerializerIterator& sit, SField::ref name)
{ return std::auto_ptr<SerializedType>(construct(sit, name)); }
int getLength() const { return 8; }
SerializedTypeID getSType() const { return STI_UINT64; }
std::string getText() const;
void add(Serializer& s) const { s.add64(value); }
@@ -224,7 +208,7 @@ protected:
void canonicalize();
STAmount* duplicate() const { return new STAmount(*this); }
static STAmount* construct(SerializerIterator&, const char* name = NULL);
static STAmount* construct(SerializerIterator&, SField::ref name);
static const int cMinOffset = -96, cMaxOffset = 80;
static const uint64 cMinValue = 1000000000000000ull, cMaxValue = 9999999999999999ull;
@@ -234,13 +218,15 @@ protected:
STAmount(bool isNeg, uint64 value) : mValue(value), mOffset(0), mIsNative(true), mIsNegative(isNeg) { ; }
STAmount(const char *name, uint64 value, bool isNegative)
STAmount(SField::ref name, uint64 value, bool isNegative)
: SerializedType(name), mValue(value), mOffset(0), mIsNative(true), mIsNegative(isNegative)
{ ; }
STAmount(const char *n, const uint160& cur, const uint160& iss, uint64 val, int off, bool isNat, bool isNeg)
: SerializedType(n), mCurrency(cur), mIssuer(iss), mValue(val), mOffset(off),
STAmount(SField::ref name, const uint160& cur, const uint160& iss, uint64 val, int off, bool isNat, bool isNeg)
: SerializedType(name), mCurrency(cur), mIssuer(iss), mValue(val), mOffset(off),
mIsNative(isNat), mIsNegative(isNeg) { ; }
STAmount(SField::ref name, const Json::Value& value);
uint64 toUInt64() const;
static uint64 muldiv(uint64, uint64, uint64);
@@ -248,38 +234,33 @@ public:
static uint64 uRateOne;
STAmount(uint64 v = 0, bool isNeg = false) : mValue(v), mOffset(0), mIsNative(true), mIsNegative(isNeg)
{ if (v==0) mIsNegative = false; }
{ if (v == 0) mIsNegative = false; }
STAmount(const char* n, uint64 v = 0)
STAmount(SField::ref n, uint64 v = 0)
: SerializedType(n), mValue(v), mOffset(0), mIsNative(true), mIsNegative(false)
{ ; }
STAmount(const uint160& uCurrencyID, const uint160& uIssuerID, uint64 uV=0, int iOff=0, bool bNegative=false)
STAmount(const uint160& uCurrencyID, const uint160& uIssuerID, uint64 uV = 0, int iOff = 0, bool bNegative = false)
: mCurrency(uCurrencyID), mIssuer(uIssuerID), mValue(uV), mOffset(iOff), mIsNegative(bNegative)
{ canonicalize(); }
// YYY This should probably require issuer too.
STAmount(const char* n, const uint160& currency, const uint160& issuer,
STAmount(SField::ref n, const uint160& currency, const uint160& issuer,
uint64 v = 0, int off = 0, bool isNeg = false) :
SerializedType(n), mCurrency(currency), mIssuer(issuer), mValue(v), mOffset(off), mIsNegative(isNeg)
{ canonicalize(); }
STAmount(const char* n, int64 v);
STAmount(SField::ref n, int64 v);
static std::auto_ptr<SerializedType> deserialize(SerializerIterator& sit, const char* name)
static std::auto_ptr<SerializedType> deserialize(SerializerIterator& sit, SField::ref name)
{ return std::auto_ptr<SerializedType>(construct(sit, name)); }
static STAmount saFromRate(uint64 uRate = 0)
{
return STAmount(CURRENCY_ONE, ACCOUNT_ONE, uRate, -9, false);
}
{ return STAmount(CURRENCY_ONE, ACCOUNT_ONE, uRate, -9, false); }
static STAmount saFromSigned(const uint160& uCurrencyID, const uint160& uIssuerID, int64 iV=0, int iOff=0)
{
return STAmount(uCurrencyID, uIssuerID, iV < 0 ? -iV : iV, iOff, iV < 0);
}
static STAmount saFromSigned(const uint160& uCurrencyID, const uint160& uIssuerID, int64 iV = 0, int iOff = 0)
{ return STAmount(uCurrencyID, uIssuerID, iV < 0 ? -iV : iV, iOff, iV < 0); }
int getLength() const { return mIsNative ? 8 : 28; }
SerializedTypeID getSType() const { return STI_AMOUNT; }
std::string getText() const;
std::string getRaw() const;
@@ -377,7 +358,7 @@ public:
// Native currency conversions, to/from display format
static uint64 convertToDisplayAmount(const STAmount& internalAmount, uint64 totalNow, uint64 totalInit);
static STAmount convertToInternalAmount(uint64 displayAmount, uint64 totalNow, uint64 totalInit,
const char* name = NULL);
SField::ref name = sfGeneric);
static std::string createHumanCurrency(const uint160& uCurrency);
static STAmount deserialize(SerializerIterator&);
@@ -394,19 +375,18 @@ class STHash128 : public SerializedType
protected:
uint128 value;
STHash128* duplicate() const { return new STHash128(name, value); }
static STHash128* construct(SerializerIterator&, const char* name = NULL);
STHash128* duplicate() const { return new STHash128(*this); }
static STHash128* construct(SerializerIterator&, SField::ref name);
public:
STHash128(const uint128& v) : value(v) { ; }
STHash128(const char* n, const uint128& v) : SerializedType(n), value(v) { ; }
STHash128(const char* n) : SerializedType(n) { ; }
STHash128(SField::ref n, const uint128& v) : SerializedType(n), value(v) { ; }
STHash128(SField::ref n) : SerializedType(n) { ; }
STHash128() { ; }
static std::auto_ptr<SerializedType> deserialize(SerializerIterator& sit, const char* name)
static std::auto_ptr<SerializedType> deserialize(SerializerIterator& sit, SField::ref name)
{ return std::auto_ptr<SerializedType>(construct(sit, name)); }
int getLength() const { return 20; }
SerializedTypeID getSType() const { return STI_HASH128; }
virtual std::string getText() const;
void add(Serializer& s) const { s.add128(value); }
@@ -423,19 +403,18 @@ class STHash160 : public SerializedType
protected:
uint160 value;
STHash160* duplicate() const { return new STHash160(name, value); }
static STHash160* construct(SerializerIterator&, const char* name = NULL);
STHash160* duplicate() const { return new STHash160(*this); }
static STHash160* construct(SerializerIterator&, SField::ref name);
public:
STHash160(const uint160& v) : value(v) { ; }
STHash160(const char* n, const uint160& v) : SerializedType(n), value(v) { ; }
STHash160(const char* n) : SerializedType(n) { ; }
STHash160(SField::ref n, const uint160& v) : SerializedType(n), value(v) { ; }
STHash160(SField::ref n) : SerializedType(n) { ; }
STHash160() { ; }
static std::auto_ptr<SerializedType> deserialize(SerializerIterator& sit, const char* name)
static std::auto_ptr<SerializedType> deserialize(SerializerIterator& sit, SField::ref name)
{ return std::auto_ptr<SerializedType>(construct(sit, name)); }
int getLength() const { return 20; }
SerializedTypeID getSType() const { return STI_HASH160; }
virtual std::string getText() const;
void add(Serializer& s) const { s.add160(value); }
@@ -452,19 +431,18 @@ class STHash256 : public SerializedType
protected:
uint256 value;
STHash256* duplicate() const { return new STHash256(name, value); }
static STHash256* construct(SerializerIterator&, const char* name = NULL);
STHash256* duplicate() const { return new STHash256(*this); }
static STHash256* construct(SerializerIterator&, SField::ref);
public:
STHash256(const uint256& v) : value(v) { ; }
STHash256(const char* n, const uint256& v) : SerializedType(n), value(v) { ; }
STHash256(const char* n) : SerializedType(n) { ; }
STHash256(SField::ref n, const uint256& v) : SerializedType(n), value(v) { ; }
STHash256(SField::ref n) : SerializedType(n) { ; }
STHash256() { ; }
static std::auto_ptr<SerializedType> deserialize(SerializerIterator& sit, const char* name)
static std::auto_ptr<SerializedType> deserialize(SerializerIterator& sit, SField::ref name)
{ return std::auto_ptr<SerializedType>(construct(sit, name)); }
int getLength() const { return 32; }
SerializedTypeID getSType() const { return STI_HASH256; }
std::string getText() const;
void add(Serializer& s) const { s.add256(value); }
@@ -481,20 +459,19 @@ class STVariableLength : public SerializedType
protected:
std::vector<unsigned char> value;
virtual STVariableLength* duplicate() const { return new STVariableLength(name, value); }
static STVariableLength* construct(SerializerIterator&, const char* name = NULL);
virtual STVariableLength* duplicate() const { return new STVariableLength(*this); }
static STVariableLength* construct(SerializerIterator&, SField::ref);
public:
STVariableLength(const std::vector<unsigned char>& v) : value(v) { ; }
STVariableLength(const char* n, const std::vector<unsigned char>& v) : SerializedType(n), value(v) { ; }
STVariableLength(const char* n) : SerializedType(n) { ; }
STVariableLength(SerializerIterator&, const char* name = NULL);
STVariableLength(SField::ref n, const std::vector<unsigned char>& v) : SerializedType(n), value(v) { ; }
STVariableLength(SField::ref n) : SerializedType(n) { ; }
STVariableLength(SerializerIterator&, SField::ref name = sfGeneric);
STVariableLength() { ; }
static std::auto_ptr<SerializedType> deserialize(SerializerIterator& sit, const char* name)
static std::auto_ptr<SerializedType> deserialize(SerializerIterator& sit, SField::ref name)
{ return std::auto_ptr<SerializedType>(construct(sit, name)); }
int getLength() const;
virtual SerializedTypeID getSType() const { return STI_VL; }
virtual std::string getText() const;
void add(Serializer& s) const { s.addVL(value); }
@@ -511,16 +488,16 @@ public:
class STAccount : public STVariableLength
{
protected:
virtual STAccount* duplicate() const { return new STAccount(name, value); }
static STAccount* construct(SerializerIterator&, const char* name = NULL);
virtual STAccount* duplicate() const { return new STAccount(*this); }
static STAccount* construct(SerializerIterator&, SField::ref);
public:
STAccount(const std::vector<unsigned char>& v) : STVariableLength(v) { ; }
STAccount(const char* n, const std::vector<unsigned char>& v) : STVariableLength(n, v) { ; }
STAccount(const char* n) : STVariableLength(n) { ; }
STAccount(SField::ref n, const std::vector<unsigned char>& v) : STVariableLength(n, v) { ; }
STAccount(SField::ref n) : STVariableLength(n) { ; }
STAccount() { ; }
static std::auto_ptr<SerializedType> deserialize(SerializerIterator& sit, const char* name)
static std::auto_ptr<SerializedType> deserialize(SerializerIterator& sit, SField::ref name)
{ return std::auto_ptr<SerializedType>(construct(sit, name)); }
SerializedTypeID getSType() const { return STI_ACCOUNT; }
@@ -649,19 +626,18 @@ class STPathSet : public SerializedType
protected:
std::vector<STPath> value;
STPathSet* duplicate() const { return new STPathSet(name, value); }
static STPathSet* construct(SerializerIterator&, const char* name = NULL);
STPathSet* duplicate() const { return new STPathSet(*this); }
static STPathSet* construct(SerializerIterator&, SField::ref);
public:
STPathSet() { ; }
STPathSet(const char* n) : SerializedType(n) { ; }
STPathSet(SField::ref n) : SerializedType(n) { ; }
STPathSet(const std::vector<STPath>& v) : value(v) { ; }
STPathSet(const char* n, const std::vector<STPath>& v) : SerializedType(n), value(v) { ; }
static std::auto_ptr<SerializedType> deserialize(SerializerIterator& sit, const char* name)
STPathSet(SField::ref n, const std::vector<STPath>& v) : SerializedType(n), value(v) { ; }
static std::auto_ptr<SerializedType> deserialize(SerializerIterator& sit, SField::ref name)
{ return std::auto_ptr<SerializedType>(construct(sit, name)); }
int getLength() const;
// std::string getText() const;
void add(Serializer& s) const;
virtual Json::Value getJson(int) const;
@@ -722,20 +698,19 @@ class STVector256 : public SerializedType
protected:
std::vector<uint256> mValue;
STVector256* duplicate() const { return new STVector256(name, mValue); }
static STVector256* construct(SerializerIterator&, const char* name = NULL);
STVector256* duplicate() const { return new STVector256(*this); }
static STVector256* construct(SerializerIterator&, SField::ref);
public:
STVector256() { ; }
STVector256(const char* n) : SerializedType(n) { ; }
STVector256(const char* n, const std::vector<uint256>& v) : SerializedType(n), mValue(v) { ; }
STVector256(SField::ref n) : SerializedType(n) { ; }
STVector256(SField::ref n, const std::vector<uint256>& v) : SerializedType(n), mValue(v) { ; }
STVector256(const std::vector<uint256>& vector) : mValue(vector) { ; }
SerializedTypeID getSType() const { return STI_VECTOR256; }
int getLength() const { return Serializer::lengthVL(mValue.size() * (256 / 8)); }
void add(Serializer& s) const;
static std::auto_ptr<SerializedType> deserialize(SerializerIterator& sit, const char* name)
static std::auto_ptr<SerializedType> deserialize(SerializerIterator& sit, SField::ref name)
{ return std::auto_ptr<SerializedType>(construct(sit, name)); }
const std::vector<uint256>& peekValue() const { return mValue; }

View File

@@ -4,29 +4,33 @@
#include "HashPrefixes.h"
SOElement SerializedValidation::sValidationFormat[] = {
{ sfFlags, "Flags", STI_UINT32, SOE_FLAGS, 0 },
{ sfLedgerHash, "LedgerHash", STI_HASH256, SOE_REQUIRED, 0 },
{ sfSigningTime, "SignTime", STI_UINT32, SOE_REQUIRED, 0 },
{ sfSigningKey, "SigningKey", STI_VL, SOE_REQUIRED, 0 },
{ sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 },
{ sfFlags, SOE_REQUIRED },
{ sfLedgerHash, SOE_REQUIRED },
{ sfLedgerSequence, SOE_OPTIONAL },
{ sfCloseTime, SOE_OPTIONAL },
{ sfLoadFee, SOE_OPTIONAL },
{ sfBaseFee, SOE_OPTIONAL },
{ sfSigningTime, SOE_REQUIRED },
{ sfSigningPubKey, SOE_REQUIRED },
{ sfInvalid, SOE_END }
};
const uint32 SerializedValidation::sFullFlag = 0x00010000;
SerializedValidation::SerializedValidation(SerializerIterator& sit, bool checkSignature)
: STObject(sValidationFormat, sit), mSignature(sit, "Signature"), mTrusted(false)
: STObject(sValidationFormat, sit, sfValidation), mSignature(sit, sfSignature), mTrusted(false)
{
if (checkSignature && !isValid()) throw std::runtime_error("Invalid validation");
}
SerializedValidation::SerializedValidation(const uint256& ledgerHash, uint32 signTime,
const NewcoinAddress& naSeed, bool isFull)
: STObject(sValidationFormat), mSignature("Signature"), mTrusted(false)
: STObject(sValidationFormat, sfValidation), mSignature(sfSignature), mTrusted(false)
{
setValueFieldH256(sfLedgerHash, ledgerHash);
setValueFieldU32(sfSigningTime, signTime);
if (naSeed.isValid())
setValueFieldVL(sfSigningKey, NewcoinAddress::createNodePublic(naSeed).getNodePublic());
setValueFieldVL(sfSigningPubKey, NewcoinAddress::createNodePublic(naSeed).getNodePublic());
if (!isFull) setFlag(sFullFlag);
NewcoinAddress::createNodePrivate(naSeed).signNodePrivate(getSigningHash(), mSignature.peekValue());
@@ -69,7 +73,7 @@ bool SerializedValidation::isValid(const uint256& signingHash) const
{
try
{
NewcoinAddress naPublicKey = NewcoinAddress::createNodePublic(getValueFieldVL(sfSigningKey));
NewcoinAddress naPublicKey = NewcoinAddress::createNodePublic(getValueFieldVL(sfSigningPubKey));
return naPublicKey.isValid() && naPublicKey.verifyNodePublic(signingHash, mSignature.peekValue());
}
catch (...)
@@ -81,7 +85,7 @@ bool SerializedValidation::isValid(const uint256& signingHash) const
NewcoinAddress SerializedValidation::getSignerPublic() const
{
NewcoinAddress a;
a.setNodePublic(getValueFieldVL(sfSigningKey));
a.setNodePublic(getValueFieldVL(sfSigningPubKey));
return a;
}

View File

@@ -9,6 +9,7 @@
#include "key.h"
#include "uint256.h"
#include "FieldNames.h"
typedef std::pair<int, std::vector<unsigned char> > TaggedListItem;
@@ -69,6 +70,7 @@ public:
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;
@@ -92,7 +94,7 @@ public:
int getDataLength() const { return mData.size(); }
const void* getDataPtr() const { return &mData.front(); }
void* getDataPtr() { return &mData.front(); }
int getLength() { return mData.size(); }
int getLength() const { return mData.size(); }
const std::vector<unsigned char>& peekData() const { return mData; }
std::vector<unsigned char> getData() const { return mData; }
std::string getString() const { return std::string(static_cast<const char *>(getDataPtr()), size()); }
@@ -143,11 +145,12 @@ protected:
public:
SerializerIterator(const Serializer& s) : mSerializer(s), mPos(0) { ; }
void reset(void) { mPos=0; }
void reset(void) { mPos = 0; }
void setPos(int p) { mPos = p; }
const Serializer& operator*(void) { return mSerializer; }
int getPos(void) { return mPos; }
bool empty() { return mPos == mSerializer.getLength(); }
int getBytesLeft();
// get functions throw on error

View File

@@ -18,7 +18,7 @@ Transaction::Transaction(const SerializedTransaction::pointer& sit, bool bValida
{
try
{
mFromPubKey.setAccountPublic(mTransaction->peekSigningPubKey());
mFromPubKey.setAccountPublic(mTransaction->getSigningPubKey());
mTransactionID = mTransaction->getTransactionID();
mAccountFrom = mTransaction->getSourceAccount();
}
@@ -92,12 +92,7 @@ bool Transaction::sign(const NewcoinAddress& naAccountPrivate)
Log(lsWARNING) << "No private key for signing";
bResult = false;
}
else if (!getSTransaction()->sign(naAccountPrivate))
{
Log(lsWARNING) << "Failed to make signature";
assert(false);
bResult = false;
}
getSTransaction()->sign(naAccountPrivate);
if (bResult)
{

View File

@@ -105,7 +105,7 @@ TER TransactionEngine::applyTransaction(const SerializedTransaction& txn, Transa
NewcoinAddress naSigningPubKey;
if (tesSUCCESS == terResult)
naSigningPubKey = NewcoinAddress::createAccountPublic(txn.peekSigningPubKey());
naSigningPubKey = NewcoinAddress::createAccountPublic(txn.getSigningPubKey());
// Consistency: really signed.
if ((tesSUCCESS == terResult) && !isSetBit(params, tapNO_CHECK_SIGN) && !txn.checkSign(naSigningPubKey))

View File

@@ -111,6 +111,8 @@ enum TER // aka TransactionEngineResult
#define isTemMalformed(x) ((x) >= temMALFORMED && (x) < tefFAILURE)
#define isTefFailure(x) ((x) >= tefFAILURE && (x) < terRETRY)
#define isTepPartial(x) ((x) >= tepPATH_PARTIAL)
#define isTepSuccess(x) ((x) >= tesSUCCESS)
#define isTerRetry(x) ((x) >= terRETRY && (x) < tesSUCCESS)
bool transResultInfo(TER terCode, std::string& strToken, std::string& strHuman);
std::string transToken(TER terCode);

View File

@@ -1,133 +1,119 @@
#include "TransactionFormats.h"
#define S_FIELD(x) sf##x, #x
#define TF_BASE \
{ sfTransactionType, SOE_REQUIRED }, \
{ sfFlags, SOE_REQUIRED }, \
{ sfSourceTag, SOE_OPTIONAL }, \
{ sfAccount, SOE_REQUIRED }, \
{ sfSequence, SOE_REQUIRED }, \
{ sfFee, SOE_REQUIRED }, \
{ sfSigningPubKey, SOE_REQUIRED }, \
{ sfTxnSignature, SOE_OPTIONAL },
TransactionFormat InnerTxnFormats[]=
TransactionFormat InnerTxnFormats[]=
{
{ "AccountSet", ttACCOUNT_SET, {
{ S_FIELD(Flags), STI_UINT32, SOE_FLAGS, 0 },
{ S_FIELD(SourceTag), STI_UINT32, SOE_IFFLAG, 1 },
{ S_FIELD(EmailHash), STI_HASH128, SOE_IFFLAG, 2 },
{ S_FIELD(WalletLocator), STI_HASH256, SOE_IFFLAG, 4 },
{ S_FIELD(MessageKey), STI_VL, SOE_IFFLAG, 8 },
{ S_FIELD(Domain), STI_VL, SOE_IFFLAG, 16 },
{ S_FIELD(TransferRate), STI_UINT32, SOE_IFFLAG, 32 },
{ S_FIELD(PublishHash), STI_HASH256, SOE_IFFLAG, 64 },
{ S_FIELD(PublishSize), STI_UINT32, SOE_IFFLAG, 128 },
{ sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 } }
},
{ "Claim", ttCLAIM, {
{ S_FIELD(Flags), STI_UINT32, SOE_FLAGS, 0 },
{ S_FIELD(Generator), STI_VL, SOE_REQUIRED, 0 },
{ S_FIELD(PublicKey), STI_VL, SOE_REQUIRED, 0 },
{ S_FIELD(Signature), STI_VL, SOE_REQUIRED, 0 },
{ S_FIELD(SourceTag), STI_UINT32, SOE_IFFLAG, 1 },
{ sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 } }
},
{ "CreditSet", ttCREDIT_SET, {
{ S_FIELD(Flags), STI_UINT32, SOE_FLAGS, 0 },
{ S_FIELD(LimitAmount), STI_AMOUNT, SOE_REQUIRED, 0 },
{ S_FIELD(QualityIn), STI_UINT32, SOE_IFFLAG, 1 },
{ S_FIELD(QualityOut), STI_UINT32, SOE_IFFLAG, 2 },
{ S_FIELD(SourceTag), STI_UINT32, SOE_IFFLAG, 4 },
{ sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 } }
},
{ "AccountSet", ttACCOUNT_SET, { TF_BASE
{ sfEmailHash, SOE_OPTIONAL },
{ sfWalletLocator, SOE_OPTIONAL },
{ sfMessageKey, SOE_OPTIONAL },
{ sfDomain, SOE_OPTIONAL },
{ sfTransferRate, SOE_OPTIONAL },
{ sfPublishHash, SOE_OPTIONAL },
{ sfPublishSize, SOE_OPTIONAL },
{ sfInvalid, SOE_END } }
},
{ "Claim", ttCLAIM, { TF_BASE
{ sfGenerator, SOE_REQUIRED },
{ sfPublicKey, SOE_REQUIRED },
{ sfSignature, SOE_REQUIRED },
{ sfInvalid, SOE_END } }
},
{ "CreditSet", ttCREDIT_SET, { TF_BASE
{ sfLimitAmount, SOE_OPTIONAL },
{ sfQualityIn, SOE_OPTIONAL },
{ sfQualityOut, SOE_OPTIONAL },
{ sfInvalid, SOE_END } }
},
/*
{ "Invoice", ttINVOICE, {
{ S_FIELD(Flags), STI_UINT32, SOE_FLAGS, 0 },
{ S_FIELD(Target), STI_ACCOUNT, SOE_REQUIRED, 0 },
{ S_FIELD(Amount), STI_AMOUNT, SOE_REQUIRED, 0 },
{ S_FIELD(SourceTag), STI_UINT32, SOE_IFFLAG, 1 },
{ S_FIELD(Destination), STI_ACCOUNT, SOE_IFFLAG, 2 },
{ S_FIELD(Identifier), STI_VL, SOE_IFFLAG, 4 },
{ sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 } }
},
{ "Invoice", ttINVOICE, { TF_BASE
{ sfTarget, SOE_REQUIRED },
{ sfAmount, SOE_REQUIRED },
{ sfDestination, SOE_OPTIONAL },
{ sfIdentifier, SOE_OPTIONAL },
{ sfInvalid, SOE_END } }
},
*/
{ "NicknameSet", ttNICKNAME_SET, {
{ S_FIELD(Flags), STI_UINT32, SOE_FLAGS, 0 },
{ S_FIELD(Nickname), STI_HASH256, SOE_REQUIRED, 0 },
{ S_FIELD(MinimumOffer), STI_AMOUNT, SOE_IFFLAG, 1 },
{ S_FIELD(Signature), STI_VL, SOE_IFFLAG, 2 },
{ S_FIELD(SourceTag), STI_UINT32, SOE_IFFLAG, 4 },
{ sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 } }
},
{ "OfferCreate", ttOFFER_CREATE, {
{ S_FIELD(Flags), STI_UINT32, SOE_FLAGS, 0 },
{ S_FIELD(TakerPays), STI_AMOUNT, SOE_REQUIRED, 0 },
{ S_FIELD(TakerGets), STI_AMOUNT, SOE_REQUIRED, 0 },
{ S_FIELD(SourceTag), STI_UINT32, SOE_IFFLAG, 1 },
{ S_FIELD(Expiration), STI_UINT32, SOE_IFFLAG, 2 },
{ sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 } }
},
{ "OfferCancel", ttOFFER_CANCEL, {
{ S_FIELD(Flags), STI_UINT32, SOE_FLAGS, 0 },
{ S_FIELD(OfferSequence), STI_UINT32, SOE_REQUIRED, 0 },
{ S_FIELD(SourceTag), STI_UINT32, SOE_IFFLAG, 1 },
{ sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 } }
},
{ "PasswordFund", ttPASSWORD_FUND, {
{ S_FIELD(Flags), STI_UINT32, SOE_FLAGS, 0 },
{ S_FIELD(Destination), STI_ACCOUNT, SOE_REQUIRED, 0 },
{ S_FIELD(SourceTag), STI_UINT32, SOE_IFFLAG, 1 },
{ sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 } }
},
{ "PasswordSet", ttPASSWORD_SET, {
{ S_FIELD(Flags), STI_UINT32, SOE_FLAGS, 0 },
{ S_FIELD(AuthorizedKey), STI_ACCOUNT, SOE_REQUIRED, 0 },
{ S_FIELD(Generator), STI_VL, SOE_REQUIRED, 0 },
{ S_FIELD(PublicKey), STI_VL, SOE_REQUIRED, 0 },
{ S_FIELD(Signature), STI_VL, SOE_REQUIRED, 0 },
{ S_FIELD(SourceTag), STI_UINT32, SOE_IFFLAG, 1 },
{ sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 } }
},
{ "Payment", ttPAYMENT, {
{ S_FIELD(Flags), STI_UINT32, SOE_FLAGS, 0 },
{ S_FIELD(Destination), STI_ACCOUNT, SOE_REQUIRED, 0 },
{ S_FIELD(Amount), STI_AMOUNT, SOE_REQUIRED, 0 },
{ S_FIELD(SendMax), STI_AMOUNT, SOE_IFFLAG, 1 },
{ S_FIELD(Paths), STI_PATHSET, SOE_IFFLAG, 2 },
{ S_FIELD(SourceTag), STI_UINT32, SOE_IFFLAG, 4 },
{ S_FIELD(InvoiceID), STI_HASH256, SOE_IFFLAG, 8 },
{ sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 } }
},
{ "WalletAdd", ttWALLET_ADD, {
{ S_FIELD(Flags), STI_UINT32, SOE_FLAGS, 0 },
{ S_FIELD(Amount), STI_AMOUNT, SOE_REQUIRED, 0 },
{ S_FIELD(AuthorizedKey), STI_ACCOUNT, SOE_REQUIRED, 0 },
{ S_FIELD(PublicKey), STI_VL, SOE_REQUIRED, 0 },
{ S_FIELD(Signature), STI_VL, SOE_REQUIRED, 0 },
{ S_FIELD(SourceTag), STI_UINT32, SOE_IFFLAG, 1 },
{ sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 } }
},
{ "Contract", ttCONTRACT, {
{ S_FIELD(Flags), STI_UINT32, SOE_FLAGS, 0 },
{ S_FIELD(Expiration), STI_UINT32, SOE_REQUIRED, 0 },
{ S_FIELD(BondAmount), STI_UINT32, SOE_REQUIRED, 0 },
{ S_FIELD(StampEscrow), STI_UINT32, SOE_REQUIRED, 0 },
{ S_FIELD(RippleEscrow), STI_AMOUNT, SOE_REQUIRED, 0 },
{ S_FIELD(CreateCode), STI_VL, SOE_REQUIRED, 0 },
{ S_FIELD(FundCode), STI_VL, SOE_REQUIRED, 0 },
{ S_FIELD(RemoveCode), STI_VL, SOE_REQUIRED, 0 },
{ S_FIELD(ExpireCode), STI_VL, SOE_REQUIRED, 0 },
{ sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 } }
},
{ "Contract", ttCONTRACT_REMOVE, {
{ S_FIELD(Flags), STI_UINT32, SOE_FLAGS, 0 },
{ S_FIELD(Target), STI_ACCOUNT, SOE_REQUIRED, 0 },
{ sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 } }
},
{ "NicknameSet", ttNICKNAME_SET, { TF_BASE
{ sfNickname, SOE_REQUIRED },
{ sfMinimumOffer, SOE_OPTIONAL },
{ sfInvalid, SOE_END } }
},
{ "OfferCreate", ttOFFER_CREATE, { TF_BASE
{ sfTakerPays, SOE_REQUIRED },
{ sfTakerGets, SOE_REQUIRED },
{ sfExpiration, SOE_OPTIONAL },
{ sfInvalid, SOE_END } }
},
{ "OfferCancel", ttOFFER_CANCEL, { TF_BASE
{ sfOfferSequence, SOE_REQUIRED },
{ sfInvalid, SOE_END } }
},
{ "PasswordFund", ttPASSWORD_FUND, { TF_BASE
{ sfDestination, SOE_REQUIRED },
{ sfInvalid, SOE_END } }
},
{ "PasswordSet", ttPASSWORD_SET, { TF_BASE
{ sfAuthorizedKey, SOE_REQUIRED },
{ sfGenerator, SOE_REQUIRED },
{ sfPublicKey, SOE_REQUIRED },
{ sfInvalid, SOE_END } }
},
{ "Payment", ttPAYMENT, { TF_BASE
{ sfDestination, SOE_REQUIRED },
{ sfAmount, SOE_REQUIRED },
{ sfSendMax, SOE_OPTIONAL },
{ sfPaths, SOE_OPTIONAL },
{ sfInvoiceID, SOE_OPTIONAL },
{ sfInvalid, SOE_END } }
},
{ "WalletAdd", ttWALLET_ADD, { TF_BASE
{ sfAmount, SOE_REQUIRED },
{ sfAuthorizedKey, SOE_REQUIRED },
{ sfPublicKey, SOE_REQUIRED },
{ sfInvalid, SOE_END } }
},
{ "Contract", ttCONTRACT, { TF_BASE
{ sfExpiration, SOE_REQUIRED },
{ sfBondAmount, SOE_REQUIRED },
{ sfStampEscrow, SOE_REQUIRED },
{ sfRippleEscrow, SOE_REQUIRED },
{ sfCreateCode, SOE_OPTIONAL },
{ sfFundCode, SOE_OPTIONAL },
{ sfRemoveCode, SOE_OPTIONAL },
{ sfExpireCode, SOE_OPTIONAL },
{ sfInvalid, SOE_END } }
},
{ "RemoveContract", ttCONTRACT_REMOVE, { TF_BASE
{ sfTarget, SOE_REQUIRED },
{ sfInvalid, SOE_END } }
},
{ NULL, ttINVALID }
};
TransactionFormat* getTxnFormat(TransactionType t)
TransactionFormat* getTxnFormat(TransactionType t)
{
return getTxnFormat(static_cast<int>(t));
}
TransactionFormat* getTxnFormat(int t)
{
TransactionFormat* f = InnerTxnFormats;
while (f->t_name != NULL)
{
if (f->t_type == t) return f;
if (f->t_type == t)
return f;
++f;
}
}
return NULL;
}
// vim:ts=4
// vim:ts=4

View File

@@ -23,17 +23,11 @@ enum TransactionType
struct TransactionFormat
{
const char *t_name;
TransactionType t_type;
SOElement elements[16];
const char * t_name;
TransactionType t_type;
SOElement elements[24];
};
const int TransactionISigningPubKey = 0;
const int TransactionISourceID = 1;
const int TransactionISequence = 2;
const int TransactionIType = 3;
const int TransactionIFee = 4;
const int TransactionMinLen = 32;
const int TransactionMaxLen = 1048576;
@@ -52,5 +46,6 @@ const uint32 tfNoRippleDirect = 0x00080000;
extern TransactionFormat InnerTxnFormats[];
extern TransactionFormat* getTxnFormat(TransactionType t);
extern TransactionFormat* getTxnFormat(int t);
#endif
// vim:ts=4

View File

@@ -66,7 +66,7 @@ Json::Value TMNEThread::getJson(int) const
TMNEAmount::TMNEAmount(int type, SerializerIterator& sit) : TransactionMetaNodeEntry(type)
{
mAmount = *dynamic_cast<STAmount*>(STAmount::deserialize(sit, NULL).get()); // Ouch
mAmount = *dynamic_cast<STAmount*>(STAmount::deserialize(sit, sfAmount).get()); // Ouch
}
void TMNEAmount::addRaw(Serializer& s) const

View File

@@ -5,7 +5,7 @@
//
#define SERVER_VERSION_MAJOR 0
#define SERVER_VERSION_MINOR 5
#define SERVER_VERSION_MINOR 6
#define SERVER_VERSION_SUB "-a"
#define SERVER_NAME "NewCoin"
@@ -15,12 +15,12 @@
(SERVER_NAME "-" SV_STRINGIZE(SERVER_VERSION_MAJOR) "." SV_STRINGIZE(SERVER_VERSION_MINOR) SERVER_VERSION_SUB)
// Version we prefer to speak:
#define PROTO_VERSION_MAJOR 0
#define PROTO_VERSION_MINOR 8
#define PROTO_VERSION_MAJOR 1
#define PROTO_VERSION_MINOR 1
// Version we will speak to:
#define MIN_PROTO_MAJOR 0
#define MIN_PROTO_MINOR 8
#define MIN_PROTO_MAJOR 1
#define MIN_PROTO_MINOR 1
#define MAKE_VERSION_INT(maj,min) ((maj << 16) | min)
#define GET_VERSION_MAJOR(ver) (ver >> 16)