mirror of
https://github.com/Xahau/xahaud.git
synced 2025-12-06 17:27:52 +00:00
Merge branch 'master' of github.com:jedmccaleb/NewCoin
This commit is contained in:
4
.gitignore
vendored
4
.gitignore
vendored
@@ -9,9 +9,13 @@
|
||||
# Ignore python compiled files.
|
||||
*.pyc
|
||||
|
||||
# Ignore backup/temps
|
||||
*~
|
||||
|
||||
# Ignore object files.
|
||||
*.o
|
||||
obj/*
|
||||
bin/newcoind
|
||||
|
||||
newcoind
|
||||
|
||||
|
||||
6
bin/network-build
Executable file
6
bin/network-build
Executable file
@@ -0,0 +1,6 @@
|
||||
#!/bin/sh -x
|
||||
|
||||
cd ~/NewCoin
|
||||
git pull
|
||||
scons -j 2
|
||||
cp -p newcoind bin/
|
||||
10
bin/network-init
Executable file
10
bin/network-init
Executable file
@@ -0,0 +1,10 @@
|
||||
#!/bin/sh
|
||||
|
||||
# XXX Should not need to make db directory. newcoind should do this.
|
||||
for SITE in $HOSTS
|
||||
do
|
||||
echo "Clearing db for:" $SITE
|
||||
DB_DIR="/var/www/$SITE/db/"
|
||||
mkdir -p "/var/www/$SITE/db/"
|
||||
rm -rf "/var/www/$SITE/db/*"
|
||||
done
|
||||
5
bin/network-restart
Executable file
5
bin/network-restart
Executable file
@@ -0,0 +1,5 @@
|
||||
#!/bin/sh -x
|
||||
|
||||
network-stop
|
||||
sleep 1
|
||||
network-start
|
||||
6
bin/network-start
Executable file
6
bin/network-start
Executable file
@@ -0,0 +1,6 @@
|
||||
#!/bin/sh
|
||||
|
||||
for SITE in $HOSTS
|
||||
do
|
||||
(nx $SITE &)
|
||||
done
|
||||
6
bin/network-stop
Executable file
6
bin/network-stop
Executable file
@@ -0,0 +1,6 @@
|
||||
#!/bin/sh
|
||||
|
||||
for SITE in $HOSTS
|
||||
do
|
||||
(nx $SITE stop &)
|
||||
done
|
||||
5
bin/network-update
Executable file
5
bin/network-update
Executable file
@@ -0,0 +1,5 @@
|
||||
#!/bin/sh -x
|
||||
echo "Building and restarting."
|
||||
|
||||
network-build
|
||||
network-restart
|
||||
7
bin/nx
Executable file
7
bin/nx
Executable file
@@ -0,0 +1,7 @@
|
||||
#!/bin/sh
|
||||
|
||||
SITE=$1
|
||||
shift
|
||||
COMMAND=$@
|
||||
cd "/var/www/$SITE"
|
||||
newcoind $COMMAND
|
||||
177
src/Amount.cpp
Normal file
177
src/Amount.cpp
Normal file
@@ -0,0 +1,177 @@
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#include "SerializedTypes.h"
|
||||
|
||||
void STAmount::canonicalize()
|
||||
{
|
||||
if(value==0)
|
||||
{
|
||||
offset=0;
|
||||
value=0;
|
||||
}
|
||||
while(value<cMinValue)
|
||||
{
|
||||
if(offset<=cMinOffset) throw std::runtime_error("value overflow");
|
||||
value*=10;
|
||||
offset-=1;
|
||||
}
|
||||
while(value>cMaxValue)
|
||||
{ // Here we can make it throw on precision loss if we wish: ((value%10)!=0)
|
||||
if(offset>=cMaxOffset) throw std::runtime_error("value underflow");
|
||||
value/=10;
|
||||
offset+=1;
|
||||
}
|
||||
assert( (value==0) || ( (value>=cMinValue) && (value<=cMaxValue) ) );
|
||||
assert( (offset>=cMinOffset) && (offset<=cMaxOffset) );
|
||||
}
|
||||
|
||||
STAmount* STAmount::construct(SerializerIterator& sit, const char *name)
|
||||
{
|
||||
uint64 value = sit.get64();
|
||||
int offset = static_cast<int>(value>>(64-8));
|
||||
offset-=142;
|
||||
value&=~(255ull<<(64-8));
|
||||
if(value==0)
|
||||
{
|
||||
if(offset!=0)
|
||||
throw std::runtime_error("invalid currency value");
|
||||
}
|
||||
else
|
||||
{
|
||||
if( (value<cMinValue) || (value>cMaxValue) || (offset<cMinOffset) || (offset>cMaxOffset) )
|
||||
throw std::runtime_error("invalid currency value");
|
||||
}
|
||||
return new STAmount(name, value, offset);
|
||||
}
|
||||
|
||||
std::string STAmount::getText() const
|
||||
{
|
||||
return boost::lexical_cast<std::string>(static_cast<double>(*this));
|
||||
}
|
||||
|
||||
void STAmount::add(Serializer& s) const
|
||||
{
|
||||
uint64 v=value;
|
||||
v+=(static_cast<uint64>(offset+142) << (64-8));
|
||||
s.add64(v);
|
||||
}
|
||||
|
||||
bool STAmount::isEquivalent(const SerializedType& t) const
|
||||
{
|
||||
const STAmount* v=dynamic_cast<const STAmount*>(&t);
|
||||
if(!v) return false;
|
||||
return (value==v->value) && (offset==v->offset);
|
||||
}
|
||||
|
||||
bool STAmount::operator==(const STAmount& a) const
|
||||
{
|
||||
return (offset==a.offset) && (value==a.value);
|
||||
}
|
||||
|
||||
bool STAmount::operator!=(const STAmount& a) const
|
||||
{
|
||||
return (offset!=a.offset) || (value!=a.value);
|
||||
}
|
||||
|
||||
bool STAmount::operator<(const STAmount& a) const
|
||||
{
|
||||
if(offset<a.offset) return true;
|
||||
if(a.offset<offset) return false;
|
||||
return value < a.value;
|
||||
}
|
||||
|
||||
bool STAmount::operator>(const STAmount& a) const
|
||||
{
|
||||
if(offset>a.offset) return true;
|
||||
if(a.offset>offset) return false;
|
||||
return value > a.value;
|
||||
}
|
||||
|
||||
bool STAmount::operator<=(const STAmount& a) const
|
||||
{
|
||||
if(offset<a.offset) return true;
|
||||
if(a.offset<offset) return false;
|
||||
return value <= a.value;
|
||||
}
|
||||
|
||||
bool STAmount::operator>=(const STAmount& a) const
|
||||
{
|
||||
if(offset>a.offset) return true;
|
||||
if(a.offset>offset) return false;
|
||||
return value >= a.value;
|
||||
}
|
||||
|
||||
STAmount& STAmount::operator+=(const STAmount& a)
|
||||
{
|
||||
*this = *this + a;
|
||||
return *this;
|
||||
}
|
||||
|
||||
STAmount& STAmount::operator-=(const STAmount& a)
|
||||
{
|
||||
*this = *this - a;
|
||||
return *this;
|
||||
}
|
||||
|
||||
STAmount& STAmount::operator=(const STAmount& a)
|
||||
{
|
||||
value=a.value;
|
||||
offset=a.offset;
|
||||
return *this;
|
||||
}
|
||||
|
||||
STAmount& STAmount::operator=(uint64 v)
|
||||
{
|
||||
return *this=STAmount(v, 0);
|
||||
}
|
||||
|
||||
STAmount& STAmount::operator+=(uint64 v)
|
||||
{
|
||||
return *this+=STAmount(v);
|
||||
}
|
||||
|
||||
STAmount& STAmount::operator-=(uint64 v)
|
||||
{
|
||||
return *this-=STAmount(v);
|
||||
}
|
||||
|
||||
STAmount operator+(STAmount v1, STAmount v2)
|
||||
{ // We can check for precision loss here (value%10)!=0
|
||||
while(v1.offset < v2.offset)
|
||||
{
|
||||
v1.value/=10;
|
||||
v1.offset+=1;
|
||||
}
|
||||
while(v2.offset < v1.offset)
|
||||
{
|
||||
v2.value/=10;
|
||||
v2.offset+=1;
|
||||
}
|
||||
// this addition cannot overflow
|
||||
return STAmount(v1.name, v1.value + v2.value, v1.offset);
|
||||
}
|
||||
|
||||
STAmount operator-(STAmount v1, STAmount v2)
|
||||
{ // We can check for precision loss here (value%10)!=0
|
||||
while(v1.offset < v2.offset)
|
||||
{
|
||||
v1.value/=10;
|
||||
v1.offset+=1;
|
||||
}
|
||||
while(v2.offset < v1.offset)
|
||||
{
|
||||
v2.value/=10;
|
||||
v2.offset+=1;
|
||||
}
|
||||
if(v1.value < v2.value) throw std::runtime_error("value overflow");
|
||||
return STAmount(v1.name, v1.value - v2.value, v1.offset);
|
||||
}
|
||||
|
||||
STAmount::operator double() const
|
||||
{
|
||||
if(!value) return 0.0;
|
||||
return static_cast<double>(value) * pow(10.0, offset);
|
||||
}
|
||||
56
src/Currency.cpp
Normal file
56
src/Currency.cpp
Normal file
@@ -0,0 +1,56 @@
|
||||
|
||||
#include "Currency.h"
|
||||
|
||||
#include <cmath>
|
||||
#include <stdexcept>
|
||||
|
||||
uint160 Currency::sNatMask("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000");
|
||||
uint160 Currency::sNatZero("FFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000");
|
||||
uint64 Amount::sMaxCanon(1ull << 63);
|
||||
|
||||
Currency::Currency(const uint160& v) : mValue(v)
|
||||
{
|
||||
if (!v) mType = ctNATIVE;
|
||||
if (!(v & sNatZero)) mType = ctNATIONAL;
|
||||
mType = ctNATIONAL;
|
||||
}
|
||||
|
||||
bool Currency::isCommensurate(const Currency& c) const
|
||||
{
|
||||
if (isNative())
|
||||
return c.isNative();
|
||||
if (isCustom())
|
||||
return mValue == c.mValue;
|
||||
if (!c.isNational()) return false;
|
||||
return (mValue & sNatMask) == (c.mValue & sNatMask);
|
||||
}
|
||||
|
||||
unsigned char Currency::getScale() const
|
||||
{
|
||||
return *(mValue.begin());
|
||||
}
|
||||
|
||||
void Currency::setScale(unsigned char s)
|
||||
{
|
||||
*(mValue.begin()) = s;
|
||||
}
|
||||
|
||||
void Amount::canonicalize()
|
||||
{ // clear high bit to avoid overflows
|
||||
if(mQuantity > sMaxCanon)
|
||||
{
|
||||
if (!mCurrency.isNational()) throw std::runtime_error("Currency overflow");
|
||||
unsigned char s = mCurrency.getScale();
|
||||
if (s==255) throw std::runtime_error("Currency overflow");
|
||||
mCurrency.setScale(s + 1);
|
||||
mQuantity /= 10.0;
|
||||
}
|
||||
}
|
||||
|
||||
double Amount::getDisplayQuantity() const
|
||||
{
|
||||
if(!mCurrency.isNational()) throw std::runtime_error("Can only scale national currencies");
|
||||
int scale=mCurrency.getScale();
|
||||
return static_cast<double>(mQuantity) * pow(10, 128-scale);
|
||||
}
|
||||
|
||||
80
src/Currency.h
Normal file
80
src/Currency.h
Normal file
@@ -0,0 +1,80 @@
|
||||
#ifndef __CURRENCY__
|
||||
#define __CURRENCY__
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "uint256.h"
|
||||
|
||||
enum CurrencyType
|
||||
{
|
||||
ctNATIVE, // Currency transaction fees are paid in
|
||||
ctNATIONAL, // State-issued or ISO-recognized currencies
|
||||
ctCUSTOM, // Custom currencies
|
||||
};
|
||||
|
||||
class Currency
|
||||
{
|
||||
protected:
|
||||
uint160 mValue;
|
||||
CurrencyType mType;
|
||||
|
||||
static uint160 sNatMask; // bits that indicate national currency ISO code and version
|
||||
static uint160 sNatZero; // bits that must be zero on a national currency
|
||||
|
||||
public:
|
||||
Currency() : mType(ctNATIVE) { ; }
|
||||
Currency(const uint160& v);
|
||||
Currency(const std::string& iso, uint16 version, unsigned char scale);
|
||||
|
||||
bool isCommensurate(const Currency&) const;
|
||||
bool isNational() const { return mType == ctNATIONAL; }
|
||||
bool isNative() const { return mType == ctNATIVE; }
|
||||
bool isCustom() const { return mType == ctCUSTOM; }
|
||||
|
||||
const uint160& getCurrency() { return mValue; }
|
||||
unsigned char getScale() const;
|
||||
void setScale(unsigned char c);
|
||||
|
||||
// These are only valid for national currencies
|
||||
std::string getISO() const;
|
||||
uint16 getVersion() const;
|
||||
};
|
||||
|
||||
class Amount
|
||||
{
|
||||
// CAUTION: Currency operations throw on overflows, underflos, or
|
||||
// incommensurate currency opeations (like adding USD to Euros)
|
||||
protected:
|
||||
Currency mCurrency;
|
||||
uint64 mQuantity;
|
||||
|
||||
void canonicalize();
|
||||
|
||||
static uint64 sMaxCanon; // Max native currency value before shift
|
||||
|
||||
public:
|
||||
|
||||
Amount(const Currency& c, const uint64& q) : mCurrency(c), mQuantity(q) { canonicalize(); }
|
||||
|
||||
const Currency& getCurrency() const { return mCurrency; }
|
||||
uint64 getQuantity() const { return mQuantity; }
|
||||
double getDisplayQuantity() const;
|
||||
|
||||
// These throw if the currencies are incommensurate
|
||||
// They handle scaling and represent the result as accurately as possible
|
||||
bool operator==(const Amount&) const;
|
||||
bool operator!=(const Amount&) const;
|
||||
bool operator>=(const Amount&) const;
|
||||
bool operator<=(const Amount&) const;
|
||||
bool operator>(const Amount&) const;
|
||||
bool operator<(const Amount&) const;
|
||||
Amount& operator+=(const Amount& a) { return *this = *this + a; }
|
||||
Amount& operator-=(const Amount& a) { return *this = *this - a; }
|
||||
|
||||
// This is used to score offers and works with incommensurate currencies
|
||||
friend void divide(const Amount& offering, const Amount& taking, uint16& exponent, uint64& mantissa);
|
||||
friend Amount& operator+(const Amount&, const Amount&);
|
||||
friend Amount& operator-(const Amount&, const Amount&);
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -32,6 +32,9 @@
|
||||
// 3) Encrypted: Original plaintext
|
||||
// 4) Encrypted: Rest of block/padding
|
||||
|
||||
// ECIES operations throw on any error such as a corrupt message or incorrect
|
||||
// key. They *must* be called in try/catch blocks.
|
||||
|
||||
// Algorithmic choices:
|
||||
#define ECIES_KEY_HASH SHA512 // Hash used to expand shared secret
|
||||
#define ECIES_KEY_LENGTH (512/8) // Size of expanded shared secret
|
||||
|
||||
@@ -9,7 +9,7 @@ LedgerEntryFormat LedgerFormats[]=
|
||||
{ S_FIELD(Flags), STI_UINT16, SOE_FLAGS, 0 },
|
||||
{ S_FIELD(Account), STI_ACCOUNT, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(Sequence), STI_UINT32, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(Balance), STI_UINT64, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(Balance), STI_AMOUNT, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(LastReceive), STI_UINT32, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(LastTxn), STI_UINT32, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(EmailHash), STI_HASH128, SOE_IFFLAG, 1 },
|
||||
@@ -23,8 +23,8 @@ LedgerEntryFormat LedgerFormats[]=
|
||||
{ S_FIELD(Borrower), STI_ACCOUNT, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(Lender), STI_ACCOUNT, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(Currency), STI_HASH160, SOE_IFFLAG, 1 },
|
||||
{ S_FIELD(Limit), STI_UINT64, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(Balance), STI_UINT64, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(Limit), STI_AMOUNT, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(Balance), STI_AMOUNT, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(CurrentRate), STI_UINT32, SOE_IFFLAG, 2 },
|
||||
{ S_FIELD(RateLock), STI_UINT32, SOE_IFFLAG, 4 },
|
||||
{ S_FIELD(NextRate), STI_UINT32, SOE_IFFLAG, 8 },
|
||||
@@ -37,7 +37,7 @@ LedgerEntryFormat LedgerFormats[]=
|
||||
{ S_FIELD(Flags), STI_UINT16, SOE_FLAGS, 0 },
|
||||
{ S_FIELD(Nickname), STI_HASH256, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(Account), STI_ACCOUNT, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(MinimumOffer), STI_UINT64, SOE_IFFLAG, 1 },
|
||||
{ S_FIELD(MinimumOffer), STI_AMOUNT, SOE_IFFLAG, 1 },
|
||||
{ S_FIELD(OfferCurrency),STI_HASH160, SOE_IFFLAG, 2 },
|
||||
{ S_FIELD(Extensions), STI_TL, SOE_IFFLAG, 32768 },
|
||||
{ sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 } }
|
||||
|
||||
@@ -1,3 +1,52 @@
|
||||
|
||||
#include "SerializedLedger.h"
|
||||
|
||||
SerializedLedger::SerializedLedger(SerializerIterator& sit, const uint256& index)
|
||||
: STObject("LedgerEntry"), mIndex(index)
|
||||
{
|
||||
uint16 type=sit.get16();
|
||||
mFormat=getLgrFormat(static_cast<LedgerEntryType>(type));
|
||||
if(mFormat==NULL) throw std::runtime_error("invalid ledger entry type");
|
||||
mType=mFormat->t_type;
|
||||
mVersion.setValue(type);
|
||||
mObject=STObject(mFormat->elements, sit, "Entry");
|
||||
}
|
||||
|
||||
SerializedLedger::SerializedLedger(LedgerEntryType type) : STObject("LedgerEntry"), 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=STObject(mFormat->elements, "Entry");
|
||||
}
|
||||
|
||||
std::string SerializedLedger::getFullText() const
|
||||
{
|
||||
std::string ret="\"";
|
||||
ret+=mIndex.GetHex();
|
||||
ret+="\" = { ";
|
||||
ret+=mFormat->t_name;
|
||||
ret+=", ";
|
||||
ret+=mObject.getFullText();
|
||||
ret+="}";
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::string SerializedLedger::getText() const
|
||||
{
|
||||
std::string ret="{";
|
||||
ret+=mIndex.GetHex();
|
||||
ret+=mVersion.getText();
|
||||
ret+=mObject.getText();
|
||||
ret+="}";
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool SerializedLedger::isEquivalent(const SerializedType& t) const
|
||||
{ // locators are not compared
|
||||
const SerializedLedger* v=dynamic_cast<const SerializedLedger*>(&t);
|
||||
if(!v) return false;
|
||||
if(mType != v->mType) return false;
|
||||
if(mObject != v->mObject) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -10,21 +10,59 @@ public:
|
||||
typedef boost::shared_ptr<SerializedLedger> pointer;
|
||||
|
||||
protected:
|
||||
uint256 mIndex;
|
||||
LedgerEntryType mType;
|
||||
STUInt16 mVersion;
|
||||
STObject mObject;
|
||||
LedgerEntryFormat* mFormat;
|
||||
|
||||
public:
|
||||
SerializedLedger(SerializerIterator& sit);
|
||||
SerializedLedger(SerializerIterator& sit, const uint256& index);
|
||||
SerializedLedger(LedgerEntryType type);
|
||||
|
||||
int getLength() const { return mVersion.getLength() + mObject.getLength(); }
|
||||
SerializedTypeID getType() const { return STI_LEDGERENTRY; }
|
||||
SerializedLedger* duplicate() const { return new SerializedLedger(*this); }
|
||||
std::string getFullText() const;
|
||||
std::string getText() const;
|
||||
void add(Serializer& s) const { mVersion.add(s); mObject.add(s); }
|
||||
SerializedTypeID getSType() const { return STI_LEDGERENTRY; }
|
||||
SerializedLedger* duplicate() const { return new SerializedLedger(*this); }
|
||||
std::string getFullText() const;
|
||||
std::string getText() const;
|
||||
void add(Serializer& s) const { mVersion.add(s); mObject.add(s); }
|
||||
virtual bool isEquivalent(const SerializedType& t) const;
|
||||
|
||||
const uint256& getIndex() const { return mIndex; }
|
||||
void setIndex(const uint256& i) { mIndex=i; }
|
||||
|
||||
LedgerEntryType getType() const { return mType; }
|
||||
uint16 getVersion() const { return mVersion.getValue(); }
|
||||
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); }
|
||||
|
||||
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); }
|
||||
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); }
|
||||
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, uint32 v) { return mObject.setValueFieldU64(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); }
|
||||
|
||||
bool getIFieldPresent(SOE_Field field) const { return mObject.isFieldPresent(field); }
|
||||
void makeIFieldPresent(SOE_Field field) { return mObject.makeFieldPresent(field); }
|
||||
void makeIFieldAbsent(SOE_Field field) { return mObject.makeFieldAbsent(field); }
|
||||
|
||||
|
||||
};
|
||||
|
||||
@@ -16,6 +16,9 @@ SerializedType* STObject::makeDefaultObject(SerializedTypeID id, const char *nam
|
||||
case STI_UINT64:
|
||||
return new STUInt64(name);
|
||||
|
||||
case STI_AMOUNT:
|
||||
return new STAmount(name);
|
||||
|
||||
case STI_HASH160:
|
||||
return new STHash160(name);
|
||||
|
||||
@@ -49,6 +52,9 @@ SerializedType* STObject::makeDeserializedObject(SerializedTypeID id, const char
|
||||
case STI_UINT64:
|
||||
return STUInt64::construct(sit, name);
|
||||
|
||||
case STI_AMOUNT:
|
||||
return STAmount::construct(sit, name);
|
||||
|
||||
case STI_HASH160:
|
||||
return STHash160::construct(sit, name);
|
||||
|
||||
@@ -167,6 +173,22 @@ std::string STObject::getText() const
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool STObject::isEquivalent(const SerializedType& t) const
|
||||
{
|
||||
const STObject* v=dynamic_cast<const STObject*>(&t);
|
||||
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))
|
||||
{
|
||||
if(it1->getSType() != it2->getSType()) return false;
|
||||
if(!it1->isEquivalent(*it2)) return false;
|
||||
++it1;
|
||||
++it2;
|
||||
}
|
||||
return (it1==end1) && (it2==end2);
|
||||
}
|
||||
|
||||
int STObject::getFieldIndex(SOE_Field field) const
|
||||
{
|
||||
int i=0;
|
||||
@@ -207,7 +229,7 @@ bool STObject::isFieldPresent(SOE_Field field) const
|
||||
{
|
||||
int index=getFieldIndex(field);
|
||||
if(index==-1) return false;
|
||||
return peekAtIndex(field).getType()==STI_OBJECT;
|
||||
return peekAtIndex(field).getSType()==STI_OBJECT;
|
||||
}
|
||||
|
||||
bool STObject::setFlag(int f)
|
||||
@@ -240,7 +262,7 @@ void STObject::makeFieldPresent(SOE_Field field)
|
||||
{
|
||||
int index=getFieldIndex(field);
|
||||
if(index==-1) throw std::runtime_error("Field not found");
|
||||
if(peekAtIndex(field).getType()!=STI_OBJECT) return;
|
||||
if(peekAtIndex(field).getSType()!=STI_OBJECT) return;
|
||||
mData.replace(index, makeDefaultObject(mType[index]->e_id, mType[index]->e_name));
|
||||
setFlag(mType[index]->e_flags);
|
||||
}
|
||||
@@ -249,7 +271,7 @@ void STObject::makeFieldAbsent(SOE_Field field)
|
||||
{
|
||||
int index=getFieldIndex(field);
|
||||
if(index==-1) throw std::runtime_error("Field not found");
|
||||
if(peekAtIndex(field).getType()==STI_OBJECT) return;
|
||||
if(peekAtIndex(field).getSType()==STI_OBJECT) return;
|
||||
mData.replace(index, new STObject(mType[index]->e_name));
|
||||
clearFlag(mType[index]->e_flags);
|
||||
}
|
||||
@@ -265,7 +287,7 @@ unsigned char STObject::getValueFieldU8(SOE_Field field) const
|
||||
{
|
||||
const SerializedType* rf=peekAtPField(field);
|
||||
if(!rf) throw std::runtime_error("Field not found");
|
||||
SerializedTypeID id=rf->getType();
|
||||
SerializedTypeID id=rf->getSType();
|
||||
if(id==STI_OBJECT) return 0; // optional field not present
|
||||
const STUInt8 *cf=dynamic_cast<const STUInt8 *>(rf);
|
||||
if(!cf) throw std::runtime_error("Wrong field type");
|
||||
@@ -276,7 +298,7 @@ uint16 STObject::getValueFieldU16(SOE_Field field) const
|
||||
{
|
||||
const SerializedType* rf=peekAtPField(field);
|
||||
if(!rf) throw std::runtime_error("Field not found");
|
||||
SerializedTypeID id=rf->getType();
|
||||
SerializedTypeID id=rf->getSType();
|
||||
if(id==STI_OBJECT) return 0; // optional field not present
|
||||
const STUInt16 *cf=dynamic_cast<const STUInt16 *>(rf);
|
||||
if(!cf) throw std::runtime_error("Wrong field type");
|
||||
@@ -287,7 +309,7 @@ uint32 STObject::getValueFieldU32(SOE_Field field) const
|
||||
{
|
||||
const SerializedType* rf=peekAtPField(field);
|
||||
if(!rf) throw std::runtime_error("Field not found");
|
||||
SerializedTypeID id=rf->getType();
|
||||
SerializedTypeID id=rf->getSType();
|
||||
if(id==STI_OBJECT) return 0; // optional field not present
|
||||
const STUInt32 *cf=dynamic_cast<const STUInt32 *>(rf);
|
||||
if(!cf) throw std::runtime_error("Wrong field type");
|
||||
@@ -298,7 +320,7 @@ uint64 STObject::getValueFieldU64(SOE_Field field) const
|
||||
{
|
||||
const SerializedType* rf=peekAtPField(field);
|
||||
if(!rf) throw std::runtime_error("Field not found");
|
||||
SerializedTypeID id=rf->getType();
|
||||
SerializedTypeID id=rf->getSType();
|
||||
if(id==STI_OBJECT) return 0; // optional field not present
|
||||
const STUInt64 *cf=dynamic_cast<const STUInt64 *>(rf);
|
||||
if(!cf) throw std::runtime_error("Wrong field type");
|
||||
@@ -309,7 +331,7 @@ uint160 STObject::getValueFieldH160(SOE_Field field) const
|
||||
{
|
||||
const SerializedType* rf=peekAtPField(field);
|
||||
if(!rf) throw std::runtime_error("Field not found");
|
||||
SerializedTypeID id=rf->getType();
|
||||
SerializedTypeID id=rf->getSType();
|
||||
if(id==STI_OBJECT) return uint160(); // optional field not present
|
||||
const STHash160 *cf=dynamic_cast<const STHash160 *>(rf);
|
||||
if(!cf) throw std::runtime_error("Wrong field type");
|
||||
@@ -320,7 +342,7 @@ uint256 STObject::getValueFieldH256(SOE_Field field) const
|
||||
{
|
||||
const SerializedType* rf=peekAtPField(field);
|
||||
if(!rf) throw std::runtime_error("Field not found");
|
||||
SerializedTypeID id=rf->getType();
|
||||
SerializedTypeID id=rf->getSType();
|
||||
if(id==STI_OBJECT) return uint256(); // optional field not present
|
||||
const STHash256 *cf=dynamic_cast<const STHash256 *>(rf);
|
||||
if(!cf) throw std::runtime_error("Wrong field type");
|
||||
@@ -331,7 +353,7 @@ std::vector<unsigned char> STObject::getValueFieldVL(SOE_Field field) const
|
||||
{
|
||||
const SerializedType* rf=peekAtPField(field);
|
||||
if(!rf) throw std::runtime_error("Field not found");
|
||||
SerializedTypeID id=rf->getType();
|
||||
SerializedTypeID id=rf->getSType();
|
||||
if(id==STI_OBJECT) return std::vector<unsigned char>(); // optional field not present
|
||||
const STVariableLength *cf=dynamic_cast<const STVariableLength *>(rf);
|
||||
if(!cf) throw std::runtime_error("Wrong field type");
|
||||
@@ -342,7 +364,7 @@ std::vector<TaggedListItem> STObject::getValueFieldTL(SOE_Field field) const
|
||||
{
|
||||
const SerializedType* rf=peekAtPField(field);
|
||||
if(!rf) throw std::runtime_error("Field not found");
|
||||
SerializedTypeID id=rf->getType();
|
||||
SerializedTypeID id=rf->getSType();
|
||||
if(id==STI_OBJECT) return std::vector<TaggedListItem>(); // optional field not present
|
||||
const STTaggedList *cf=dynamic_cast<const STTaggedList *>(rf);
|
||||
if(!cf) throw std::runtime_error("Wrong field type");
|
||||
@@ -353,12 +375,12 @@ void STObject::setValueFieldU8(SOE_Field field, unsigned char v)
|
||||
{
|
||||
SerializedType* rf=getPField(field);
|
||||
if(!rf) throw std::runtime_error("Field not found");
|
||||
SerializedTypeID id=rf->getType();
|
||||
SerializedTypeID id=rf->getSType();
|
||||
if(id==STI_OBJECT)
|
||||
{
|
||||
makeFieldPresent(field);
|
||||
rf=getPField(field);
|
||||
id=rf->getType();
|
||||
id=rf->getSType();
|
||||
}
|
||||
STUInt8* cf=dynamic_cast<STUInt8*>(rf);
|
||||
if(!cf) throw(std::runtime_error("Wrong field type"));
|
||||
@@ -369,12 +391,12 @@ void STObject::setValueFieldU16(SOE_Field field, uint16 v)
|
||||
{
|
||||
SerializedType* rf=getPField(field);
|
||||
if(!rf) throw std::runtime_error("Field not found");
|
||||
SerializedTypeID id=rf->getType();
|
||||
SerializedTypeID id=rf->getSType();
|
||||
if(id==STI_OBJECT)
|
||||
{
|
||||
makeFieldPresent(field);
|
||||
rf=getPField(field);
|
||||
id=rf->getType();
|
||||
id=rf->getSType();
|
||||
}
|
||||
STUInt16* cf=dynamic_cast<STUInt16*>(rf);
|
||||
if(!cf) throw(std::runtime_error("Wrong field type"));
|
||||
@@ -385,12 +407,12 @@ void STObject::setValueFieldU32(SOE_Field field, uint32 v)
|
||||
{
|
||||
SerializedType* rf=getPField(field);
|
||||
if(!rf) throw std::runtime_error("Field not found");
|
||||
SerializedTypeID id=rf->getType();
|
||||
SerializedTypeID id=rf->getSType();
|
||||
if(id==STI_OBJECT)
|
||||
{
|
||||
makeFieldPresent(field);
|
||||
rf=getPField(field);
|
||||
id=rf->getType();
|
||||
id=rf->getSType();
|
||||
}
|
||||
STUInt32* cf=dynamic_cast<STUInt32*>(rf);
|
||||
if(!cf) throw(std::runtime_error("Wrong field type"));
|
||||
@@ -401,12 +423,12 @@ void STObject::setValueFieldU64(SOE_Field field, uint64 v)
|
||||
{
|
||||
SerializedType* rf=getPField(field);
|
||||
if(!rf) throw std::runtime_error("Field not found");
|
||||
SerializedTypeID id=rf->getType();
|
||||
SerializedTypeID id=rf->getSType();
|
||||
if(id==STI_OBJECT)
|
||||
{
|
||||
makeFieldPresent(field);
|
||||
rf=getPField(field);
|
||||
id=rf->getType();
|
||||
id=rf->getSType();
|
||||
}
|
||||
STUInt64* cf=dynamic_cast<STUInt64*>(rf);
|
||||
if(!cf) throw(std::runtime_error("Wrong field type"));
|
||||
@@ -417,12 +439,12 @@ void STObject::setValueFieldH160(SOE_Field field, const uint160& v)
|
||||
{
|
||||
SerializedType* rf=getPField(field);
|
||||
if(!rf) throw std::runtime_error("Field not found");
|
||||
SerializedTypeID id=rf->getType();
|
||||
SerializedTypeID id=rf->getSType();
|
||||
if(id==STI_OBJECT)
|
||||
{
|
||||
makeFieldPresent(field);
|
||||
rf=getPField(field);
|
||||
id=rf->getType();
|
||||
id=rf->getSType();
|
||||
}
|
||||
STHash160* cf=dynamic_cast<STHash160*>(rf);
|
||||
if(!cf) throw(std::runtime_error("Wrong field type"));
|
||||
@@ -433,12 +455,12 @@ void STObject::setValueFieldVL(SOE_Field field, const std::vector<unsigned char>
|
||||
{
|
||||
SerializedType* rf=getPField(field);
|
||||
if(!rf) throw std::runtime_error("Field not found");
|
||||
SerializedTypeID id=rf->getType();
|
||||
SerializedTypeID id=rf->getSType();
|
||||
if(id==STI_OBJECT)
|
||||
{
|
||||
makeFieldPresent(field);
|
||||
rf=getPField(field);
|
||||
id=rf->getType();
|
||||
id=rf->getSType();
|
||||
}
|
||||
STVariableLength* cf=dynamic_cast<STVariableLength*>(rf);
|
||||
if(!cf) throw(std::runtime_error("Wrong field type"));
|
||||
@@ -449,12 +471,12 @@ void STObject::setValueFieldTL(SOE_Field field, const std::vector<TaggedListItem
|
||||
{
|
||||
SerializedType* rf=getPField(field);
|
||||
if(!rf) throw std::runtime_error("Field not found");
|
||||
SerializedTypeID id=rf->getType();
|
||||
SerializedTypeID id=rf->getSType();
|
||||
if(id==STI_OBJECT)
|
||||
{
|
||||
makeFieldPresent(field);
|
||||
rf=getPField(field);
|
||||
id=rf->getType();
|
||||
id=rf->getSType();
|
||||
}
|
||||
STTaggedList* cf=dynamic_cast<STTaggedList*>(rf);
|
||||
if(!cf) throw(std::runtime_error("Wrong field type"));
|
||||
@@ -467,7 +489,7 @@ Json::Value STObject::getJson(int options) const
|
||||
int index=1;
|
||||
for(boost::ptr_vector<SerializedType>::const_iterator it=mData.begin(), end=mData.end(); it!=end; ++it, ++index)
|
||||
{
|
||||
if(it->getType()!=STI_NOTPRESENT)
|
||||
if(it->getSType()!=STI_NOTPRESENT)
|
||||
{
|
||||
if(it->getName()==NULL)
|
||||
ret[boost::lexical_cast<std::string>(index)]=it->getText();
|
||||
|
||||
@@ -56,8 +56,9 @@ public:
|
||||
virtual ~STObject() { ; }
|
||||
|
||||
int getLength() const;
|
||||
SerializedTypeID getType() const { return STI_OBJECT; }
|
||||
SerializedTypeID getSType() const { return STI_OBJECT; }
|
||||
STObject* duplicate() const { return new STObject(*this); }
|
||||
virtual bool isEquivalent(const SerializedType& t) const;
|
||||
|
||||
void add(Serializer& s) const;
|
||||
std::string getFullText() const;
|
||||
|
||||
@@ -77,6 +77,16 @@ int SerializedTransaction::getTransaction(Serializer& s, bool include_length) co
|
||||
return l;
|
||||
}
|
||||
|
||||
bool SerializedTransaction::isEquivalent(const SerializedType& t) const
|
||||
{ // Signatures are not compared
|
||||
const SerializedTransaction* v=dynamic_cast<const SerializedTransaction*>(&t);
|
||||
if(!v) return false;
|
||||
if(type != v->type) return false;
|
||||
if(mMiddleTxn != v->mMiddleTxn) return false;
|
||||
if(mInnerTxn != v->mInnerTxn) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
uint256 SerializedTransaction::getSigningHash() const
|
||||
{
|
||||
Serializer s;
|
||||
@@ -206,7 +216,7 @@ bool SerializedTransaction::getITFieldPresent(SOE_Field field) const
|
||||
return mInnerTxn.isFieldPresent(field);
|
||||
}
|
||||
|
||||
const SerializedType& SerializedTransaction::peekITField(SOE_Field field)
|
||||
const SerializedType& SerializedTransaction::peekITField(SOE_Field field) const
|
||||
{
|
||||
return mInnerTxn.peekAtField(field);
|
||||
}
|
||||
|
||||
@@ -26,11 +26,12 @@ public:
|
||||
|
||||
// STObject functions
|
||||
int getLength() const;
|
||||
SerializedTypeID getType() const { return STI_TRANSACTION; }
|
||||
SerializedTypeID getSType() const { return STI_TRANSACTION; }
|
||||
SerializedTransaction* duplicate() const { return new SerializedTransaction(*this); }
|
||||
std::string getFullText() const;
|
||||
std::string getText() const;
|
||||
void add(Serializer& s) const { getTransaction(s, true); }
|
||||
virtual bool isEquivalent(const SerializedType& t) const;
|
||||
|
||||
// outer transaction functions / signature functions
|
||||
std::vector<unsigned char> getSignature() const;
|
||||
@@ -62,7 +63,7 @@ public:
|
||||
// inner transaction field functions
|
||||
int getITFieldIndex(SOE_Field field) const;
|
||||
int getITFieldCount() const;
|
||||
const SerializedType& peekITField(SOE_Field field);
|
||||
const SerializedType& peekITField(SOE_Field field) const;
|
||||
SerializedType& getITField(SOE_Field field);
|
||||
|
||||
// inner transaction field value functions
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
std::string SerializedType::getFullText() const
|
||||
{
|
||||
std::string ret;
|
||||
if(getType()!=STI_NOTPRESENT)
|
||||
if(getSType()!=STI_NOTPRESENT)
|
||||
{
|
||||
if(name!=NULL)
|
||||
{
|
||||
@@ -31,6 +31,12 @@ std::string STUInt8::getText() const
|
||||
return boost::lexical_cast<std::string>(value);
|
||||
}
|
||||
|
||||
bool STUInt8::isEquivalent(const SerializedType& t) const
|
||||
{
|
||||
const STUInt8* v=dynamic_cast<const STUInt8*>(&t);
|
||||
return v && (value==v->value);
|
||||
}
|
||||
|
||||
STUInt16* STUInt16::construct(SerializerIterator& u, const char *name)
|
||||
{
|
||||
return new STUInt16(name, u.get16());
|
||||
@@ -41,8 +47,14 @@ std::string STUInt16::getText() const
|
||||
return boost::lexical_cast<std::string>(value);
|
||||
}
|
||||
|
||||
STUInt32* STUInt32::construct(SerializerIterator& u, const char *name)
|
||||
bool STUInt16::isEquivalent(const SerializedType& t) const
|
||||
{
|
||||
const STUInt16* v=dynamic_cast<const STUInt16*>(&t);
|
||||
return v && (value==v->value);
|
||||
}
|
||||
|
||||
STUInt32* STUInt32::construct(SerializerIterator& u, const char *name)
|
||||
{
|
||||
return new STUInt32(name, u.get32());
|
||||
}
|
||||
|
||||
@@ -51,6 +63,12 @@ std::string STUInt32::getText() const
|
||||
return boost::lexical_cast<std::string>(value);
|
||||
}
|
||||
|
||||
bool STUInt32::isEquivalent(const SerializedType& t) const
|
||||
{
|
||||
const STUInt32* v=dynamic_cast<const STUInt32*>(&t);
|
||||
return v && (value==v->value);
|
||||
}
|
||||
|
||||
STUInt64* STUInt64::construct(SerializerIterator& u, const char *name)
|
||||
{
|
||||
return new STUInt64(name, u.get64());
|
||||
@@ -61,6 +79,12 @@ std::string STUInt64::getText() const
|
||||
return boost::lexical_cast<std::string>(value);
|
||||
}
|
||||
|
||||
bool STUInt64::isEquivalent(const SerializedType& t) const
|
||||
{
|
||||
const STUInt64* v=dynamic_cast<const STUInt64*>(&t);
|
||||
return v && (value==v->value);
|
||||
}
|
||||
|
||||
STHash128* STHash128::construct(SerializerIterator& u, const char *name)
|
||||
{
|
||||
return new STHash128(name, u.get128());
|
||||
@@ -71,6 +95,12 @@ std::string STHash128::getText() const
|
||||
return value.GetHex();
|
||||
}
|
||||
|
||||
bool STHash128::isEquivalent(const SerializedType& t) const
|
||||
{
|
||||
const STHash128* v=dynamic_cast<const STHash128*>(&t);
|
||||
return v && (value==v->value);
|
||||
}
|
||||
|
||||
STHash160* STHash160::construct(SerializerIterator& u, const char *name)
|
||||
{
|
||||
return new STHash160(name, u.get160());
|
||||
@@ -81,6 +111,12 @@ std::string STHash160::getText() const
|
||||
return value.GetHex();
|
||||
}
|
||||
|
||||
bool STHash160::isEquivalent(const SerializedType& t) const
|
||||
{
|
||||
const STHash160* v=dynamic_cast<const STHash160*>(&t);
|
||||
return v && (value==v->value);
|
||||
}
|
||||
|
||||
STHash256* STHash256::construct(SerializerIterator& u, const char *name)
|
||||
{
|
||||
return new STHash256(name, u.get256());
|
||||
@@ -91,6 +127,12 @@ std::string STHash256::getText() const
|
||||
return value.GetHex();
|
||||
}
|
||||
|
||||
bool STHash256::isEquivalent(const SerializedType& t) const
|
||||
{
|
||||
const STHash256* v=dynamic_cast<const STHash256*>(&t);
|
||||
return v && (value==v->value);
|
||||
}
|
||||
|
||||
static std::string hex(const std::vector<unsigned char>& value)
|
||||
{
|
||||
int dlen=value.size(), i=0;
|
||||
@@ -115,6 +157,12 @@ 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);
|
||||
return v && (value==v->value);
|
||||
}
|
||||
|
||||
std::string STAccount::getText() const
|
||||
{
|
||||
uint160 u;
|
||||
@@ -177,4 +225,8 @@ int STTaggedList::getLength() const
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
bool STTaggedList::isEquivalent(const SerializedType& t) const
|
||||
{
|
||||
const STTaggedList* v=dynamic_cast<const STTaggedList*>(&t);
|
||||
return v && (value==v->value);
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ enum SerializedTypeID
|
||||
// standard types
|
||||
STI_OBJECT=1, STI_UINT8=2, STI_UINT16=3, STI_UINT32=4, STI_UINT64=5,
|
||||
STI_HASH128=6, STI_HASH160=7, STI_HASH256=8, STI_VL=9, STI_TL=10,
|
||||
STI_AMOUNT=11,
|
||||
|
||||
// high level types
|
||||
STI_ACCOUNT=100, STI_TRANSACTION=101, STI_LEDGERENTRY=102
|
||||
@@ -29,13 +30,14 @@ public:
|
||||
|
||||
SerializedType() : name(NULL) { ; }
|
||||
SerializedType(const char *n) : name(n) { ; }
|
||||
SerializedType(const SerializedType& n) : name(n.name) { ; }
|
||||
virtual ~SerializedType() { ; }
|
||||
|
||||
void setName(const char *n) { name=n; }
|
||||
const char *getName() const { return name; }
|
||||
|
||||
virtual int getLength() const { return 0; }
|
||||
virtual SerializedTypeID getType() const { return STI_NOTPRESENT; }
|
||||
virtual SerializedTypeID getSType() const { return STI_NOTPRESENT; }
|
||||
virtual SerializedType* duplicate() const { return new SerializedType(name); }
|
||||
|
||||
virtual std::string getFullText() const;
|
||||
@@ -46,6 +48,13 @@ public:
|
||||
|
||||
SerializedType* new_clone(const SerializedType& s) { return s.duplicate(); }
|
||||
void delete_clone(const SerializedType* s) { boost::checked_delete(s); }
|
||||
|
||||
virtual bool isEquivalent(const SerializedType& t) const { return true; }
|
||||
|
||||
bool operator==(const SerializedType& t) const
|
||||
{ return (getSType()==t.getSType()) && isEquivalent(t); }
|
||||
bool operator!=(const SerializedType& t) const
|
||||
{ return (getSType()!=t.getSType()) || !isEquivalent(t); }
|
||||
};
|
||||
|
||||
class STUInt8 : public SerializedType
|
||||
@@ -60,7 +69,7 @@ public:
|
||||
static STUInt8* construct(SerializerIterator&, const char *name=NULL);
|
||||
|
||||
int getLength() const { return 1; }
|
||||
SerializedTypeID getType() const { return STI_UINT8; }
|
||||
SerializedTypeID getSType() const { return STI_UINT8; }
|
||||
STUInt8* duplicate() const { return new STUInt8(name, value); }
|
||||
std::string getText() const;
|
||||
void add(Serializer& s) const { s.add8(value); }
|
||||
@@ -70,6 +79,7 @@ public:
|
||||
|
||||
operator unsigned char() const { return value; }
|
||||
STUInt8& operator=(unsigned char v) { value=v; return *this; }
|
||||
virtual bool isEquivalent(const SerializedType& t) const;
|
||||
};
|
||||
|
||||
class STUInt16 : public SerializedType
|
||||
@@ -84,7 +94,7 @@ public:
|
||||
static STUInt16* construct(SerializerIterator&, const char *name=NULL);
|
||||
|
||||
int getLength() const { return 2; }
|
||||
SerializedTypeID getType() const { return STI_UINT16; }
|
||||
SerializedTypeID getSType() const { return STI_UINT16; }
|
||||
STUInt16* duplicate() const { return new STUInt16(name, value); }
|
||||
std::string getText() const;
|
||||
void add(Serializer& s) const { s.add16(value); }
|
||||
@@ -94,6 +104,7 @@ public:
|
||||
|
||||
operator uint16() const { return value; }
|
||||
STUInt16& operator=(uint16 v) { value=v; return *this; }
|
||||
virtual bool isEquivalent(const SerializedType& t) const;
|
||||
};
|
||||
|
||||
class STUInt32 : public SerializedType
|
||||
@@ -108,7 +119,7 @@ public:
|
||||
static STUInt32* construct(SerializerIterator&, const char *name=NULL);
|
||||
|
||||
int getLength() const { return 4; }
|
||||
SerializedTypeID getType() const { return STI_UINT32; }
|
||||
SerializedTypeID getSType() const { return STI_UINT32; }
|
||||
STUInt32* duplicate() const { return new STUInt32(name, value); }
|
||||
std::string getText() const;
|
||||
void add(Serializer& s) const { s.add32(value); }
|
||||
@@ -118,6 +129,7 @@ public:
|
||||
|
||||
operator uint32() const { return value; }
|
||||
STUInt32& operator=(uint32 v) { value=v; return *this; }
|
||||
virtual bool isEquivalent(const SerializedType& t) const;
|
||||
};
|
||||
|
||||
class STUInt64 : public SerializedType
|
||||
@@ -132,7 +144,7 @@ public:
|
||||
static STUInt64* construct(SerializerIterator&, const char *name=NULL);
|
||||
|
||||
int getLength() const { return 8; }
|
||||
SerializedTypeID getType() const { return STI_UINT64; }
|
||||
SerializedTypeID getSType() const { return STI_UINT64; }
|
||||
STUInt64* duplicate() const { return new STUInt64(name, value); }
|
||||
std::string getText() const;
|
||||
void add(Serializer& s) const { s.add64(value); }
|
||||
@@ -142,6 +154,77 @@ public:
|
||||
|
||||
operator uint64() const { return value; }
|
||||
STUInt64& operator=(uint64 v) { value=v; return *this; }
|
||||
virtual bool isEquivalent(const SerializedType& t) const;
|
||||
};
|
||||
|
||||
class STAmount : public SerializedType
|
||||
{
|
||||
// Internal form:
|
||||
// 1: If amount is zero, then offset and value are both zero.
|
||||
// 2: Otherwise:
|
||||
// legal offset range is -96 to +80 inclusive
|
||||
// value range is 10^15 to (10^16 - 1) inclusive
|
||||
// amount = value * [10 ^ offset]
|
||||
|
||||
// Wire form:
|
||||
// High 8 bits are (offset+142), legal range is, 80 to 22 inclusive
|
||||
// Low 56 bits are value, legal range is 10^15 to (10^16 - 1) inclusive
|
||||
|
||||
protected:
|
||||
int offset; // These variables *always* hold canonical values on entry/exit
|
||||
uint64 value;
|
||||
|
||||
void canonicalize();
|
||||
|
||||
static const int cMinOffset=-96, cMaxOffset=80;
|
||||
static const uint64 cMinValue=1000000000000000ull, cMaxValue=9999999999999999ull;
|
||||
|
||||
public:
|
||||
STAmount(uint64 v=0, int off=0) : offset(off), value(v)
|
||||
{ canonicalize(); } // (1,0)=$1 (1,-2)=$.01 (100,0)=(10000,-2)=$.01
|
||||
STAmount(const char *n, uint64 v=0, int off=1) : SerializedType(n), offset(off), value(v)
|
||||
{ canonicalize(); }
|
||||
STAmount(const STAmount& a) : SerializedType(a), offset(a.offset), value(a.value) { ; }
|
||||
static STAmount* construct(SerializerIterator&, const char *name=NULL);
|
||||
|
||||
int getLength() const { return 8; }
|
||||
SerializedTypeID getSType() const { return STI_AMOUNT; }
|
||||
STAmount* duplicate() const { return new STAmount(name, offset, value); }
|
||||
std::string getText() const;
|
||||
void add(Serializer& s) const;
|
||||
|
||||
int getOffset() const { return offset; }
|
||||
uint64 getValue() const { return value; }
|
||||
|
||||
virtual bool isEquivalent(const SerializedType& t) const;
|
||||
|
||||
bool operator==(const STAmount&) const;
|
||||
bool operator!=(const STAmount&) const;
|
||||
bool operator<(const STAmount&) const;
|
||||
bool operator>(const STAmount&) const;
|
||||
bool operator<=(const STAmount&) const;
|
||||
bool operator>=(const STAmount&) const;
|
||||
|
||||
STAmount& operator+=(const STAmount&);
|
||||
STAmount& operator-=(const STAmount&);
|
||||
STAmount& operator=(const STAmount&);
|
||||
STAmount& operator+=(uint64);
|
||||
STAmount& operator-=(uint64);
|
||||
STAmount& operator=(uint64);
|
||||
|
||||
operator double() const;
|
||||
|
||||
friend STAmount operator+(STAmount v1, STAmount v2);
|
||||
friend STAmount operator-(STAmount v1, STAmount v2);
|
||||
|
||||
// Someone is offering X for Y, what is the rate?
|
||||
friend STAmount getRate(const STAmount& offerIn, const STAmount& offerOut);
|
||||
|
||||
// Someone is offering X for Y, I pay Z, how much do I get?
|
||||
friend STAmount getClaimed(const STAmount& offerIn, const STAmount& offerOut, const STAmount& paid);
|
||||
|
||||
// Someone is offering X for Y, I need Z, how much do I pay
|
||||
friend STAmount getNeeded(const STAmount& offerIn, const STAmount& offerOut, const STAmount& needed);
|
||||
};
|
||||
|
||||
class STHash128 : public SerializedType
|
||||
@@ -157,7 +240,7 @@ public:
|
||||
static STHash128* construct(SerializerIterator&, const char *name=NULL);
|
||||
|
||||
int getLength() const { return 20; }
|
||||
SerializedTypeID getType() const { return STI_HASH128; }
|
||||
SerializedTypeID getSType() const { return STI_HASH128; }
|
||||
STHash128* duplicate() const { return new STHash128(name, value); }
|
||||
virtual std::string getText() const;
|
||||
void add(Serializer& s) const { s.add128(value); }
|
||||
@@ -167,6 +250,7 @@ public:
|
||||
|
||||
operator uint128() const { return value; }
|
||||
STHash128& operator=(const uint128& v) { value=v; return *this; }
|
||||
virtual bool isEquivalent(const SerializedType& t) const;
|
||||
};
|
||||
|
||||
class STHash160 : public SerializedType
|
||||
@@ -182,7 +266,7 @@ public:
|
||||
static STHash160* construct(SerializerIterator&, const char *name=NULL);
|
||||
|
||||
int getLength() const { return 20; }
|
||||
SerializedTypeID getType() const { return STI_HASH160; }
|
||||
SerializedTypeID getSType() const { return STI_HASH160; }
|
||||
STHash160* duplicate() const { return new STHash160(name, value); }
|
||||
virtual std::string getText() const;
|
||||
void add(Serializer& s) const { s.add160(value); }
|
||||
@@ -192,6 +276,7 @@ public:
|
||||
|
||||
operator uint160() const { return value; }
|
||||
STHash160& operator=(const uint160& v) { value=v; return *this; }
|
||||
virtual bool isEquivalent(const SerializedType& t) const;
|
||||
};
|
||||
|
||||
class STHash256 : public SerializedType
|
||||
@@ -207,7 +292,7 @@ public:
|
||||
static STHash256* construct(SerializerIterator&, const char *name=NULL);
|
||||
|
||||
int getLength() const { return 32; }
|
||||
SerializedTypeID getType() const { return STI_HASH256; }
|
||||
SerializedTypeID getSType() const { return STI_HASH256; }
|
||||
STHash256* duplicate() const { return new STHash256(name, value); }
|
||||
std::string getText() const;
|
||||
void add(Serializer& s) const { s.add256(value); }
|
||||
@@ -217,6 +302,7 @@ public:
|
||||
|
||||
operator uint256() const { return value; }
|
||||
STHash256& operator=(const uint256& v) { value=v; return *this; }
|
||||
virtual bool isEquivalent(const SerializedType& t) const;
|
||||
};
|
||||
|
||||
class STVariableLength : public SerializedType
|
||||
@@ -233,7 +319,7 @@ public:
|
||||
static STVariableLength* construct(SerializerIterator&, const char *name=NULL);
|
||||
|
||||
int getLength() const;
|
||||
virtual SerializedTypeID getType() const { return STI_VL; }
|
||||
virtual SerializedTypeID getSType() const { return STI_VL; }
|
||||
virtual STVariableLength* duplicate() const { return new STVariableLength(name, value); }
|
||||
virtual std::string getText() const;
|
||||
void add(Serializer& s) const { s.addVL(value); }
|
||||
@@ -245,6 +331,7 @@ public:
|
||||
|
||||
operator std::vector<unsigned char>() const { return value; }
|
||||
STVariableLength& operator=(const std::vector<unsigned char>& v) { value=v; return *this; }
|
||||
virtual bool isEquivalent(const SerializedType& t) const;
|
||||
};
|
||||
|
||||
class STAccount : public STVariableLength
|
||||
@@ -257,7 +344,7 @@ public:
|
||||
STAccount() { ; }
|
||||
static STAccount* construct(SerializerIterator&, const char *name=NULL);
|
||||
|
||||
SerializedTypeID getType() const { return STI_ACCOUNT; }
|
||||
SerializedTypeID getSType() const { return STI_ACCOUNT; }
|
||||
virtual STAccount* duplicate() const { return new STAccount(name, value); }
|
||||
std::string getText() const;
|
||||
|
||||
@@ -280,7 +367,7 @@ public:
|
||||
static STTaggedList* construct(SerializerIterator&, const char *name=NULL);
|
||||
|
||||
int getLength() const;
|
||||
SerializedTypeID getType() const { return STI_TL; }
|
||||
SerializedTypeID getSType() const { return STI_TL; }
|
||||
STTaggedList* duplicate() const { return new STTaggedList(name, value); }
|
||||
std::string getText() const;
|
||||
void add(Serializer& s) const { if(s.addTaggedList(value)<0) throw(0); }
|
||||
@@ -299,6 +386,7 @@ public:
|
||||
|
||||
operator std::vector<TaggedListItem>() const { return value; }
|
||||
STTaggedList& operator=(const std::vector<TaggedListItem>& v) { value=v; return *this; }
|
||||
virtual bool isEquivalent(const SerializedType& t) const;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -8,7 +8,7 @@ TransactionFormat InnerTxnFormats[]=
|
||||
{ "MakePayment", ttMAKE_PAYMENT, {
|
||||
{ S_FIELD(Flags), STI_UINT16, SOE_FLAGS, 0 },
|
||||
{ S_FIELD(Destination), STI_ACCOUNT, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(Amount), STI_UINT64, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(Amount), STI_AMOUNT, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(Currency), STI_HASH160, SOE_IFFLAG, 1 },
|
||||
{ S_FIELD(SourceTag), STI_UINT32, SOE_IFFLAG, 2 },
|
||||
{ S_FIELD(TargetLedger), STI_UINT32, SOE_IFFLAG, 4 },
|
||||
@@ -19,7 +19,7 @@ TransactionFormat InnerTxnFormats[]=
|
||||
{ "Invoice", ttINVOICE, {
|
||||
{ S_FIELD(Flags), STI_UINT16, SOE_FLAGS, 0 },
|
||||
{ S_FIELD(Target), STI_ACCOUNT, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(Amount), STI_UINT64, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(Amount), STI_AMOUNT, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(Currency), STI_HASH160, SOE_IFFLAG, 1 },
|
||||
{ S_FIELD(SourceTag), STI_UINT32, SOE_IFFLAG, 2 },
|
||||
{ S_FIELD(Destination), STI_ACCOUNT, SOE_IFFLAG, 4 },
|
||||
@@ -30,9 +30,9 @@ TransactionFormat InnerTxnFormats[]=
|
||||
},
|
||||
{ "Offer", ttEXCHANGE_OFFER, {
|
||||
{ S_FIELD(Flags), STI_UINT16, SOE_FLAGS, 0 },
|
||||
{ S_FIELD(AmountIn), STI_UINT64, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(AmountIn), STI_AMOUNT, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(CurrencyIn), STI_HASH160, SOE_IFFLAG, 2 },
|
||||
{ S_FIELD(AmountOut), STI_UINT64, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(AmountOut), STI_AMOUNT, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(CurrencyOut), STI_HASH160, SOE_IFFLAG, 4 },
|
||||
{ S_FIELD(SourceTag), STI_UINT32, SOE_IFFLAG, 8 },
|
||||
{ S_FIELD(Destination), STI_ACCOUNT, SOE_IFFLAG, 16 },
|
||||
|
||||
Reference in New Issue
Block a user