mirror of
https://github.com/XRPLF/rippled.git
synced 2025-12-06 17:27:55 +00:00
Reformatting using AStyle
This commit is contained in:
@@ -1,18 +1,18 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
Copyright (c) 2011-2013, OpenCoin, Inc.
|
||||
Copyright (c) 2011-2013, OpenCoin, Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
@@ -25,161 +25,176 @@ char const* Base58::s_currentAlphabet = Base58::getRippleAlphabet ();
|
||||
|
||||
char const* Base58::getCurrentAlphabet ()
|
||||
{
|
||||
return s_currentAlphabet;
|
||||
return s_currentAlphabet;
|
||||
}
|
||||
|
||||
void Base58::setCurrentAlphabet (char const* alphabet)
|
||||
{
|
||||
s_currentAlphabet = alphabet;
|
||||
s_currentAlphabet = alphabet;
|
||||
}
|
||||
|
||||
char const* Base58::getBitcoinAlphabet ()
|
||||
{
|
||||
return "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
|
||||
return "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
|
||||
}
|
||||
|
||||
char const* Base58::getRippleAlphabet ()
|
||||
{
|
||||
return "rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz";
|
||||
return "rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz";
|
||||
}
|
||||
|
||||
char const* Base58::getTestnetAlphabet ()
|
||||
{
|
||||
return "RPShNAF39wBUDnEGHJKLM4pQrsT7VWXYZ2bcdeCg65jkm8ofqi1tuvaxyz";
|
||||
return "RPShNAF39wBUDnEGHJKLM4pQrsT7VWXYZ2bcdeCg65jkm8ofqi1tuvaxyz";
|
||||
}
|
||||
|
||||
std::string Base58::encode (const unsigned char* pbegin, const unsigned char* pend)
|
||||
{
|
||||
char const* alphabet = getCurrentAlphabet ();
|
||||
char const* alphabet = getCurrentAlphabet ();
|
||||
|
||||
CAutoBN_CTX pctx;
|
||||
CBigNum bn58 = 58;
|
||||
CBigNum bn0 = 0;
|
||||
CAutoBN_CTX pctx;
|
||||
CBigNum bn58 = 58;
|
||||
CBigNum bn0 = 0;
|
||||
|
||||
// Convert big endian data to little endian
|
||||
// Extra zero at the end make sure bignum will interpret as a positive number
|
||||
Blob vchTmp(pend-pbegin+1, 0);
|
||||
std::reverse_copy(pbegin, pend, vchTmp.begin());
|
||||
// Convert big endian data to little endian
|
||||
// Extra zero at the end make sure bignum will interpret as a positive number
|
||||
Blob vchTmp (pend - pbegin + 1, 0);
|
||||
std::reverse_copy (pbegin, pend, vchTmp.begin ());
|
||||
|
||||
// Convert little endian data to bignum
|
||||
CBigNum bn(vchTmp);
|
||||
// Convert little endian data to bignum
|
||||
CBigNum bn (vchTmp);
|
||||
|
||||
// Convert bignum to std::string
|
||||
std::string str;
|
||||
// Expected size increase from base58 conversion is approximately 137%
|
||||
// use 138% to be safe
|
||||
str.reserve((pend - pbegin) * 138 / 100 + 1);
|
||||
CBigNum dv;
|
||||
CBigNum rem;
|
||||
while (bn > bn0)
|
||||
{
|
||||
if (!BN_div(&dv, &rem, &bn, &bn58, pctx))
|
||||
throw bignum_error("EncodeBase58 : BN_div failed");
|
||||
bn = dv;
|
||||
unsigned int c = rem.getuint();
|
||||
str += alphabet [c];
|
||||
}
|
||||
// Convert bignum to std::string
|
||||
std::string str;
|
||||
// Expected size increase from base58 conversion is approximately 137%
|
||||
// use 138% to be safe
|
||||
str.reserve ((pend - pbegin) * 138 / 100 + 1);
|
||||
CBigNum dv;
|
||||
CBigNum rem;
|
||||
|
||||
// Leading zeroes encoded as base58 zeros
|
||||
for (const unsigned char* p = pbegin; p < pend && *p == 0; p++)
|
||||
str += alphabet [0];
|
||||
while (bn > bn0)
|
||||
{
|
||||
if (!BN_div (&dv, &rem, &bn, &bn58, pctx))
|
||||
throw bignum_error ("EncodeBase58 : BN_div failed");
|
||||
|
||||
// Convert little endian std::string to big endian
|
||||
reverse(str.begin(), str.end());
|
||||
return str;
|
||||
bn = dv;
|
||||
unsigned int c = rem.getuint ();
|
||||
str += alphabet [c];
|
||||
}
|
||||
|
||||
// Leading zeroes encoded as base58 zeros
|
||||
for (const unsigned char* p = pbegin; p < pend && *p == 0; p++)
|
||||
str += alphabet [0];
|
||||
|
||||
// Convert little endian std::string to big endian
|
||||
reverse (str.begin (), str.end ());
|
||||
return str;
|
||||
}
|
||||
|
||||
std::string Base58::encode (Blob const& vch)
|
||||
{
|
||||
return encode (&vch[0], &vch[0] + vch.size());
|
||||
return encode (&vch[0], &vch[0] + vch.size ());
|
||||
}
|
||||
|
||||
std::string Base58::encodeWithCheck (Blob const& vchIn)
|
||||
{
|
||||
// add 4-byte hash check to the end
|
||||
Blob vch(vchIn);
|
||||
uint256 hash = SHA256Hash(vch.begin(), vch.end());
|
||||
vch.insert(vch.end(), (unsigned char*)&hash, (unsigned char*)&hash + 4);
|
||||
return encode (vch);
|
||||
// add 4-byte hash check to the end
|
||||
Blob vch (vchIn);
|
||||
uint256 hash = SHA256Hash (vch.begin (), vch.end ());
|
||||
vch.insert (vch.end (), (unsigned char*)&hash, (unsigned char*)&hash + 4);
|
||||
return encode (vch);
|
||||
}
|
||||
|
||||
bool Base58::decode (const char* psz, Blob& vchRet, const char* pAlpha)
|
||||
{
|
||||
assert (pAlpha != 0);
|
||||
assert (pAlpha != 0);
|
||||
|
||||
CAutoBN_CTX pctx;
|
||||
vchRet.clear();
|
||||
CBigNum bn58 = 58;
|
||||
CBigNum bn = 0;
|
||||
CBigNum bnChar;
|
||||
while (isspace(*psz))
|
||||
psz++;
|
||||
CAutoBN_CTX pctx;
|
||||
vchRet.clear ();
|
||||
CBigNum bn58 = 58;
|
||||
CBigNum bn = 0;
|
||||
CBigNum bnChar;
|
||||
|
||||
// Convert big endian string to bignum
|
||||
for (const char* p = psz; *p; p++)
|
||||
{
|
||||
const char* p1 = strchr(pAlpha, *p);
|
||||
if (p1 == NULL)
|
||||
{
|
||||
while (isspace(*p))
|
||||
p++;
|
||||
if (*p != '\0')
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
bnChar.setuint(p1 - pAlpha);
|
||||
if (!BN_mul(&bn, &bn, &bn58, pctx))
|
||||
throw bignum_error("DecodeBase58 : BN_mul failed");
|
||||
bn += bnChar;
|
||||
}
|
||||
while (isspace (*psz))
|
||||
psz++;
|
||||
|
||||
// Get bignum as little endian data
|
||||
Blob vchTmp = bn.getvch();
|
||||
// Convert big endian string to bignum
|
||||
for (const char* p = psz; *p; p++)
|
||||
{
|
||||
const char* p1 = strchr (pAlpha, *p);
|
||||
|
||||
// Trim off sign byte if present
|
||||
if (vchTmp.size() >= 2 && vchTmp.end()[-1] == 0 && vchTmp.end()[-2] >= 0x80)
|
||||
vchTmp.erase(vchTmp.end()-1);
|
||||
if (p1 == NULL)
|
||||
{
|
||||
while (isspace (*p))
|
||||
p++;
|
||||
|
||||
// Restore leading zeros
|
||||
int nLeadingZeros = 0;
|
||||
for (const char* p = psz; *p == pAlpha[0]; p++)
|
||||
nLeadingZeros++;
|
||||
vchRet.assign(nLeadingZeros + vchTmp.size(), 0);
|
||||
if (*p != '\0')
|
||||
return false;
|
||||
|
||||
// Convert little endian data to big endian
|
||||
std::reverse_copy(vchTmp.begin(), vchTmp.end(), vchRet.end() - vchTmp.size());
|
||||
return true;
|
||||
break;
|
||||
}
|
||||
|
||||
bnChar.setuint (p1 - pAlpha);
|
||||
|
||||
if (!BN_mul (&bn, &bn, &bn58, pctx))
|
||||
throw bignum_error ("DecodeBase58 : BN_mul failed");
|
||||
|
||||
bn += bnChar;
|
||||
}
|
||||
|
||||
// Get bignum as little endian data
|
||||
Blob vchTmp = bn.getvch ();
|
||||
|
||||
// Trim off sign byte if present
|
||||
if (vchTmp.size () >= 2 && vchTmp.end ()[-1] == 0 && vchTmp.end ()[-2] >= 0x80)
|
||||
vchTmp.erase (vchTmp.end () - 1);
|
||||
|
||||
// Restore leading zeros
|
||||
int nLeadingZeros = 0;
|
||||
|
||||
for (const char* p = psz; *p == pAlpha[0]; p++)
|
||||
nLeadingZeros++;
|
||||
|
||||
vchRet.assign (nLeadingZeros + vchTmp.size (), 0);
|
||||
|
||||
// Convert little endian data to big endian
|
||||
std::reverse_copy (vchTmp.begin (), vchTmp.end (), vchRet.end () - vchTmp.size ());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Base58::decode (const std::string& str, Blob& vchRet)
|
||||
{
|
||||
return decode (str.c_str(), vchRet);
|
||||
return decode (str.c_str (), vchRet);
|
||||
}
|
||||
|
||||
bool Base58::decodeWithCheck (const char* psz, Blob& vchRet, const char* pAlphabet)
|
||||
{
|
||||
assert (pAlphabet != NULL);
|
||||
assert (pAlphabet != NULL);
|
||||
|
||||
if (!decode (psz, vchRet, pAlphabet))
|
||||
return false;
|
||||
if (vchRet.size() < 4)
|
||||
{
|
||||
vchRet.clear();
|
||||
return false;
|
||||
}
|
||||
uint256 hash = SHA256Hash(vchRet.begin(), vchRet.end()-4);
|
||||
if (memcmp(&hash, &vchRet.end()[-4], 4) != 0)
|
||||
{
|
||||
vchRet.clear();
|
||||
return false;
|
||||
}
|
||||
vchRet.resize(vchRet.size()-4);
|
||||
return true;
|
||||
if (!decode (psz, vchRet, pAlphabet))
|
||||
return false;
|
||||
|
||||
if (vchRet.size () < 4)
|
||||
{
|
||||
vchRet.clear ();
|
||||
return false;
|
||||
}
|
||||
|
||||
uint256 hash = SHA256Hash (vchRet.begin (), vchRet.end () - 4);
|
||||
|
||||
if (memcmp (&hash, &vchRet.end ()[-4], 4) != 0)
|
||||
{
|
||||
vchRet.clear ();
|
||||
return false;
|
||||
}
|
||||
|
||||
vchRet.resize (vchRet.size () - 4);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Base58::decodeWithCheck (const std::string& str, Blob& vchRet, const char* pAlphabet)
|
||||
{
|
||||
return decodeWithCheck (str.c_str(), vchRet, pAlphabet);
|
||||
return decodeWithCheck (str.c_str (), vchRet, pAlphabet);
|
||||
}
|
||||
|
||||
// vim:ts=4
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
Copyright (c) 2011-2013, OpenCoin, Inc.
|
||||
Copyright (c) 2011-2013, OpenCoin, Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
@@ -36,25 +36,25 @@
|
||||
class Base58
|
||||
{
|
||||
public:
|
||||
// VFALCO TODO clean up this poor API
|
||||
static char const* getCurrentAlphabet ();
|
||||
static void setCurrentAlphabet (char const* alphabet);
|
||||
// VFALCO TODO clean up this poor API
|
||||
static char const* getCurrentAlphabet ();
|
||||
static void setCurrentAlphabet (char const* alphabet);
|
||||
|
||||
static char const* getBitcoinAlphabet ();
|
||||
static char const* getRippleAlphabet ();
|
||||
static char const* getTestnetAlphabet ();
|
||||
static char const* getBitcoinAlphabet ();
|
||||
static char const* getRippleAlphabet ();
|
||||
static char const* getTestnetAlphabet ();
|
||||
|
||||
static std::string encode (const unsigned char* pbegin, const unsigned char* pend);
|
||||
static std::string encode (Blob const& vch);
|
||||
static std::string encodeWithCheck (Blob const& vchIn);
|
||||
static std::string encode (const unsigned char* pbegin, const unsigned char* pend);
|
||||
static std::string encode (Blob const& vch);
|
||||
static std::string encodeWithCheck (Blob const& vchIn);
|
||||
|
||||
static bool decode (const char* psz, Blob& vchRet, const char* pAlphabet=getCurrentAlphabet ());
|
||||
static bool decode (const std::string& str, Blob& vchRet);
|
||||
static bool decodeWithCheck (const char* psz, Blob& vchRet, const char* pAlphabet=getCurrentAlphabet ());
|
||||
static bool decodeWithCheck (const std::string& str, Blob& vchRet, const char* pAlphabet);
|
||||
static bool decode (const char* psz, Blob& vchRet, const char* pAlphabet = getCurrentAlphabet ());
|
||||
static bool decode (const std::string& str, Blob& vchRet);
|
||||
static bool decodeWithCheck (const char* psz, Blob& vchRet, const char* pAlphabet = getCurrentAlphabet ());
|
||||
static bool decodeWithCheck (const std::string& str, Blob& vchRet, const char* pAlphabet);
|
||||
|
||||
private:
|
||||
static char const* s_currentAlphabet;
|
||||
static char const* s_currentAlphabet;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
Copyright (c) 2011-2013, OpenCoin, Inc.
|
||||
Copyright (c) 2011-2013, OpenCoin, Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
@@ -29,91 +29,118 @@
|
||||
// - Doubleclicking selects the whole number as one word if it's all alphanumeric.
|
||||
//
|
||||
|
||||
CBase58Data::CBase58Data()
|
||||
: nVersion(1)
|
||||
CBase58Data::CBase58Data ()
|
||||
: nVersion (1)
|
||||
{
|
||||
}
|
||||
|
||||
CBase58Data::~CBase58Data()
|
||||
CBase58Data::~CBase58Data ()
|
||||
{
|
||||
if (!vchData.empty())
|
||||
memset(&vchData[0], 0, vchData.size());
|
||||
if (!vchData.empty ())
|
||||
memset (&vchData[0], 0, vchData.size ());
|
||||
}
|
||||
|
||||
void CBase58Data::SetData(int nVersionIn, Blob const& vchDataIn)
|
||||
void CBase58Data::SetData (int nVersionIn, Blob const& vchDataIn)
|
||||
{
|
||||
nVersion = nVersionIn;
|
||||
vchData = vchDataIn;
|
||||
nVersion = nVersionIn;
|
||||
vchData = vchDataIn;
|
||||
}
|
||||
|
||||
void CBase58Data::SetData(int nVersionIn, const void* pdata, size_t nSize)
|
||||
void CBase58Data::SetData (int nVersionIn, const void* pdata, size_t nSize)
|
||||
{
|
||||
nVersion = nVersionIn;
|
||||
vchData.resize(nSize);
|
||||
vchData.resize (nSize);
|
||||
|
||||
if (nSize)
|
||||
memcpy(&vchData[0], pdata, nSize);
|
||||
memcpy (&vchData[0], pdata, nSize);
|
||||
}
|
||||
|
||||
void CBase58Data::SetData(int nVersionIn, const unsigned char *pbegin, const unsigned char *pend)
|
||||
void CBase58Data::SetData (int nVersionIn, const unsigned char* pbegin, const unsigned char* pend)
|
||||
{
|
||||
SetData(nVersionIn, (void*)pbegin, pend - pbegin);
|
||||
SetData (nVersionIn, (void*)pbegin, pend - pbegin);
|
||||
}
|
||||
|
||||
bool CBase58Data::SetString(const char* psz, unsigned char version, const char* pAlphabet)
|
||||
bool CBase58Data::SetString (const char* psz, unsigned char version, const char* pAlphabet)
|
||||
{
|
||||
Blob vchTemp;
|
||||
Base58::decodeWithCheck (psz, vchTemp, pAlphabet);
|
||||
if (vchTemp.empty() || vchTemp[0] != version)
|
||||
|
||||
if (vchTemp.empty () || vchTemp[0] != version)
|
||||
{
|
||||
vchData.clear();
|
||||
vchData.clear ();
|
||||
nVersion = 1;
|
||||
return false;
|
||||
}
|
||||
|
||||
nVersion = vchTemp[0];
|
||||
vchData.resize(vchTemp.size() - 1);
|
||||
if (!vchData.empty())
|
||||
memcpy(&vchData[0], &vchTemp[1], vchData.size());
|
||||
memset(&vchTemp[0], 0, vchTemp.size());
|
||||
vchData.resize (vchTemp.size () - 1);
|
||||
|
||||
if (!vchData.empty ())
|
||||
memcpy (&vchData[0], &vchTemp[1], vchData.size ());
|
||||
|
||||
memset (&vchTemp[0], 0, vchTemp.size ());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CBase58Data::SetString(const std::string& str, unsigned char version)
|
||||
bool CBase58Data::SetString (const std::string& str, unsigned char version)
|
||||
{
|
||||
return SetString(str.c_str(), version);
|
||||
return SetString (str.c_str (), version);
|
||||
}
|
||||
|
||||
std::string CBase58Data::ToString() const
|
||||
std::string CBase58Data::ToString () const
|
||||
{
|
||||
Blob vch(1, nVersion);
|
||||
Blob vch (1, nVersion);
|
||||
|
||||
vch.insert(vch.end(), vchData.begin(), vchData.end());
|
||||
vch.insert (vch.end (), vchData.begin (), vchData.end ());
|
||||
|
||||
return Base58::encodeWithCheck (vch);
|
||||
}
|
||||
|
||||
int CBase58Data::CompareTo(const CBase58Data& b58) const
|
||||
int CBase58Data::CompareTo (const CBase58Data& b58) const
|
||||
{
|
||||
if (nVersion < b58.nVersion) return -1;
|
||||
|
||||
if (nVersion > b58.nVersion) return 1;
|
||||
|
||||
if (vchData < b58.vchData) return -1;
|
||||
|
||||
if (vchData > b58.vchData) return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool CBase58Data::operator==(const CBase58Data& b58) const { return CompareTo(b58) == 0; }
|
||||
bool CBase58Data::operator!=(const CBase58Data& b58) const { return CompareTo(b58) != 0; }
|
||||
bool CBase58Data::operator<=(const CBase58Data& b58) const { return CompareTo(b58) <= 0; }
|
||||
bool CBase58Data::operator>=(const CBase58Data& b58) const { return CompareTo(b58) >= 0; }
|
||||
bool CBase58Data::operator< (const CBase58Data& b58) const { return CompareTo(b58) < 0; }
|
||||
bool CBase58Data::operator> (const CBase58Data& b58) const { return CompareTo(b58) > 0; }
|
||||
bool CBase58Data::operator== (const CBase58Data& b58) const
|
||||
{
|
||||
return CompareTo (b58) == 0;
|
||||
}
|
||||
bool CBase58Data::operator!= (const CBase58Data& b58) const
|
||||
{
|
||||
return CompareTo (b58) != 0;
|
||||
}
|
||||
bool CBase58Data::operator<= (const CBase58Data& b58) const
|
||||
{
|
||||
return CompareTo (b58) <= 0;
|
||||
}
|
||||
bool CBase58Data::operator>= (const CBase58Data& b58) const
|
||||
{
|
||||
return CompareTo (b58) >= 0;
|
||||
}
|
||||
bool CBase58Data::operator< (const CBase58Data& b58) const
|
||||
{
|
||||
return CompareTo (b58) < 0;
|
||||
}
|
||||
bool CBase58Data::operator> (const CBase58Data& b58) const
|
||||
{
|
||||
return CompareTo (b58) > 0;
|
||||
}
|
||||
|
||||
std::size_t hash_value(const CBase58Data& b58)
|
||||
std::size_t hash_value (const CBase58Data& b58)
|
||||
{
|
||||
std::size_t seed = HashMaps::getInstance ().getNonce <size_t> ()
|
||||
+ (b58.nVersion * HashMaps::goldenRatio);
|
||||
|
||||
boost::hash_combine (seed, b58.vchData);
|
||||
|
||||
|
||||
return seed;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
Copyright (c) 2011-2013, OpenCoin, Inc.
|
||||
Copyright (c) 2011-2013, OpenCoin, Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
@@ -37,28 +37,28 @@ protected:
|
||||
unsigned char nVersion;
|
||||
Blob vchData;
|
||||
|
||||
CBase58Data();
|
||||
~CBase58Data();
|
||||
CBase58Data ();
|
||||
~CBase58Data ();
|
||||
|
||||
void SetData(int nVersionIn, Blob const& vchDataIn);
|
||||
void SetData(int nVersionIn, const void* pdata, size_t nSize);
|
||||
void SetData(int nVersionIn, const unsigned char *pbegin, const unsigned char *pend);
|
||||
void SetData (int nVersionIn, Blob const& vchDataIn);
|
||||
void SetData (int nVersionIn, const void* pdata, size_t nSize);
|
||||
void SetData (int nVersionIn, const unsigned char* pbegin, const unsigned char* pend);
|
||||
|
||||
public:
|
||||
bool SetString(const char* psz, unsigned char version, const char* pAlphabet = Base58::getCurrentAlphabet());
|
||||
bool SetString(const std::string& str, unsigned char version);
|
||||
bool SetString (const char* psz, unsigned char version, const char* pAlphabet = Base58::getCurrentAlphabet ());
|
||||
bool SetString (const std::string& str, unsigned char version);
|
||||
|
||||
std::string ToString() const;
|
||||
int CompareTo(const CBase58Data& b58) const;
|
||||
std::string ToString () const;
|
||||
int CompareTo (const CBase58Data& b58) const;
|
||||
|
||||
bool operator==(const CBase58Data& b58) const;
|
||||
bool operator!=(const CBase58Data& b58) const;
|
||||
bool operator<=(const CBase58Data& b58) const;
|
||||
bool operator>=(const CBase58Data& b58) const;
|
||||
bool operator== (const CBase58Data& b58) const;
|
||||
bool operator!= (const CBase58Data& b58) const;
|
||||
bool operator<= (const CBase58Data& b58) const;
|
||||
bool operator>= (const CBase58Data& b58) const;
|
||||
bool operator< (const CBase58Data& b58) const;
|
||||
bool operator> (const CBase58Data& b58) const;
|
||||
|
||||
friend std::size_t hash_value(const CBase58Data& b58);
|
||||
friend std::size_t hash_value (const CBase58Data& b58);
|
||||
};
|
||||
|
||||
extern std::size_t hash_value (const CBase58Data& b58);
|
||||
|
||||
@@ -3,528 +3,635 @@
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
CBigNum::CBigNum()
|
||||
CBigNum::CBigNum ()
|
||||
{
|
||||
BN_init(this);
|
||||
BN_init (this);
|
||||
}
|
||||
|
||||
CBigNum::CBigNum(const CBigNum& b)
|
||||
CBigNum::CBigNum (const CBigNum& b)
|
||||
{
|
||||
BN_init(this);
|
||||
if (!BN_copy(this, &b))
|
||||
{
|
||||
BN_clear_free(this);
|
||||
throw bignum_error("CBigNum::CBigNum(const CBigNum&) : BN_copy failed");
|
||||
}
|
||||
BN_init (this);
|
||||
|
||||
if (!BN_copy (this, &b))
|
||||
{
|
||||
BN_clear_free (this);
|
||||
throw bignum_error ("CBigNum::CBigNum(const CBigNum&) : BN_copy failed");
|
||||
}
|
||||
}
|
||||
|
||||
CBigNum& CBigNum::operator=(const CBigNum& b)
|
||||
CBigNum& CBigNum::operator= (const CBigNum& b)
|
||||
{
|
||||
if (!BN_copy(this, &b))
|
||||
throw bignum_error("CBigNum::operator= : BN_copy failed");
|
||||
return (*this);
|
||||
if (!BN_copy (this, &b))
|
||||
throw bignum_error ("CBigNum::operator= : BN_copy failed");
|
||||
|
||||
return (*this);
|
||||
}
|
||||
|
||||
CBigNum::~CBigNum()
|
||||
CBigNum::~CBigNum ()
|
||||
{
|
||||
BN_clear_free(this);
|
||||
BN_clear_free (this);
|
||||
}
|
||||
|
||||
CBigNum::CBigNum(char n) { BN_init(this); if (n >= 0) setulong(n); else setint64(n); }
|
||||
CBigNum::CBigNum(short n) { BN_init(this); if (n >= 0) setulong(n); else setint64(n); }
|
||||
CBigNum::CBigNum(int n) { BN_init(this); if (n >= 0) setulong(n); else setint64(n); }
|
||||
CBigNum::CBigNum(long n) { BN_init(this); if (n >= 0) setulong(n); else setint64(n); }
|
||||
CBigNum::CBigNum(int64 n) { BN_init(this); setint64(n); }
|
||||
CBigNum::CBigNum(unsigned char n) { BN_init(this); setulong(n); }
|
||||
CBigNum::CBigNum(unsigned short n) { BN_init(this); setulong(n); }
|
||||
CBigNum::CBigNum(unsigned int n) { BN_init(this); setulong(n); }
|
||||
CBigNum::CBigNum(uint64 n) { BN_init(this); setuint64(n); }
|
||||
CBigNum::CBigNum(uint256 n) { BN_init(this); setuint256(n); }
|
||||
|
||||
CBigNum::CBigNum(Blob const& vch)
|
||||
CBigNum::CBigNum (char n)
|
||||
{
|
||||
BN_init(this);
|
||||
setvch(vch);
|
||||
BN_init (this);
|
||||
|
||||
if (n >= 0) setulong (n);
|
||||
else setint64 (n);
|
||||
}
|
||||
CBigNum::CBigNum (short n)
|
||||
{
|
||||
BN_init (this);
|
||||
|
||||
if (n >= 0) setulong (n);
|
||||
else setint64 (n);
|
||||
}
|
||||
CBigNum::CBigNum (int n)
|
||||
{
|
||||
BN_init (this);
|
||||
|
||||
if (n >= 0) setulong (n);
|
||||
else setint64 (n);
|
||||
}
|
||||
CBigNum::CBigNum (long n)
|
||||
{
|
||||
BN_init (this);
|
||||
|
||||
if (n >= 0) setulong (n);
|
||||
else setint64 (n);
|
||||
}
|
||||
CBigNum::CBigNum (int64 n)
|
||||
{
|
||||
BN_init (this);
|
||||
setint64 (n);
|
||||
}
|
||||
CBigNum::CBigNum (unsigned char n)
|
||||
{
|
||||
BN_init (this);
|
||||
setulong (n);
|
||||
}
|
||||
CBigNum::CBigNum (unsigned short n)
|
||||
{
|
||||
BN_init (this);
|
||||
setulong (n);
|
||||
}
|
||||
CBigNum::CBigNum (unsigned int n)
|
||||
{
|
||||
BN_init (this);
|
||||
setulong (n);
|
||||
}
|
||||
CBigNum::CBigNum (uint64 n)
|
||||
{
|
||||
BN_init (this);
|
||||
setuint64 (n);
|
||||
}
|
||||
CBigNum::CBigNum (uint256 n)
|
||||
{
|
||||
BN_init (this);
|
||||
setuint256 (n);
|
||||
}
|
||||
|
||||
void CBigNum::setuint(unsigned int n)
|
||||
CBigNum::CBigNum (Blob const& vch)
|
||||
{
|
||||
setulong(static_cast<unsigned long>(n));
|
||||
BN_init (this);
|
||||
setvch (vch);
|
||||
}
|
||||
|
||||
unsigned int CBigNum::getuint() const
|
||||
void CBigNum::setuint (unsigned int n)
|
||||
{
|
||||
return BN_get_word(this);
|
||||
setulong (static_cast<unsigned long> (n));
|
||||
}
|
||||
|
||||
int CBigNum::getint() const
|
||||
unsigned int CBigNum::getuint () const
|
||||
{
|
||||
unsigned long n = BN_get_word(this);
|
||||
if (!BN_is_negative(this))
|
||||
return (n > INT_MAX ? INT_MAX : n);
|
||||
else
|
||||
return (n > INT_MAX ? INT_MIN : -(int)n);
|
||||
return BN_get_word (this);
|
||||
}
|
||||
|
||||
void CBigNum::setint64(int64 n)
|
||||
int CBigNum::getint () const
|
||||
{
|
||||
unsigned char pch[sizeof(n) + 6];
|
||||
unsigned char* p = pch + 4;
|
||||
bool fNegative = false;
|
||||
if (n < (int64)0)
|
||||
{
|
||||
n = -n;
|
||||
fNegative = true;
|
||||
}
|
||||
bool fLeadingZeroes = true;
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
unsigned char c = (n >> 56) & 0xff;
|
||||
n <<= 8;
|
||||
if (fLeadingZeroes)
|
||||
{
|
||||
if (c == 0)
|
||||
continue;
|
||||
if (c & 0x80)
|
||||
*p++ = (fNegative ? 0x80 : 0);
|
||||
else if (fNegative)
|
||||
c |= 0x80;
|
||||
fLeadingZeroes = false;
|
||||
}
|
||||
*p++ = c;
|
||||
}
|
||||
unsigned int nSize = p - (pch + 4);
|
||||
pch[0] = (nSize >> 24) & 0xff;
|
||||
pch[1] = (nSize >> 16) & 0xff;
|
||||
pch[2] = (nSize >> 8) & 0xff;
|
||||
pch[3] = (nSize) & 0xff;
|
||||
BN_mpi2bn(pch, p - pch, this);
|
||||
unsigned long n = BN_get_word (this);
|
||||
|
||||
if (!BN_is_negative (this))
|
||||
return (n > INT_MAX ? INT_MAX : n);
|
||||
else
|
||||
return (n > INT_MAX ? INT_MIN : - (int)n);
|
||||
}
|
||||
|
||||
uint64 CBigNum::getuint64() const
|
||||
void CBigNum::setint64 (int64 n)
|
||||
{
|
||||
unsigned char pch[sizeof (n) + 6];
|
||||
unsigned char* p = pch + 4;
|
||||
bool fNegative = false;
|
||||
|
||||
if (n < (int64)0)
|
||||
{
|
||||
n = -n;
|
||||
fNegative = true;
|
||||
}
|
||||
|
||||
bool fLeadingZeroes = true;
|
||||
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
unsigned char c = (n >> 56) & 0xff;
|
||||
n <<= 8;
|
||||
|
||||
if (fLeadingZeroes)
|
||||
{
|
||||
if (c == 0)
|
||||
continue;
|
||||
|
||||
if (c & 0x80)
|
||||
*p++ = (fNegative ? 0x80 : 0);
|
||||
else if (fNegative)
|
||||
c |= 0x80;
|
||||
|
||||
fLeadingZeroes = false;
|
||||
}
|
||||
|
||||
*p++ = c;
|
||||
}
|
||||
|
||||
unsigned int nSize = p - (pch + 4);
|
||||
pch[0] = (nSize >> 24) & 0xff;
|
||||
pch[1] = (nSize >> 16) & 0xff;
|
||||
pch[2] = (nSize >> 8) & 0xff;
|
||||
pch[3] = (nSize) & 0xff;
|
||||
BN_mpi2bn (pch, p - pch, this);
|
||||
}
|
||||
|
||||
uint64 CBigNum::getuint64 () const
|
||||
{
|
||||
#if (ULONG_MAX > UINT_MAX)
|
||||
return static_cast<uint64>(getulong());
|
||||
return static_cast<uint64> (getulong ());
|
||||
#else
|
||||
int len = BN_num_bytes(this);
|
||||
if (len > 8)
|
||||
throw std::runtime_error("BN getuint64 overflow");
|
||||
int len = BN_num_bytes (this);
|
||||
|
||||
unsigned char buf[8];
|
||||
memset(buf, 0, sizeof(buf));
|
||||
BN_bn2bin(this, buf + 8 - len);
|
||||
return
|
||||
static_cast<uint64>(buf[0]) << 56 | static_cast<uint64>(buf[1]) << 48 |
|
||||
static_cast<uint64>(buf[2]) << 40 | static_cast<uint64>(buf[3]) << 32 |
|
||||
static_cast<uint64>(buf[4]) << 24 | static_cast<uint64>(buf[5]) << 16 |
|
||||
static_cast<uint64>(buf[6]) << 8 | static_cast<uint64>(buf[7]);
|
||||
if (len > 8)
|
||||
throw std::runtime_error ("BN getuint64 overflow");
|
||||
|
||||
unsigned char buf[8];
|
||||
memset (buf, 0, sizeof (buf));
|
||||
BN_bn2bin (this, buf + 8 - len);
|
||||
return
|
||||
static_cast<uint64> (buf[0]) << 56 | static_cast<uint64> (buf[1]) << 48 |
|
||||
static_cast<uint64> (buf[2]) << 40 | static_cast<uint64> (buf[3]) << 32 |
|
||||
static_cast<uint64> (buf[4]) << 24 | static_cast<uint64> (buf[5]) << 16 |
|
||||
static_cast<uint64> (buf[6]) << 8 | static_cast<uint64> (buf[7]);
|
||||
#endif
|
||||
}
|
||||
|
||||
void CBigNum::setuint64(uint64 n)
|
||||
void CBigNum::setuint64 (uint64 n)
|
||||
{
|
||||
#if (ULONG_MAX > UINT_MAX)
|
||||
setulong(static_cast<unsigned long>(n));
|
||||
setulong (static_cast<unsigned long> (n));
|
||||
#else
|
||||
unsigned char buf[8];
|
||||
buf[0] = static_cast<unsigned char>((n >> 56) & 0xff);
|
||||
buf[1] = static_cast<unsigned char>((n >> 48) & 0xff);
|
||||
buf[2] = static_cast<unsigned char>((n >> 40) & 0xff);
|
||||
buf[3] = static_cast<unsigned char>((n >> 32) & 0xff);
|
||||
buf[4] = static_cast<unsigned char>((n >> 24) & 0xff);
|
||||
buf[5] = static_cast<unsigned char>((n >> 16) & 0xff);
|
||||
buf[6] = static_cast<unsigned char>((n >> 8) & 0xff);
|
||||
buf[7] = static_cast<unsigned char>((n) & 0xff);
|
||||
BN_bin2bn(buf, 8, this);
|
||||
unsigned char buf[8];
|
||||
buf[0] = static_cast<unsigned char> ((n >> 56) & 0xff);
|
||||
buf[1] = static_cast<unsigned char> ((n >> 48) & 0xff);
|
||||
buf[2] = static_cast<unsigned char> ((n >> 40) & 0xff);
|
||||
buf[3] = static_cast<unsigned char> ((n >> 32) & 0xff);
|
||||
buf[4] = static_cast<unsigned char> ((n >> 24) & 0xff);
|
||||
buf[5] = static_cast<unsigned char> ((n >> 16) & 0xff);
|
||||
buf[6] = static_cast<unsigned char> ((n >> 8) & 0xff);
|
||||
buf[7] = static_cast<unsigned char> ((n) & 0xff);
|
||||
BN_bin2bn (buf, 8, this);
|
||||
#endif
|
||||
}
|
||||
|
||||
void CBigNum::setuint256(uint256 const& n)
|
||||
void CBigNum::setuint256 (uint256 const& n)
|
||||
{
|
||||
BN_bin2bn(n.begin(), n.size(), NULL);
|
||||
BN_bin2bn (n.begin (), n.size (), NULL);
|
||||
}
|
||||
|
||||
uint256 CBigNum::getuint256()
|
||||
uint256 CBigNum::getuint256 ()
|
||||
{
|
||||
uint256 ret;
|
||||
unsigned int size = BN_num_bytes(this);
|
||||
if (size > ret.size())
|
||||
return ret;
|
||||
BN_bn2bin(this, ret.begin() + (ret.size() - BN_num_bytes(this)));
|
||||
return ret;
|
||||
uint256 ret;
|
||||
unsigned int size = BN_num_bytes (this);
|
||||
|
||||
if (size > ret.size ())
|
||||
return ret;
|
||||
|
||||
BN_bn2bin (this, ret.begin () + (ret.size () - BN_num_bytes (this)));
|
||||
return ret;
|
||||
}
|
||||
|
||||
void CBigNum::setvch(Blob const& vch)
|
||||
void CBigNum::setvch (Blob const& vch)
|
||||
{
|
||||
Blob vch2(vch.size() + 4);
|
||||
unsigned int nSize = vch.size();
|
||||
// BIGNUM's byte stream format expects 4 bytes of
|
||||
// big endian size data info at the front
|
||||
vch2[0] = (nSize >> 24) & 0xff;
|
||||
vch2[1] = (nSize >> 16) & 0xff;
|
||||
vch2[2] = (nSize >> 8) & 0xff;
|
||||
vch2[3] = (nSize >> 0) & 0xff;
|
||||
// swap data to big endian
|
||||
std::reverse_copy(vch.begin(), vch.end(), vch2.begin() + 4);
|
||||
BN_mpi2bn(&vch2[0], vch2.size(), this);
|
||||
Blob vch2 (vch.size () + 4);
|
||||
unsigned int nSize = vch.size ();
|
||||
// BIGNUM's byte stream format expects 4 bytes of
|
||||
// big endian size data info at the front
|
||||
vch2[0] = (nSize >> 24) & 0xff;
|
||||
vch2[1] = (nSize >> 16) & 0xff;
|
||||
vch2[2] = (nSize >> 8) & 0xff;
|
||||
vch2[3] = (nSize >> 0) & 0xff;
|
||||
// swap data to big endian
|
||||
std::reverse_copy (vch.begin (), vch.end (), vch2.begin () + 4);
|
||||
BN_mpi2bn (&vch2[0], vch2.size (), this);
|
||||
}
|
||||
|
||||
Blob CBigNum::getvch() const
|
||||
Blob CBigNum::getvch () const
|
||||
{
|
||||
unsigned int nSize = BN_bn2mpi(this, NULL);
|
||||
if (nSize < 4)
|
||||
return Blob ();
|
||||
Blob vch(nSize);
|
||||
BN_bn2mpi(this, &vch[0]);
|
||||
vch.erase(vch.begin(), vch.begin() + 4);
|
||||
reverse(vch.begin(), vch.end());
|
||||
return vch;
|
||||
unsigned int nSize = BN_bn2mpi (this, NULL);
|
||||
|
||||
if (nSize < 4)
|
||||
return Blob ();
|
||||
|
||||
Blob vch (nSize);
|
||||
BN_bn2mpi (this, &vch[0]);
|
||||
vch.erase (vch.begin (), vch.begin () + 4);
|
||||
reverse (vch.begin (), vch.end ());
|
||||
return vch;
|
||||
}
|
||||
|
||||
CBigNum& CBigNum::SetCompact(unsigned int nCompact)
|
||||
CBigNum& CBigNum::SetCompact (unsigned int nCompact)
|
||||
{
|
||||
unsigned int nSize = nCompact >> 24;
|
||||
Blob vch(4 + nSize);
|
||||
vch[3] = nSize;
|
||||
if (nSize >= 1) vch[4] = (nCompact >> 16) & 0xff;
|
||||
if (nSize >= 2) vch[5] = (nCompact >> 8) & 0xff;
|
||||
if (nSize >= 3) vch[6] = (nCompact >> 0) & 0xff;
|
||||
BN_mpi2bn(&vch[0], vch.size(), this);
|
||||
return *this;
|
||||
unsigned int nSize = nCompact >> 24;
|
||||
Blob vch (4 + nSize);
|
||||
vch[3] = nSize;
|
||||
|
||||
if (nSize >= 1) vch[4] = (nCompact >> 16) & 0xff;
|
||||
|
||||
if (nSize >= 2) vch[5] = (nCompact >> 8) & 0xff;
|
||||
|
||||
if (nSize >= 3) vch[6] = (nCompact >> 0) & 0xff;
|
||||
|
||||
BN_mpi2bn (&vch[0], vch.size (), this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
unsigned int CBigNum::GetCompact() const
|
||||
unsigned int CBigNum::GetCompact () const
|
||||
{
|
||||
unsigned int nSize = BN_bn2mpi(this, NULL);
|
||||
Blob vch(nSize);
|
||||
nSize -= 4;
|
||||
BN_bn2mpi(this, &vch[0]);
|
||||
unsigned int nCompact = nSize << 24;
|
||||
if (nSize >= 1) nCompact |= (vch[4] << 16);
|
||||
if (nSize >= 2) nCompact |= (vch[5] << 8);
|
||||
if (nSize >= 3) nCompact |= (vch[6] << 0);
|
||||
return nCompact;
|
||||
unsigned int nSize = BN_bn2mpi (this, NULL);
|
||||
Blob vch (nSize);
|
||||
nSize -= 4;
|
||||
BN_bn2mpi (this, &vch[0]);
|
||||
unsigned int nCompact = nSize << 24;
|
||||
|
||||
if (nSize >= 1) nCompact |= (vch[4] << 16);
|
||||
|
||||
if (nSize >= 2) nCompact |= (vch[5] << 8);
|
||||
|
||||
if (nSize >= 3) nCompact |= (vch[6] << 0);
|
||||
|
||||
return nCompact;
|
||||
}
|
||||
|
||||
void CBigNum::SetHex(const std::string& str)
|
||||
void CBigNum::SetHex (const std::string& str)
|
||||
{
|
||||
// skip 0x
|
||||
const char* psz = str.c_str();
|
||||
while (isspace(*psz))
|
||||
psz++;
|
||||
bool fNegative = false;
|
||||
if (*psz == '-')
|
||||
{
|
||||
fNegative = true;
|
||||
psz++;
|
||||
}
|
||||
if (psz[0] == '0' && tolower(psz[1]) == 'x')
|
||||
psz += 2;
|
||||
while (isspace(*psz))
|
||||
psz++;
|
||||
// skip 0x
|
||||
const char* psz = str.c_str ();
|
||||
|
||||
// hex string to bignum
|
||||
static char phexdigit[256] = {
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,1,2,3,4,5,6,7,8,9,0,0,0,0,0,0,
|
||||
0,0xa,0xb,0xc,0xd,0xe,0xf,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0xa,0xb,0xc,0xd,0xe,0xf,0,0,0,0,0,0,0,0,0 };
|
||||
*this = 0;
|
||||
while (isxdigit(*psz))
|
||||
{
|
||||
*this <<= 4;
|
||||
int n = phexdigit[(int) *psz++];
|
||||
*this += n;
|
||||
}
|
||||
if (fNegative)
|
||||
*this = 0 - *this;
|
||||
while (isspace (*psz))
|
||||
psz++;
|
||||
|
||||
bool fNegative = false;
|
||||
|
||||
if (*psz == '-')
|
||||
{
|
||||
fNegative = true;
|
||||
psz++;
|
||||
}
|
||||
|
||||
if (psz[0] == '0' && tolower (psz[1]) == 'x')
|
||||
psz += 2;
|
||||
|
||||
while (isspace (*psz))
|
||||
psz++;
|
||||
|
||||
// hex string to bignum
|
||||
static char phexdigit[256] =
|
||||
{
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0,
|
||||
0, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
*this = 0;
|
||||
|
||||
while (isxdigit (*psz))
|
||||
{
|
||||
*this <<= 4;
|
||||
int n = phexdigit[ (int) * psz++];
|
||||
*this += n;
|
||||
}
|
||||
|
||||
if (fNegative)
|
||||
*this = 0 - *this;
|
||||
}
|
||||
|
||||
std::string CBigNum::ToString(int nBase) const
|
||||
std::string CBigNum::ToString (int nBase) const
|
||||
{
|
||||
CAutoBN_CTX pctx;
|
||||
CBigNum bnBase = nBase;
|
||||
CBigNum bn0 = 0;
|
||||
std::string str;
|
||||
CBigNum bn = *this;
|
||||
BN_set_negative(&bn, false);
|
||||
CBigNum dv;
|
||||
CBigNum rem;
|
||||
if (BN_cmp(&bn, &bn0) == 0)
|
||||
return "0";
|
||||
while (BN_cmp(&bn, &bn0) > 0)
|
||||
{
|
||||
if (!BN_div(&dv, &rem, &bn, &bnBase, pctx))
|
||||
throw bignum_error("CBigNum::ToString() : BN_div failed");
|
||||
bn = dv;
|
||||
unsigned int c = rem.getuint();
|
||||
str += "0123456789abcdef"[c];
|
||||
}
|
||||
if (BN_is_negative(this))
|
||||
str += "-";
|
||||
reverse(str.begin(), str.end());
|
||||
return str;
|
||||
CAutoBN_CTX pctx;
|
||||
CBigNum bnBase = nBase;
|
||||
CBigNum bn0 = 0;
|
||||
std::string str;
|
||||
CBigNum bn = *this;
|
||||
BN_set_negative (&bn, false);
|
||||
CBigNum dv;
|
||||
CBigNum rem;
|
||||
|
||||
if (BN_cmp (&bn, &bn0) == 0)
|
||||
return "0";
|
||||
|
||||
while (BN_cmp (&bn, &bn0) > 0)
|
||||
{
|
||||
if (!BN_div (&dv, &rem, &bn, &bnBase, pctx))
|
||||
throw bignum_error ("CBigNum::ToString() : BN_div failed");
|
||||
|
||||
bn = dv;
|
||||
unsigned int c = rem.getuint ();
|
||||
str += "0123456789abcdef"[c];
|
||||
}
|
||||
|
||||
if (BN_is_negative (this))
|
||||
str += "-";
|
||||
|
||||
reverse (str.begin (), str.end ());
|
||||
return str;
|
||||
}
|
||||
|
||||
std::string CBigNum::GetHex() const
|
||||
std::string CBigNum::GetHex () const
|
||||
{
|
||||
return ToString(16);
|
||||
return ToString (16);
|
||||
}
|
||||
|
||||
bool CBigNum::operator!() const
|
||||
bool CBigNum::operator! () const
|
||||
{
|
||||
return BN_is_zero(this);
|
||||
return BN_is_zero (this);
|
||||
}
|
||||
|
||||
CBigNum& CBigNum::operator+=(const CBigNum& b)
|
||||
CBigNum& CBigNum::operator+= (const CBigNum& b)
|
||||
{
|
||||
if (!BN_add(this, this, &b))
|
||||
throw bignum_error("CBigNum::operator+= : BN_add failed");
|
||||
return *this;
|
||||
if (!BN_add (this, this, &b))
|
||||
throw bignum_error ("CBigNum::operator+= : BN_add failed");
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
CBigNum& CBigNum::operator-=(const CBigNum& b)
|
||||
CBigNum& CBigNum::operator-= (const CBigNum& b)
|
||||
{
|
||||
*this = *this - b;
|
||||
return *this;
|
||||
*this = *this - b;
|
||||
return *this;
|
||||
}
|
||||
|
||||
CBigNum& CBigNum::operator*=(const CBigNum& b)
|
||||
CBigNum& CBigNum::operator*= (const CBigNum& b)
|
||||
{
|
||||
CAutoBN_CTX pctx;
|
||||
if (!BN_mul(this, this, &b, pctx))
|
||||
throw bignum_error("CBigNum::operator*= : BN_mul failed");
|
||||
return *this;
|
||||
CAutoBN_CTX pctx;
|
||||
|
||||
if (!BN_mul (this, this, &b, pctx))
|
||||
throw bignum_error ("CBigNum::operator*= : BN_mul failed");
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
CBigNum& CBigNum::operator/=(const CBigNum& b)
|
||||
CBigNum& CBigNum::operator/= (const CBigNum& b)
|
||||
{
|
||||
*this = *this / b;
|
||||
return *this;
|
||||
*this = *this / b;
|
||||
return *this;
|
||||
}
|
||||
|
||||
CBigNum& CBigNum::operator%=(const CBigNum& b)
|
||||
CBigNum& CBigNum::operator%= (const CBigNum& b)
|
||||
{
|
||||
*this = *this % b;
|
||||
return *this;
|
||||
*this = *this % b;
|
||||
return *this;
|
||||
}
|
||||
|
||||
CBigNum& CBigNum::operator<<=(unsigned int shift)
|
||||
CBigNum& CBigNum::operator<<= (unsigned int shift)
|
||||
{
|
||||
if (!BN_lshift(this, this, shift))
|
||||
throw bignum_error("CBigNum:operator<<= : BN_lshift failed");
|
||||
return *this;
|
||||
if (!BN_lshift (this, this, shift))
|
||||
throw bignum_error ("CBigNum:operator<<= : BN_lshift failed");
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
CBigNum& CBigNum::operator>>=(unsigned int shift)
|
||||
CBigNum& CBigNum::operator>>= (unsigned int shift)
|
||||
{
|
||||
// Note: BN_rshift segfaults on 64-bit if 2^shift is greater than the number
|
||||
// if built on ubuntu 9.04 or 9.10, probably depends on version of openssl
|
||||
CBigNum a = 1;
|
||||
a <<= shift;
|
||||
if (BN_cmp(&a, this) > 0)
|
||||
{
|
||||
*this = 0;
|
||||
return *this;
|
||||
}
|
||||
// Note: BN_rshift segfaults on 64-bit if 2^shift is greater than the number
|
||||
// if built on ubuntu 9.04 or 9.10, probably depends on version of openssl
|
||||
CBigNum a = 1;
|
||||
a <<= shift;
|
||||
|
||||
if (!BN_rshift(this, this, shift))
|
||||
throw bignum_error("CBigNum:operator>>= : BN_rshift failed");
|
||||
return *this;
|
||||
if (BN_cmp (&a, this) > 0)
|
||||
{
|
||||
*this = 0;
|
||||
return *this;
|
||||
}
|
||||
|
||||
if (!BN_rshift (this, this, shift))
|
||||
throw bignum_error ("CBigNum:operator>>= : BN_rshift failed");
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
CBigNum& CBigNum::operator++()
|
||||
CBigNum& CBigNum::operator++ ()
|
||||
{
|
||||
// prefix operator
|
||||
if (!BN_add(this, this, BN_value_one()))
|
||||
throw bignum_error("CBigNum::operator++ : BN_add failed");
|
||||
return *this;
|
||||
// prefix operator
|
||||
if (!BN_add (this, this, BN_value_one ()))
|
||||
throw bignum_error ("CBigNum::operator++ : BN_add failed");
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
const CBigNum CBigNum::operator++(int)
|
||||
const CBigNum CBigNum::operator++ (int)
|
||||
{
|
||||
// postfix operator
|
||||
const CBigNum ret = *this;
|
||||
++(*this);
|
||||
return ret;
|
||||
// postfix operator
|
||||
const CBigNum ret = *this;
|
||||
++ (*this);
|
||||
return ret;
|
||||
}
|
||||
|
||||
CBigNum& CBigNum::operator--()
|
||||
CBigNum& CBigNum::operator-- ()
|
||||
{
|
||||
// prefix operator
|
||||
CBigNum r;
|
||||
if (!BN_sub(&r, this, BN_value_one()))
|
||||
throw bignum_error("CBigNum::operator-- : BN_sub failed");
|
||||
*this = r;
|
||||
return *this;
|
||||
// prefix operator
|
||||
CBigNum r;
|
||||
|
||||
if (!BN_sub (&r, this, BN_value_one ()))
|
||||
throw bignum_error ("CBigNum::operator-- : BN_sub failed");
|
||||
|
||||
*this = r;
|
||||
return *this;
|
||||
}
|
||||
|
||||
const CBigNum CBigNum::operator--(int)
|
||||
const CBigNum CBigNum::operator-- (int)
|
||||
{
|
||||
// postfix operator
|
||||
const CBigNum ret = *this;
|
||||
--(*this);
|
||||
return ret;
|
||||
// postfix operator
|
||||
const CBigNum ret = *this;
|
||||
-- (*this);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void CBigNum::setulong(unsigned long n)
|
||||
void CBigNum::setulong (unsigned long n)
|
||||
{
|
||||
if (!BN_set_word(this, n))
|
||||
throw bignum_error("CBigNum conversion from unsigned long : BN_set_word failed");
|
||||
if (!BN_set_word (this, n))
|
||||
throw bignum_error ("CBigNum conversion from unsigned long : BN_set_word failed");
|
||||
}
|
||||
|
||||
unsigned long CBigNum::getulong() const
|
||||
unsigned long CBigNum::getulong () const
|
||||
{
|
||||
return BN_get_word(this);
|
||||
return BN_get_word (this);
|
||||
}
|
||||
|
||||
const CBigNum operator+(const CBigNum& a, const CBigNum& b)
|
||||
const CBigNum operator+ (const CBigNum& a, const CBigNum& b)
|
||||
{
|
||||
CBigNum r;
|
||||
if (!BN_add(&r, &a, &b))
|
||||
throw bignum_error("CBigNum::operator+ : BN_add failed");
|
||||
return r;
|
||||
CBigNum r;
|
||||
|
||||
if (!BN_add (&r, &a, &b))
|
||||
throw bignum_error ("CBigNum::operator+ : BN_add failed");
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
const CBigNum operator-(const CBigNum& a, const CBigNum& b)
|
||||
const CBigNum operator- (const CBigNum& a, const CBigNum& b)
|
||||
{
|
||||
CBigNum r;
|
||||
if (!BN_sub(&r, &a, &b))
|
||||
throw bignum_error("CBigNum::operator- : BN_sub failed");
|
||||
return r;
|
||||
CBigNum r;
|
||||
|
||||
if (!BN_sub (&r, &a, &b))
|
||||
throw bignum_error ("CBigNum::operator- : BN_sub failed");
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
const CBigNum operator-(const CBigNum& a)
|
||||
const CBigNum operator- (const CBigNum& a)
|
||||
{
|
||||
CBigNum r(a);
|
||||
BN_set_negative(&r, !BN_is_negative(&r));
|
||||
return r;
|
||||
CBigNum r (a);
|
||||
BN_set_negative (&r, !BN_is_negative (&r));
|
||||
return r;
|
||||
}
|
||||
|
||||
const CBigNum operator*(const CBigNum& a, const CBigNum& b)
|
||||
const CBigNum operator* (const CBigNum& a, const CBigNum& b)
|
||||
{
|
||||
CAutoBN_CTX pctx;
|
||||
CBigNum r;
|
||||
if (!BN_mul(&r, &a, &b, pctx))
|
||||
throw bignum_error("CBigNum::operator* : BN_mul failed");
|
||||
return r;
|
||||
CAutoBN_CTX pctx;
|
||||
CBigNum r;
|
||||
|
||||
if (!BN_mul (&r, &a, &b, pctx))
|
||||
throw bignum_error ("CBigNum::operator* : BN_mul failed");
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
const CBigNum operator/(const CBigNum& a, const CBigNum& b)
|
||||
const CBigNum operator/ (const CBigNum& a, const CBigNum& b)
|
||||
{
|
||||
CAutoBN_CTX pctx;
|
||||
CBigNum r;
|
||||
if (!BN_div(&r, NULL, &a, &b, pctx))
|
||||
throw bignum_error("CBigNum::operator/ : BN_div failed");
|
||||
return r;
|
||||
CAutoBN_CTX pctx;
|
||||
CBigNum r;
|
||||
|
||||
if (!BN_div (&r, NULL, &a, &b, pctx))
|
||||
throw bignum_error ("CBigNum::operator/ : BN_div failed");
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
const CBigNum operator%(const CBigNum& a, const CBigNum& b)
|
||||
const CBigNum operator% (const CBigNum& a, const CBigNum& b)
|
||||
{
|
||||
CAutoBN_CTX pctx;
|
||||
CBigNum r;
|
||||
if (!BN_mod(&r, &a, &b, pctx))
|
||||
throw bignum_error("CBigNum::operator% : BN_div failed");
|
||||
return r;
|
||||
CAutoBN_CTX pctx;
|
||||
CBigNum r;
|
||||
|
||||
if (!BN_mod (&r, &a, &b, pctx))
|
||||
throw bignum_error ("CBigNum::operator% : BN_div failed");
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
const CBigNum operator<<(const CBigNum& a, unsigned int shift)
|
||||
const CBigNum operator<< (const CBigNum& a, unsigned int shift)
|
||||
{
|
||||
CBigNum r;
|
||||
if (!BN_lshift(&r, &a, shift))
|
||||
throw bignum_error("CBigNum:operator<< : BN_lshift failed");
|
||||
return r;
|
||||
CBigNum r;
|
||||
|
||||
if (!BN_lshift (&r, &a, shift))
|
||||
throw bignum_error ("CBigNum:operator<< : BN_lshift failed");
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
const CBigNum operator>>(const CBigNum& a, unsigned int shift)
|
||||
const CBigNum operator>> (const CBigNum& a, unsigned int shift)
|
||||
{
|
||||
CBigNum r = a;
|
||||
r >>= shift;
|
||||
return r;
|
||||
CBigNum r = a;
|
||||
r >>= shift;
|
||||
return r;
|
||||
}
|
||||
|
||||
bool operator== (const CBigNum& a, const CBigNum& b)
|
||||
{
|
||||
return (BN_cmp(&a, &b) == 0);
|
||||
return (BN_cmp (&a, &b) == 0);
|
||||
}
|
||||
|
||||
bool operator!= (const CBigNum& a, const CBigNum& b)
|
||||
{
|
||||
return (BN_cmp(&a, &b) != 0);
|
||||
return (BN_cmp (&a, &b) != 0);
|
||||
}
|
||||
|
||||
bool operator<= (const CBigNum& a, const CBigNum& b)
|
||||
{
|
||||
return (BN_cmp(&a, &b) <= 0);
|
||||
return (BN_cmp (&a, &b) <= 0);
|
||||
}
|
||||
|
||||
bool operator>= (const CBigNum& a, const CBigNum& b)
|
||||
{
|
||||
return (BN_cmp(&a, &b) >= 0);
|
||||
return (BN_cmp (&a, &b) >= 0);
|
||||
}
|
||||
|
||||
bool operator< (const CBigNum& a, const CBigNum& b)
|
||||
{
|
||||
return (BN_cmp(&a, &b) < 0);
|
||||
return (BN_cmp (&a, &b) < 0);
|
||||
}
|
||||
|
||||
bool operator> (const CBigNum& a, const CBigNum& b)
|
||||
{
|
||||
return (BN_cmp(&a, &b) > 0);
|
||||
return (BN_cmp (&a, &b) > 0);
|
||||
}
|
||||
|
||||
#if (ULONG_MAX > UINT_MAX)
|
||||
|
||||
int BN_add_word64 (BIGNUM* bn, uint64 word)
|
||||
{
|
||||
return BN_add_word(bn, word);
|
||||
return BN_add_word (bn, word);
|
||||
}
|
||||
|
||||
int BN_sub_word64 (BIGNUM* bn, uint64 word)
|
||||
{
|
||||
return BN_sub_word(bn, word);
|
||||
return BN_sub_word (bn, word);
|
||||
}
|
||||
|
||||
int BN_mul_word64 (BIGNUM* bn, uint64 word)
|
||||
{
|
||||
return BN_mul_word(bn, word);
|
||||
return BN_mul_word (bn, word);
|
||||
}
|
||||
|
||||
uint64 BN_div_word64 (BIGNUM* bn, uint64 word)
|
||||
{
|
||||
return BN_div_word(bn, word);
|
||||
return BN_div_word (bn, word);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
int BN_add_word64 (BIGNUM *a, uint64 w)
|
||||
int BN_add_word64 (BIGNUM* a, uint64 w)
|
||||
{
|
||||
CBigNum bn(w);
|
||||
return BN_add(a, &bn, a);
|
||||
CBigNum bn (w);
|
||||
return BN_add (a, &bn, a);
|
||||
}
|
||||
|
||||
int BN_sub_word64 (BIGNUM *a, uint64 w)
|
||||
int BN_sub_word64 (BIGNUM* a, uint64 w)
|
||||
{
|
||||
CBigNum bn(w);
|
||||
return BN_sub(a, &bn, a);
|
||||
CBigNum bn (w);
|
||||
return BN_sub (a, &bn, a);
|
||||
}
|
||||
|
||||
int BN_mul_word64 (BIGNUM *a, uint64 w)
|
||||
int BN_mul_word64 (BIGNUM* a, uint64 w)
|
||||
{
|
||||
CBigNum bn(w);
|
||||
CAutoBN_CTX ctx;
|
||||
return BN_mul(a, &bn, a, ctx);
|
||||
CBigNum bn (w);
|
||||
CAutoBN_CTX ctx;
|
||||
return BN_mul (a, &bn, a, ctx);
|
||||
}
|
||||
|
||||
uint64 BN_div_word64 (BIGNUM *a, uint64 w)
|
||||
uint64 BN_div_word64 (BIGNUM* a, uint64 w)
|
||||
{
|
||||
CBigNum bn(w);
|
||||
CAutoBN_CTX ctx;
|
||||
return (BN_div(a, NULL, a, &bn, ctx) == 1) ? 0 : ((uint64)-1);
|
||||
CBigNum bn (w);
|
||||
CAutoBN_CTX ctx;
|
||||
return (BN_div (a, NULL, a, &bn, ctx) == 1) ? 0 : ((uint64) - 1);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
class bignum_error : public std::runtime_error
|
||||
{
|
||||
public:
|
||||
explicit bignum_error(const std::string& str) : std::runtime_error(str) {}
|
||||
explicit bignum_error (const std::string& str) : std::runtime_error (str) {}
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@@ -22,111 +22,128 @@ public:
|
||||
class CAutoBN_CTX
|
||||
{
|
||||
private:
|
||||
CAutoBN_CTX(const CAutoBN_CTX&); // no implementation
|
||||
CAutoBN_CTX& operator=(const CAutoBN_CTX&); // no implementation
|
||||
CAutoBN_CTX (const CAutoBN_CTX&); // no implementation
|
||||
CAutoBN_CTX& operator= (const CAutoBN_CTX&); // no implementation
|
||||
|
||||
protected:
|
||||
BN_CTX* pctx;
|
||||
CAutoBN_CTX& operator=(BN_CTX* pnew) { pctx = pnew; return *this; }
|
||||
BN_CTX* pctx;
|
||||
CAutoBN_CTX& operator= (BN_CTX* pnew)
|
||||
{
|
||||
pctx = pnew;
|
||||
return *this;
|
||||
}
|
||||
|
||||
public:
|
||||
CAutoBN_CTX()
|
||||
{
|
||||
pctx = BN_CTX_new();
|
||||
if (pctx == NULL)
|
||||
throw bignum_error("CAutoBN_CTX : BN_CTX_new() returned NULL");
|
||||
}
|
||||
CAutoBN_CTX ()
|
||||
{
|
||||
pctx = BN_CTX_new ();
|
||||
|
||||
~CAutoBN_CTX()
|
||||
{
|
||||
if (pctx != NULL)
|
||||
BN_CTX_free(pctx);
|
||||
}
|
||||
if (pctx == NULL)
|
||||
throw bignum_error ("CAutoBN_CTX : BN_CTX_new() returned NULL");
|
||||
}
|
||||
|
||||
operator BN_CTX*() { return pctx; }
|
||||
BN_CTX& operator*() { return *pctx; }
|
||||
BN_CTX** operator&() { return &pctx; }
|
||||
bool operator!() { return (pctx == NULL); }
|
||||
~CAutoBN_CTX ()
|
||||
{
|
||||
if (pctx != NULL)
|
||||
BN_CTX_free (pctx);
|
||||
}
|
||||
|
||||
operator BN_CTX* ()
|
||||
{
|
||||
return pctx;
|
||||
}
|
||||
BN_CTX& operator* ()
|
||||
{
|
||||
return *pctx;
|
||||
}
|
||||
BN_CTX** operator& ()
|
||||
{
|
||||
return &pctx;
|
||||
}
|
||||
bool operator! ()
|
||||
{
|
||||
return (pctx == NULL);
|
||||
}
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// VFALCO TODO figure out a way to remove the dependency on openssl in the
|
||||
// header. Maybe rewrite this to use cryptopp.
|
||||
// header. Maybe rewrite this to use cryptopp.
|
||||
|
||||
class CBigNum : public BIGNUM
|
||||
{
|
||||
public:
|
||||
CBigNum();
|
||||
CBigNum(const CBigNum& b);
|
||||
CBigNum& operator=(const CBigNum& b);
|
||||
CBigNum(char n);
|
||||
CBigNum(short n);
|
||||
CBigNum(int n);
|
||||
CBigNum(long n);
|
||||
CBigNum(int64 n);
|
||||
CBigNum(unsigned char n);
|
||||
CBigNum(unsigned short n);
|
||||
CBigNum(unsigned int n);
|
||||
CBigNum(uint64 n);
|
||||
explicit CBigNum(uint256 n);
|
||||
explicit CBigNum(Blob const& vch);
|
||||
~CBigNum();
|
||||
CBigNum ();
|
||||
CBigNum (const CBigNum& b);
|
||||
CBigNum& operator= (const CBigNum& b);
|
||||
CBigNum (char n);
|
||||
CBigNum (short n);
|
||||
CBigNum (int n);
|
||||
CBigNum (long n);
|
||||
CBigNum (int64 n);
|
||||
CBigNum (unsigned char n);
|
||||
CBigNum (unsigned short n);
|
||||
CBigNum (unsigned int n);
|
||||
CBigNum (uint64 n);
|
||||
explicit CBigNum (uint256 n);
|
||||
explicit CBigNum (Blob const& vch);
|
||||
~CBigNum ();
|
||||
|
||||
void setuint(unsigned int n);
|
||||
unsigned int getuint() const;
|
||||
int getint() const;
|
||||
void setint64(int64 n);
|
||||
uint64 getuint64() const;
|
||||
void setuint64(uint64 n);
|
||||
void setuint256(uint256 const& n);
|
||||
uint256 getuint256();
|
||||
void setvch(Blob const& vch);
|
||||
Blob getvch() const;
|
||||
CBigNum& SetCompact(unsigned int nCompact);
|
||||
unsigned int GetCompact() const;
|
||||
void SetHex(const std::string& str);
|
||||
std::string ToString(int nBase=10) const;
|
||||
std::string GetHex() const;
|
||||
bool operator!() const;
|
||||
CBigNum& operator+=(const CBigNum& b);
|
||||
CBigNum& operator-=(const CBigNum& b);
|
||||
CBigNum& operator*=(const CBigNum& b);
|
||||
CBigNum& operator/=(const CBigNum& b);
|
||||
CBigNum& operator%=(const CBigNum& b);
|
||||
CBigNum& operator<<=(unsigned int shift);
|
||||
CBigNum& operator>>=(unsigned int shift);
|
||||
CBigNum& operator++();
|
||||
CBigNum& operator--();
|
||||
const CBigNum operator++(int);
|
||||
const CBigNum operator--(int);
|
||||
void setuint (unsigned int n);
|
||||
unsigned int getuint () const;
|
||||
int getint () const;
|
||||
void setint64 (int64 n);
|
||||
uint64 getuint64 () const;
|
||||
void setuint64 (uint64 n);
|
||||
void setuint256 (uint256 const& n);
|
||||
uint256 getuint256 ();
|
||||
void setvch (Blob const& vch);
|
||||
Blob getvch () const;
|
||||
CBigNum& SetCompact (unsigned int nCompact);
|
||||
unsigned int GetCompact () const;
|
||||
void SetHex (const std::string& str);
|
||||
std::string ToString (int nBase = 10) const;
|
||||
std::string GetHex () const;
|
||||
bool operator! () const;
|
||||
CBigNum& operator+= (const CBigNum& b);
|
||||
CBigNum& operator-= (const CBigNum& b);
|
||||
CBigNum& operator*= (const CBigNum& b);
|
||||
CBigNum& operator/= (const CBigNum& b);
|
||||
CBigNum& operator%= (const CBigNum& b);
|
||||
CBigNum& operator<<= (unsigned int shift);
|
||||
CBigNum& operator>>= (unsigned int shift);
|
||||
CBigNum& operator++ ();
|
||||
CBigNum& operator-- ();
|
||||
const CBigNum operator++ (int);
|
||||
const CBigNum operator-- (int);
|
||||
|
||||
friend inline const CBigNum operator-(const CBigNum& a, const CBigNum& b);
|
||||
friend inline const CBigNum operator/(const CBigNum& a, const CBigNum& b);
|
||||
friend inline const CBigNum operator%(const CBigNum& a, const CBigNum& b);
|
||||
friend inline const CBigNum operator- (const CBigNum& a, const CBigNum& b);
|
||||
friend inline const CBigNum operator/ (const CBigNum& a, const CBigNum& b);
|
||||
friend inline const CBigNum operator% (const CBigNum& a, const CBigNum& b);
|
||||
|
||||
private:
|
||||
// private because the size of an unsigned long varies by platform
|
||||
// private because the size of an unsigned long varies by platform
|
||||
|
||||
void setulong(unsigned long n);
|
||||
unsigned long getulong() const;
|
||||
void setulong (unsigned long n);
|
||||
unsigned long getulong () const;
|
||||
};
|
||||
|
||||
const CBigNum operator+(const CBigNum& a, const CBigNum& b);
|
||||
const CBigNum operator-(const CBigNum& a, const CBigNum& b);
|
||||
const CBigNum operator-(const CBigNum& a);
|
||||
const CBigNum operator*(const CBigNum& a, const CBigNum& b);
|
||||
const CBigNum operator/(const CBigNum& a, const CBigNum& b);
|
||||
const CBigNum operator%(const CBigNum& a, const CBigNum& b);
|
||||
const CBigNum operator<<(const CBigNum& a, unsigned int shift);
|
||||
const CBigNum operator>>(const CBigNum& a, unsigned int shift);
|
||||
const CBigNum operator+ (const CBigNum& a, const CBigNum& b);
|
||||
const CBigNum operator- (const CBigNum& a, const CBigNum& b);
|
||||
const CBigNum operator- (const CBigNum& a);
|
||||
const CBigNum operator* (const CBigNum& a, const CBigNum& b);
|
||||
const CBigNum operator/ (const CBigNum& a, const CBigNum& b);
|
||||
const CBigNum operator% (const CBigNum& a, const CBigNum& b);
|
||||
const CBigNum operator<< (const CBigNum& a, unsigned int shift);
|
||||
const CBigNum operator>> (const CBigNum& a, unsigned int shift);
|
||||
|
||||
bool operator==(const CBigNum& a, const CBigNum& b);
|
||||
bool operator!=(const CBigNum& a, const CBigNum& b);
|
||||
bool operator<=(const CBigNum& a, const CBigNum& b);
|
||||
bool operator>=(const CBigNum& a, const CBigNum& b);
|
||||
bool operator<(const CBigNum& a, const CBigNum& b);
|
||||
bool operator>(const CBigNum& a, const CBigNum& b);
|
||||
bool operator== (const CBigNum& a, const CBigNum& b);
|
||||
bool operator!= (const CBigNum& a, const CBigNum& b);
|
||||
bool operator<= (const CBigNum& a, const CBigNum& b);
|
||||
bool operator>= (const CBigNum& a, const CBigNum& b);
|
||||
bool operator< (const CBigNum& a, const CBigNum& b);
|
||||
bool operator> (const CBigNum& a, const CBigNum& b);
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@@ -141,10 +158,10 @@ bool operator>(const CBigNum& a, const CBigNum& b);
|
||||
//#endif
|
||||
|
||||
// VFALCO I believe only STAmount uses these
|
||||
extern int BN_add_word64 (BIGNUM *a, uint64 w);
|
||||
extern int BN_sub_word64 (BIGNUM *a, uint64 w);
|
||||
extern int BN_mul_word64 (BIGNUM *a, uint64 w);
|
||||
extern uint64 BN_div_word64 (BIGNUM *a, uint64 w);
|
||||
extern int BN_add_word64 (BIGNUM* a, uint64 w);
|
||||
extern int BN_sub_word64 (BIGNUM* a, uint64 w);
|
||||
extern int BN_mul_word64 (BIGNUM* a, uint64 w);
|
||||
extern uint64 BN_div_word64 (BIGNUM* a, uint64 w);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
Copyright (c) 2011-2013, OpenCoin, Inc.
|
||||
Copyright (c) 2011-2013, OpenCoin, Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
@@ -36,261 +36,280 @@
|
||||
/*
|
||||
int static inline EC_KEY_regenerate_key(EC_KEY *eckey, BIGNUM *priv_key)
|
||||
{
|
||||
int okay = 0;
|
||||
BN_CTX *ctx = NULL;
|
||||
EC_POINT *pub_key = NULL;
|
||||
int okay = 0;
|
||||
BN_CTX *ctx = NULL;
|
||||
EC_POINT *pub_key = NULL;
|
||||
|
||||
if (!eckey) return 0;
|
||||
if (!eckey) return 0;
|
||||
|
||||
const EC_GROUP *group = EC_KEY_get0_group(eckey);
|
||||
const EC_GROUP *group = EC_KEY_get0_group(eckey);
|
||||
|
||||
if ((ctx = BN_CTX_new()) == NULL)
|
||||
goto err;
|
||||
if ((ctx = BN_CTX_new()) == NULL)
|
||||
goto err;
|
||||
|
||||
pub_key = EC_POINT_new(group);
|
||||
pub_key = EC_POINT_new(group);
|
||||
|
||||
if (pub_key == NULL)
|
||||
goto err;
|
||||
if (pub_key == NULL)
|
||||
goto err;
|
||||
|
||||
if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, ctx))
|
||||
goto err;
|
||||
if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, ctx))
|
||||
goto err;
|
||||
|
||||
EC_KEY_set_conv_form(eckey, POINT_CONVERSION_COMPRESSED);
|
||||
EC_KEY_set_private_key(eckey, priv_key);
|
||||
EC_KEY_set_public_key(eckey, pub_key);
|
||||
EC_KEY_set_conv_form(eckey, POINT_CONVERSION_COMPRESSED);
|
||||
EC_KEY_set_private_key(eckey, priv_key);
|
||||
EC_KEY_set_public_key(eckey, pub_key);
|
||||
|
||||
okay = 1;
|
||||
okay = 1;
|
||||
|
||||
err:
|
||||
|
||||
if (pub_key)
|
||||
EC_POINT_free(pub_key);
|
||||
if (ctx != NULL)
|
||||
BN_CTX_free(ctx);
|
||||
if (pub_key)
|
||||
EC_POINT_free(pub_key);
|
||||
if (ctx != NULL)
|
||||
BN_CTX_free(ctx);
|
||||
|
||||
return (okay);
|
||||
return (okay);
|
||||
}
|
||||
*/
|
||||
|
||||
class key_error : public std::runtime_error
|
||||
{
|
||||
public:
|
||||
explicit key_error(const std::string& str) : std::runtime_error(str) {}
|
||||
explicit key_error (const std::string& str) : std::runtime_error (str) {}
|
||||
};
|
||||
|
||||
class CKey
|
||||
{
|
||||
protected:
|
||||
EC_KEY* pkey;
|
||||
bool fSet;
|
||||
EC_KEY* pkey;
|
||||
bool fSet;
|
||||
|
||||
|
||||
public:
|
||||
typedef boost::shared_ptr<CKey> pointer;
|
||||
typedef boost::shared_ptr<CKey> pointer;
|
||||
|
||||
CKey()
|
||||
{
|
||||
pkey = EC_KEY_new_by_curve_name(NID_secp256k1);
|
||||
EC_KEY_set_conv_form(pkey, POINT_CONVERSION_COMPRESSED);
|
||||
if (pkey == NULL)
|
||||
throw key_error("CKey::CKey() : EC_KEY_new_by_curve_name failed");
|
||||
fSet = false;
|
||||
}
|
||||
CKey ()
|
||||
{
|
||||
pkey = EC_KEY_new_by_curve_name (NID_secp256k1);
|
||||
EC_KEY_set_conv_form (pkey, POINT_CONVERSION_COMPRESSED);
|
||||
|
||||
CKey(const CKey& b)
|
||||
{
|
||||
pkey = EC_KEY_dup(b.pkey);
|
||||
EC_KEY_set_conv_form(pkey, POINT_CONVERSION_COMPRESSED);
|
||||
if (pkey == NULL)
|
||||
throw key_error("CKey::CKey(const CKey&) : EC_KEY_dup failed");
|
||||
fSet = b.fSet;
|
||||
}
|
||||
if (pkey == NULL)
|
||||
throw key_error ("CKey::CKey() : EC_KEY_new_by_curve_name failed");
|
||||
|
||||
CKey& operator=(const CKey& b)
|
||||
{
|
||||
if (!EC_KEY_copy(pkey, b.pkey))
|
||||
throw key_error("CKey::operator=(const CKey&) : EC_KEY_copy failed");
|
||||
fSet = b.fSet;
|
||||
return (*this);
|
||||
}
|
||||
fSet = false;
|
||||
}
|
||||
|
||||
CKey (const CKey& b)
|
||||
{
|
||||
pkey = EC_KEY_dup (b.pkey);
|
||||
EC_KEY_set_conv_form (pkey, POINT_CONVERSION_COMPRESSED);
|
||||
|
||||
if (pkey == NULL)
|
||||
throw key_error ("CKey::CKey(const CKey&) : EC_KEY_dup failed");
|
||||
|
||||
fSet = b.fSet;
|
||||
}
|
||||
|
||||
CKey& operator= (const CKey& b)
|
||||
{
|
||||
if (!EC_KEY_copy (pkey, b.pkey))
|
||||
throw key_error ("CKey::operator=(const CKey&) : EC_KEY_copy failed");
|
||||
|
||||
fSet = b.fSet;
|
||||
return (*this);
|
||||
}
|
||||
|
||||
|
||||
~CKey()
|
||||
{
|
||||
EC_KEY_free(pkey);
|
||||
}
|
||||
~CKey ()
|
||||
{
|
||||
EC_KEY_free (pkey);
|
||||
}
|
||||
|
||||
|
||||
static uint128 PassPhraseToKey(const std::string& passPhrase);
|
||||
static EC_KEY* GenerateRootDeterministicKey(const uint128& passPhrase);
|
||||
static EC_KEY* GenerateRootPubKey(BIGNUM* pubGenerator);
|
||||
static EC_KEY* GeneratePublicDeterministicKey(const RippleAddress& generator, int n);
|
||||
static EC_KEY* GeneratePrivateDeterministicKey(const RippleAddress& family, const BIGNUM* rootPriv, int n);
|
||||
static EC_KEY* GeneratePrivateDeterministicKey(const RippleAddress& family, uint256 const& rootPriv, int n);
|
||||
static uint128 PassPhraseToKey (const std::string& passPhrase);
|
||||
static EC_KEY* GenerateRootDeterministicKey (const uint128& passPhrase);
|
||||
static EC_KEY* GenerateRootPubKey (BIGNUM* pubGenerator);
|
||||
static EC_KEY* GeneratePublicDeterministicKey (const RippleAddress& generator, int n);
|
||||
static EC_KEY* GeneratePrivateDeterministicKey (const RippleAddress& family, const BIGNUM* rootPriv, int n);
|
||||
static EC_KEY* GeneratePrivateDeterministicKey (const RippleAddress& family, uint256 const& rootPriv, int n);
|
||||
|
||||
CKey(const uint128& passPhrase) : fSet(false)
|
||||
{
|
||||
pkey = GenerateRootDeterministicKey(passPhrase);
|
||||
fSet = true;
|
||||
assert(pkey);
|
||||
}
|
||||
CKey (const uint128& passPhrase) : fSet (false)
|
||||
{
|
||||
pkey = GenerateRootDeterministicKey (passPhrase);
|
||||
fSet = true;
|
||||
assert (pkey);
|
||||
}
|
||||
|
||||
CKey(const RippleAddress& generator, int n) : fSet(false)
|
||||
{ // public deterministic key
|
||||
pkey = GeneratePublicDeterministicKey(generator, n);
|
||||
fSet = true;
|
||||
assert(pkey);
|
||||
}
|
||||
CKey (const RippleAddress& generator, int n) : fSet (false)
|
||||
{
|
||||
// public deterministic key
|
||||
pkey = GeneratePublicDeterministicKey (generator, n);
|
||||
fSet = true;
|
||||
assert (pkey);
|
||||
}
|
||||
|
||||
CKey(const RippleAddress& base, const BIGNUM* rootPrivKey, int n) : fSet(false)
|
||||
{ // private deterministic key
|
||||
pkey = GeneratePrivateDeterministicKey(base, rootPrivKey, n);
|
||||
fSet = true;
|
||||
assert(pkey);
|
||||
}
|
||||
CKey (const RippleAddress& base, const BIGNUM* rootPrivKey, int n) : fSet (false)
|
||||
{
|
||||
// private deterministic key
|
||||
pkey = GeneratePrivateDeterministicKey (base, rootPrivKey, n);
|
||||
fSet = true;
|
||||
assert (pkey);
|
||||
}
|
||||
|
||||
CKey(uint256 const& privateKey) : pkey(NULL), fSet(false)
|
||||
{
|
||||
// XXX Broken pkey is null.
|
||||
SetPrivateKeyU(privateKey);
|
||||
}
|
||||
CKey (uint256 const& privateKey) : pkey (NULL), fSet (false)
|
||||
{
|
||||
// XXX Broken pkey is null.
|
||||
SetPrivateKeyU (privateKey);
|
||||
}
|
||||
|
||||
#if 0
|
||||
CKey(const RippleAddress& masterKey, int keyNum, bool isPublic) : pkey(NULL), fSet(false)
|
||||
{
|
||||
if (isPublic)
|
||||
SetPubSeq(masterKey, keyNum);
|
||||
else
|
||||
SetPrivSeq(masterKey, keyNum); // broken, need seed
|
||||
fSet = true;
|
||||
}
|
||||
CKey (const RippleAddress& masterKey, int keyNum, bool isPublic) : pkey (NULL), fSet (false)
|
||||
{
|
||||
if (isPublic)
|
||||
SetPubSeq (masterKey, keyNum);
|
||||
else
|
||||
SetPrivSeq (masterKey, keyNum); // broken, need seed
|
||||
|
||||
fSet = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool IsNull() const
|
||||
{
|
||||
return !fSet;
|
||||
}
|
||||
bool IsNull () const
|
||||
{
|
||||
return !fSet;
|
||||
}
|
||||
|
||||
void MakeNewKey()
|
||||
{
|
||||
if (!EC_KEY_generate_key(pkey))
|
||||
throw key_error("CKey::MakeNewKey() : EC_KEY_generate_key failed");
|
||||
EC_KEY_set_conv_form(pkey, POINT_CONVERSION_COMPRESSED);
|
||||
fSet = true;
|
||||
}
|
||||
void MakeNewKey ()
|
||||
{
|
||||
if (!EC_KEY_generate_key (pkey))
|
||||
throw key_error ("CKey::MakeNewKey() : EC_KEY_generate_key failed");
|
||||
|
||||
// XXX Still used!
|
||||
BIGNUM* GetSecretBN() const
|
||||
{ // DEPRECATED
|
||||
return BN_dup(EC_KEY_get0_private_key(pkey));
|
||||
}
|
||||
EC_KEY_set_conv_form (pkey, POINT_CONVERSION_COMPRESSED);
|
||||
fSet = true;
|
||||
}
|
||||
|
||||
void GetPrivateKeyU(uint256& privKey)
|
||||
{
|
||||
const BIGNUM* bn = EC_KEY_get0_private_key(pkey);
|
||||
if (bn == NULL)
|
||||
throw key_error("CKey::GetPrivateKeyU: EC_KEY_get0_private_key failed");
|
||||
privKey.zero();
|
||||
BN_bn2bin(bn, privKey.begin() + (privKey.size() - BN_num_bytes(bn)));
|
||||
}
|
||||
// XXX Still used!
|
||||
BIGNUM* GetSecretBN () const
|
||||
{
|
||||
// DEPRECATED
|
||||
return BN_dup (EC_KEY_get0_private_key (pkey));
|
||||
}
|
||||
|
||||
bool SetPrivateKeyU(uint256 const& key, bool bThrow=false)
|
||||
{
|
||||
// XXX Broken if pkey is not set.
|
||||
BIGNUM* bn = BN_bin2bn(key.begin(), key.size(), NULL);
|
||||
bool bSuccess = !!EC_KEY_set_private_key(pkey, bn);
|
||||
void GetPrivateKeyU (uint256& privKey)
|
||||
{
|
||||
const BIGNUM* bn = EC_KEY_get0_private_key (pkey);
|
||||
|
||||
BN_clear_free(bn);
|
||||
if (bn == NULL)
|
||||
throw key_error ("CKey::GetPrivateKeyU: EC_KEY_get0_private_key failed");
|
||||
|
||||
if (bSuccess)
|
||||
{
|
||||
fSet = true;
|
||||
}
|
||||
else if (bThrow)
|
||||
{
|
||||
throw key_error("CKey::SetPrivateKeyU: EC_KEY_set_private_key failed");
|
||||
}
|
||||
privKey.zero ();
|
||||
BN_bn2bin (bn, privKey.begin () + (privKey.size () - BN_num_bytes (bn)));
|
||||
}
|
||||
|
||||
return bSuccess;
|
||||
}
|
||||
bool SetPrivateKeyU (uint256 const& key, bool bThrow = false)
|
||||
{
|
||||
// XXX Broken if pkey is not set.
|
||||
BIGNUM* bn = BN_bin2bn (key.begin (), key.size (), NULL);
|
||||
bool bSuccess = !!EC_KEY_set_private_key (pkey, bn);
|
||||
|
||||
bool SetPubKey(const void *ptr, size_t len)
|
||||
{
|
||||
const unsigned char* pbegin = static_cast<const unsigned char *>(ptr);
|
||||
if (!o2i_ECPublicKey(&pkey, &pbegin, len))
|
||||
return false;
|
||||
EC_KEY_set_conv_form(pkey, POINT_CONVERSION_COMPRESSED);
|
||||
fSet = true;
|
||||
return true;
|
||||
}
|
||||
BN_clear_free (bn);
|
||||
|
||||
bool SetPubKey(Blob const& vchPubKey)
|
||||
{
|
||||
return SetPubKey(&vchPubKey[0], vchPubKey.size());
|
||||
}
|
||||
if (bSuccess)
|
||||
{
|
||||
fSet = true;
|
||||
}
|
||||
else if (bThrow)
|
||||
{
|
||||
throw key_error ("CKey::SetPrivateKeyU: EC_KEY_set_private_key failed");
|
||||
}
|
||||
|
||||
bool SetPubKey(const std::string& pubKey)
|
||||
{
|
||||
return SetPubKey(pubKey.data(), pubKey.size());
|
||||
}
|
||||
return bSuccess;
|
||||
}
|
||||
|
||||
Blob GetPubKey() const
|
||||
{
|
||||
unsigned int nSize = i2o_ECPublicKey(pkey, NULL);
|
||||
assert(nSize<=33);
|
||||
if (!nSize)
|
||||
throw key_error("CKey::GetPubKey() : i2o_ECPublicKey failed");
|
||||
Blob vchPubKey(33, 0);
|
||||
unsigned char* pbegin = &vchPubKey[0];
|
||||
if (i2o_ECPublicKey(pkey, &pbegin) != nSize)
|
||||
throw key_error("CKey::GetPubKey() : i2o_ECPublicKey returned unexpected size");
|
||||
assert(vchPubKey.size()<=33);
|
||||
return vchPubKey;
|
||||
}
|
||||
bool SetPubKey (const void* ptr, size_t len)
|
||||
{
|
||||
const unsigned char* pbegin = static_cast<const unsigned char*> (ptr);
|
||||
|
||||
bool Sign(uint256 const& hash, Blob& vchSig)
|
||||
{
|
||||
unsigned char pchSig[10000];
|
||||
unsigned int nSize = 0;
|
||||
if (!o2i_ECPublicKey (&pkey, &pbegin, len))
|
||||
return false;
|
||||
|
||||
vchSig.clear();
|
||||
EC_KEY_set_conv_form (pkey, POINT_CONVERSION_COMPRESSED);
|
||||
fSet = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!ECDSA_sign(0, (unsigned char*)hash.begin(), hash.size(), pchSig, &nSize, pkey))
|
||||
return false;
|
||||
bool SetPubKey (Blob const& vchPubKey)
|
||||
{
|
||||
return SetPubKey (&vchPubKey[0], vchPubKey.size ());
|
||||
}
|
||||
|
||||
vchSig.resize(nSize);
|
||||
memcpy(&vchSig[0], pchSig, nSize);
|
||||
bool SetPubKey (const std::string& pubKey)
|
||||
{
|
||||
return SetPubKey (pubKey.data (), pubKey.size ());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
Blob GetPubKey () const
|
||||
{
|
||||
unsigned int nSize = i2o_ECPublicKey (pkey, NULL);
|
||||
assert (nSize <= 33);
|
||||
|
||||
bool Verify(uint256 const& hash, const void *sig, size_t sigLen) const
|
||||
{
|
||||
// -1 = error, 0 = bad sig, 1 = good
|
||||
if (ECDSA_verify(0, hash.begin(), hash.size(), (const unsigned char *) sig, sigLen, pkey) != 1)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
if (!nSize)
|
||||
throw key_error ("CKey::GetPubKey() : i2o_ECPublicKey failed");
|
||||
|
||||
bool Verify(uint256 const& hash, Blob const& vchSig) const
|
||||
{
|
||||
return Verify(hash, &vchSig[0], vchSig.size());
|
||||
}
|
||||
Blob vchPubKey (33, 0);
|
||||
unsigned char* pbegin = &vchPubKey[0];
|
||||
|
||||
bool Verify(uint256 const& hash, const std::string& sig) const
|
||||
{
|
||||
return Verify(hash, sig.data(), sig.size());
|
||||
}
|
||||
if (i2o_ECPublicKey (pkey, &pbegin) != nSize)
|
||||
throw key_error ("CKey::GetPubKey() : i2o_ECPublicKey returned unexpected size");
|
||||
|
||||
// ECIES functions. These throw on failure
|
||||
assert (vchPubKey.size () <= 33);
|
||||
return vchPubKey;
|
||||
}
|
||||
|
||||
// returns a 32-byte secret unique to these two keys. At least one private key must be known.
|
||||
void getECIESSecret(CKey& otherKey, uint256& enc_key, uint256& hmac_key);
|
||||
bool Sign (uint256 const& hash, Blob& vchSig)
|
||||
{
|
||||
unsigned char pchSig[10000];
|
||||
unsigned int nSize = 0;
|
||||
|
||||
// encrypt/decrypt functions with integrity checking.
|
||||
// Note that the other side must somehow know what keys to use
|
||||
Blob encryptECIES(CKey& otherKey, Blob const& plaintext);
|
||||
Blob decryptECIES(CKey& otherKey, Blob const& ciphertext);
|
||||
vchSig.clear ();
|
||||
|
||||
if (!ECDSA_sign (0, (unsigned char*)hash.begin (), hash.size (), pchSig, &nSize, pkey))
|
||||
return false;
|
||||
|
||||
vchSig.resize (nSize);
|
||||
memcpy (&vchSig[0], pchSig, nSize);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Verify (uint256 const& hash, const void* sig, size_t sigLen) const
|
||||
{
|
||||
// -1 = error, 0 = bad sig, 1 = good
|
||||
if (ECDSA_verify (0, hash.begin (), hash.size (), (const unsigned char*) sig, sigLen, pkey) != 1)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Verify (uint256 const& hash, Blob const& vchSig) const
|
||||
{
|
||||
return Verify (hash, &vchSig[0], vchSig.size ());
|
||||
}
|
||||
|
||||
bool Verify (uint256 const& hash, const std::string& sig) const
|
||||
{
|
||||
return Verify (hash, sig.data (), sig.size ());
|
||||
}
|
||||
|
||||
// ECIES functions. These throw on failure
|
||||
|
||||
// returns a 32-byte secret unique to these two keys. At least one private key must be known.
|
||||
void getECIESSecret (CKey& otherKey, uint256& enc_key, uint256& hmac_key);
|
||||
|
||||
// encrypt/decrypt functions with integrity checking.
|
||||
// Note that the other side must somehow know what keys to use
|
||||
Blob encryptECIES (CKey& otherKey, Blob const& plaintext);
|
||||
Blob decryptECIES (CKey& otherKey, Blob const& ciphertext);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -4,328 +4,375 @@
|
||||
// Functions to add CKey support for deterministic EC keys
|
||||
|
||||
// <-- seed
|
||||
uint128 CKey::PassPhraseToKey(const std::string& passPhrase)
|
||||
uint128 CKey::PassPhraseToKey (const std::string& passPhrase)
|
||||
{
|
||||
Serializer s;
|
||||
Serializer s;
|
||||
|
||||
s.addRaw(passPhrase);
|
||||
uint256 hash256 = s.getSHA512Half();
|
||||
uint128 ret(hash256);
|
||||
s.addRaw (passPhrase);
|
||||
uint256 hash256 = s.getSHA512Half ();
|
||||
uint128 ret (hash256);
|
||||
|
||||
s.secureErase();
|
||||
s.secureErase ();
|
||||
|
||||
return ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
// --> seed
|
||||
// <-- private root generator + public root generator
|
||||
EC_KEY* CKey::GenerateRootDeterministicKey(const uint128& seed)
|
||||
EC_KEY* CKey::GenerateRootDeterministicKey (const uint128& seed)
|
||||
{
|
||||
BN_CTX* ctx=BN_CTX_new();
|
||||
if(!ctx) return NULL;
|
||||
BN_CTX* ctx = BN_CTX_new ();
|
||||
|
||||
EC_KEY* pkey=EC_KEY_new_by_curve_name(NID_secp256k1);
|
||||
if(!pkey)
|
||||
{
|
||||
BN_CTX_free(ctx);
|
||||
return NULL;
|
||||
}
|
||||
EC_KEY_set_conv_form(pkey, POINT_CONVERSION_COMPRESSED);
|
||||
if (!ctx) return NULL;
|
||||
|
||||
BIGNUM* order=BN_new();
|
||||
if(!order)
|
||||
{
|
||||
BN_CTX_free(ctx);
|
||||
EC_KEY_free(pkey);
|
||||
return NULL;
|
||||
}
|
||||
if(!EC_GROUP_get_order(EC_KEY_get0_group(pkey), order, ctx))
|
||||
{
|
||||
assert(false);
|
||||
BN_free(order);
|
||||
EC_KEY_free(pkey);
|
||||
BN_CTX_free(ctx);
|
||||
return NULL;
|
||||
}
|
||||
EC_KEY* pkey = EC_KEY_new_by_curve_name (NID_secp256k1);
|
||||
|
||||
BIGNUM *privKey=NULL;
|
||||
int seq=0;
|
||||
do
|
||||
{ // private key must be non-zero and less than the curve's order
|
||||
Serializer s((128+32)/8);
|
||||
s.add128(seed);
|
||||
s.add32(seq++);
|
||||
uint256 root=s.getSHA512Half();
|
||||
s.secureErase();
|
||||
privKey=BN_bin2bn((const unsigned char *) &root, sizeof(root), privKey);
|
||||
if(privKey==NULL)
|
||||
{
|
||||
EC_KEY_free(pkey);
|
||||
BN_free(order);
|
||||
BN_CTX_free(ctx);
|
||||
}
|
||||
root.zero();
|
||||
} while(BN_is_zero(privKey) || (BN_cmp(privKey, order)>=0));
|
||||
if (!pkey)
|
||||
{
|
||||
BN_CTX_free (ctx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BN_free(order);
|
||||
EC_KEY_set_conv_form (pkey, POINT_CONVERSION_COMPRESSED);
|
||||
|
||||
if(!EC_KEY_set_private_key(pkey, privKey))
|
||||
{ // set the random point as the private key
|
||||
assert(false);
|
||||
EC_KEY_free(pkey);
|
||||
BN_clear_free(privKey);
|
||||
BN_CTX_free(ctx);
|
||||
return NULL;
|
||||
}
|
||||
BIGNUM* order = BN_new ();
|
||||
|
||||
EC_POINT *pubKey=EC_POINT_new(EC_KEY_get0_group(pkey));
|
||||
if(!EC_POINT_mul(EC_KEY_get0_group(pkey), pubKey, privKey, NULL, NULL, ctx))
|
||||
{ // compute the corresponding public key point
|
||||
assert(false);
|
||||
BN_clear_free(privKey);
|
||||
EC_POINT_free(pubKey);
|
||||
EC_KEY_free(pkey);
|
||||
BN_CTX_free(ctx);
|
||||
return NULL;
|
||||
}
|
||||
BN_clear_free(privKey);
|
||||
if(!EC_KEY_set_public_key(pkey, pubKey))
|
||||
{
|
||||
assert(false);
|
||||
EC_POINT_free(pubKey);
|
||||
EC_KEY_free(pkey);
|
||||
BN_CTX_free(ctx);
|
||||
return NULL;
|
||||
}
|
||||
EC_POINT_free(pubKey);
|
||||
if (!order)
|
||||
{
|
||||
BN_CTX_free (ctx);
|
||||
EC_KEY_free (pkey);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BN_CTX_free(ctx);
|
||||
if (!EC_GROUP_get_order (EC_KEY_get0_group (pkey), order, ctx))
|
||||
{
|
||||
assert (false);
|
||||
BN_free (order);
|
||||
EC_KEY_free (pkey);
|
||||
BN_CTX_free (ctx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BIGNUM* privKey = NULL;
|
||||
int seq = 0;
|
||||
|
||||
do
|
||||
{
|
||||
// private key must be non-zero and less than the curve's order
|
||||
Serializer s ((128 + 32) / 8);
|
||||
s.add128 (seed);
|
||||
s.add32 (seq++);
|
||||
uint256 root = s.getSHA512Half ();
|
||||
s.secureErase ();
|
||||
privKey = BN_bin2bn ((const unsigned char*) &root, sizeof (root), privKey);
|
||||
|
||||
if (privKey == NULL)
|
||||
{
|
||||
EC_KEY_free (pkey);
|
||||
BN_free (order);
|
||||
BN_CTX_free (ctx);
|
||||
}
|
||||
|
||||
root.zero ();
|
||||
}
|
||||
while (BN_is_zero (privKey) || (BN_cmp (privKey, order) >= 0));
|
||||
|
||||
BN_free (order);
|
||||
|
||||
if (!EC_KEY_set_private_key (pkey, privKey))
|
||||
{
|
||||
// set the random point as the private key
|
||||
assert (false);
|
||||
EC_KEY_free (pkey);
|
||||
BN_clear_free (privKey);
|
||||
BN_CTX_free (ctx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
EC_POINT* pubKey = EC_POINT_new (EC_KEY_get0_group (pkey));
|
||||
|
||||
if (!EC_POINT_mul (EC_KEY_get0_group (pkey), pubKey, privKey, NULL, NULL, ctx))
|
||||
{
|
||||
// compute the corresponding public key point
|
||||
assert (false);
|
||||
BN_clear_free (privKey);
|
||||
EC_POINT_free (pubKey);
|
||||
EC_KEY_free (pkey);
|
||||
BN_CTX_free (ctx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BN_clear_free (privKey);
|
||||
|
||||
if (!EC_KEY_set_public_key (pkey, pubKey))
|
||||
{
|
||||
assert (false);
|
||||
EC_POINT_free (pubKey);
|
||||
EC_KEY_free (pkey);
|
||||
BN_CTX_free (ctx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
EC_POINT_free (pubKey);
|
||||
|
||||
BN_CTX_free (ctx);
|
||||
|
||||
#ifdef EC_DEBUG
|
||||
assert(EC_KEY_check_key(pkey)==1); // CAUTION: This check is *very* expensive
|
||||
assert (EC_KEY_check_key (pkey) == 1); // CAUTION: This check is *very* expensive
|
||||
#endif
|
||||
return pkey;
|
||||
return pkey;
|
||||
}
|
||||
|
||||
// Take ripple address.
|
||||
// --> root public generator (consumes)
|
||||
// <-- root public generator in EC format
|
||||
EC_KEY* CKey::GenerateRootPubKey(BIGNUM* pubGenerator)
|
||||
EC_KEY* CKey::GenerateRootPubKey (BIGNUM* pubGenerator)
|
||||
{
|
||||
if (pubGenerator == NULL)
|
||||
{
|
||||
assert(false);
|
||||
return NULL;
|
||||
}
|
||||
if (pubGenerator == NULL)
|
||||
{
|
||||
assert (false);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
EC_KEY* pkey = EC_KEY_new_by_curve_name(NID_secp256k1);
|
||||
if (!pkey)
|
||||
{
|
||||
BN_free(pubGenerator);
|
||||
return NULL;
|
||||
}
|
||||
EC_KEY_set_conv_form(pkey, POINT_CONVERSION_COMPRESSED);
|
||||
EC_KEY* pkey = EC_KEY_new_by_curve_name (NID_secp256k1);
|
||||
|
||||
EC_POINT* pubPoint = EC_POINT_bn2point(EC_KEY_get0_group(pkey), pubGenerator, NULL, NULL);
|
||||
BN_free(pubGenerator);
|
||||
if(!pubPoint)
|
||||
{
|
||||
assert(false);
|
||||
EC_KEY_free(pkey);
|
||||
return NULL;
|
||||
}
|
||||
if (!pkey)
|
||||
{
|
||||
BN_free (pubGenerator);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(!EC_KEY_set_public_key(pkey, pubPoint))
|
||||
{
|
||||
assert(false);
|
||||
EC_POINT_free(pubPoint);
|
||||
EC_KEY_free(pkey);
|
||||
return NULL;
|
||||
}
|
||||
EC_POINT_free(pubPoint);
|
||||
EC_KEY_set_conv_form (pkey, POINT_CONVERSION_COMPRESSED);
|
||||
|
||||
return pkey;
|
||||
EC_POINT* pubPoint = EC_POINT_bn2point (EC_KEY_get0_group (pkey), pubGenerator, NULL, NULL);
|
||||
BN_free (pubGenerator);
|
||||
|
||||
if (!pubPoint)
|
||||
{
|
||||
assert (false);
|
||||
EC_KEY_free (pkey);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!EC_KEY_set_public_key (pkey, pubPoint))
|
||||
{
|
||||
assert (false);
|
||||
EC_POINT_free (pubPoint);
|
||||
EC_KEY_free (pkey);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
EC_POINT_free (pubPoint);
|
||||
|
||||
return pkey;
|
||||
}
|
||||
|
||||
// --> public generator
|
||||
static BIGNUM* makeHash(const RippleAddress& pubGen, int seq, BIGNUM* order)
|
||||
static BIGNUM* makeHash (const RippleAddress& pubGen, int seq, BIGNUM* order)
|
||||
{
|
||||
int subSeq=0;
|
||||
BIGNUM* ret=NULL;
|
||||
do
|
||||
{
|
||||
Serializer s((33*8+32+32)/8);
|
||||
s.addRaw(pubGen.getGenerator());
|
||||
s.add32(seq);
|
||||
s.add32(subSeq++);
|
||||
uint256 root=s.getSHA512Half();
|
||||
s.secureErase();
|
||||
ret=BN_bin2bn((const unsigned char *) &root, sizeof(root), ret);
|
||||
if(!ret) return NULL;
|
||||
} while (BN_is_zero(ret) || (BN_cmp(ret, order)>=0));
|
||||
int subSeq = 0;
|
||||
BIGNUM* ret = NULL;
|
||||
|
||||
return ret;
|
||||
do
|
||||
{
|
||||
Serializer s ((33 * 8 + 32 + 32) / 8);
|
||||
s.addRaw (pubGen.getGenerator ());
|
||||
s.add32 (seq);
|
||||
s.add32 (subSeq++);
|
||||
uint256 root = s.getSHA512Half ();
|
||||
s.secureErase ();
|
||||
ret = BN_bin2bn ((const unsigned char*) &root, sizeof (root), ret);
|
||||
|
||||
if (!ret) return NULL;
|
||||
}
|
||||
while (BN_is_zero (ret) || (BN_cmp (ret, order) >= 0));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// --> public generator
|
||||
EC_KEY* CKey::GeneratePublicDeterministicKey(const RippleAddress& pubGen, int seq)
|
||||
{ // publicKey(n) = rootPublicKey EC_POINT_+ Hash(pubHash|seq)*point
|
||||
EC_KEY* rootKey = CKey::GenerateRootPubKey(pubGen.getGeneratorBN());
|
||||
const EC_POINT* rootPubKey = EC_KEY_get0_public_key(rootKey);
|
||||
BN_CTX* ctx = BN_CTX_new();
|
||||
EC_KEY* pkey = EC_KEY_new_by_curve_name(NID_secp256k1);
|
||||
EC_POINT* newPoint = 0;
|
||||
BIGNUM* order = 0;
|
||||
BIGNUM* hash = 0;
|
||||
bool success = true;
|
||||
EC_KEY* CKey::GeneratePublicDeterministicKey (const RippleAddress& pubGen, int seq)
|
||||
{
|
||||
// publicKey(n) = rootPublicKey EC_POINT_+ Hash(pubHash|seq)*point
|
||||
EC_KEY* rootKey = CKey::GenerateRootPubKey (pubGen.getGeneratorBN ());
|
||||
const EC_POINT* rootPubKey = EC_KEY_get0_public_key (rootKey);
|
||||
BN_CTX* ctx = BN_CTX_new ();
|
||||
EC_KEY* pkey = EC_KEY_new_by_curve_name (NID_secp256k1);
|
||||
EC_POINT* newPoint = 0;
|
||||
BIGNUM* order = 0;
|
||||
BIGNUM* hash = 0;
|
||||
bool success = true;
|
||||
|
||||
if (!ctx || !pkey) success = false;
|
||||
if (!ctx || !pkey) success = false;
|
||||
|
||||
if (success)
|
||||
EC_KEY_set_conv_form(pkey, POINT_CONVERSION_COMPRESSED);
|
||||
if (success)
|
||||
EC_KEY_set_conv_form (pkey, POINT_CONVERSION_COMPRESSED);
|
||||
|
||||
if (success) {
|
||||
newPoint = EC_POINT_new(EC_KEY_get0_group(pkey));
|
||||
if(!newPoint) success = false;
|
||||
}
|
||||
if (success)
|
||||
{
|
||||
newPoint = EC_POINT_new (EC_KEY_get0_group (pkey));
|
||||
|
||||
if (success) {
|
||||
order = BN_new();
|
||||
if (!newPoint) success = false;
|
||||
}
|
||||
|
||||
if(!order || !EC_GROUP_get_order(EC_KEY_get0_group(pkey), order, ctx))
|
||||
success = false;
|
||||
}
|
||||
if (success)
|
||||
{
|
||||
order = BN_new ();
|
||||
|
||||
// Calculate the private additional key.
|
||||
if (success) {
|
||||
hash = makeHash(pubGen, seq, order);
|
||||
if(!hash) success = false;
|
||||
}
|
||||
if (!order || !EC_GROUP_get_order (EC_KEY_get0_group (pkey), order, ctx))
|
||||
success = false;
|
||||
}
|
||||
|
||||
if (success) {
|
||||
// Calculate the corresponding public key.
|
||||
EC_POINT_mul(EC_KEY_get0_group(pkey), newPoint, hash, NULL, NULL, ctx);
|
||||
// Calculate the private additional key.
|
||||
if (success)
|
||||
{
|
||||
hash = makeHash (pubGen, seq, order);
|
||||
|
||||
// Add the master public key and set.
|
||||
EC_POINT_add(EC_KEY_get0_group(pkey), newPoint, newPoint, rootPubKey, ctx);
|
||||
EC_KEY_set_public_key(pkey, newPoint);
|
||||
}
|
||||
if (!hash) success = false;
|
||||
}
|
||||
|
||||
if (order) BN_free(order);
|
||||
if (hash) BN_free(hash);
|
||||
if (newPoint) EC_POINT_free(newPoint);
|
||||
if (ctx) BN_CTX_free(ctx);
|
||||
if (rootKey) EC_KEY_free(rootKey);
|
||||
if (pkey && !success) EC_KEY_free(pkey);
|
||||
if (success)
|
||||
{
|
||||
// Calculate the corresponding public key.
|
||||
EC_POINT_mul (EC_KEY_get0_group (pkey), newPoint, hash, NULL, NULL, ctx);
|
||||
|
||||
return success ? pkey : NULL;
|
||||
// Add the master public key and set.
|
||||
EC_POINT_add (EC_KEY_get0_group (pkey), newPoint, newPoint, rootPubKey, ctx);
|
||||
EC_KEY_set_public_key (pkey, newPoint);
|
||||
}
|
||||
|
||||
if (order) BN_free (order);
|
||||
|
||||
if (hash) BN_free (hash);
|
||||
|
||||
if (newPoint) EC_POINT_free (newPoint);
|
||||
|
||||
if (ctx) BN_CTX_free (ctx);
|
||||
|
||||
if (rootKey) EC_KEY_free (rootKey);
|
||||
|
||||
if (pkey && !success) EC_KEY_free (pkey);
|
||||
|
||||
return success ? pkey : NULL;
|
||||
}
|
||||
|
||||
EC_KEY* CKey::GeneratePrivateDeterministicKey(const RippleAddress& pubGen, uint256 const& u, int seq)
|
||||
EC_KEY* CKey::GeneratePrivateDeterministicKey (const RippleAddress& pubGen, uint256 const& u, int seq)
|
||||
{
|
||||
CBigNum bn(u);
|
||||
return GeneratePrivateDeterministicKey(pubGen, static_cast<BIGNUM*>(&bn), seq);
|
||||
CBigNum bn (u);
|
||||
return GeneratePrivateDeterministicKey (pubGen, static_cast<BIGNUM*> (&bn), seq);
|
||||
}
|
||||
|
||||
// --> root private key
|
||||
EC_KEY* CKey::GeneratePrivateDeterministicKey(const RippleAddress& pubGen, const BIGNUM* rootPrivKey, int seq)
|
||||
{ // privateKey(n) = (rootPrivateKey + Hash(pubHash|seq)) % order
|
||||
BN_CTX* ctx=BN_CTX_new();
|
||||
if(ctx==NULL) return NULL;
|
||||
|
||||
EC_KEY* pkey=EC_KEY_new_by_curve_name(NID_secp256k1);
|
||||
if(pkey==NULL)
|
||||
{
|
||||
BN_CTX_free(ctx);
|
||||
return NULL;
|
||||
}
|
||||
EC_KEY_set_conv_form(pkey, POINT_CONVERSION_COMPRESSED);
|
||||
|
||||
BIGNUM* order=BN_new();
|
||||
if(order==NULL)
|
||||
{
|
||||
BN_CTX_free(ctx);
|
||||
EC_KEY_free(pkey);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(!EC_GROUP_get_order(EC_KEY_get0_group(pkey), order, ctx))
|
||||
{
|
||||
BN_free(order);
|
||||
BN_CTX_free(ctx);
|
||||
EC_KEY_free(pkey);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// calculate the private additional key
|
||||
BIGNUM* privKey=makeHash(pubGen, seq, order);
|
||||
if(privKey==NULL)
|
||||
{
|
||||
BN_free(order);
|
||||
BN_CTX_free(ctx);
|
||||
EC_KEY_free(pkey);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// calculate the final private key
|
||||
BN_mod_add(privKey, privKey, rootPrivKey, order, ctx);
|
||||
BN_free(order);
|
||||
EC_KEY_set_private_key(pkey, privKey);
|
||||
|
||||
// compute the corresponding public key
|
||||
EC_POINT* pubKey=EC_POINT_new(EC_KEY_get0_group(pkey));
|
||||
if(!pubKey)
|
||||
{
|
||||
BN_clear_free(privKey);
|
||||
BN_CTX_free(ctx);
|
||||
EC_KEY_free(pkey);
|
||||
return NULL;
|
||||
}
|
||||
if(EC_POINT_mul(EC_KEY_get0_group(pkey), pubKey, privKey, NULL, NULL, ctx)==0)
|
||||
{
|
||||
BN_clear_free(privKey);
|
||||
EC_POINT_free(pubKey);
|
||||
EC_KEY_free(pkey);
|
||||
BN_CTX_free(ctx);
|
||||
return NULL;
|
||||
}
|
||||
BN_clear_free(privKey);
|
||||
EC_KEY_set_public_key(pkey, pubKey);
|
||||
|
||||
EC_POINT_free(pubKey);
|
||||
BN_CTX_free(ctx);
|
||||
|
||||
return pkey;
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(DeterministicKeys_test)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(DeterminsticKeys_test1)
|
||||
EC_KEY* CKey::GeneratePrivateDeterministicKey (const RippleAddress& pubGen, const BIGNUM* rootPrivKey, int seq)
|
||||
{
|
||||
Log(lsDEBUG) << "Beginning deterministic key test";
|
||||
// privateKey(n) = (rootPrivateKey + Hash(pubHash|seq)) % order
|
||||
BN_CTX* ctx = BN_CTX_new ();
|
||||
|
||||
uint128 seed1, seed2;
|
||||
seed1.SetHex("71ED064155FFADFA38782C5E0158CB26");
|
||||
seed2.SetHex("CF0C3BE4485961858C4198515AE5B965");
|
||||
CKey root1(seed1), root2(seed2);
|
||||
if (ctx == NULL) return NULL;
|
||||
|
||||
uint256 priv1, priv2;
|
||||
root1.GetPrivateKeyU(priv1);
|
||||
root2.GetPrivateKeyU(priv2);
|
||||
EC_KEY* pkey = EC_KEY_new_by_curve_name (NID_secp256k1);
|
||||
|
||||
if (priv1.GetHex() != "7CFBA64F771E93E817E15039215430B53F7401C34931D111EAB3510B22DBB0D8")
|
||||
BOOST_FAIL("Incorrect private key for generator");
|
||||
if (priv2.GetHex() != "98BC2EACB26EB021D1A6293C044D88BA2F0B6729A2772DEEBF2E21A263C1740B")
|
||||
BOOST_FAIL("Incorrect private key for generator");
|
||||
if (pkey == NULL)
|
||||
{
|
||||
BN_CTX_free (ctx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
RippleAddress nSeed;
|
||||
nSeed.setSeed(seed1);
|
||||
if (nSeed.humanSeed() != "shHM53KPZ87Gwdqarm1bAmPeXg8Tn")
|
||||
BOOST_FAIL("Incorrect human seed");
|
||||
if (nSeed.humanSeed1751() != "MAD BODY ACE MINT OKAY HUB WHAT DATA SACK FLAT DANA MATH")
|
||||
BOOST_FAIL("Incorrect 1751 seed");
|
||||
EC_KEY_set_conv_form (pkey, POINT_CONVERSION_COMPRESSED);
|
||||
|
||||
BIGNUM* order = BN_new ();
|
||||
|
||||
if (order == NULL)
|
||||
{
|
||||
BN_CTX_free (ctx);
|
||||
EC_KEY_free (pkey);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!EC_GROUP_get_order (EC_KEY_get0_group (pkey), order, ctx))
|
||||
{
|
||||
BN_free (order);
|
||||
BN_CTX_free (ctx);
|
||||
EC_KEY_free (pkey);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// calculate the private additional key
|
||||
BIGNUM* privKey = makeHash (pubGen, seq, order);
|
||||
|
||||
if (privKey == NULL)
|
||||
{
|
||||
BN_free (order);
|
||||
BN_CTX_free (ctx);
|
||||
EC_KEY_free (pkey);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// calculate the final private key
|
||||
BN_mod_add (privKey, privKey, rootPrivKey, order, ctx);
|
||||
BN_free (order);
|
||||
EC_KEY_set_private_key (pkey, privKey);
|
||||
|
||||
// compute the corresponding public key
|
||||
EC_POINT* pubKey = EC_POINT_new (EC_KEY_get0_group (pkey));
|
||||
|
||||
if (!pubKey)
|
||||
{
|
||||
BN_clear_free (privKey);
|
||||
BN_CTX_free (ctx);
|
||||
EC_KEY_free (pkey);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (EC_POINT_mul (EC_KEY_get0_group (pkey), pubKey, privKey, NULL, NULL, ctx) == 0)
|
||||
{
|
||||
BN_clear_free (privKey);
|
||||
EC_POINT_free (pubKey);
|
||||
EC_KEY_free (pkey);
|
||||
BN_CTX_free (ctx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BN_clear_free (privKey);
|
||||
EC_KEY_set_public_key (pkey, pubKey);
|
||||
|
||||
EC_POINT_free (pubKey);
|
||||
BN_CTX_free (ctx);
|
||||
|
||||
return pkey;
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END();
|
||||
BOOST_AUTO_TEST_SUITE (DeterministicKeys_test)
|
||||
|
||||
BOOST_AUTO_TEST_CASE (DeterminsticKeys_test1)
|
||||
{
|
||||
Log (lsDEBUG) << "Beginning deterministic key test";
|
||||
|
||||
uint128 seed1, seed2;
|
||||
seed1.SetHex ("71ED064155FFADFA38782C5E0158CB26");
|
||||
seed2.SetHex ("CF0C3BE4485961858C4198515AE5B965");
|
||||
CKey root1 (seed1), root2 (seed2);
|
||||
|
||||
uint256 priv1, priv2;
|
||||
root1.GetPrivateKeyU (priv1);
|
||||
root2.GetPrivateKeyU (priv2);
|
||||
|
||||
if (priv1.GetHex () != "7CFBA64F771E93E817E15039215430B53F7401C34931D111EAB3510B22DBB0D8")
|
||||
BOOST_FAIL ("Incorrect private key for generator");
|
||||
|
||||
if (priv2.GetHex () != "98BC2EACB26EB021D1A6293C044D88BA2F0B6729A2772DEEBF2E21A263C1740B")
|
||||
BOOST_FAIL ("Incorrect private key for generator");
|
||||
|
||||
RippleAddress nSeed;
|
||||
nSeed.setSeed (seed1);
|
||||
|
||||
if (nSeed.humanSeed () != "shHM53KPZ87Gwdqarm1bAmPeXg8Tn")
|
||||
BOOST_FAIL ("Incorrect human seed");
|
||||
|
||||
if (nSeed.humanSeed1751 () != "MAD BODY ACE MINT OKAY HUB WHAT DATA SACK FLAT DANA MATH")
|
||||
BOOST_FAIL ("Incorrect 1751 seed");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END ();
|
||||
|
||||
// vim:ts=4
|
||||
|
||||
@@ -24,267 +24,288 @@
|
||||
// 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
|
||||
#define ECIES_MIN_SEC (128/8) // The minimum equivalent security
|
||||
#define ECIES_ENC_ALGO EVP_aes_256_cbc() // Encryption algorithm
|
||||
#define ECIES_ENC_KEY_TYPE uint256 // Type used to hold shared secret
|
||||
#define ECIES_ENC_KEY_SIZE (256/8) // Encryption key size
|
||||
#define ECIES_ENC_BLK_SIZE (128/8) // Encryption block size
|
||||
#define ECIES_ENC_IV_TYPE uint128 // Type used to hold IV
|
||||
#define ECIES_HMAC_ALGO EVP_sha256() // HMAC algorithm
|
||||
#define ECIES_HMAC_KEY_TYPE uint256 // Type used to hold HMAC key
|
||||
#define ECIES_HMAC_KEY_SIZE (256/8) // Size of HMAC key
|
||||
#define ECIES_HMAC_TYPE uint256 // Type used to hold HMAC value
|
||||
#define ECIES_HMAC_SIZE (256/8) // Size of HMAC value
|
||||
#define ECIES_KEY_HASH SHA512 // Hash used to expand shared secret
|
||||
#define ECIES_KEY_LENGTH (512/8) // Size of expanded shared secret
|
||||
#define ECIES_MIN_SEC (128/8) // The minimum equivalent security
|
||||
#define ECIES_ENC_ALGO EVP_aes_256_cbc() // Encryption algorithm
|
||||
#define ECIES_ENC_KEY_TYPE uint256 // Type used to hold shared secret
|
||||
#define ECIES_ENC_KEY_SIZE (256/8) // Encryption key size
|
||||
#define ECIES_ENC_BLK_SIZE (128/8) // Encryption block size
|
||||
#define ECIES_ENC_IV_TYPE uint128 // Type used to hold IV
|
||||
#define ECIES_HMAC_ALGO EVP_sha256() // HMAC algorithm
|
||||
#define ECIES_HMAC_KEY_TYPE uint256 // Type used to hold HMAC key
|
||||
#define ECIES_HMAC_KEY_SIZE (256/8) // Size of HMAC key
|
||||
#define ECIES_HMAC_TYPE uint256 // Type used to hold HMAC value
|
||||
#define ECIES_HMAC_SIZE (256/8) // Size of HMAC value
|
||||
|
||||
void CKey::getECIESSecret(CKey& otherKey, ECIES_ENC_KEY_TYPE& enc_key, ECIES_HMAC_KEY_TYPE& hmac_key)
|
||||
{ // Retrieve a secret generated from an EC key pair. At least one private key must be known.
|
||||
if (!pkey || !otherKey.pkey)
|
||||
throw std::runtime_error("missing key");
|
||||
void CKey::getECIESSecret (CKey& otherKey, ECIES_ENC_KEY_TYPE& enc_key, ECIES_HMAC_KEY_TYPE& hmac_key)
|
||||
{
|
||||
// Retrieve a secret generated from an EC key pair. At least one private key must be known.
|
||||
if (!pkey || !otherKey.pkey)
|
||||
throw std::runtime_error ("missing key");
|
||||
|
||||
EC_KEY *pubkey, *privkey;
|
||||
if (EC_KEY_get0_private_key(pkey))
|
||||
{
|
||||
privkey = pkey;
|
||||
pubkey = otherKey.pkey;
|
||||
}
|
||||
else if (EC_KEY_get0_private_key(otherKey.pkey))
|
||||
{
|
||||
privkey = otherKey.pkey;
|
||||
pubkey = pkey;
|
||||
}
|
||||
else throw std::runtime_error("no private key");
|
||||
EC_KEY* pubkey, *privkey;
|
||||
|
||||
unsigned char rawbuf[512];
|
||||
int buflen = ECDH_compute_key(rawbuf, 512, EC_KEY_get0_public_key(pubkey), privkey, NULL);
|
||||
if (buflen < ECIES_MIN_SEC)
|
||||
throw std::runtime_error("ecdh key failed");
|
||||
if (EC_KEY_get0_private_key (pkey))
|
||||
{
|
||||
privkey = pkey;
|
||||
pubkey = otherKey.pkey;
|
||||
}
|
||||
else if (EC_KEY_get0_private_key (otherKey.pkey))
|
||||
{
|
||||
privkey = otherKey.pkey;
|
||||
pubkey = pkey;
|
||||
}
|
||||
else throw std::runtime_error ("no private key");
|
||||
|
||||
unsigned char hbuf[ECIES_KEY_LENGTH];
|
||||
ECIES_KEY_HASH(rawbuf, buflen, hbuf);
|
||||
memset(rawbuf, 0, ECIES_HMAC_KEY_SIZE);
|
||||
unsigned char rawbuf[512];
|
||||
int buflen = ECDH_compute_key (rawbuf, 512, EC_KEY_get0_public_key (pubkey), privkey, NULL);
|
||||
|
||||
assert((ECIES_ENC_KEY_SIZE + ECIES_HMAC_KEY_SIZE) >= ECIES_KEY_LENGTH);
|
||||
memcpy(enc_key.begin(), hbuf, ECIES_ENC_KEY_SIZE);
|
||||
memcpy(hmac_key.begin(), hbuf + ECIES_ENC_KEY_SIZE, ECIES_HMAC_KEY_SIZE);
|
||||
memset(hbuf, 0, ECIES_KEY_LENGTH);
|
||||
if (buflen < ECIES_MIN_SEC)
|
||||
throw std::runtime_error ("ecdh key failed");
|
||||
|
||||
unsigned char hbuf[ECIES_KEY_LENGTH];
|
||||
ECIES_KEY_HASH (rawbuf, buflen, hbuf);
|
||||
memset (rawbuf, 0, ECIES_HMAC_KEY_SIZE);
|
||||
|
||||
assert ((ECIES_ENC_KEY_SIZE + ECIES_HMAC_KEY_SIZE) >= ECIES_KEY_LENGTH);
|
||||
memcpy (enc_key.begin (), hbuf, ECIES_ENC_KEY_SIZE);
|
||||
memcpy (hmac_key.begin (), hbuf + ECIES_ENC_KEY_SIZE, ECIES_HMAC_KEY_SIZE);
|
||||
memset (hbuf, 0, ECIES_KEY_LENGTH);
|
||||
}
|
||||
|
||||
static ECIES_HMAC_TYPE makeHMAC(const ECIES_HMAC_KEY_TYPE& secret, Blob const& data)
|
||||
static ECIES_HMAC_TYPE makeHMAC (const ECIES_HMAC_KEY_TYPE& secret, Blob const& data)
|
||||
{
|
||||
HMAC_CTX ctx;
|
||||
HMAC_CTX_init(&ctx);
|
||||
|
||||
if (HMAC_Init_ex(&ctx, secret.begin(), ECIES_HMAC_KEY_SIZE, ECIES_HMAC_ALGO, NULL) != 1)
|
||||
{
|
||||
HMAC_CTX_cleanup(&ctx);
|
||||
throw std::runtime_error("init hmac");
|
||||
}
|
||||
HMAC_CTX ctx;
|
||||
HMAC_CTX_init (&ctx);
|
||||
|
||||
if (HMAC_Update(&ctx, &(data.front()), data.size()) != 1)
|
||||
{
|
||||
HMAC_CTX_cleanup(&ctx);
|
||||
throw std::runtime_error("update hmac");
|
||||
}
|
||||
if (HMAC_Init_ex (&ctx, secret.begin (), ECIES_HMAC_KEY_SIZE, ECIES_HMAC_ALGO, NULL) != 1)
|
||||
{
|
||||
HMAC_CTX_cleanup (&ctx);
|
||||
throw std::runtime_error ("init hmac");
|
||||
}
|
||||
|
||||
ECIES_HMAC_TYPE ret;
|
||||
unsigned int ml = ECIES_HMAC_SIZE;
|
||||
if (HMAC_Final(&ctx, ret.begin(), &ml) != 1)
|
||||
{
|
||||
HMAC_CTX_cleanup(&ctx);
|
||||
throw std::runtime_error("finalize hmac");
|
||||
}
|
||||
assert(ml == ECIES_HMAC_SIZE);
|
||||
HMAC_CTX_cleanup(&ctx);
|
||||
if (HMAC_Update (&ctx, & (data.front ()), data.size ()) != 1)
|
||||
{
|
||||
HMAC_CTX_cleanup (&ctx);
|
||||
throw std::runtime_error ("update hmac");
|
||||
}
|
||||
|
||||
return ret;
|
||||
ECIES_HMAC_TYPE ret;
|
||||
unsigned int ml = ECIES_HMAC_SIZE;
|
||||
|
||||
if (HMAC_Final (&ctx, ret.begin (), &ml) != 1)
|
||||
{
|
||||
HMAC_CTX_cleanup (&ctx);
|
||||
throw std::runtime_error ("finalize hmac");
|
||||
}
|
||||
|
||||
assert (ml == ECIES_HMAC_SIZE);
|
||||
HMAC_CTX_cleanup (&ctx);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
Blob CKey::encryptECIES(CKey& otherKey, Blob const& plaintext)
|
||||
Blob CKey::encryptECIES (CKey& otherKey, Blob const& plaintext)
|
||||
{
|
||||
|
||||
ECIES_ENC_IV_TYPE iv;
|
||||
RandomNumbers::getInstance ().fillBytes (iv.begin (), ECIES_ENC_BLK_SIZE);
|
||||
ECIES_ENC_IV_TYPE iv;
|
||||
RandomNumbers::getInstance ().fillBytes (iv.begin (), ECIES_ENC_BLK_SIZE);
|
||||
|
||||
ECIES_ENC_KEY_TYPE secret;
|
||||
ECIES_HMAC_KEY_TYPE hmacKey;
|
||||
ECIES_ENC_KEY_TYPE secret;
|
||||
ECIES_HMAC_KEY_TYPE hmacKey;
|
||||
|
||||
getECIESSecret(otherKey, secret, hmacKey);
|
||||
ECIES_HMAC_TYPE hmac = makeHMAC(hmacKey, plaintext);
|
||||
hmacKey.zero();
|
||||
getECIESSecret (otherKey, secret, hmacKey);
|
||||
ECIES_HMAC_TYPE hmac = makeHMAC (hmacKey, plaintext);
|
||||
hmacKey.zero ();
|
||||
|
||||
EVP_CIPHER_CTX ctx;
|
||||
EVP_CIPHER_CTX_init(&ctx);
|
||||
EVP_CIPHER_CTX ctx;
|
||||
EVP_CIPHER_CTX_init (&ctx);
|
||||
|
||||
if (EVP_EncryptInit_ex(&ctx, ECIES_ENC_ALGO, NULL, secret.begin(), iv.begin()) != 1)
|
||||
{
|
||||
EVP_CIPHER_CTX_cleanup(&ctx);
|
||||
secret.zero();
|
||||
throw std::runtime_error("init cipher ctx");
|
||||
}
|
||||
secret.zero();
|
||||
if (EVP_EncryptInit_ex (&ctx, ECIES_ENC_ALGO, NULL, secret.begin (), iv.begin ()) != 1)
|
||||
{
|
||||
EVP_CIPHER_CTX_cleanup (&ctx);
|
||||
secret.zero ();
|
||||
throw std::runtime_error ("init cipher ctx");
|
||||
}
|
||||
|
||||
Blob out(plaintext.size() + ECIES_HMAC_SIZE + ECIES_ENC_KEY_SIZE + ECIES_ENC_BLK_SIZE, 0);
|
||||
int len = 0, bytesWritten;
|
||||
secret.zero ();
|
||||
|
||||
// output IV
|
||||
memcpy(&(out.front()), iv.begin(), ECIES_ENC_BLK_SIZE);
|
||||
len = ECIES_ENC_BLK_SIZE;
|
||||
Blob out (plaintext.size () + ECIES_HMAC_SIZE + ECIES_ENC_KEY_SIZE + ECIES_ENC_BLK_SIZE, 0);
|
||||
int len = 0, bytesWritten;
|
||||
|
||||
// Encrypt/output HMAC
|
||||
bytesWritten = out.capacity() - len;
|
||||
assert(bytesWritten>0);
|
||||
if (EVP_EncryptUpdate(&ctx, &(out.front()) + len, &bytesWritten, hmac.begin(), ECIES_HMAC_SIZE) < 0)
|
||||
{
|
||||
EVP_CIPHER_CTX_cleanup(&ctx);
|
||||
throw std::runtime_error("");
|
||||
}
|
||||
len += bytesWritten;
|
||||
// output IV
|
||||
memcpy (& (out.front ()), iv.begin (), ECIES_ENC_BLK_SIZE);
|
||||
len = ECIES_ENC_BLK_SIZE;
|
||||
|
||||
// encrypt/output plaintext
|
||||
bytesWritten = out.capacity() - len;
|
||||
assert(bytesWritten>0);
|
||||
if (EVP_EncryptUpdate(&ctx, &(out.front()) + len, &bytesWritten, &(plaintext.front()), plaintext.size()) < 0)
|
||||
{
|
||||
EVP_CIPHER_CTX_cleanup(&ctx);
|
||||
throw std::runtime_error("");
|
||||
}
|
||||
len += bytesWritten;
|
||||
// Encrypt/output HMAC
|
||||
bytesWritten = out.capacity () - len;
|
||||
assert (bytesWritten > 0);
|
||||
|
||||
// finalize
|
||||
bytesWritten = out.capacity() - len;
|
||||
if (EVP_EncryptFinal_ex(&ctx, &(out.front()) + len, &bytesWritten) < 0)
|
||||
{
|
||||
EVP_CIPHER_CTX_cleanup(&ctx);
|
||||
throw std::runtime_error("encryption error");
|
||||
}
|
||||
len += bytesWritten;
|
||||
if (EVP_EncryptUpdate (&ctx, & (out.front ()) + len, &bytesWritten, hmac.begin (), ECIES_HMAC_SIZE) < 0)
|
||||
{
|
||||
EVP_CIPHER_CTX_cleanup (&ctx);
|
||||
throw std::runtime_error ("");
|
||||
}
|
||||
|
||||
// Output contains: IV, encrypted HMAC, encrypted data, encrypted padding
|
||||
assert(len <= (plaintext.size() + ECIES_HMAC_SIZE + (2 * ECIES_ENC_BLK_SIZE)));
|
||||
assert(len >= (plaintext.size() + ECIES_HMAC_SIZE + ECIES_ENC_BLK_SIZE)); // IV, HMAC, data
|
||||
out.resize(len);
|
||||
EVP_CIPHER_CTX_cleanup(&ctx);
|
||||
return out;
|
||||
len += bytesWritten;
|
||||
|
||||
// encrypt/output plaintext
|
||||
bytesWritten = out.capacity () - len;
|
||||
assert (bytesWritten > 0);
|
||||
|
||||
if (EVP_EncryptUpdate (&ctx, & (out.front ()) + len, &bytesWritten, & (plaintext.front ()), plaintext.size ()) < 0)
|
||||
{
|
||||
EVP_CIPHER_CTX_cleanup (&ctx);
|
||||
throw std::runtime_error ("");
|
||||
}
|
||||
|
||||
len += bytesWritten;
|
||||
|
||||
// finalize
|
||||
bytesWritten = out.capacity () - len;
|
||||
|
||||
if (EVP_EncryptFinal_ex (&ctx, & (out.front ()) + len, &bytesWritten) < 0)
|
||||
{
|
||||
EVP_CIPHER_CTX_cleanup (&ctx);
|
||||
throw std::runtime_error ("encryption error");
|
||||
}
|
||||
|
||||
len += bytesWritten;
|
||||
|
||||
// Output contains: IV, encrypted HMAC, encrypted data, encrypted padding
|
||||
assert (len <= (plaintext.size () + ECIES_HMAC_SIZE + (2 * ECIES_ENC_BLK_SIZE)));
|
||||
assert (len >= (plaintext.size () + ECIES_HMAC_SIZE + ECIES_ENC_BLK_SIZE)); // IV, HMAC, data
|
||||
out.resize (len);
|
||||
EVP_CIPHER_CTX_cleanup (&ctx);
|
||||
return out;
|
||||
}
|
||||
|
||||
Blob CKey::decryptECIES(CKey& otherKey, Blob const& ciphertext)
|
||||
Blob CKey::decryptECIES (CKey& otherKey, Blob const& ciphertext)
|
||||
{
|
||||
// minimum ciphertext = IV + HMAC + 1 block
|
||||
if (ciphertext.size() < ((2 * ECIES_ENC_BLK_SIZE) + ECIES_HMAC_SIZE) )
|
||||
throw std::runtime_error("ciphertext too short");
|
||||
// minimum ciphertext = IV + HMAC + 1 block
|
||||
if (ciphertext.size () < ((2 * ECIES_ENC_BLK_SIZE) + ECIES_HMAC_SIZE) )
|
||||
throw std::runtime_error ("ciphertext too short");
|
||||
|
||||
// extract IV
|
||||
ECIES_ENC_IV_TYPE iv;
|
||||
memcpy(iv.begin(), &(ciphertext.front()), ECIES_ENC_BLK_SIZE);
|
||||
// extract IV
|
||||
ECIES_ENC_IV_TYPE iv;
|
||||
memcpy (iv.begin (), & (ciphertext.front ()), ECIES_ENC_BLK_SIZE);
|
||||
|
||||
// begin decrypting
|
||||
EVP_CIPHER_CTX ctx;
|
||||
EVP_CIPHER_CTX_init(&ctx);
|
||||
// begin decrypting
|
||||
EVP_CIPHER_CTX ctx;
|
||||
EVP_CIPHER_CTX_init (&ctx);
|
||||
|
||||
ECIES_ENC_KEY_TYPE secret;
|
||||
ECIES_HMAC_KEY_TYPE hmacKey;
|
||||
getECIESSecret(otherKey, secret, hmacKey);
|
||||
ECIES_ENC_KEY_TYPE secret;
|
||||
ECIES_HMAC_KEY_TYPE hmacKey;
|
||||
getECIESSecret (otherKey, secret, hmacKey);
|
||||
|
||||
if (EVP_DecryptInit_ex(&ctx, ECIES_ENC_ALGO, NULL, secret.begin(), iv.begin()) != 1)
|
||||
{
|
||||
secret.zero();
|
||||
hmacKey.zero();
|
||||
EVP_CIPHER_CTX_cleanup(&ctx);
|
||||
throw std::runtime_error("unable to init cipher");
|
||||
}
|
||||
|
||||
// decrypt mac
|
||||
ECIES_HMAC_TYPE hmac;
|
||||
int outlen = ECIES_HMAC_SIZE;
|
||||
if ( (EVP_DecryptUpdate(&ctx, hmac.begin(), &outlen,
|
||||
&(ciphertext.front()) + ECIES_ENC_BLK_SIZE, ECIES_HMAC_SIZE + 1) != 1) || (outlen != ECIES_HMAC_SIZE) )
|
||||
{
|
||||
secret.zero();
|
||||
hmacKey.zero();
|
||||
EVP_CIPHER_CTX_cleanup(&ctx);
|
||||
throw std::runtime_error("unable to extract hmac");
|
||||
}
|
||||
|
||||
// decrypt plaintext (after IV and encrypted mac)
|
||||
Blob plaintext(ciphertext.size() - ECIES_HMAC_SIZE - ECIES_ENC_BLK_SIZE);
|
||||
outlen = plaintext.size();
|
||||
if (EVP_DecryptUpdate(&ctx, &(plaintext.front()), &outlen,
|
||||
&(ciphertext.front()) + ECIES_ENC_BLK_SIZE + ECIES_HMAC_SIZE + 1,
|
||||
ciphertext.size() - ECIES_ENC_BLK_SIZE - ECIES_HMAC_SIZE - 1) != 1)
|
||||
{
|
||||
secret.zero();
|
||||
hmacKey.zero();
|
||||
EVP_CIPHER_CTX_cleanup(&ctx);
|
||||
throw std::runtime_error("unable to extract plaintext");
|
||||
}
|
||||
if (EVP_DecryptInit_ex (&ctx, ECIES_ENC_ALGO, NULL, secret.begin (), iv.begin ()) != 1)
|
||||
{
|
||||
secret.zero ();
|
||||
hmacKey.zero ();
|
||||
EVP_CIPHER_CTX_cleanup (&ctx);
|
||||
throw std::runtime_error ("unable to init cipher");
|
||||
}
|
||||
|
||||
// decrypt padding
|
||||
int flen = 0;
|
||||
if (EVP_DecryptFinal(&ctx, &(plaintext.front()) + outlen, &flen) != 1)
|
||||
{
|
||||
secret.zero();
|
||||
hmacKey.zero();
|
||||
EVP_CIPHER_CTX_cleanup(&ctx);
|
||||
throw std::runtime_error("plaintext had bad padding");
|
||||
}
|
||||
plaintext.resize(flen + outlen);
|
||||
// decrypt mac
|
||||
ECIES_HMAC_TYPE hmac;
|
||||
int outlen = ECIES_HMAC_SIZE;
|
||||
|
||||
// verify integrity
|
||||
if (hmac != makeHMAC(hmacKey, plaintext))
|
||||
{
|
||||
secret.zero();
|
||||
hmacKey.zero();
|
||||
EVP_CIPHER_CTX_cleanup(&ctx);
|
||||
throw std::runtime_error("plaintext had bad hmac");
|
||||
}
|
||||
secret.zero();
|
||||
hmacKey.zero();
|
||||
if ( (EVP_DecryptUpdate (&ctx, hmac.begin (), &outlen,
|
||||
& (ciphertext.front ()) + ECIES_ENC_BLK_SIZE, ECIES_HMAC_SIZE + 1) != 1) || (outlen != ECIES_HMAC_SIZE) )
|
||||
{
|
||||
secret.zero ();
|
||||
hmacKey.zero ();
|
||||
EVP_CIPHER_CTX_cleanup (&ctx);
|
||||
throw std::runtime_error ("unable to extract hmac");
|
||||
}
|
||||
|
||||
EVP_CIPHER_CTX_cleanup(&ctx);
|
||||
return plaintext;
|
||||
// decrypt plaintext (after IV and encrypted mac)
|
||||
Blob plaintext (ciphertext.size () - ECIES_HMAC_SIZE - ECIES_ENC_BLK_SIZE);
|
||||
outlen = plaintext.size ();
|
||||
|
||||
if (EVP_DecryptUpdate (&ctx, & (plaintext.front ()), &outlen,
|
||||
& (ciphertext.front ()) + ECIES_ENC_BLK_SIZE + ECIES_HMAC_SIZE + 1,
|
||||
ciphertext.size () - ECIES_ENC_BLK_SIZE - ECIES_HMAC_SIZE - 1) != 1)
|
||||
{
|
||||
secret.zero ();
|
||||
hmacKey.zero ();
|
||||
EVP_CIPHER_CTX_cleanup (&ctx);
|
||||
throw std::runtime_error ("unable to extract plaintext");
|
||||
}
|
||||
|
||||
// decrypt padding
|
||||
int flen = 0;
|
||||
|
||||
if (EVP_DecryptFinal (&ctx, & (plaintext.front ()) + outlen, &flen) != 1)
|
||||
{
|
||||
secret.zero ();
|
||||
hmacKey.zero ();
|
||||
EVP_CIPHER_CTX_cleanup (&ctx);
|
||||
throw std::runtime_error ("plaintext had bad padding");
|
||||
}
|
||||
|
||||
plaintext.resize (flen + outlen);
|
||||
|
||||
// verify integrity
|
||||
if (hmac != makeHMAC (hmacKey, plaintext))
|
||||
{
|
||||
secret.zero ();
|
||||
hmacKey.zero ();
|
||||
EVP_CIPHER_CTX_cleanup (&ctx);
|
||||
throw std::runtime_error ("plaintext had bad hmac");
|
||||
}
|
||||
|
||||
secret.zero ();
|
||||
hmacKey.zero ();
|
||||
|
||||
EVP_CIPHER_CTX_cleanup (&ctx);
|
||||
return plaintext;
|
||||
}
|
||||
|
||||
bool checkECIES(void)
|
||||
bool checkECIES (void)
|
||||
{
|
||||
CKey senderPriv, recipientPriv, senderPub, recipientPub;
|
||||
CKey senderPriv, recipientPriv, senderPub, recipientPub;
|
||||
|
||||
for (int i = 0; i < 30000; ++i)
|
||||
{
|
||||
if ((i % 100) == 0)
|
||||
{ // generate new keys every 100 times
|
||||
// std::cerr << "new keys" << std::endl;
|
||||
senderPriv.MakeNewKey();
|
||||
recipientPriv.MakeNewKey();
|
||||
for (int i = 0; i < 30000; ++i)
|
||||
{
|
||||
if ((i % 100) == 0)
|
||||
{
|
||||
// generate new keys every 100 times
|
||||
// std::cerr << "new keys" << std::endl;
|
||||
senderPriv.MakeNewKey ();
|
||||
recipientPriv.MakeNewKey ();
|
||||
|
||||
if (!senderPub.SetPubKey(senderPriv.GetPubKey()))
|
||||
throw std::runtime_error("key error");
|
||||
if (!recipientPub.SetPubKey(recipientPriv.GetPubKey()))
|
||||
throw std::runtime_error("key error");
|
||||
}
|
||||
if (!senderPub.SetPubKey (senderPriv.GetPubKey ()))
|
||||
throw std::runtime_error ("key error");
|
||||
|
||||
// generate message
|
||||
Blob message(4096);
|
||||
int msglen = i%3000;
|
||||
if (!recipientPub.SetPubKey (recipientPriv.GetPubKey ()))
|
||||
throw std::runtime_error ("key error");
|
||||
}
|
||||
|
||||
RandomNumbers::getInstance ().fillBytes (&message.front(), msglen);
|
||||
message.resize(msglen);
|
||||
// generate message
|
||||
Blob message (4096);
|
||||
int msglen = i % 3000;
|
||||
|
||||
// encrypt message with sender's private key and recipient's public key
|
||||
Blob ciphertext = senderPriv.encryptECIES(recipientPub, message);
|
||||
RandomNumbers::getInstance ().fillBytes (&message.front (), msglen);
|
||||
message.resize (msglen);
|
||||
|
||||
// decrypt message with recipient's private key and sender's public key
|
||||
Blob decrypt = recipientPriv.decryptECIES(senderPub, ciphertext);
|
||||
// encrypt message with sender's private key and recipient's public key
|
||||
Blob ciphertext = senderPriv.encryptECIES (recipientPub, message);
|
||||
|
||||
if (decrypt != message)
|
||||
{
|
||||
assert(false);
|
||||
return false;
|
||||
}
|
||||
// std::cerr << "Msg(" << msglen << ") ok " << ciphertext.size() << std::endl;
|
||||
}
|
||||
return true;
|
||||
// decrypt message with recipient's private key and sender's public key
|
||||
Blob decrypt = recipientPriv.decryptECIES (senderPub, ciphertext);
|
||||
|
||||
if (decrypt != message)
|
||||
{
|
||||
assert (false);
|
||||
return false;
|
||||
}
|
||||
|
||||
// std::cerr << "Msg(" << msglen << ") ok " << ciphertext.size() << std::endl;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// vim:ts=4
|
||||
|
||||
@@ -12,363 +12,370 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
char const* RFC1751::s_dictionary [2048] = {
|
||||
"A", "ABE", "ACE", "ACT", "AD", "ADA", "ADD",
|
||||
"AGO", "AID", "AIM", "AIR", "ALL", "ALP", "AM", "AMY", "AN", "ANA",
|
||||
"AND", "ANN", "ANT", "ANY", "APE", "APS", "APT", "ARC", "ARE", "ARK",
|
||||
"ARM", "ART", "AS", "ASH", "ASK", "AT", "ATE", "AUG", "AUK", "AVE",
|
||||
"AWE", "AWK", "AWL", "AWN", "AX", "AYE", "BAD", "BAG", "BAH", "BAM",
|
||||
"BAN", "BAR", "BAT", "BAY", "BE", "BED", "BEE", "BEG", "BEN", "BET",
|
||||
"BEY", "BIB", "BID", "BIG", "BIN", "BIT", "BOB", "BOG", "BON", "BOO",
|
||||
"BOP", "BOW", "BOY", "BUB", "BUD", "BUG", "BUM", "BUN", "BUS", "BUT",
|
||||
"BUY", "BY", "BYE", "CAB", "CAL", "CAM", "CAN", "CAP", "CAR", "CAT",
|
||||
"CAW", "COD", "COG", "COL", "CON", "COO", "COP", "COT", "COW", "COY",
|
||||
"CRY", "CUB", "CUE", "CUP", "CUR", "CUT", "DAB", "DAD", "DAM", "DAN",
|
||||
"DAR", "DAY", "DEE", "DEL", "DEN", "DES", "DEW", "DID", "DIE", "DIG",
|
||||
"DIN", "DIP", "DO", "DOE", "DOG", "DON", "DOT", "DOW", "DRY", "DUB",
|
||||
"DUD", "DUE", "DUG", "DUN", "EAR", "EAT", "ED", "EEL", "EGG", "EGO",
|
||||
"ELI", "ELK", "ELM", "ELY", "EM", "END", "EST", "ETC", "EVA", "EVE",
|
||||
"EWE", "EYE", "FAD", "FAN", "FAR", "FAT", "FAY", "FED", "FEE", "FEW",
|
||||
"FIB", "FIG", "FIN", "FIR", "FIT", "FLO", "FLY", "FOE", "FOG", "FOR",
|
||||
"FRY", "FUM", "FUN", "FUR", "GAB", "GAD", "GAG", "GAL", "GAM", "GAP",
|
||||
"GAS", "GAY", "GEE", "GEL", "GEM", "GET", "GIG", "GIL", "GIN", "GO",
|
||||
"GOT", "GUM", "GUN", "GUS", "GUT", "GUY", "GYM", "GYP", "HA", "HAD",
|
||||
"HAL", "HAM", "HAN", "HAP", "HAS", "HAT", "HAW", "HAY", "HE", "HEM",
|
||||
"HEN", "HER", "HEW", "HEY", "HI", "HID", "HIM", "HIP", "HIS", "HIT",
|
||||
"HO", "HOB", "HOC", "HOE", "HOG", "HOP", "HOT", "HOW", "HUB", "HUE",
|
||||
"HUG", "HUH", "HUM", "HUT", "I", "ICY", "IDA", "IF", "IKE", "ILL",
|
||||
"INK", "INN", "IO", "ION", "IQ", "IRA", "IRE", "IRK", "IS", "IT", "ITS",
|
||||
"IVY", "JAB", "JAG", "JAM", "JAN", "JAR", "JAW", "JAY", "JET", "JIG",
|
||||
"JIM", "JO", "JOB", "JOE", "JOG", "JOT", "JOY", "JUG", "JUT", "KAY",
|
||||
"KEG", "KEN", "KEY", "KID", "KIM", "KIN", "KIT", "LA", "LAB", "LAC",
|
||||
"LAD", "LAG", "LAM", "LAP", "LAW", "LAY", "LEA", "LED", "LEE", "LEG",
|
||||
"LEN", "LEO", "LET", "LEW", "LID", "LIE", "LIN", "LIP", "LIT", "LO",
|
||||
"LOB", "LOG", "LOP", "LOS", "LOT", "LOU", "LOW", "LOY", "LUG", "LYE",
|
||||
"MA", "MAC", "MAD", "MAE", "MAN", "MAO", "MAP", "MAT", "MAW", "MAY",
|
||||
"ME", "MEG", "MEL", "MEN", "MET", "MEW", "MID", "MIN", "MIT", "MOB",
|
||||
"MOD", "MOE", "MOO", "MOP", "MOS", "MOT", "MOW", "MUD", "MUG", "MUM",
|
||||
"MY", "NAB", "NAG", "NAN", "NAP", "NAT", "NAY", "NE", "NED", "NEE",
|
||||
"NET", "NEW", "NIB", "NIL", "NIP", "NIT", "NO", "NOB", "NOD", "NON",
|
||||
"NOR", "NOT", "NOV", "NOW", "NU", "NUN", "NUT", "O", "OAF", "OAK",
|
||||
"OAR", "OAT", "ODD", "ODE", "OF", "OFF", "OFT", "OH", "OIL", "OK",
|
||||
"OLD", "ON", "ONE", "OR", "ORB", "ORE", "ORR", "OS", "OTT", "OUR",
|
||||
"OUT", "OVA", "OW", "OWE", "OWL", "OWN", "OX", "PA", "PAD", "PAL",
|
||||
"PAM", "PAN", "PAP", "PAR", "PAT", "PAW", "PAY", "PEA", "PEG", "PEN",
|
||||
"PEP", "PER", "PET", "PEW", "PHI", "PI", "PIE", "PIN", "PIT", "PLY",
|
||||
"PO", "POD", "POE", "POP", "POT", "POW", "PRO", "PRY", "PUB", "PUG",
|
||||
"PUN", "PUP", "PUT", "QUO", "RAG", "RAM", "RAN", "RAP", "RAT", "RAW",
|
||||
"RAY", "REB", "RED", "REP", "RET", "RIB", "RID", "RIG", "RIM", "RIO",
|
||||
"RIP", "ROB", "ROD", "ROE", "RON", "ROT", "ROW", "ROY", "RUB", "RUE",
|
||||
"RUG", "RUM", "RUN", "RYE", "SAC", "SAD", "SAG", "SAL", "SAM", "SAN",
|
||||
"SAP", "SAT", "SAW", "SAY", "SEA", "SEC", "SEE", "SEN", "SET", "SEW",
|
||||
"SHE", "SHY", "SIN", "SIP", "SIR", "SIS", "SIT", "SKI", "SKY", "SLY",
|
||||
"SO", "SOB", "SOD", "SON", "SOP", "SOW", "SOY", "SPA", "SPY", "SUB",
|
||||
"SUD", "SUE", "SUM", "SUN", "SUP", "TAB", "TAD", "TAG", "TAN", "TAP",
|
||||
"TAR", "TEA", "TED", "TEE", "TEN", "THE", "THY", "TIC", "TIE", "TIM",
|
||||
"TIN", "TIP", "TO", "TOE", "TOG", "TOM", "TON", "TOO", "TOP", "TOW",
|
||||
"TOY", "TRY", "TUB", "TUG", "TUM", "TUN", "TWO", "UN", "UP", "US",
|
||||
"USE", "VAN", "VAT", "VET", "VIE", "WAD", "WAG", "WAR", "WAS", "WAY",
|
||||
"WE", "WEB", "WED", "WEE", "WET", "WHO", "WHY", "WIN", "WIT", "WOK",
|
||||
"WON", "WOO", "WOW", "WRY", "WU", "YAM", "YAP", "YAW", "YE", "YEA",
|
||||
"YES", "YET", "YOU", "ABED", "ABEL", "ABET", "ABLE", "ABUT", "ACHE",
|
||||
"ACID", "ACME", "ACRE", "ACTA", "ACTS", "ADAM", "ADDS", "ADEN", "AFAR",
|
||||
"AFRO", "AGEE", "AHEM", "AHOY", "AIDA", "AIDE", "AIDS", "AIRY", "AJAR",
|
||||
"AKIN", "ALAN", "ALEC", "ALGA", "ALIA", "ALLY", "ALMA", "ALOE", "ALSO",
|
||||
"ALTO", "ALUM", "ALVA", "AMEN", "AMES", "AMID", "AMMO", "AMOK", "AMOS",
|
||||
"AMRA", "ANDY", "ANEW", "ANNA", "ANNE", "ANTE", "ANTI", "AQUA", "ARAB",
|
||||
"ARCH", "AREA", "ARGO", "ARID", "ARMY", "ARTS", "ARTY", "ASIA", "ASKS",
|
||||
"ATOM", "AUNT", "AURA", "AUTO", "AVER", "AVID", "AVIS", "AVON", "AVOW",
|
||||
"AWAY", "AWRY", "BABE", "BABY", "BACH", "BACK", "BADE", "BAIL", "BAIT",
|
||||
"BAKE", "BALD", "BALE", "BALI", "BALK", "BALL", "BALM", "BAND", "BANE",
|
||||
"BANG", "BANK", "BARB", "BARD", "BARE", "BARK", "BARN", "BARR", "BASE",
|
||||
"BASH", "BASK", "BASS", "BATE", "BATH", "BAWD", "BAWL", "BEAD", "BEAK",
|
||||
"BEAM", "BEAN", "BEAR", "BEAT", "BEAU", "BECK", "BEEF", "BEEN", "BEER",
|
||||
"BEET", "BELA", "BELL", "BELT", "BEND", "BENT", "BERG", "BERN", "BERT",
|
||||
"BESS", "BEST", "BETA", "BETH", "BHOY", "BIAS", "BIDE", "BIEN", "BILE",
|
||||
"BILK", "BILL", "BIND", "BING", "BIRD", "BITE", "BITS", "BLAB", "BLAT",
|
||||
"BLED", "BLEW", "BLOB", "BLOC", "BLOT", "BLOW", "BLUE", "BLUM", "BLUR",
|
||||
"BOAR", "BOAT", "BOCA", "BOCK", "BODE", "BODY", "BOGY", "BOHR", "BOIL",
|
||||
"BOLD", "BOLO", "BOLT", "BOMB", "BONA", "BOND", "BONE", "BONG", "BONN",
|
||||
"BONY", "BOOK", "BOOM", "BOON", "BOOT", "BORE", "BORG", "BORN", "BOSE",
|
||||
"BOSS", "BOTH", "BOUT", "BOWL", "BOYD", "BRAD", "BRAE", "BRAG", "BRAN",
|
||||
"BRAY", "BRED", "BREW", "BRIG", "BRIM", "BROW", "BUCK", "BUDD", "BUFF",
|
||||
"BULB", "BULK", "BULL", "BUNK", "BUNT", "BUOY", "BURG", "BURL", "BURN",
|
||||
"BURR", "BURT", "BURY", "BUSH", "BUSS", "BUST", "BUSY", "BYTE", "CADY",
|
||||
"CAFE", "CAGE", "CAIN", "CAKE", "CALF", "CALL", "CALM", "CAME", "CANE",
|
||||
"CANT", "CARD", "CARE", "CARL", "CARR", "CART", "CASE", "CASH", "CASK",
|
||||
"CAST", "CAVE", "CEIL", "CELL", "CENT", "CERN", "CHAD", "CHAR", "CHAT",
|
||||
"CHAW", "CHEF", "CHEN", "CHEW", "CHIC", "CHIN", "CHOU", "CHOW", "CHUB",
|
||||
"CHUG", "CHUM", "CITE", "CITY", "CLAD", "CLAM", "CLAN", "CLAW", "CLAY",
|
||||
"CLOD", "CLOG", "CLOT", "CLUB", "CLUE", "COAL", "COAT", "COCA", "COCK",
|
||||
"COCO", "CODA", "CODE", "CODY", "COED", "COIL", "COIN", "COKE", "COLA",
|
||||
"COLD", "COLT", "COMA", "COMB", "COME", "COOK", "COOL", "COON", "COOT",
|
||||
"CORD", "CORE", "CORK", "CORN", "COST", "COVE", "COWL", "CRAB", "CRAG",
|
||||
"CRAM", "CRAY", "CREW", "CRIB", "CROW", "CRUD", "CUBA", "CUBE", "CUFF",
|
||||
"CULL", "CULT", "CUNY", "CURB", "CURD", "CURE", "CURL", "CURT", "CUTS",
|
||||
"DADE", "DALE", "DAME", "DANA", "DANE", "DANG", "DANK", "DARE", "DARK",
|
||||
"DARN", "DART", "DASH", "DATA", "DATE", "DAVE", "DAVY", "DAWN", "DAYS",
|
||||
"DEAD", "DEAF", "DEAL", "DEAN", "DEAR", "DEBT", "DECK", "DEED", "DEEM",
|
||||
"DEER", "DEFT", "DEFY", "DELL", "DENT", "DENY", "DESK", "DIAL", "DICE",
|
||||
"DIED", "DIET", "DIME", "DINE", "DING", "DINT", "DIRE", "DIRT", "DISC",
|
||||
"DISH", "DISK", "DIVE", "DOCK", "DOES", "DOLE", "DOLL", "DOLT", "DOME",
|
||||
"DONE", "DOOM", "DOOR", "DORA", "DOSE", "DOTE", "DOUG", "DOUR", "DOVE",
|
||||
"DOWN", "DRAB", "DRAG", "DRAM", "DRAW", "DREW", "DRUB", "DRUG", "DRUM",
|
||||
"DUAL", "DUCK", "DUCT", "DUEL", "DUET", "DUKE", "DULL", "DUMB", "DUNE",
|
||||
"DUNK", "DUSK", "DUST", "DUTY", "EACH", "EARL", "EARN", "EASE", "EAST",
|
||||
"EASY", "EBEN", "ECHO", "EDDY", "EDEN", "EDGE", "EDGY", "EDIT", "EDNA",
|
||||
"EGAN", "ELAN", "ELBA", "ELLA", "ELSE", "EMIL", "EMIT", "EMMA", "ENDS",
|
||||
"ERIC", "EROS", "EVEN", "EVER", "EVIL", "EYED", "FACE", "FACT", "FADE",
|
||||
"FAIL", "FAIN", "FAIR", "FAKE", "FALL", "FAME", "FANG", "FARM", "FAST",
|
||||
"FATE", "FAWN", "FEAR", "FEAT", "FEED", "FEEL", "FEET", "FELL", "FELT",
|
||||
"FEND", "FERN", "FEST", "FEUD", "FIEF", "FIGS", "FILE", "FILL", "FILM",
|
||||
"FIND", "FINE", "FINK", "FIRE", "FIRM", "FISH", "FISK", "FIST", "FITS",
|
||||
"FIVE", "FLAG", "FLAK", "FLAM", "FLAT", "FLAW", "FLEA", "FLED", "FLEW",
|
||||
"FLIT", "FLOC", "FLOG", "FLOW", "FLUB", "FLUE", "FOAL", "FOAM", "FOGY",
|
||||
"FOIL", "FOLD", "FOLK", "FOND", "FONT", "FOOD", "FOOL", "FOOT", "FORD",
|
||||
"FORE", "FORK", "FORM", "FORT", "FOSS", "FOUL", "FOUR", "FOWL", "FRAU",
|
||||
"FRAY", "FRED", "FREE", "FRET", "FREY", "FROG", "FROM", "FUEL", "FULL",
|
||||
"FUME", "FUND", "FUNK", "FURY", "FUSE", "FUSS", "GAFF", "GAGE", "GAIL",
|
||||
"GAIN", "GAIT", "GALA", "GALE", "GALL", "GALT", "GAME", "GANG", "GARB",
|
||||
"GARY", "GASH", "GATE", "GAUL", "GAUR", "GAVE", "GAWK", "GEAR", "GELD",
|
||||
"GENE", "GENT", "GERM", "GETS", "GIBE", "GIFT", "GILD", "GILL", "GILT",
|
||||
"GINA", "GIRD", "GIRL", "GIST", "GIVE", "GLAD", "GLEE", "GLEN", "GLIB",
|
||||
"GLOB", "GLOM", "GLOW", "GLUE", "GLUM", "GLUT", "GOAD", "GOAL", "GOAT",
|
||||
"GOER", "GOES", "GOLD", "GOLF", "GONE", "GONG", "GOOD", "GOOF", "GORE",
|
||||
"GORY", "GOSH", "GOUT", "GOWN", "GRAB", "GRAD", "GRAY", "GREG", "GREW",
|
||||
"GREY", "GRID", "GRIM", "GRIN", "GRIT", "GROW", "GRUB", "GULF", "GULL",
|
||||
"GUNK", "GURU", "GUSH", "GUST", "GWEN", "GWYN", "HAAG", "HAAS", "HACK",
|
||||
"HAIL", "HAIR", "HALE", "HALF", "HALL", "HALO", "HALT", "HAND", "HANG",
|
||||
"HANK", "HANS", "HARD", "HARK", "HARM", "HART", "HASH", "HAST", "HATE",
|
||||
"HATH", "HAUL", "HAVE", "HAWK", "HAYS", "HEAD", "HEAL", "HEAR", "HEAT",
|
||||
"HEBE", "HECK", "HEED", "HEEL", "HEFT", "HELD", "HELL", "HELM", "HERB",
|
||||
"HERD", "HERE", "HERO", "HERS", "HESS", "HEWN", "HICK", "HIDE", "HIGH",
|
||||
"HIKE", "HILL", "HILT", "HIND", "HINT", "HIRE", "HISS", "HIVE", "HOBO",
|
||||
"HOCK", "HOFF", "HOLD", "HOLE", "HOLM", "HOLT", "HOME", "HONE", "HONK",
|
||||
"HOOD", "HOOF", "HOOK", "HOOT", "HORN", "HOSE", "HOST", "HOUR", "HOVE",
|
||||
"HOWE", "HOWL", "HOYT", "HUCK", "HUED", "HUFF", "HUGE", "HUGH", "HUGO",
|
||||
"HULK", "HULL", "HUNK", "HUNT", "HURD", "HURL", "HURT", "HUSH", "HYDE",
|
||||
"HYMN", "IBIS", "ICON", "IDEA", "IDLE", "IFFY", "INCA", "INCH", "INTO",
|
||||
"IONS", "IOTA", "IOWA", "IRIS", "IRMA", "IRON", "ISLE", "ITCH", "ITEM",
|
||||
"IVAN", "JACK", "JADE", "JAIL", "JAKE", "JANE", "JAVA", "JEAN", "JEFF",
|
||||
"JERK", "JESS", "JEST", "JIBE", "JILL", "JILT", "JIVE", "JOAN", "JOBS",
|
||||
"JOCK", "JOEL", "JOEY", "JOHN", "JOIN", "JOKE", "JOLT", "JOVE", "JUDD",
|
||||
"JUDE", "JUDO", "JUDY", "JUJU", "JUKE", "JULY", "JUNE", "JUNK", "JUNO",
|
||||
"JURY", "JUST", "JUTE", "KAHN", "KALE", "KANE", "KANT", "KARL", "KATE",
|
||||
"KEEL", "KEEN", "KENO", "KENT", "KERN", "KERR", "KEYS", "KICK", "KILL",
|
||||
"KIND", "KING", "KIRK", "KISS", "KITE", "KLAN", "KNEE", "KNEW", "KNIT",
|
||||
"KNOB", "KNOT", "KNOW", "KOCH", "KONG", "KUDO", "KURD", "KURT", "KYLE",
|
||||
"LACE", "LACK", "LACY", "LADY", "LAID", "LAIN", "LAIR", "LAKE", "LAMB",
|
||||
"LAME", "LAND", "LANE", "LANG", "LARD", "LARK", "LASS", "LAST", "LATE",
|
||||
"LAUD", "LAVA", "LAWN", "LAWS", "LAYS", "LEAD", "LEAF", "LEAK", "LEAN",
|
||||
"LEAR", "LEEK", "LEER", "LEFT", "LEND", "LENS", "LENT", "LEON", "LESK",
|
||||
"LESS", "LEST", "LETS", "LIAR", "LICE", "LICK", "LIED", "LIEN", "LIES",
|
||||
"LIEU", "LIFE", "LIFT", "LIKE", "LILA", "LILT", "LILY", "LIMA", "LIMB",
|
||||
"LIME", "LIND", "LINE", "LINK", "LINT", "LION", "LISA", "LIST", "LIVE",
|
||||
"LOAD", "LOAF", "LOAM", "LOAN", "LOCK", "LOFT", "LOGE", "LOIS", "LOLA",
|
||||
"LONE", "LONG", "LOOK", "LOON", "LOOT", "LORD", "LORE", "LOSE", "LOSS",
|
||||
"LOST", "LOUD", "LOVE", "LOWE", "LUCK", "LUCY", "LUGE", "LUKE", "LULU",
|
||||
"LUND", "LUNG", "LURA", "LURE", "LURK", "LUSH", "LUST", "LYLE", "LYNN",
|
||||
"LYON", "LYRA", "MACE", "MADE", "MAGI", "MAID", "MAIL", "MAIN", "MAKE",
|
||||
"MALE", "MALI", "MALL", "MALT", "MANA", "MANN", "MANY", "MARC", "MARE",
|
||||
"MARK", "MARS", "MART", "MARY", "MASH", "MASK", "MASS", "MAST", "MATE",
|
||||
"MATH", "MAUL", "MAYO", "MEAD", "MEAL", "MEAN", "MEAT", "MEEK", "MEET",
|
||||
"MELD", "MELT", "MEMO", "MEND", "MENU", "MERT", "MESH", "MESS", "MICE",
|
||||
"MIKE", "MILD", "MILE", "MILK", "MILL", "MILT", "MIMI", "MIND", "MINE",
|
||||
"MINI", "MINK", "MINT", "MIRE", "MISS", "MIST", "MITE", "MITT", "MOAN",
|
||||
"MOAT", "MOCK", "MODE", "MOLD", "MOLE", "MOLL", "MOLT", "MONA", "MONK",
|
||||
"MONT", "MOOD", "MOON", "MOOR", "MOOT", "MORE", "MORN", "MORT", "MOSS",
|
||||
"MOST", "MOTH", "MOVE", "MUCH", "MUCK", "MUDD", "MUFF", "MULE", "MULL",
|
||||
"MURK", "MUSH", "MUST", "MUTE", "MUTT", "MYRA", "MYTH", "NAGY", "NAIL",
|
||||
"NAIR", "NAME", "NARY", "NASH", "NAVE", "NAVY", "NEAL", "NEAR", "NEAT",
|
||||
"NECK", "NEED", "NEIL", "NELL", "NEON", "NERO", "NESS", "NEST", "NEWS",
|
||||
"NEWT", "NIBS", "NICE", "NICK", "NILE", "NINA", "NINE", "NOAH", "NODE",
|
||||
"NOEL", "NOLL", "NONE", "NOOK", "NOON", "NORM", "NOSE", "NOTE", "NOUN",
|
||||
"NOVA", "NUDE", "NULL", "NUMB", "OATH", "OBEY", "OBOE", "ODIN", "OHIO",
|
||||
"OILY", "OINT", "OKAY", "OLAF", "OLDY", "OLGA", "OLIN", "OMAN", "OMEN",
|
||||
"OMIT", "ONCE", "ONES", "ONLY", "ONTO", "ONUS", "ORAL", "ORGY", "OSLO",
|
||||
"OTIS", "OTTO", "OUCH", "OUST", "OUTS", "OVAL", "OVEN", "OVER", "OWLY",
|
||||
"OWNS", "QUAD", "QUIT", "QUOD", "RACE", "RACK", "RACY", "RAFT", "RAGE",
|
||||
"RAID", "RAIL", "RAIN", "RAKE", "RANK", "RANT", "RARE", "RASH", "RATE",
|
||||
"RAVE", "RAYS", "READ", "REAL", "REAM", "REAR", "RECK", "REED", "REEF",
|
||||
"REEK", "REEL", "REID", "REIN", "RENA", "REND", "RENT", "REST", "RICE",
|
||||
"RICH", "RICK", "RIDE", "RIFT", "RILL", "RIME", "RING", "RINK", "RISE",
|
||||
"RISK", "RITE", "ROAD", "ROAM", "ROAR", "ROBE", "ROCK", "RODE", "ROIL",
|
||||
"ROLL", "ROME", "ROOD", "ROOF", "ROOK", "ROOM", "ROOT", "ROSA", "ROSE",
|
||||
"ROSS", "ROSY", "ROTH", "ROUT", "ROVE", "ROWE", "ROWS", "RUBE", "RUBY",
|
||||
"RUDE", "RUDY", "RUIN", "RULE", "RUNG", "RUNS", "RUNT", "RUSE", "RUSH",
|
||||
"RUSK", "RUSS", "RUST", "RUTH", "SACK", "SAFE", "SAGE", "SAID", "SAIL",
|
||||
"SALE", "SALK", "SALT", "SAME", "SAND", "SANE", "SANG", "SANK", "SARA",
|
||||
"SAUL", "SAVE", "SAYS", "SCAN", "SCAR", "SCAT", "SCOT", "SEAL", "SEAM",
|
||||
"SEAR", "SEAT", "SEED", "SEEK", "SEEM", "SEEN", "SEES", "SELF", "SELL",
|
||||
"SEND", "SENT", "SETS", "SEWN", "SHAG", "SHAM", "SHAW", "SHAY", "SHED",
|
||||
"SHIM", "SHIN", "SHOD", "SHOE", "SHOT", "SHOW", "SHUN", "SHUT", "SICK",
|
||||
"SIDE", "SIFT", "SIGH", "SIGN", "SILK", "SILL", "SILO", "SILT", "SINE",
|
||||
"SING", "SINK", "SIRE", "SITE", "SITS", "SITU", "SKAT", "SKEW", "SKID",
|
||||
"SKIM", "SKIN", "SKIT", "SLAB", "SLAM", "SLAT", "SLAY", "SLED", "SLEW",
|
||||
"SLID", "SLIM", "SLIT", "SLOB", "SLOG", "SLOT", "SLOW", "SLUG", "SLUM",
|
||||
"SLUR", "SMOG", "SMUG", "SNAG", "SNOB", "SNOW", "SNUB", "SNUG", "SOAK",
|
||||
"SOAR", "SOCK", "SODA", "SOFA", "SOFT", "SOIL", "SOLD", "SOME", "SONG",
|
||||
"SOON", "SOOT", "SORE", "SORT", "SOUL", "SOUR", "SOWN", "STAB", "STAG",
|
||||
"STAN", "STAR", "STAY", "STEM", "STEW", "STIR", "STOW", "STUB", "STUN",
|
||||
"SUCH", "SUDS", "SUIT", "SULK", "SUMS", "SUNG", "SUNK", "SURE", "SURF",
|
||||
"SWAB", "SWAG", "SWAM", "SWAN", "SWAT", "SWAY", "SWIM", "SWUM", "TACK",
|
||||
"TACT", "TAIL", "TAKE", "TALE", "TALK", "TALL", "TANK", "TASK", "TATE",
|
||||
"TAUT", "TEAL", "TEAM", "TEAR", "TECH", "TEEM", "TEEN", "TEET", "TELL",
|
||||
"TEND", "TENT", "TERM", "TERN", "TESS", "TEST", "THAN", "THAT", "THEE",
|
||||
"THEM", "THEN", "THEY", "THIN", "THIS", "THUD", "THUG", "TICK", "TIDE",
|
||||
"TIDY", "TIED", "TIER", "TILE", "TILL", "TILT", "TIME", "TINA", "TINE",
|
||||
"TINT", "TINY", "TIRE", "TOAD", "TOGO", "TOIL", "TOLD", "TOLL", "TONE",
|
||||
"TONG", "TONY", "TOOK", "TOOL", "TOOT", "TORE", "TORN", "TOTE", "TOUR",
|
||||
"TOUT", "TOWN", "TRAG", "TRAM", "TRAY", "TREE", "TREK", "TRIG", "TRIM",
|
||||
"TRIO", "TROD", "TROT", "TROY", "TRUE", "TUBA", "TUBE", "TUCK", "TUFT",
|
||||
"TUNA", "TUNE", "TUNG", "TURF", "TURN", "TUSK", "TWIG", "TWIN", "TWIT",
|
||||
"ULAN", "UNIT", "URGE", "USED", "USER", "USES", "UTAH", "VAIL", "VAIN",
|
||||
"VALE", "VARY", "VASE", "VAST", "VEAL", "VEDA", "VEIL", "VEIN", "VEND",
|
||||
"VENT", "VERB", "VERY", "VETO", "VICE", "VIEW", "VINE", "VISE", "VOID",
|
||||
"VOLT", "VOTE", "WACK", "WADE", "WAGE", "WAIL", "WAIT", "WAKE", "WALE",
|
||||
"WALK", "WALL", "WALT", "WAND", "WANE", "WANG", "WANT", "WARD", "WARM",
|
||||
"WARN", "WART", "WASH", "WAST", "WATS", "WATT", "WAVE", "WAVY", "WAYS",
|
||||
"WEAK", "WEAL", "WEAN", "WEAR", "WEED", "WEEK", "WEIR", "WELD", "WELL",
|
||||
"WELT", "WENT", "WERE", "WERT", "WEST", "WHAM", "WHAT", "WHEE", "WHEN",
|
||||
"WHET", "WHOA", "WHOM", "WICK", "WIFE", "WILD", "WILL", "WIND", "WINE",
|
||||
"WING", "WINK", "WINO", "WIRE", "WISE", "WISH", "WITH", "WOLF", "WONT",
|
||||
"WOOD", "WOOL", "WORD", "WORE", "WORK", "WORM", "WORN", "WOVE", "WRIT",
|
||||
"WYNN", "YALE", "YANG", "YANK", "YARD", "YARN", "YAWL", "YAWN", "YEAH",
|
||||
"YEAR", "YELL", "YOGA", "YOKE"
|
||||
char const* RFC1751::s_dictionary [2048] =
|
||||
{
|
||||
"A", "ABE", "ACE", "ACT", "AD", "ADA", "ADD",
|
||||
"AGO", "AID", "AIM", "AIR", "ALL", "ALP", "AM", "AMY", "AN", "ANA",
|
||||
"AND", "ANN", "ANT", "ANY", "APE", "APS", "APT", "ARC", "ARE", "ARK",
|
||||
"ARM", "ART", "AS", "ASH", "ASK", "AT", "ATE", "AUG", "AUK", "AVE",
|
||||
"AWE", "AWK", "AWL", "AWN", "AX", "AYE", "BAD", "BAG", "BAH", "BAM",
|
||||
"BAN", "BAR", "BAT", "BAY", "BE", "BED", "BEE", "BEG", "BEN", "BET",
|
||||
"BEY", "BIB", "BID", "BIG", "BIN", "BIT", "BOB", "BOG", "BON", "BOO",
|
||||
"BOP", "BOW", "BOY", "BUB", "BUD", "BUG", "BUM", "BUN", "BUS", "BUT",
|
||||
"BUY", "BY", "BYE", "CAB", "CAL", "CAM", "CAN", "CAP", "CAR", "CAT",
|
||||
"CAW", "COD", "COG", "COL", "CON", "COO", "COP", "COT", "COW", "COY",
|
||||
"CRY", "CUB", "CUE", "CUP", "CUR", "CUT", "DAB", "DAD", "DAM", "DAN",
|
||||
"DAR", "DAY", "DEE", "DEL", "DEN", "DES", "DEW", "DID", "DIE", "DIG",
|
||||
"DIN", "DIP", "DO", "DOE", "DOG", "DON", "DOT", "DOW", "DRY", "DUB",
|
||||
"DUD", "DUE", "DUG", "DUN", "EAR", "EAT", "ED", "EEL", "EGG", "EGO",
|
||||
"ELI", "ELK", "ELM", "ELY", "EM", "END", "EST", "ETC", "EVA", "EVE",
|
||||
"EWE", "EYE", "FAD", "FAN", "FAR", "FAT", "FAY", "FED", "FEE", "FEW",
|
||||
"FIB", "FIG", "FIN", "FIR", "FIT", "FLO", "FLY", "FOE", "FOG", "FOR",
|
||||
"FRY", "FUM", "FUN", "FUR", "GAB", "GAD", "GAG", "GAL", "GAM", "GAP",
|
||||
"GAS", "GAY", "GEE", "GEL", "GEM", "GET", "GIG", "GIL", "GIN", "GO",
|
||||
"GOT", "GUM", "GUN", "GUS", "GUT", "GUY", "GYM", "GYP", "HA", "HAD",
|
||||
"HAL", "HAM", "HAN", "HAP", "HAS", "HAT", "HAW", "HAY", "HE", "HEM",
|
||||
"HEN", "HER", "HEW", "HEY", "HI", "HID", "HIM", "HIP", "HIS", "HIT",
|
||||
"HO", "HOB", "HOC", "HOE", "HOG", "HOP", "HOT", "HOW", "HUB", "HUE",
|
||||
"HUG", "HUH", "HUM", "HUT", "I", "ICY", "IDA", "IF", "IKE", "ILL",
|
||||
"INK", "INN", "IO", "ION", "IQ", "IRA", "IRE", "IRK", "IS", "IT", "ITS",
|
||||
"IVY", "JAB", "JAG", "JAM", "JAN", "JAR", "JAW", "JAY", "JET", "JIG",
|
||||
"JIM", "JO", "JOB", "JOE", "JOG", "JOT", "JOY", "JUG", "JUT", "KAY",
|
||||
"KEG", "KEN", "KEY", "KID", "KIM", "KIN", "KIT", "LA", "LAB", "LAC",
|
||||
"LAD", "LAG", "LAM", "LAP", "LAW", "LAY", "LEA", "LED", "LEE", "LEG",
|
||||
"LEN", "LEO", "LET", "LEW", "LID", "LIE", "LIN", "LIP", "LIT", "LO",
|
||||
"LOB", "LOG", "LOP", "LOS", "LOT", "LOU", "LOW", "LOY", "LUG", "LYE",
|
||||
"MA", "MAC", "MAD", "MAE", "MAN", "MAO", "MAP", "MAT", "MAW", "MAY",
|
||||
"ME", "MEG", "MEL", "MEN", "MET", "MEW", "MID", "MIN", "MIT", "MOB",
|
||||
"MOD", "MOE", "MOO", "MOP", "MOS", "MOT", "MOW", "MUD", "MUG", "MUM",
|
||||
"MY", "NAB", "NAG", "NAN", "NAP", "NAT", "NAY", "NE", "NED", "NEE",
|
||||
"NET", "NEW", "NIB", "NIL", "NIP", "NIT", "NO", "NOB", "NOD", "NON",
|
||||
"NOR", "NOT", "NOV", "NOW", "NU", "NUN", "NUT", "O", "OAF", "OAK",
|
||||
"OAR", "OAT", "ODD", "ODE", "OF", "OFF", "OFT", "OH", "OIL", "OK",
|
||||
"OLD", "ON", "ONE", "OR", "ORB", "ORE", "ORR", "OS", "OTT", "OUR",
|
||||
"OUT", "OVA", "OW", "OWE", "OWL", "OWN", "OX", "PA", "PAD", "PAL",
|
||||
"PAM", "PAN", "PAP", "PAR", "PAT", "PAW", "PAY", "PEA", "PEG", "PEN",
|
||||
"PEP", "PER", "PET", "PEW", "PHI", "PI", "PIE", "PIN", "PIT", "PLY",
|
||||
"PO", "POD", "POE", "POP", "POT", "POW", "PRO", "PRY", "PUB", "PUG",
|
||||
"PUN", "PUP", "PUT", "QUO", "RAG", "RAM", "RAN", "RAP", "RAT", "RAW",
|
||||
"RAY", "REB", "RED", "REP", "RET", "RIB", "RID", "RIG", "RIM", "RIO",
|
||||
"RIP", "ROB", "ROD", "ROE", "RON", "ROT", "ROW", "ROY", "RUB", "RUE",
|
||||
"RUG", "RUM", "RUN", "RYE", "SAC", "SAD", "SAG", "SAL", "SAM", "SAN",
|
||||
"SAP", "SAT", "SAW", "SAY", "SEA", "SEC", "SEE", "SEN", "SET", "SEW",
|
||||
"SHE", "SHY", "SIN", "SIP", "SIR", "SIS", "SIT", "SKI", "SKY", "SLY",
|
||||
"SO", "SOB", "SOD", "SON", "SOP", "SOW", "SOY", "SPA", "SPY", "SUB",
|
||||
"SUD", "SUE", "SUM", "SUN", "SUP", "TAB", "TAD", "TAG", "TAN", "TAP",
|
||||
"TAR", "TEA", "TED", "TEE", "TEN", "THE", "THY", "TIC", "TIE", "TIM",
|
||||
"TIN", "TIP", "TO", "TOE", "TOG", "TOM", "TON", "TOO", "TOP", "TOW",
|
||||
"TOY", "TRY", "TUB", "TUG", "TUM", "TUN", "TWO", "UN", "UP", "US",
|
||||
"USE", "VAN", "VAT", "VET", "VIE", "WAD", "WAG", "WAR", "WAS", "WAY",
|
||||
"WE", "WEB", "WED", "WEE", "WET", "WHO", "WHY", "WIN", "WIT", "WOK",
|
||||
"WON", "WOO", "WOW", "WRY", "WU", "YAM", "YAP", "YAW", "YE", "YEA",
|
||||
"YES", "YET", "YOU", "ABED", "ABEL", "ABET", "ABLE", "ABUT", "ACHE",
|
||||
"ACID", "ACME", "ACRE", "ACTA", "ACTS", "ADAM", "ADDS", "ADEN", "AFAR",
|
||||
"AFRO", "AGEE", "AHEM", "AHOY", "AIDA", "AIDE", "AIDS", "AIRY", "AJAR",
|
||||
"AKIN", "ALAN", "ALEC", "ALGA", "ALIA", "ALLY", "ALMA", "ALOE", "ALSO",
|
||||
"ALTO", "ALUM", "ALVA", "AMEN", "AMES", "AMID", "AMMO", "AMOK", "AMOS",
|
||||
"AMRA", "ANDY", "ANEW", "ANNA", "ANNE", "ANTE", "ANTI", "AQUA", "ARAB",
|
||||
"ARCH", "AREA", "ARGO", "ARID", "ARMY", "ARTS", "ARTY", "ASIA", "ASKS",
|
||||
"ATOM", "AUNT", "AURA", "AUTO", "AVER", "AVID", "AVIS", "AVON", "AVOW",
|
||||
"AWAY", "AWRY", "BABE", "BABY", "BACH", "BACK", "BADE", "BAIL", "BAIT",
|
||||
"BAKE", "BALD", "BALE", "BALI", "BALK", "BALL", "BALM", "BAND", "BANE",
|
||||
"BANG", "BANK", "BARB", "BARD", "BARE", "BARK", "BARN", "BARR", "BASE",
|
||||
"BASH", "BASK", "BASS", "BATE", "BATH", "BAWD", "BAWL", "BEAD", "BEAK",
|
||||
"BEAM", "BEAN", "BEAR", "BEAT", "BEAU", "BECK", "BEEF", "BEEN", "BEER",
|
||||
"BEET", "BELA", "BELL", "BELT", "BEND", "BENT", "BERG", "BERN", "BERT",
|
||||
"BESS", "BEST", "BETA", "BETH", "BHOY", "BIAS", "BIDE", "BIEN", "BILE",
|
||||
"BILK", "BILL", "BIND", "BING", "BIRD", "BITE", "BITS", "BLAB", "BLAT",
|
||||
"BLED", "BLEW", "BLOB", "BLOC", "BLOT", "BLOW", "BLUE", "BLUM", "BLUR",
|
||||
"BOAR", "BOAT", "BOCA", "BOCK", "BODE", "BODY", "BOGY", "BOHR", "BOIL",
|
||||
"BOLD", "BOLO", "BOLT", "BOMB", "BONA", "BOND", "BONE", "BONG", "BONN",
|
||||
"BONY", "BOOK", "BOOM", "BOON", "BOOT", "BORE", "BORG", "BORN", "BOSE",
|
||||
"BOSS", "BOTH", "BOUT", "BOWL", "BOYD", "BRAD", "BRAE", "BRAG", "BRAN",
|
||||
"BRAY", "BRED", "BREW", "BRIG", "BRIM", "BROW", "BUCK", "BUDD", "BUFF",
|
||||
"BULB", "BULK", "BULL", "BUNK", "BUNT", "BUOY", "BURG", "BURL", "BURN",
|
||||
"BURR", "BURT", "BURY", "BUSH", "BUSS", "BUST", "BUSY", "BYTE", "CADY",
|
||||
"CAFE", "CAGE", "CAIN", "CAKE", "CALF", "CALL", "CALM", "CAME", "CANE",
|
||||
"CANT", "CARD", "CARE", "CARL", "CARR", "CART", "CASE", "CASH", "CASK",
|
||||
"CAST", "CAVE", "CEIL", "CELL", "CENT", "CERN", "CHAD", "CHAR", "CHAT",
|
||||
"CHAW", "CHEF", "CHEN", "CHEW", "CHIC", "CHIN", "CHOU", "CHOW", "CHUB",
|
||||
"CHUG", "CHUM", "CITE", "CITY", "CLAD", "CLAM", "CLAN", "CLAW", "CLAY",
|
||||
"CLOD", "CLOG", "CLOT", "CLUB", "CLUE", "COAL", "COAT", "COCA", "COCK",
|
||||
"COCO", "CODA", "CODE", "CODY", "COED", "COIL", "COIN", "COKE", "COLA",
|
||||
"COLD", "COLT", "COMA", "COMB", "COME", "COOK", "COOL", "COON", "COOT",
|
||||
"CORD", "CORE", "CORK", "CORN", "COST", "COVE", "COWL", "CRAB", "CRAG",
|
||||
"CRAM", "CRAY", "CREW", "CRIB", "CROW", "CRUD", "CUBA", "CUBE", "CUFF",
|
||||
"CULL", "CULT", "CUNY", "CURB", "CURD", "CURE", "CURL", "CURT", "CUTS",
|
||||
"DADE", "DALE", "DAME", "DANA", "DANE", "DANG", "DANK", "DARE", "DARK",
|
||||
"DARN", "DART", "DASH", "DATA", "DATE", "DAVE", "DAVY", "DAWN", "DAYS",
|
||||
"DEAD", "DEAF", "DEAL", "DEAN", "DEAR", "DEBT", "DECK", "DEED", "DEEM",
|
||||
"DEER", "DEFT", "DEFY", "DELL", "DENT", "DENY", "DESK", "DIAL", "DICE",
|
||||
"DIED", "DIET", "DIME", "DINE", "DING", "DINT", "DIRE", "DIRT", "DISC",
|
||||
"DISH", "DISK", "DIVE", "DOCK", "DOES", "DOLE", "DOLL", "DOLT", "DOME",
|
||||
"DONE", "DOOM", "DOOR", "DORA", "DOSE", "DOTE", "DOUG", "DOUR", "DOVE",
|
||||
"DOWN", "DRAB", "DRAG", "DRAM", "DRAW", "DREW", "DRUB", "DRUG", "DRUM",
|
||||
"DUAL", "DUCK", "DUCT", "DUEL", "DUET", "DUKE", "DULL", "DUMB", "DUNE",
|
||||
"DUNK", "DUSK", "DUST", "DUTY", "EACH", "EARL", "EARN", "EASE", "EAST",
|
||||
"EASY", "EBEN", "ECHO", "EDDY", "EDEN", "EDGE", "EDGY", "EDIT", "EDNA",
|
||||
"EGAN", "ELAN", "ELBA", "ELLA", "ELSE", "EMIL", "EMIT", "EMMA", "ENDS",
|
||||
"ERIC", "EROS", "EVEN", "EVER", "EVIL", "EYED", "FACE", "FACT", "FADE",
|
||||
"FAIL", "FAIN", "FAIR", "FAKE", "FALL", "FAME", "FANG", "FARM", "FAST",
|
||||
"FATE", "FAWN", "FEAR", "FEAT", "FEED", "FEEL", "FEET", "FELL", "FELT",
|
||||
"FEND", "FERN", "FEST", "FEUD", "FIEF", "FIGS", "FILE", "FILL", "FILM",
|
||||
"FIND", "FINE", "FINK", "FIRE", "FIRM", "FISH", "FISK", "FIST", "FITS",
|
||||
"FIVE", "FLAG", "FLAK", "FLAM", "FLAT", "FLAW", "FLEA", "FLED", "FLEW",
|
||||
"FLIT", "FLOC", "FLOG", "FLOW", "FLUB", "FLUE", "FOAL", "FOAM", "FOGY",
|
||||
"FOIL", "FOLD", "FOLK", "FOND", "FONT", "FOOD", "FOOL", "FOOT", "FORD",
|
||||
"FORE", "FORK", "FORM", "FORT", "FOSS", "FOUL", "FOUR", "FOWL", "FRAU",
|
||||
"FRAY", "FRED", "FREE", "FRET", "FREY", "FROG", "FROM", "FUEL", "FULL",
|
||||
"FUME", "FUND", "FUNK", "FURY", "FUSE", "FUSS", "GAFF", "GAGE", "GAIL",
|
||||
"GAIN", "GAIT", "GALA", "GALE", "GALL", "GALT", "GAME", "GANG", "GARB",
|
||||
"GARY", "GASH", "GATE", "GAUL", "GAUR", "GAVE", "GAWK", "GEAR", "GELD",
|
||||
"GENE", "GENT", "GERM", "GETS", "GIBE", "GIFT", "GILD", "GILL", "GILT",
|
||||
"GINA", "GIRD", "GIRL", "GIST", "GIVE", "GLAD", "GLEE", "GLEN", "GLIB",
|
||||
"GLOB", "GLOM", "GLOW", "GLUE", "GLUM", "GLUT", "GOAD", "GOAL", "GOAT",
|
||||
"GOER", "GOES", "GOLD", "GOLF", "GONE", "GONG", "GOOD", "GOOF", "GORE",
|
||||
"GORY", "GOSH", "GOUT", "GOWN", "GRAB", "GRAD", "GRAY", "GREG", "GREW",
|
||||
"GREY", "GRID", "GRIM", "GRIN", "GRIT", "GROW", "GRUB", "GULF", "GULL",
|
||||
"GUNK", "GURU", "GUSH", "GUST", "GWEN", "GWYN", "HAAG", "HAAS", "HACK",
|
||||
"HAIL", "HAIR", "HALE", "HALF", "HALL", "HALO", "HALT", "HAND", "HANG",
|
||||
"HANK", "HANS", "HARD", "HARK", "HARM", "HART", "HASH", "HAST", "HATE",
|
||||
"HATH", "HAUL", "HAVE", "HAWK", "HAYS", "HEAD", "HEAL", "HEAR", "HEAT",
|
||||
"HEBE", "HECK", "HEED", "HEEL", "HEFT", "HELD", "HELL", "HELM", "HERB",
|
||||
"HERD", "HERE", "HERO", "HERS", "HESS", "HEWN", "HICK", "HIDE", "HIGH",
|
||||
"HIKE", "HILL", "HILT", "HIND", "HINT", "HIRE", "HISS", "HIVE", "HOBO",
|
||||
"HOCK", "HOFF", "HOLD", "HOLE", "HOLM", "HOLT", "HOME", "HONE", "HONK",
|
||||
"HOOD", "HOOF", "HOOK", "HOOT", "HORN", "HOSE", "HOST", "HOUR", "HOVE",
|
||||
"HOWE", "HOWL", "HOYT", "HUCK", "HUED", "HUFF", "HUGE", "HUGH", "HUGO",
|
||||
"HULK", "HULL", "HUNK", "HUNT", "HURD", "HURL", "HURT", "HUSH", "HYDE",
|
||||
"HYMN", "IBIS", "ICON", "IDEA", "IDLE", "IFFY", "INCA", "INCH", "INTO",
|
||||
"IONS", "IOTA", "IOWA", "IRIS", "IRMA", "IRON", "ISLE", "ITCH", "ITEM",
|
||||
"IVAN", "JACK", "JADE", "JAIL", "JAKE", "JANE", "JAVA", "JEAN", "JEFF",
|
||||
"JERK", "JESS", "JEST", "JIBE", "JILL", "JILT", "JIVE", "JOAN", "JOBS",
|
||||
"JOCK", "JOEL", "JOEY", "JOHN", "JOIN", "JOKE", "JOLT", "JOVE", "JUDD",
|
||||
"JUDE", "JUDO", "JUDY", "JUJU", "JUKE", "JULY", "JUNE", "JUNK", "JUNO",
|
||||
"JURY", "JUST", "JUTE", "KAHN", "KALE", "KANE", "KANT", "KARL", "KATE",
|
||||
"KEEL", "KEEN", "KENO", "KENT", "KERN", "KERR", "KEYS", "KICK", "KILL",
|
||||
"KIND", "KING", "KIRK", "KISS", "KITE", "KLAN", "KNEE", "KNEW", "KNIT",
|
||||
"KNOB", "KNOT", "KNOW", "KOCH", "KONG", "KUDO", "KURD", "KURT", "KYLE",
|
||||
"LACE", "LACK", "LACY", "LADY", "LAID", "LAIN", "LAIR", "LAKE", "LAMB",
|
||||
"LAME", "LAND", "LANE", "LANG", "LARD", "LARK", "LASS", "LAST", "LATE",
|
||||
"LAUD", "LAVA", "LAWN", "LAWS", "LAYS", "LEAD", "LEAF", "LEAK", "LEAN",
|
||||
"LEAR", "LEEK", "LEER", "LEFT", "LEND", "LENS", "LENT", "LEON", "LESK",
|
||||
"LESS", "LEST", "LETS", "LIAR", "LICE", "LICK", "LIED", "LIEN", "LIES",
|
||||
"LIEU", "LIFE", "LIFT", "LIKE", "LILA", "LILT", "LILY", "LIMA", "LIMB",
|
||||
"LIME", "LIND", "LINE", "LINK", "LINT", "LION", "LISA", "LIST", "LIVE",
|
||||
"LOAD", "LOAF", "LOAM", "LOAN", "LOCK", "LOFT", "LOGE", "LOIS", "LOLA",
|
||||
"LONE", "LONG", "LOOK", "LOON", "LOOT", "LORD", "LORE", "LOSE", "LOSS",
|
||||
"LOST", "LOUD", "LOVE", "LOWE", "LUCK", "LUCY", "LUGE", "LUKE", "LULU",
|
||||
"LUND", "LUNG", "LURA", "LURE", "LURK", "LUSH", "LUST", "LYLE", "LYNN",
|
||||
"LYON", "LYRA", "MACE", "MADE", "MAGI", "MAID", "MAIL", "MAIN", "MAKE",
|
||||
"MALE", "MALI", "MALL", "MALT", "MANA", "MANN", "MANY", "MARC", "MARE",
|
||||
"MARK", "MARS", "MART", "MARY", "MASH", "MASK", "MASS", "MAST", "MATE",
|
||||
"MATH", "MAUL", "MAYO", "MEAD", "MEAL", "MEAN", "MEAT", "MEEK", "MEET",
|
||||
"MELD", "MELT", "MEMO", "MEND", "MENU", "MERT", "MESH", "MESS", "MICE",
|
||||
"MIKE", "MILD", "MILE", "MILK", "MILL", "MILT", "MIMI", "MIND", "MINE",
|
||||
"MINI", "MINK", "MINT", "MIRE", "MISS", "MIST", "MITE", "MITT", "MOAN",
|
||||
"MOAT", "MOCK", "MODE", "MOLD", "MOLE", "MOLL", "MOLT", "MONA", "MONK",
|
||||
"MONT", "MOOD", "MOON", "MOOR", "MOOT", "MORE", "MORN", "MORT", "MOSS",
|
||||
"MOST", "MOTH", "MOVE", "MUCH", "MUCK", "MUDD", "MUFF", "MULE", "MULL",
|
||||
"MURK", "MUSH", "MUST", "MUTE", "MUTT", "MYRA", "MYTH", "NAGY", "NAIL",
|
||||
"NAIR", "NAME", "NARY", "NASH", "NAVE", "NAVY", "NEAL", "NEAR", "NEAT",
|
||||
"NECK", "NEED", "NEIL", "NELL", "NEON", "NERO", "NESS", "NEST", "NEWS",
|
||||
"NEWT", "NIBS", "NICE", "NICK", "NILE", "NINA", "NINE", "NOAH", "NODE",
|
||||
"NOEL", "NOLL", "NONE", "NOOK", "NOON", "NORM", "NOSE", "NOTE", "NOUN",
|
||||
"NOVA", "NUDE", "NULL", "NUMB", "OATH", "OBEY", "OBOE", "ODIN", "OHIO",
|
||||
"OILY", "OINT", "OKAY", "OLAF", "OLDY", "OLGA", "OLIN", "OMAN", "OMEN",
|
||||
"OMIT", "ONCE", "ONES", "ONLY", "ONTO", "ONUS", "ORAL", "ORGY", "OSLO",
|
||||
"OTIS", "OTTO", "OUCH", "OUST", "OUTS", "OVAL", "OVEN", "OVER", "OWLY",
|
||||
"OWNS", "QUAD", "QUIT", "QUOD", "RACE", "RACK", "RACY", "RAFT", "RAGE",
|
||||
"RAID", "RAIL", "RAIN", "RAKE", "RANK", "RANT", "RARE", "RASH", "RATE",
|
||||
"RAVE", "RAYS", "READ", "REAL", "REAM", "REAR", "RECK", "REED", "REEF",
|
||||
"REEK", "REEL", "REID", "REIN", "RENA", "REND", "RENT", "REST", "RICE",
|
||||
"RICH", "RICK", "RIDE", "RIFT", "RILL", "RIME", "RING", "RINK", "RISE",
|
||||
"RISK", "RITE", "ROAD", "ROAM", "ROAR", "ROBE", "ROCK", "RODE", "ROIL",
|
||||
"ROLL", "ROME", "ROOD", "ROOF", "ROOK", "ROOM", "ROOT", "ROSA", "ROSE",
|
||||
"ROSS", "ROSY", "ROTH", "ROUT", "ROVE", "ROWE", "ROWS", "RUBE", "RUBY",
|
||||
"RUDE", "RUDY", "RUIN", "RULE", "RUNG", "RUNS", "RUNT", "RUSE", "RUSH",
|
||||
"RUSK", "RUSS", "RUST", "RUTH", "SACK", "SAFE", "SAGE", "SAID", "SAIL",
|
||||
"SALE", "SALK", "SALT", "SAME", "SAND", "SANE", "SANG", "SANK", "SARA",
|
||||
"SAUL", "SAVE", "SAYS", "SCAN", "SCAR", "SCAT", "SCOT", "SEAL", "SEAM",
|
||||
"SEAR", "SEAT", "SEED", "SEEK", "SEEM", "SEEN", "SEES", "SELF", "SELL",
|
||||
"SEND", "SENT", "SETS", "SEWN", "SHAG", "SHAM", "SHAW", "SHAY", "SHED",
|
||||
"SHIM", "SHIN", "SHOD", "SHOE", "SHOT", "SHOW", "SHUN", "SHUT", "SICK",
|
||||
"SIDE", "SIFT", "SIGH", "SIGN", "SILK", "SILL", "SILO", "SILT", "SINE",
|
||||
"SING", "SINK", "SIRE", "SITE", "SITS", "SITU", "SKAT", "SKEW", "SKID",
|
||||
"SKIM", "SKIN", "SKIT", "SLAB", "SLAM", "SLAT", "SLAY", "SLED", "SLEW",
|
||||
"SLID", "SLIM", "SLIT", "SLOB", "SLOG", "SLOT", "SLOW", "SLUG", "SLUM",
|
||||
"SLUR", "SMOG", "SMUG", "SNAG", "SNOB", "SNOW", "SNUB", "SNUG", "SOAK",
|
||||
"SOAR", "SOCK", "SODA", "SOFA", "SOFT", "SOIL", "SOLD", "SOME", "SONG",
|
||||
"SOON", "SOOT", "SORE", "SORT", "SOUL", "SOUR", "SOWN", "STAB", "STAG",
|
||||
"STAN", "STAR", "STAY", "STEM", "STEW", "STIR", "STOW", "STUB", "STUN",
|
||||
"SUCH", "SUDS", "SUIT", "SULK", "SUMS", "SUNG", "SUNK", "SURE", "SURF",
|
||||
"SWAB", "SWAG", "SWAM", "SWAN", "SWAT", "SWAY", "SWIM", "SWUM", "TACK",
|
||||
"TACT", "TAIL", "TAKE", "TALE", "TALK", "TALL", "TANK", "TASK", "TATE",
|
||||
"TAUT", "TEAL", "TEAM", "TEAR", "TECH", "TEEM", "TEEN", "TEET", "TELL",
|
||||
"TEND", "TENT", "TERM", "TERN", "TESS", "TEST", "THAN", "THAT", "THEE",
|
||||
"THEM", "THEN", "THEY", "THIN", "THIS", "THUD", "THUG", "TICK", "TIDE",
|
||||
"TIDY", "TIED", "TIER", "TILE", "TILL", "TILT", "TIME", "TINA", "TINE",
|
||||
"TINT", "TINY", "TIRE", "TOAD", "TOGO", "TOIL", "TOLD", "TOLL", "TONE",
|
||||
"TONG", "TONY", "TOOK", "TOOL", "TOOT", "TORE", "TORN", "TOTE", "TOUR",
|
||||
"TOUT", "TOWN", "TRAG", "TRAM", "TRAY", "TREE", "TREK", "TRIG", "TRIM",
|
||||
"TRIO", "TROD", "TROT", "TROY", "TRUE", "TUBA", "TUBE", "TUCK", "TUFT",
|
||||
"TUNA", "TUNE", "TUNG", "TURF", "TURN", "TUSK", "TWIG", "TWIN", "TWIT",
|
||||
"ULAN", "UNIT", "URGE", "USED", "USER", "USES", "UTAH", "VAIL", "VAIN",
|
||||
"VALE", "VARY", "VASE", "VAST", "VEAL", "VEDA", "VEIL", "VEIN", "VEND",
|
||||
"VENT", "VERB", "VERY", "VETO", "VICE", "VIEW", "VINE", "VISE", "VOID",
|
||||
"VOLT", "VOTE", "WACK", "WADE", "WAGE", "WAIL", "WAIT", "WAKE", "WALE",
|
||||
"WALK", "WALL", "WALT", "WAND", "WANE", "WANG", "WANT", "WARD", "WARM",
|
||||
"WARN", "WART", "WASH", "WAST", "WATS", "WATT", "WAVE", "WAVY", "WAYS",
|
||||
"WEAK", "WEAL", "WEAN", "WEAR", "WEED", "WEEK", "WEIR", "WELD", "WELL",
|
||||
"WELT", "WENT", "WERE", "WERT", "WEST", "WHAM", "WHAT", "WHEE", "WHEN",
|
||||
"WHET", "WHOA", "WHOM", "WICK", "WIFE", "WILD", "WILL", "WIND", "WINE",
|
||||
"WING", "WINK", "WINO", "WIRE", "WISE", "WISH", "WITH", "WOLF", "WONT",
|
||||
"WOOD", "WOOL", "WORD", "WORE", "WORK", "WORM", "WORN", "WOVE", "WRIT",
|
||||
"WYNN", "YALE", "YANG", "YANK", "YARD", "YARN", "YAWL", "YAWN", "YEAH",
|
||||
"YEAR", "YELL", "YOGA", "YOKE"
|
||||
};
|
||||
|
||||
/* Extract 'length' bits from the char array 's'
|
||||
starting with bit 'start' */
|
||||
unsigned long RFC1751::extract(char *s, int start, int length)
|
||||
unsigned long RFC1751::extract (char* s, int start, int length)
|
||||
{
|
||||
unsigned char cl;
|
||||
unsigned char cc;
|
||||
unsigned char cr;
|
||||
unsigned long x;
|
||||
unsigned char cl;
|
||||
unsigned char cc;
|
||||
unsigned char cr;
|
||||
unsigned long x;
|
||||
|
||||
assert(length <= 11);
|
||||
assert(start >= 0);
|
||||
assert(length >= 0);
|
||||
assert(start+length <= 66);
|
||||
assert (length <= 11);
|
||||
assert (start >= 0);
|
||||
assert (length >= 0);
|
||||
assert (start + length <= 66);
|
||||
|
||||
cl = s[start/8]; // get components
|
||||
cc = s[start/8 +1];
|
||||
cr = s[start/8 +2];
|
||||
cl = s[start / 8]; // get components
|
||||
cc = s[start / 8 + 1];
|
||||
cr = s[start / 8 + 2];
|
||||
|
||||
x = ((long)(cl<<8 | cc) <<8 | cr) ; // Put bits together
|
||||
x = x >> (24 - (length + (start%8))); // Right justify number
|
||||
x = ( x & (0xffff >> (16-length) ) ); // Trim extra bits.
|
||||
x = ((long) (cl << 8 | cc) << 8 | cr) ; // Put bits together
|
||||
x = x >> (24 - (length + (start % 8))); // Right justify number
|
||||
x = ( x & (0xffff >> (16 - length) ) ); // Trim extra bits.
|
||||
|
||||
return x;
|
||||
return x;
|
||||
}
|
||||
|
||||
// Encode 8 bytes in 'c' as a string of English words.
|
||||
// Returns a pointer to a static buffer
|
||||
void RFC1751::btoe(std::string& strHuman, const std::string& strData)
|
||||
void RFC1751::btoe (std::string& strHuman, const std::string& strData)
|
||||
{
|
||||
char caBuffer[9]; /* add in room for the parity 2 bits*/
|
||||
int p, i;
|
||||
char caBuffer[9]; /* add in room for the parity 2 bits*/
|
||||
int p, i;
|
||||
|
||||
memcpy(caBuffer, strData.c_str(), 8);
|
||||
memcpy (caBuffer, strData.c_str (), 8);
|
||||
|
||||
// compute parity: merely add groups of two bits.
|
||||
for(p = 0, i = 0; i < 64; i += 2)
|
||||
p += extract(caBuffer, i, 2);
|
||||
// compute parity: merely add groups of two bits.
|
||||
for (p = 0, i = 0; i < 64; i += 2)
|
||||
p += extract (caBuffer, i, 2);
|
||||
|
||||
caBuffer[8] = char(p) << 6;
|
||||
caBuffer[8] = char (p) << 6;
|
||||
|
||||
strHuman = std::string()
|
||||
+ s_dictionary[extract(caBuffer, 0, 11)] + " "
|
||||
+ s_dictionary[extract(caBuffer, 11, 11)] + " "
|
||||
+ s_dictionary[extract(caBuffer, 22, 11)] + " "
|
||||
+ s_dictionary[extract(caBuffer, 33, 11)] + " "
|
||||
+ s_dictionary[extract(caBuffer, 44, 11)] + " "
|
||||
+ s_dictionary[extract(caBuffer, 55, 11)];
|
||||
strHuman = std::string ()
|
||||
+ s_dictionary[extract (caBuffer, 0, 11)] + " "
|
||||
+ s_dictionary[extract (caBuffer, 11, 11)] + " "
|
||||
+ s_dictionary[extract (caBuffer, 22, 11)] + " "
|
||||
+ s_dictionary[extract (caBuffer, 33, 11)] + " "
|
||||
+ s_dictionary[extract (caBuffer, 44, 11)] + " "
|
||||
+ s_dictionary[extract (caBuffer, 55, 11)];
|
||||
}
|
||||
|
||||
void RFC1751::insert(char *s, int x, int start, int length)
|
||||
void RFC1751::insert (char* s, int x, int start, int length)
|
||||
{
|
||||
unsigned char cl;
|
||||
unsigned char cc;
|
||||
unsigned char cr;
|
||||
unsigned long y;
|
||||
int shift;
|
||||
unsigned char cl;
|
||||
unsigned char cc;
|
||||
unsigned char cr;
|
||||
unsigned long y;
|
||||
int shift;
|
||||
|
||||
assert(length <= 11);
|
||||
assert(start >= 0);
|
||||
assert(length >= 0);
|
||||
assert(start+length <= 66);
|
||||
assert (length <= 11);
|
||||
assert (start >= 0);
|
||||
assert (length >= 0);
|
||||
assert (start + length <= 66);
|
||||
|
||||
shift = ((8 -(( start + length) % 8))%8);
|
||||
y = (long) x << shift;
|
||||
cl = (y >> 16) & 0xff;
|
||||
cc = (y >> 8) & 0xff;
|
||||
cr = y & 0xff;
|
||||
if(shift + length > 16){
|
||||
s[start /8] |= cl;
|
||||
s[start/8 +1] |= cc;
|
||||
s[start/8 +2] |= cr;
|
||||
} else if(shift +length > 8){
|
||||
s[start/8] |= cc;
|
||||
s[start/8 + 1] |= cr;
|
||||
} else {
|
||||
s[start/8] |= cr;
|
||||
}
|
||||
shift = ((8 - (( start + length) % 8)) % 8);
|
||||
y = (long) x << shift;
|
||||
cl = (y >> 16) & 0xff;
|
||||
cc = (y >> 8) & 0xff;
|
||||
cr = y & 0xff;
|
||||
|
||||
if (shift + length > 16)
|
||||
{
|
||||
s[start / 8] |= cl;
|
||||
s[start / 8 + 1] |= cc;
|
||||
s[start / 8 + 2] |= cr;
|
||||
}
|
||||
else if (shift + length > 8)
|
||||
{
|
||||
s[start / 8] |= cc;
|
||||
s[start / 8 + 1] |= cr;
|
||||
}
|
||||
else
|
||||
{
|
||||
s[start / 8] |= cr;
|
||||
}
|
||||
}
|
||||
|
||||
void RFC1751::standard(std::string& strWord)
|
||||
void RFC1751::standard (std::string& strWord)
|
||||
{
|
||||
BOOST_FOREACH(char cLetter, strWord)
|
||||
{
|
||||
if(!isascii(cLetter))
|
||||
{
|
||||
; // nothing
|
||||
}
|
||||
else if(islower(cLetter))
|
||||
{
|
||||
cLetter = toupper(cLetter);
|
||||
}
|
||||
else if(cLetter == '1')
|
||||
{
|
||||
cLetter = 'L';
|
||||
}
|
||||
else if(cLetter == '0')
|
||||
{
|
||||
cLetter = 'O';
|
||||
}
|
||||
else if(cLetter == '5')
|
||||
{
|
||||
cLetter = 'S';
|
||||
}
|
||||
}
|
||||
BOOST_FOREACH (char cLetter, strWord)
|
||||
{
|
||||
if (!isascii (cLetter))
|
||||
{
|
||||
; // nothing
|
||||
}
|
||||
else if (islower (cLetter))
|
||||
{
|
||||
cLetter = toupper (cLetter);
|
||||
}
|
||||
else if (cLetter == '1')
|
||||
{
|
||||
cLetter = 'L';
|
||||
}
|
||||
else if (cLetter == '0')
|
||||
{
|
||||
cLetter = 'O';
|
||||
}
|
||||
else if (cLetter == '5')
|
||||
{
|
||||
cLetter = 'S';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Binary search of dictionary.
|
||||
int RFC1751::wsrch (const std::string& strWord, int iMin, int iMax)
|
||||
{
|
||||
int iResult = -1;
|
||||
int iResult = -1;
|
||||
|
||||
while (iResult < 0 && iMin != iMax)
|
||||
{
|
||||
// Have a range to search.
|
||||
int iMid = iMin+(iMax-iMin)/2;
|
||||
int iDir = strWord.compare(s_dictionary[iMid]);
|
||||
while (iResult < 0 && iMin != iMax)
|
||||
{
|
||||
// Have a range to search.
|
||||
int iMid = iMin + (iMax - iMin) / 2;
|
||||
int iDir = strWord.compare (s_dictionary[iMid]);
|
||||
|
||||
if (!iDir)
|
||||
{
|
||||
iResult = iMid; // Found it.
|
||||
}
|
||||
else if (iDir < 0)
|
||||
{
|
||||
iMax = iMid; // key < middle, middle is new max.
|
||||
}
|
||||
else
|
||||
{
|
||||
iMin = iMid+1; // key > middle, new min is past the middle.
|
||||
}
|
||||
}
|
||||
if (!iDir)
|
||||
{
|
||||
iResult = iMid; // Found it.
|
||||
}
|
||||
else if (iDir < 0)
|
||||
{
|
||||
iMax = iMid; // key < middle, middle is new max.
|
||||
}
|
||||
else
|
||||
{
|
||||
iMin = iMid + 1; // key > middle, new min is past the middle.
|
||||
}
|
||||
}
|
||||
|
||||
return iResult;
|
||||
return iResult;
|
||||
}
|
||||
|
||||
// Convert 6 words to binary.
|
||||
@@ -379,91 +386,92 @@ int RFC1751::wsrch (const std::string& strWord, int iMin, int iMax)
|
||||
// -2 words OK but parity is wrong
|
||||
int RFC1751::etob (std::string& strData, std::vector<std::string> vsHuman)
|
||||
{
|
||||
int i, p, v,l;
|
||||
char b[9];
|
||||
int i, p, v, l;
|
||||
char b[9];
|
||||
|
||||
if (6 != vsHuman.size())
|
||||
return -1;
|
||||
if (6 != vsHuman.size ())
|
||||
return -1;
|
||||
|
||||
memset(b, 0, sizeof(b));
|
||||
memset (b, 0, sizeof (b));
|
||||
|
||||
p=0;
|
||||
BOOST_FOREACH(std::string& strWord, vsHuman)
|
||||
{
|
||||
l = strWord.length();
|
||||
if(l > 4 || l < 1)
|
||||
return -1;
|
||||
p = 0;
|
||||
BOOST_FOREACH (std::string & strWord, vsHuman)
|
||||
{
|
||||
l = strWord.length ();
|
||||
|
||||
standard (strWord);
|
||||
if (l > 4 || l < 1)
|
||||
return -1;
|
||||
|
||||
v = wsrch(strWord,
|
||||
l < 4 ? 0 : 571,
|
||||
l < 4 ? 570 : 2048);
|
||||
standard (strWord);
|
||||
|
||||
if(v < 0 )
|
||||
return 0;
|
||||
v = wsrch (strWord,
|
||||
l < 4 ? 0 : 571,
|
||||
l < 4 ? 570 : 2048);
|
||||
|
||||
insert(b, v, p, 11);
|
||||
p +=11;
|
||||
}
|
||||
if (v < 0 )
|
||||
return 0;
|
||||
|
||||
/* now check the parity of what we got */
|
||||
for(p = 0, i = 0; i < 64; i +=2)
|
||||
p += extract(b, i, 2);
|
||||
insert (b, v, p, 11);
|
||||
p += 11;
|
||||
}
|
||||
|
||||
if( (p & 3) != extract(b, 64,2) )
|
||||
return -2;
|
||||
/* now check the parity of what we got */
|
||||
for (p = 0, i = 0; i < 64; i += 2)
|
||||
p += extract (b, i, 2);
|
||||
|
||||
strData.assign(b, 8);
|
||||
if ( (p & 3) != extract (b, 64, 2) )
|
||||
return -2;
|
||||
|
||||
return 1;
|
||||
strData.assign (b, 8);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** Convert words seperated by spaces into a 128 bit key in big-endian format.
|
||||
/** Convert words seperated by spaces into a 128 bit key in big-endian format.
|
||||
|
||||
@return
|
||||
1 if succeeded
|
||||
0 if word not in dictionary
|
||||
-1 if badly formed string
|
||||
-2 if words are okay but parity is wrong.
|
||||
@return
|
||||
1 if succeeded
|
||||
0 if word not in dictionary
|
||||
-1 if badly formed string
|
||||
-2 if words are okay but parity is wrong.
|
||||
*/
|
||||
int RFC1751::getKeyFromEnglish (std::string& strKey, const std::string& strHuman)
|
||||
{
|
||||
std::vector<std::string> vWords;
|
||||
std::string strFirst, strSecond;
|
||||
int rc=0;
|
||||
std::string strFirst, strSecond;
|
||||
int rc = 0;
|
||||
|
||||
std::string strTrimmed(strHuman);
|
||||
std::string strTrimmed (strHuman);
|
||||
|
||||
boost::algorithm::trim(strTrimmed);
|
||||
boost::algorithm::trim (strTrimmed);
|
||||
|
||||
boost::algorithm::split(vWords, strTrimmed,
|
||||
boost::algorithm::is_space(), boost::algorithm::token_compress_on);
|
||||
boost::algorithm::split (vWords, strTrimmed,
|
||||
boost::algorithm::is_space (), boost::algorithm::token_compress_on);
|
||||
|
||||
rc = 12 == vWords.size() ? 1 : -1;
|
||||
|
||||
if (1 == rc)
|
||||
rc = etob(strFirst, vWords | boost::adaptors::copied(0, 6));
|
||||
|
||||
if (1 == rc)
|
||||
rc = etob(strSecond, vWords | boost::adaptors::copied(6, 12));
|
||||
rc = 12 == vWords.size () ? 1 : -1;
|
||||
|
||||
if (1 == rc)
|
||||
strKey = strFirst + strSecond;
|
||||
rc = etob (strFirst, vWords | boost::adaptors::copied (0, 6));
|
||||
|
||||
return rc;
|
||||
if (1 == rc)
|
||||
rc = etob (strSecond, vWords | boost::adaptors::copied (6, 12));
|
||||
|
||||
if (1 == rc)
|
||||
strKey = strFirst + strSecond;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/** Convert to human from a 128 bit key in big-endian format
|
||||
*/
|
||||
void RFC1751::getEnglishFromKey (std::string& strHuman, const std::string& strKey)
|
||||
{
|
||||
std::string strFirst, strSecond;
|
||||
std::string strFirst, strSecond;
|
||||
|
||||
btoe(strFirst, strKey.substr(0, 8));
|
||||
btoe(strSecond, strKey.substr(8, 8));
|
||||
btoe (strFirst, strKey.substr (0, 8));
|
||||
btoe (strSecond, strKey.substr (8, 8));
|
||||
|
||||
strHuman = strFirst + " " + strSecond;
|
||||
strHuman = strFirst + " " + strSecond;
|
||||
}
|
||||
|
||||
// vim:ts=4
|
||||
|
||||
@@ -4,19 +4,19 @@
|
||||
class RFC1751
|
||||
{
|
||||
public:
|
||||
static int getKeyFromEnglish (std::string& strKey, const std::string& strHuman);
|
||||
static int getKeyFromEnglish (std::string& strKey, const std::string& strHuman);
|
||||
|
||||
static void getEnglishFromKey (std::string& strHuman, const std::string& strKey);
|
||||
static void getEnglishFromKey (std::string& strHuman, const std::string& strKey);
|
||||
|
||||
private:
|
||||
static unsigned long extract (char *s, int start, int length);
|
||||
static void btoe (std::string& strHuman, const std::string& strData);
|
||||
static void insert (char *s, int x, int start, int length);
|
||||
static void standard (std::string& strWord);
|
||||
static int wsrch (const std::string& strWord, int iMin, int iMax);
|
||||
static int etob (std::string& strData, std::vector<std::string> vsHuman);
|
||||
static unsigned long extract (char* s, int start, int length);
|
||||
static void btoe (std::string& strHuman, const std::string& strData);
|
||||
static void insert (char* s, int x, int start, int length);
|
||||
static void standard (std::string& strWord);
|
||||
static int wsrch (const std::string& strWord, int iMin, int iMax);
|
||||
static int etob (std::string& strData, std::vector<std::string> vsHuman);
|
||||
|
||||
static char const* s_dictionary [];
|
||||
static char const* s_dictionary [];
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -5,12 +5,12 @@ std::map<int, SField::ptr> SField::codeToField;
|
||||
boost::mutex SField::mapMutex;
|
||||
int SField::num = 0;
|
||||
|
||||
SField sfInvalid(-1), sfGeneric(0);
|
||||
SField sfLedgerEntry(STI_LEDGERENTRY, 1, "LedgerEntry");
|
||||
SField sfTransaction(STI_TRANSACTION, 1, "Transaction");
|
||||
SField sfValidation(STI_VALIDATION, 1, "Validation");
|
||||
SField sfHash(STI_HASH256, 257, "hash");
|
||||
SField sfIndex(STI_HASH256, 258, "index");
|
||||
SField sfInvalid (-1), sfGeneric (0);
|
||||
SField sfLedgerEntry (STI_LEDGERENTRY, 1, "LedgerEntry");
|
||||
SField sfTransaction (STI_TRANSACTION, 1, "Transaction");
|
||||
SField sfValidation (STI_VALIDATION, 1, "Validation");
|
||||
SField sfHash (STI_HASH256, 257, "hash");
|
||||
SField sfIndex (STI_HASH256, 258, "index");
|
||||
|
||||
#define FIELD(name, type, index) SField sf##name(FIELD_CODE(STI_##type, index), STI_##type, index, #name);
|
||||
#define TYPE(name, type, index)
|
||||
@@ -18,50 +18,53 @@ SField sfIndex(STI_HASH256, 258, "index");
|
||||
#undef FIELD
|
||||
#undef TYPE
|
||||
|
||||
static int initFields()
|
||||
static int initFields ()
|
||||
{
|
||||
sfTxnSignature.notSigningField();
|
||||
sfTxnSignatures.notSigningField();
|
||||
sfSignature.notSigningField();
|
||||
sfTxnSignature.notSigningField ();
|
||||
sfTxnSignatures.notSigningField ();
|
||||
sfSignature.notSigningField ();
|
||||
|
||||
sfIndexes.setMeta(SField::sMD_Never);
|
||||
sfPreviousTxnID.setMeta(SField::sMD_DeleteFinal);
|
||||
sfPreviousTxnLgrSeq.setMeta(SField::sMD_DeleteFinal);
|
||||
sfLedgerEntryType.setMeta(SField::sMD_Never);
|
||||
sfRootIndex.setMeta(SField::sMD_Always);
|
||||
sfIndexes.setMeta (SField::sMD_Never);
|
||||
sfPreviousTxnID.setMeta (SField::sMD_DeleteFinal);
|
||||
sfPreviousTxnLgrSeq.setMeta (SField::sMD_DeleteFinal);
|
||||
sfLedgerEntryType.setMeta (SField::sMD_Never);
|
||||
sfRootIndex.setMeta (SField::sMD_Always);
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
static const int f = initFields();
|
||||
static const int f = initFields ();
|
||||
|
||||
|
||||
SField::SField(SerializedTypeID tid, int fv) : fieldCode(FIELD_CODE(tid, fv)), fieldType(tid), fieldValue(fv),
|
||||
fieldMeta(sMD_Default), fieldNum(++num), signingField(true)
|
||||
{ // call with the map mutex
|
||||
fieldName = lexical_cast_i(tid) + "/" + lexical_cast_i(fv);
|
||||
codeToField[fieldCode] = this;
|
||||
assert((fv != 1) || ((tid != STI_ARRAY) && (tid!=STI_OBJECT)));
|
||||
SField::SField (SerializedTypeID tid, int fv) : fieldCode (FIELD_CODE (tid, fv)), fieldType (tid), fieldValue (fv),
|
||||
fieldMeta (sMD_Default), fieldNum (++num), signingField (true)
|
||||
{
|
||||
// call with the map mutex
|
||||
fieldName = lexical_cast_i (tid) + "/" + lexical_cast_i (fv);
|
||||
codeToField[fieldCode] = this;
|
||||
assert ((fv != 1) || ((tid != STI_ARRAY) && (tid != STI_OBJECT)));
|
||||
}
|
||||
|
||||
SField::ref SField::getField(int code)
|
||||
SField::ref SField::getField (int code)
|
||||
{
|
||||
int type = code >> 16;
|
||||
int field = code % 0xffff;
|
||||
int type = code >> 16;
|
||||
int field = code % 0xffff;
|
||||
|
||||
if ((type <= 0) || (field <= 0))
|
||||
return sfInvalid;
|
||||
if ((type <= 0) || (field <= 0))
|
||||
return sfInvalid;
|
||||
|
||||
boost::mutex::scoped_lock sl(mapMutex);
|
||||
boost::mutex::scoped_lock sl (mapMutex);
|
||||
|
||||
std::map<int, SField::ptr>::iterator it = codeToField.find(code);
|
||||
if (it != codeToField.end())
|
||||
return *(it->second);
|
||||
std::map<int, SField::ptr>::iterator it = codeToField.find (code);
|
||||
|
||||
if (field > 255) // don't dynamically extend types that have no binary encoding
|
||||
return sfInvalid;
|
||||
if (it != codeToField.end ())
|
||||
return * (it->second);
|
||||
|
||||
switch (type)
|
||||
{ // types we are willing to dynamically extend
|
||||
if (field > 255) // don't dynamically extend types that have no binary encoding
|
||||
return sfInvalid;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
// types we are willing to dynamically extend
|
||||
|
||||
#define FIELD(name, type, index)
|
||||
#define TYPE(name, type, index) case STI_##type:
|
||||
@@ -69,56 +72,62 @@ SField::ref SField::getField(int code)
|
||||
#undef FIELD
|
||||
#undef TYPE
|
||||
|
||||
break;
|
||||
default:
|
||||
return sfInvalid;
|
||||
}
|
||||
break;
|
||||
|
||||
return *(new SField(static_cast<SerializedTypeID>(type), field));
|
||||
default:
|
||||
return sfInvalid;
|
||||
}
|
||||
|
||||
return * (new SField (static_cast<SerializedTypeID> (type), field));
|
||||
}
|
||||
|
||||
int SField::compare(SField::ref f1, SField::ref f2)
|
||||
{ // -1 = f1 comes before f2, 0 = illegal combination, 1 = f1 comes after f2
|
||||
if ((f1.fieldCode <= 0) || (f2.fieldCode <= 0))
|
||||
return 0;
|
||||
|
||||
if (f1.fieldCode < f2.fieldCode)
|
||||
return -1;
|
||||
|
||||
if (f2.fieldCode < f1.fieldCode)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string SField::getName() const
|
||||
int SField::compare (SField::ref f1, SField::ref f2)
|
||||
{
|
||||
if (!fieldName.empty())
|
||||
return fieldName;
|
||||
if (fieldValue == 0)
|
||||
return "";
|
||||
return boost::lexical_cast<std::string>(static_cast<int>(fieldType)) + "/" +
|
||||
boost::lexical_cast<std::string>(fieldValue);
|
||||
// -1 = f1 comes before f2, 0 = illegal combination, 1 = f1 comes after f2
|
||||
if ((f1.fieldCode <= 0) || (f2.fieldCode <= 0))
|
||||
return 0;
|
||||
|
||||
if (f1.fieldCode < f2.fieldCode)
|
||||
return -1;
|
||||
|
||||
if (f2.fieldCode < f1.fieldCode)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
SField::ref SField::getField(const std::string& fieldName)
|
||||
{ // OPTIMIZEME me with a map. CHECKME this is case sensitive
|
||||
boost::mutex::scoped_lock sl(mapMutex);
|
||||
typedef std::map<int, SField::ptr>::value_type int_sfref_pair;
|
||||
BOOST_FOREACH(const int_sfref_pair& fieldPair, codeToField)
|
||||
{
|
||||
if (fieldPair.second->fieldName == fieldName)
|
||||
return *(fieldPair.second);
|
||||
}
|
||||
return sfInvalid;
|
||||
}
|
||||
|
||||
SField::~SField()
|
||||
std::string SField::getName () const
|
||||
{
|
||||
boost::mutex::scoped_lock sl(mapMutex);
|
||||
std::map<int, ptr>::iterator it = codeToField.find(fieldCode);
|
||||
if ((it != codeToField.end()) && (it->second == this))
|
||||
codeToField.erase(it);
|
||||
if (!fieldName.empty ())
|
||||
return fieldName;
|
||||
|
||||
if (fieldValue == 0)
|
||||
return "";
|
||||
|
||||
return boost::lexical_cast<std::string> (static_cast<int> (fieldType)) + "/" +
|
||||
boost::lexical_cast<std::string> (fieldValue);
|
||||
}
|
||||
|
||||
SField::ref SField::getField (const std::string& fieldName)
|
||||
{
|
||||
// OPTIMIZEME me with a map. CHECKME this is case sensitive
|
||||
boost::mutex::scoped_lock sl (mapMutex);
|
||||
typedef std::map<int, SField::ptr>::value_type int_sfref_pair;
|
||||
BOOST_FOREACH (const int_sfref_pair & fieldPair, codeToField)
|
||||
{
|
||||
if (fieldPair.second->fieldName == fieldName)
|
||||
return * (fieldPair.second);
|
||||
}
|
||||
return sfInvalid;
|
||||
}
|
||||
|
||||
SField::~SField ()
|
||||
{
|
||||
boost::mutex::scoped_lock sl (mapMutex);
|
||||
std::map<int, ptr>::iterator it = codeToField.find (fieldCode);
|
||||
|
||||
if ((it != codeToField.end ()) && (it->second == this))
|
||||
codeToField.erase (it);
|
||||
}
|
||||
|
||||
// vim:ts=4
|
||||
|
||||
@@ -6,10 +6,10 @@
|
||||
|
||||
enum SerializedTypeID
|
||||
{
|
||||
// special types
|
||||
STI_UNKNOWN = -2,
|
||||
STI_DONE = -1,
|
||||
STI_NOTPRESENT = 0,
|
||||
// special types
|
||||
STI_UNKNOWN = -2,
|
||||
STI_DONE = -1,
|
||||
STI_NOTPRESENT = 0,
|
||||
|
||||
#define TYPE(name, field, value) STI_##field = value,
|
||||
#define FIELD(name, field, value)
|
||||
@@ -17,10 +17,10 @@ enum SerializedTypeID
|
||||
#undef TYPE
|
||||
#undef FIELD
|
||||
|
||||
// high level types
|
||||
STI_TRANSACTION = 10001,
|
||||
STI_LEDGERENTRY = 10002,
|
||||
STI_VALIDATION = 10003,
|
||||
// high level types
|
||||
STI_TRANSACTION = 10001,
|
||||
STI_LEDGERENTRY = 10002,
|
||||
STI_VALIDATION = 10003,
|
||||
};
|
||||
|
||||
/** Identifies fields.
|
||||
@@ -32,112 +32,168 @@ enum SerializedTypeID
|
||||
class SField
|
||||
{
|
||||
public:
|
||||
typedef const SField& ref;
|
||||
typedef SField const * ptr;
|
||||
typedef const SField& ref;
|
||||
typedef SField const* ptr;
|
||||
|
||||
static const int sMD_Never = 0x00;
|
||||
static const int sMD_ChangeOrig = 0x01; // original value when it changes
|
||||
static const int sMD_ChangeNew = 0x02; // new value when it changes
|
||||
static const int sMD_DeleteFinal = 0x04; // final value when it is deleted
|
||||
static const int sMD_Create = 0x08; // value when it's created
|
||||
static const int sMD_Always = 0x10; // value when node containing it is affected at all
|
||||
static const int sMD_Default = sMD_ChangeOrig | sMD_ChangeNew | sMD_DeleteFinal | sMD_Create;
|
||||
static const int sMD_Never = 0x00;
|
||||
static const int sMD_ChangeOrig = 0x01; // original value when it changes
|
||||
static const int sMD_ChangeNew = 0x02; // new value when it changes
|
||||
static const int sMD_DeleteFinal = 0x04; // final value when it is deleted
|
||||
static const int sMD_Create = 0x08; // value when it's created
|
||||
static const int sMD_Always = 0x10; // value when node containing it is affected at all
|
||||
static const int sMD_Default = sMD_ChangeOrig | sMD_ChangeNew | sMD_DeleteFinal | sMD_Create;
|
||||
|
||||
public:
|
||||
|
||||
const int fieldCode; // (type<<16)|index
|
||||
const SerializedTypeID fieldType; // STI_*
|
||||
const int fieldValue; // Code number for protocol
|
||||
std::string fieldName;
|
||||
int fieldMeta;
|
||||
int fieldNum;
|
||||
bool signingField;
|
||||
const int fieldCode; // (type<<16)|index
|
||||
const SerializedTypeID fieldType; // STI_*
|
||||
const int fieldValue; // Code number for protocol
|
||||
std::string fieldName;
|
||||
int fieldMeta;
|
||||
int fieldNum;
|
||||
bool signingField;
|
||||
|
||||
SField (int fc, SerializedTypeID tid, int fv, const char* fn)
|
||||
SField (int fc, SerializedTypeID tid, int fv, const char* fn)
|
||||
: fieldCode (fc)
|
||||
, fieldType (tid)
|
||||
, fieldValue (fv)
|
||||
, fieldName (fn)
|
||||
, fieldMeta (sMD_Default)
|
||||
, signingField (true)
|
||||
{
|
||||
boost::mutex::scoped_lock sl(mapMutex);
|
||||
{
|
||||
boost::mutex::scoped_lock sl (mapMutex);
|
||||
|
||||
codeToField[fieldCode] = this;
|
||||
|
||||
fieldNum = ++num;
|
||||
}
|
||||
|
||||
SField (SerializedTypeID tid, int fv, const char *fn)
|
||||
fieldNum = ++num;
|
||||
}
|
||||
|
||||
SField (SerializedTypeID tid, int fv, const char* fn)
|
||||
: fieldCode (FIELD_CODE (tid, fv))
|
||||
, fieldType (tid)
|
||||
, fieldValue (fv)
|
||||
, fieldName (fn)
|
||||
, fieldMeta (sMD_Default)
|
||||
, signingField (true)
|
||||
{
|
||||
boost::mutex::scoped_lock sl(mapMutex);
|
||||
{
|
||||
boost::mutex::scoped_lock sl (mapMutex);
|
||||
|
||||
codeToField[fieldCode] = this;
|
||||
|
||||
fieldNum = ++num;
|
||||
}
|
||||
|
||||
explicit SField (int fc)
|
||||
fieldNum = ++num;
|
||||
}
|
||||
|
||||
explicit SField (int fc)
|
||||
: fieldCode (fc)
|
||||
, fieldType (STI_UNKNOWN)
|
||||
, fieldValue (0)
|
||||
, fieldMeta (sMD_Never)
|
||||
, signingField (true)
|
||||
{
|
||||
boost::mutex::scoped_lock sl(mapMutex);
|
||||
fieldNum = ++num;
|
||||
}
|
||||
{
|
||||
boost::mutex::scoped_lock sl (mapMutex);
|
||||
fieldNum = ++num;
|
||||
}
|
||||
|
||||
~SField ();
|
||||
~SField ();
|
||||
|
||||
static SField::ref getField (int fieldCode);
|
||||
static SField::ref getField (const std::string& fieldName);
|
||||
static SField::ref getField (int type, int value) { return getField(FIELD_CODE(type, value)); }
|
||||
static SField::ref getField (SerializedTypeID type, int value) { return getField(FIELD_CODE(type, value)); }
|
||||
static SField::ref getField (int fieldCode);
|
||||
static SField::ref getField (const std::string& fieldName);
|
||||
static SField::ref getField (int type, int value)
|
||||
{
|
||||
return getField (FIELD_CODE (type, value));
|
||||
}
|
||||
static SField::ref getField (SerializedTypeID type, int value)
|
||||
{
|
||||
return getField (FIELD_CODE (type, value));
|
||||
}
|
||||
|
||||
std::string getName() const;
|
||||
bool hasName() const { return !fieldName.empty(); }
|
||||
std::string getName () const;
|
||||
bool hasName () const
|
||||
{
|
||||
return !fieldName.empty ();
|
||||
}
|
||||
|
||||
bool isGeneric() const { return fieldCode == 0; }
|
||||
bool isInvalid() const { return fieldCode == -1; }
|
||||
bool isUseful() const { return fieldCode > 0; }
|
||||
bool isKnown() const { return fieldType != STI_UNKNOWN; }
|
||||
bool isBinary() const { return fieldValue < 256; }
|
||||
bool isGeneric () const
|
||||
{
|
||||
return fieldCode == 0;
|
||||
}
|
||||
bool isInvalid () const
|
||||
{
|
||||
return fieldCode == -1;
|
||||
}
|
||||
bool isUseful () const
|
||||
{
|
||||
return fieldCode > 0;
|
||||
}
|
||||
bool isKnown () const
|
||||
{
|
||||
return fieldType != STI_UNKNOWN;
|
||||
}
|
||||
bool isBinary () const
|
||||
{
|
||||
return fieldValue < 256;
|
||||
}
|
||||
|
||||
// VFALCO NOTE What is a discardable field?
|
||||
bool isDiscardable() const { return fieldValue > 256; }
|
||||
bool isDiscardable () const
|
||||
{
|
||||
return fieldValue > 256;
|
||||
}
|
||||
|
||||
int getCode() const { return fieldCode; }
|
||||
int getNum() const { return fieldNum; }
|
||||
static int getNumFields() { return num; }
|
||||
int getCode () const
|
||||
{
|
||||
return fieldCode;
|
||||
}
|
||||
int getNum () const
|
||||
{
|
||||
return fieldNum;
|
||||
}
|
||||
static int getNumFields ()
|
||||
{
|
||||
return num;
|
||||
}
|
||||
|
||||
bool isSigningField() const { return signingField; }
|
||||
void notSigningField() { signingField = false; }
|
||||
bool shouldMeta(int c) const { return (fieldMeta & c) != 0; }
|
||||
void setMeta(int c) { fieldMeta = c; }
|
||||
bool isSigningField () const
|
||||
{
|
||||
return signingField;
|
||||
}
|
||||
void notSigningField ()
|
||||
{
|
||||
signingField = false;
|
||||
}
|
||||
bool shouldMeta (int c) const
|
||||
{
|
||||
return (fieldMeta & c) != 0;
|
||||
}
|
||||
void setMeta (int c)
|
||||
{
|
||||
fieldMeta = c;
|
||||
}
|
||||
|
||||
bool shouldInclude(bool withSigningField) const
|
||||
{ return (fieldValue < 256) && (withSigningField || signingField); }
|
||||
bool shouldInclude (bool withSigningField) const
|
||||
{
|
||||
return (fieldValue < 256) && (withSigningField || signingField);
|
||||
}
|
||||
|
||||
bool operator== (const SField& f) const { return fieldCode == f.fieldCode; }
|
||||
bool operator== (const SField& f) const
|
||||
{
|
||||
return fieldCode == f.fieldCode;
|
||||
}
|
||||
|
||||
bool operator!= (const SField& f) const { return fieldCode != f.fieldCode; }
|
||||
bool operator!= (const SField& f) const
|
||||
{
|
||||
return fieldCode != f.fieldCode;
|
||||
}
|
||||
|
||||
static int compare(SField::ref f1, SField::ref f2);
|
||||
static int compare (SField::ref f1, SField::ref f2);
|
||||
|
||||
// VFALCO TODO make these private
|
||||
protected:
|
||||
static std::map<int, ptr> codeToField;
|
||||
static boost::mutex mapMutex;
|
||||
static int num;
|
||||
static std::map<int, ptr> codeToField;
|
||||
static boost::mutex mapMutex;
|
||||
static int num;
|
||||
|
||||
SField (SerializedTypeID id, int val);
|
||||
SField (SerializedTypeID id, int val);
|
||||
};
|
||||
|
||||
extern SField sfInvalid, sfGeneric, sfLedgerEntry, sfTransaction, sfValidation;
|
||||
|
||||
@@ -3,137 +3,143 @@ std::map <int, LedgerEntryFormat*> LedgerEntryFormat::byType;
|
||||
|
||||
std::map <std::string, LedgerEntryFormat*> LedgerEntryFormat::byName;
|
||||
|
||||
#define LEF_BASE \
|
||||
<< SOElement(sfLedgerIndex, SOE_OPTIONAL) \
|
||||
<< SOElement(sfLedgerEntryType, SOE_REQUIRED) \
|
||||
<< SOElement(sfFlags, SOE_REQUIRED)
|
||||
#define LEF_BASE \
|
||||
<< SOElement(sfLedgerIndex, SOE_OPTIONAL) \
|
||||
<< SOElement(sfLedgerEntryType, SOE_REQUIRED) \
|
||||
<< SOElement(sfFlags, SOE_REQUIRED)
|
||||
|
||||
#define DECLARE_LEF(name, type) lef = new LedgerEntryFormat(#name, type); (*lef) LEF_BASE
|
||||
|
||||
void LEFInit()
|
||||
void LEFInit ()
|
||||
{
|
||||
LedgerEntryFormat* lef;
|
||||
LedgerEntryFormat* lef;
|
||||
|
||||
DECLARE_LEF(AccountRoot, ltACCOUNT_ROOT)
|
||||
<< SOElement(sfAccount, SOE_REQUIRED)
|
||||
<< SOElement(sfSequence, SOE_REQUIRED)
|
||||
<< SOElement(sfBalance, SOE_REQUIRED)
|
||||
<< SOElement(sfOwnerCount, SOE_REQUIRED)
|
||||
<< SOElement(sfPreviousTxnID, SOE_REQUIRED)
|
||||
<< SOElement(sfPreviousTxnLgrSeq, SOE_REQUIRED)
|
||||
<< SOElement(sfRegularKey, SOE_OPTIONAL)
|
||||
<< SOElement(sfEmailHash, SOE_OPTIONAL)
|
||||
<< SOElement(sfWalletLocator, SOE_OPTIONAL)
|
||||
<< SOElement(sfWalletSize, SOE_OPTIONAL)
|
||||
<< SOElement(sfMessageKey, SOE_OPTIONAL)
|
||||
<< SOElement(sfTransferRate, SOE_OPTIONAL)
|
||||
<< SOElement(sfDomain, SOE_OPTIONAL)
|
||||
;
|
||||
DECLARE_LEF (AccountRoot, ltACCOUNT_ROOT)
|
||||
<< SOElement (sfAccount, SOE_REQUIRED)
|
||||
<< SOElement (sfSequence, SOE_REQUIRED)
|
||||
<< SOElement (sfBalance, SOE_REQUIRED)
|
||||
<< SOElement (sfOwnerCount, SOE_REQUIRED)
|
||||
<< SOElement (sfPreviousTxnID, SOE_REQUIRED)
|
||||
<< SOElement (sfPreviousTxnLgrSeq, SOE_REQUIRED)
|
||||
<< SOElement (sfRegularKey, SOE_OPTIONAL)
|
||||
<< SOElement (sfEmailHash, SOE_OPTIONAL)
|
||||
<< SOElement (sfWalletLocator, SOE_OPTIONAL)
|
||||
<< SOElement (sfWalletSize, SOE_OPTIONAL)
|
||||
<< SOElement (sfMessageKey, SOE_OPTIONAL)
|
||||
<< SOElement (sfTransferRate, SOE_OPTIONAL)
|
||||
<< SOElement (sfDomain, SOE_OPTIONAL)
|
||||
;
|
||||
|
||||
DECLARE_LEF(Contract, ltCONTRACT)
|
||||
<< SOElement(sfAccount, SOE_REQUIRED)
|
||||
<< SOElement(sfBalance, SOE_REQUIRED)
|
||||
<< SOElement(sfPreviousTxnID, SOE_REQUIRED)
|
||||
<< SOElement(sfPreviousTxnLgrSeq, SOE_REQUIRED)
|
||||
<< SOElement(sfIssuer, SOE_REQUIRED)
|
||||
<< SOElement(sfOwner, SOE_REQUIRED)
|
||||
<< SOElement(sfExpiration, SOE_REQUIRED)
|
||||
<< SOElement(sfBondAmount, SOE_REQUIRED)
|
||||
<< SOElement(sfCreateCode, SOE_OPTIONAL)
|
||||
<< SOElement(sfFundCode, SOE_OPTIONAL)
|
||||
<< SOElement(sfRemoveCode, SOE_OPTIONAL)
|
||||
<< SOElement(sfExpireCode, SOE_OPTIONAL)
|
||||
;
|
||||
DECLARE_LEF (Contract, ltCONTRACT)
|
||||
<< SOElement (sfAccount, SOE_REQUIRED)
|
||||
<< SOElement (sfBalance, SOE_REQUIRED)
|
||||
<< SOElement (sfPreviousTxnID, SOE_REQUIRED)
|
||||
<< SOElement (sfPreviousTxnLgrSeq, SOE_REQUIRED)
|
||||
<< SOElement (sfIssuer, SOE_REQUIRED)
|
||||
<< SOElement (sfOwner, SOE_REQUIRED)
|
||||
<< SOElement (sfExpiration, SOE_REQUIRED)
|
||||
<< SOElement (sfBondAmount, SOE_REQUIRED)
|
||||
<< SOElement (sfCreateCode, SOE_OPTIONAL)
|
||||
<< SOElement (sfFundCode, SOE_OPTIONAL)
|
||||
<< SOElement (sfRemoveCode, SOE_OPTIONAL)
|
||||
<< SOElement (sfExpireCode, SOE_OPTIONAL)
|
||||
;
|
||||
|
||||
DECLARE_LEF(DirectoryNode, ltDIR_NODE)
|
||||
<< SOElement(sfOwner, SOE_OPTIONAL) // for owner directories
|
||||
<< SOElement(sfTakerPaysCurrency, SOE_OPTIONAL) // for order book directories
|
||||
<< SOElement(sfTakerPaysIssuer, SOE_OPTIONAL) // for order book directories
|
||||
<< SOElement(sfTakerGetsCurrency, SOE_OPTIONAL) // for order book directories
|
||||
<< SOElement(sfTakerGetsIssuer, SOE_OPTIONAL) // for order book directories
|
||||
<< SOElement(sfExchangeRate, SOE_OPTIONAL) // for order book directories
|
||||
<< SOElement(sfIndexes, SOE_REQUIRED)
|
||||
<< SOElement(sfRootIndex, SOE_REQUIRED)
|
||||
<< SOElement(sfIndexNext, SOE_OPTIONAL)
|
||||
<< SOElement(sfIndexPrevious, SOE_OPTIONAL)
|
||||
;
|
||||
DECLARE_LEF (DirectoryNode, ltDIR_NODE)
|
||||
<< SOElement (sfOwner, SOE_OPTIONAL) // for owner directories
|
||||
<< SOElement (sfTakerPaysCurrency, SOE_OPTIONAL) // for order book directories
|
||||
<< SOElement (sfTakerPaysIssuer, SOE_OPTIONAL) // for order book directories
|
||||
<< SOElement (sfTakerGetsCurrency, SOE_OPTIONAL) // for order book directories
|
||||
<< SOElement (sfTakerGetsIssuer, SOE_OPTIONAL) // for order book directories
|
||||
<< SOElement (sfExchangeRate, SOE_OPTIONAL) // for order book directories
|
||||
<< SOElement (sfIndexes, SOE_REQUIRED)
|
||||
<< SOElement (sfRootIndex, SOE_REQUIRED)
|
||||
<< SOElement (sfIndexNext, SOE_OPTIONAL)
|
||||
<< SOElement (sfIndexPrevious, SOE_OPTIONAL)
|
||||
;
|
||||
|
||||
DECLARE_LEF(GeneratorMap, ltGENERATOR_MAP)
|
||||
<< SOElement(sfGenerator, SOE_REQUIRED)
|
||||
;
|
||||
DECLARE_LEF (GeneratorMap, ltGENERATOR_MAP)
|
||||
<< SOElement (sfGenerator, SOE_REQUIRED)
|
||||
;
|
||||
|
||||
DECLARE_LEF(Nickname, ltNICKNAME)
|
||||
<< SOElement(sfAccount, SOE_REQUIRED)
|
||||
<< SOElement(sfMinimumOffer, SOE_OPTIONAL)
|
||||
;
|
||||
DECLARE_LEF (Nickname, ltNICKNAME)
|
||||
<< SOElement (sfAccount, SOE_REQUIRED)
|
||||
<< SOElement (sfMinimumOffer, SOE_OPTIONAL)
|
||||
;
|
||||
|
||||
DECLARE_LEF(Offer, ltOFFER)
|
||||
<< SOElement(sfAccount, SOE_REQUIRED)
|
||||
<< SOElement(sfSequence, SOE_REQUIRED)
|
||||
<< SOElement(sfTakerPays, SOE_REQUIRED)
|
||||
<< SOElement(sfTakerGets, SOE_REQUIRED)
|
||||
<< SOElement(sfBookDirectory, SOE_REQUIRED)
|
||||
<< SOElement(sfBookNode, SOE_REQUIRED)
|
||||
<< SOElement(sfOwnerNode, SOE_REQUIRED)
|
||||
<< SOElement(sfPreviousTxnID, SOE_REQUIRED)
|
||||
<< SOElement(sfPreviousTxnLgrSeq, SOE_REQUIRED)
|
||||
<< SOElement(sfExpiration, SOE_OPTIONAL)
|
||||
;
|
||||
DECLARE_LEF (Offer, ltOFFER)
|
||||
<< SOElement (sfAccount, SOE_REQUIRED)
|
||||
<< SOElement (sfSequence, SOE_REQUIRED)
|
||||
<< SOElement (sfTakerPays, SOE_REQUIRED)
|
||||
<< SOElement (sfTakerGets, SOE_REQUIRED)
|
||||
<< SOElement (sfBookDirectory, SOE_REQUIRED)
|
||||
<< SOElement (sfBookNode, SOE_REQUIRED)
|
||||
<< SOElement (sfOwnerNode, SOE_REQUIRED)
|
||||
<< SOElement (sfPreviousTxnID, SOE_REQUIRED)
|
||||
<< SOElement (sfPreviousTxnLgrSeq, SOE_REQUIRED)
|
||||
<< SOElement (sfExpiration, SOE_OPTIONAL)
|
||||
;
|
||||
|
||||
DECLARE_LEF(RippleState, ltRIPPLE_STATE)
|
||||
<< SOElement(sfBalance, SOE_REQUIRED)
|
||||
<< SOElement(sfLowLimit, SOE_REQUIRED)
|
||||
<< SOElement(sfHighLimit, SOE_REQUIRED)
|
||||
<< SOElement(sfPreviousTxnID, SOE_REQUIRED)
|
||||
<< SOElement(sfPreviousTxnLgrSeq, SOE_REQUIRED)
|
||||
<< SOElement(sfLowNode, SOE_OPTIONAL)
|
||||
<< SOElement(sfLowQualityIn, SOE_OPTIONAL)
|
||||
<< SOElement(sfLowQualityOut, SOE_OPTIONAL)
|
||||
<< SOElement(sfHighNode, SOE_OPTIONAL)
|
||||
<< SOElement(sfHighQualityIn, SOE_OPTIONAL)
|
||||
<< SOElement(sfHighQualityOut, SOE_OPTIONAL)
|
||||
;
|
||||
DECLARE_LEF (RippleState, ltRIPPLE_STATE)
|
||||
<< SOElement (sfBalance, SOE_REQUIRED)
|
||||
<< SOElement (sfLowLimit, SOE_REQUIRED)
|
||||
<< SOElement (sfHighLimit, SOE_REQUIRED)
|
||||
<< SOElement (sfPreviousTxnID, SOE_REQUIRED)
|
||||
<< SOElement (sfPreviousTxnLgrSeq, SOE_REQUIRED)
|
||||
<< SOElement (sfLowNode, SOE_OPTIONAL)
|
||||
<< SOElement (sfLowQualityIn, SOE_OPTIONAL)
|
||||
<< SOElement (sfLowQualityOut, SOE_OPTIONAL)
|
||||
<< SOElement (sfHighNode, SOE_OPTIONAL)
|
||||
<< SOElement (sfHighQualityIn, SOE_OPTIONAL)
|
||||
<< SOElement (sfHighQualityOut, SOE_OPTIONAL)
|
||||
;
|
||||
|
||||
DECLARE_LEF(LedgerHashes, ltLEDGER_HASHES)
|
||||
<< SOElement(sfFirstLedgerSequence, SOE_OPTIONAL) // Remove if we do a ledger restart
|
||||
<< SOElement(sfLastLedgerSequence, SOE_OPTIONAL)
|
||||
<< SOElement(sfHashes, SOE_REQUIRED)
|
||||
;
|
||||
DECLARE_LEF (LedgerHashes, ltLEDGER_HASHES)
|
||||
<< SOElement (sfFirstLedgerSequence, SOE_OPTIONAL) // Remove if we do a ledger restart
|
||||
<< SOElement (sfLastLedgerSequence, SOE_OPTIONAL)
|
||||
<< SOElement (sfHashes, SOE_REQUIRED)
|
||||
;
|
||||
|
||||
DECLARE_LEF(EnabledFeatures, ltFEATURES)
|
||||
<< SOElement(sfFeatures, SOE_REQUIRED)
|
||||
;
|
||||
DECLARE_LEF (EnabledFeatures, ltFEATURES)
|
||||
<< SOElement (sfFeatures, SOE_REQUIRED)
|
||||
;
|
||||
|
||||
DECLARE_LEF(FeeSettings, ltFEE_SETTINGS)
|
||||
<< SOElement(sfBaseFee, SOE_REQUIRED)
|
||||
<< SOElement(sfReferenceFeeUnits, SOE_REQUIRED)
|
||||
<< SOElement(sfReserveBase, SOE_REQUIRED)
|
||||
<< SOElement(sfReserveIncrement, SOE_REQUIRED)
|
||||
;
|
||||
DECLARE_LEF (FeeSettings, ltFEE_SETTINGS)
|
||||
<< SOElement (sfBaseFee, SOE_REQUIRED)
|
||||
<< SOElement (sfReferenceFeeUnits, SOE_REQUIRED)
|
||||
<< SOElement (sfReserveBase, SOE_REQUIRED)
|
||||
<< SOElement (sfReserveIncrement, SOE_REQUIRED)
|
||||
;
|
||||
}
|
||||
|
||||
LedgerEntryFormat* LedgerEntryFormat::getLgrFormat(LedgerEntryType t)
|
||||
LedgerEntryFormat* LedgerEntryFormat::getLgrFormat (LedgerEntryType t)
|
||||
{
|
||||
std::map<int, LedgerEntryFormat*>::iterator it = byType.find(static_cast<int>(t));
|
||||
if (it == byType.end())
|
||||
return NULL;
|
||||
return it->second;
|
||||
std::map<int, LedgerEntryFormat*>::iterator it = byType.find (static_cast<int> (t));
|
||||
|
||||
if (it == byType.end ())
|
||||
return NULL;
|
||||
|
||||
return it->second;
|
||||
}
|
||||
|
||||
LedgerEntryFormat* LedgerEntryFormat::getLgrFormat(int t)
|
||||
LedgerEntryFormat* LedgerEntryFormat::getLgrFormat (int t)
|
||||
{
|
||||
std::map<int, LedgerEntryFormat*>::iterator it = byType.find((t));
|
||||
if (it == byType.end())
|
||||
return NULL;
|
||||
return it->second;
|
||||
std::map<int, LedgerEntryFormat*>::iterator it = byType.find ((t));
|
||||
|
||||
if (it == byType.end ())
|
||||
return NULL;
|
||||
|
||||
return it->second;
|
||||
}
|
||||
|
||||
LedgerEntryFormat* LedgerEntryFormat::getLgrFormat(const std::string& t)
|
||||
LedgerEntryFormat* LedgerEntryFormat::getLgrFormat (const std::string& t)
|
||||
{
|
||||
std::map<std::string, LedgerEntryFormat*>::iterator it = byName.find((t));
|
||||
if (it == byName.end())
|
||||
return NULL;
|
||||
return it->second;
|
||||
std::map<std::string, LedgerEntryFormat*>::iterator it = byName.find ((t));
|
||||
|
||||
if (it == byName.end ())
|
||||
return NULL;
|
||||
|
||||
return it->second;
|
||||
}
|
||||
|
||||
// vim:ts=4
|
||||
|
||||
@@ -4,79 +4,79 @@
|
||||
// Used as the type of a transaction or the type of a ledger entry.
|
||||
enum LedgerEntryType
|
||||
{
|
||||
ltINVALID = -1,
|
||||
ltACCOUNT_ROOT = 'a',
|
||||
ltDIR_NODE = 'd',
|
||||
ltGENERATOR_MAP = 'g',
|
||||
ltRIPPLE_STATE = 'r',
|
||||
ltNICKNAME = 'n',
|
||||
ltOFFER = 'o',
|
||||
ltCONTRACT = 'c',
|
||||
ltLEDGER_HASHES = 'h',
|
||||
ltFEATURES = 'f',
|
||||
ltFEE_SETTINGS = 's',
|
||||
ltINVALID = -1,
|
||||
ltACCOUNT_ROOT = 'a',
|
||||
ltDIR_NODE = 'd',
|
||||
ltGENERATOR_MAP = 'g',
|
||||
ltRIPPLE_STATE = 'r',
|
||||
ltNICKNAME = 'n',
|
||||
ltOFFER = 'o',
|
||||
ltCONTRACT = 'c',
|
||||
ltLEDGER_HASHES = 'h',
|
||||
ltFEATURES = 'f',
|
||||
ltFEE_SETTINGS = 's',
|
||||
};
|
||||
|
||||
// Used as a prefix for computing ledger indexes (keys).
|
||||
enum LedgerNameSpace
|
||||
{
|
||||
spaceAccount = 'a',
|
||||
spaceDirNode = 'd',
|
||||
spaceGenerator = 'g',
|
||||
spaceNickname = 'n',
|
||||
spaceRipple = 'r',
|
||||
spaceOffer = 'o', // Entry for an offer.
|
||||
spaceOwnerDir = 'O', // Directory of things owned by an account.
|
||||
spaceBookDir = 'B', // Directory of order books.
|
||||
spaceContract = 'c',
|
||||
spaceSkipList = 's',
|
||||
spaceFeature = 'f',
|
||||
spaceFee = 'e',
|
||||
spaceAccount = 'a',
|
||||
spaceDirNode = 'd',
|
||||
spaceGenerator = 'g',
|
||||
spaceNickname = 'n',
|
||||
spaceRipple = 'r',
|
||||
spaceOffer = 'o', // Entry for an offer.
|
||||
spaceOwnerDir = 'O', // Directory of things owned by an account.
|
||||
spaceBookDir = 'B', // Directory of order books.
|
||||
spaceContract = 'c',
|
||||
spaceSkipList = 's',
|
||||
spaceFeature = 'f',
|
||||
spaceFee = 'e',
|
||||
};
|
||||
|
||||
enum LedgerSpecificFlags
|
||||
{
|
||||
// ltACCOUNT_ROOT
|
||||
lsfPasswordSpent = 0x00010000, // True, if password set fee is spent.
|
||||
lsfRequireDestTag = 0x00020000, // True, to require a DestinationTag for payments.
|
||||
lsfRequireAuth = 0x00040000, // True, to require a authorization to hold IOUs.
|
||||
lsfDisallowXRP = 0x00080000, // True, to disallow sending XRP.
|
||||
// ltACCOUNT_ROOT
|
||||
lsfPasswordSpent = 0x00010000, // True, if password set fee is spent.
|
||||
lsfRequireDestTag = 0x00020000, // True, to require a DestinationTag for payments.
|
||||
lsfRequireAuth = 0x00040000, // True, to require a authorization to hold IOUs.
|
||||
lsfDisallowXRP = 0x00080000, // True, to disallow sending XRP.
|
||||
|
||||
// ltOFFER
|
||||
lsfPassive = 0x00010000,
|
||||
lsfSell = 0x00020000, // True, offer was placed as a sell.
|
||||
// ltOFFER
|
||||
lsfPassive = 0x00010000,
|
||||
lsfSell = 0x00020000, // True, offer was placed as a sell.
|
||||
|
||||
// ltRIPPLE_STATE
|
||||
lsfLowReserve = 0x00010000, // True, if entry counts toward reserve.
|
||||
lsfHighReserve = 0x00020000,
|
||||
lsfLowAuth = 0x00040000,
|
||||
lsfHighAuth = 0x00080000,
|
||||
// ltRIPPLE_STATE
|
||||
lsfLowReserve = 0x00010000, // True, if entry counts toward reserve.
|
||||
lsfHighReserve = 0x00020000,
|
||||
lsfLowAuth = 0x00040000,
|
||||
lsfHighAuth = 0x00080000,
|
||||
};
|
||||
|
||||
class LedgerEntryFormat
|
||||
{
|
||||
public:
|
||||
std::string t_name;
|
||||
LedgerEntryType t_type;
|
||||
SOTemplate elements;
|
||||
std::string t_name;
|
||||
LedgerEntryType t_type;
|
||||
SOTemplate elements;
|
||||
|
||||
static std::map<int, LedgerEntryFormat*> byType;
|
||||
static std::map<std::string, LedgerEntryFormat*> byName;
|
||||
static std::map<int, LedgerEntryFormat*> byType;
|
||||
static std::map<std::string, LedgerEntryFormat*> byName;
|
||||
|
||||
LedgerEntryFormat(const char *name, LedgerEntryType type) : t_name(name), t_type(type)
|
||||
{
|
||||
byName[name] = this;
|
||||
byType[type] = this;
|
||||
}
|
||||
LedgerEntryFormat& operator<<(const SOElement& el)
|
||||
{
|
||||
elements.push_back(el);
|
||||
return *this;
|
||||
}
|
||||
LedgerEntryFormat (const char* name, LedgerEntryType type) : t_name (name), t_type (type)
|
||||
{
|
||||
byName[name] = this;
|
||||
byType[type] = this;
|
||||
}
|
||||
LedgerEntryFormat& operator<< (const SOElement& el)
|
||||
{
|
||||
elements.push_back (el);
|
||||
return *this;
|
||||
}
|
||||
|
||||
static LedgerEntryFormat* getLgrFormat(LedgerEntryType t);
|
||||
static LedgerEntryFormat* getLgrFormat(const std::string& t);
|
||||
static LedgerEntryFormat* getLgrFormat(int t);
|
||||
static LedgerEntryFormat* getLgrFormat (LedgerEntryType t);
|
||||
static LedgerEntryFormat* getLgrFormat (const std::string& t);
|
||||
static LedgerEntryFormat* getLgrFormat (int t);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -2,39 +2,42 @@
|
||||
|
||||
PackedMessage::PackedMessage (::google::protobuf::Message const& message, int type)
|
||||
{
|
||||
unsigned const messageBytes = message.ByteSize ();
|
||||
unsigned const messageBytes = message.ByteSize ();
|
||||
|
||||
assert (messageBytes != 0);
|
||||
|
||||
|
||||
mBuffer.resize (kHeaderBytes + messageBytes);
|
||||
|
||||
encodeHeader (messageBytes, type);
|
||||
|
||||
|
||||
if (messageBytes != 0)
|
||||
{
|
||||
message.SerializeToArray (&mBuffer [PackedMessage::kHeaderBytes], messageBytes);
|
||||
{
|
||||
message.SerializeToArray (&mBuffer [PackedMessage::kHeaderBytes], messageBytes);
|
||||
|
||||
#ifdef DEBUG
|
||||
// std::cerr << "PackedMessage: type=" << type << ", datalen=" << msg_size << std::endl;
|
||||
// std::cerr << "PackedMessage: type=" << type << ", datalen=" << msg_size << std::endl;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool PackedMessage::operator== (PackedMessage const& other) const
|
||||
{
|
||||
return mBuffer == other.mBuffer;
|
||||
return mBuffer == other.mBuffer;
|
||||
}
|
||||
|
||||
unsigned PackedMessage::getLength (std::vector <uint8_t> const& buf)
|
||||
{
|
||||
unsigned result;
|
||||
|
||||
if (buf.size() >= PackedMessage::kHeaderBytes)
|
||||
if (buf.size () >= PackedMessage::kHeaderBytes)
|
||||
{
|
||||
result = buf [0];
|
||||
result <<= 8; result |= buf [1];
|
||||
result <<= 8; result |= buf [2];
|
||||
result <<= 8; result |= buf [3];
|
||||
result = buf [0];
|
||||
result <<= 8;
|
||||
result |= buf [1];
|
||||
result <<= 8;
|
||||
result |= buf [2];
|
||||
result <<= 8;
|
||||
result |= buf [3];
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -46,21 +49,22 @@ unsigned PackedMessage::getLength (std::vector <uint8_t> const& buf)
|
||||
|
||||
int PackedMessage::getType (std::vector<uint8_t> const& buf)
|
||||
{
|
||||
if(buf.size() < PackedMessage::kHeaderBytes)
|
||||
return 0;
|
||||
if (buf.size () < PackedMessage::kHeaderBytes)
|
||||
return 0;
|
||||
|
||||
int ret = buf[4];
|
||||
ret <<= 8; ret |= buf[5];
|
||||
return ret;
|
||||
int ret = buf[4];
|
||||
ret <<= 8;
|
||||
ret |= buf[5];
|
||||
return ret;
|
||||
}
|
||||
|
||||
void PackedMessage::encodeHeader (unsigned size, int type)
|
||||
void PackedMessage::encodeHeader (unsigned size, int type)
|
||||
{
|
||||
assert(mBuffer.size() >= PackedMessage::kHeaderBytes);
|
||||
mBuffer[0] = static_cast<boost::uint8_t>((size >> 24) & 0xFF);
|
||||
mBuffer[1] = static_cast<boost::uint8_t>((size >> 16) & 0xFF);
|
||||
mBuffer[2] = static_cast<boost::uint8_t>((size >> 8) & 0xFF);
|
||||
mBuffer[3] = static_cast<boost::uint8_t>(size & 0xFF);
|
||||
mBuffer[4] = static_cast<boost::uint8_t>((type >> 8) & 0xFF);
|
||||
mBuffer[5] = static_cast<boost::uint8_t>(type & 0xFF);
|
||||
assert (mBuffer.size () >= PackedMessage::kHeaderBytes);
|
||||
mBuffer[0] = static_cast<boost::uint8_t> ((size >> 24) & 0xFF);
|
||||
mBuffer[1] = static_cast<boost::uint8_t> ((size >> 16) & 0xFF);
|
||||
mBuffer[2] = static_cast<boost::uint8_t> ((size >> 8) & 0xFF);
|
||||
mBuffer[3] = static_cast<boost::uint8_t> (size & 0xFF);
|
||||
mBuffer[4] = static_cast<boost::uint8_t> ((type >> 8) & 0xFF);
|
||||
mBuffer[5] = static_cast<boost::uint8_t> (type & 0xFF);
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ class PackedMessage : public boost::enable_shared_from_this <PackedMessage>
|
||||
{
|
||||
public:
|
||||
typedef boost::shared_ptr< ::google::protobuf::Message > MessagePointer;
|
||||
typedef boost::shared_ptr<PackedMessage> pointer;
|
||||
typedef boost::shared_ptr<PackedMessage> pointer;
|
||||
|
||||
public:
|
||||
/** Number of bytes in a message header.
|
||||
@@ -26,27 +26,27 @@ public:
|
||||
/** Retrieve the packed message data.
|
||||
*/
|
||||
// VFALCO TODO shouldn't this be const?
|
||||
std::vector <uint8_t>& getBuffer()
|
||||
std::vector <uint8_t>& getBuffer ()
|
||||
{
|
||||
return mBuffer;
|
||||
}
|
||||
|
||||
/** Determine bytewise equality.
|
||||
*/
|
||||
bool operator == (PackedMessage const& other) const;
|
||||
bool operator == (PackedMessage const& other) const;
|
||||
|
||||
/** Calculate the length of a packed message.
|
||||
*/
|
||||
static unsigned getLength (std::vector <uint8_t> const& buf);
|
||||
|
||||
static unsigned getLength (std::vector <uint8_t> const& buf);
|
||||
|
||||
/** Determine the type of a packed message.
|
||||
*/
|
||||
static int getType (std::vector <uint8_t> const& buf);
|
||||
|
||||
private:
|
||||
// Encodes the size and type into a header at the beginning of buf
|
||||
//
|
||||
void encodeHeader (unsigned size, int type);
|
||||
// Encodes the size and type into a header at the beginning of buf
|
||||
//
|
||||
void encodeHeader (unsigned size, int type);
|
||||
|
||||
std::vector <uint8_t> mBuffer;
|
||||
};
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -8,180 +8,194 @@
|
||||
class RippleAddress : public CBase58Data
|
||||
{
|
||||
private:
|
||||
typedef enum {
|
||||
VER_NONE = 1,
|
||||
VER_NODE_PUBLIC = 28,
|
||||
VER_NODE_PRIVATE = 32,
|
||||
VER_ACCOUNT_ID = 0,
|
||||
VER_ACCOUNT_PUBLIC = 35,
|
||||
VER_ACCOUNT_PRIVATE = 34,
|
||||
VER_FAMILY_GENERATOR = 41,
|
||||
VER_FAMILY_SEED = 33,
|
||||
} VersionEncoding;
|
||||
typedef enum
|
||||
{
|
||||
VER_NONE = 1,
|
||||
VER_NODE_PUBLIC = 28,
|
||||
VER_NODE_PRIVATE = 32,
|
||||
VER_ACCOUNT_ID = 0,
|
||||
VER_ACCOUNT_PUBLIC = 35,
|
||||
VER_ACCOUNT_PRIVATE = 34,
|
||||
VER_FAMILY_GENERATOR = 41,
|
||||
VER_FAMILY_SEED = 33,
|
||||
} VersionEncoding;
|
||||
|
||||
bool mIsValid;
|
||||
bool mIsValid;
|
||||
|
||||
public:
|
||||
RippleAddress();
|
||||
RippleAddress ();
|
||||
|
||||
// For public and private key, checks if they are legal.
|
||||
bool isValid() const { return mIsValid; }
|
||||
// For public and private key, checks if they are legal.
|
||||
bool isValid () const
|
||||
{
|
||||
return mIsValid;
|
||||
}
|
||||
|
||||
void clear();
|
||||
bool isSet() const;
|
||||
void clear ();
|
||||
bool isSet () const;
|
||||
|
||||
std::string humanAddressType() const;
|
||||
std::string humanAddressType () const;
|
||||
|
||||
//
|
||||
// Node Public - Also used for Validators
|
||||
//
|
||||
uint160 getNodeID() const;
|
||||
Blob const& getNodePublic() const;
|
||||
//
|
||||
// Node Public - Also used for Validators
|
||||
//
|
||||
uint160 getNodeID () const;
|
||||
Blob const& getNodePublic () const;
|
||||
|
||||
std::string humanNodePublic() const;
|
||||
std::string humanNodePublic () const;
|
||||
|
||||
bool setNodePublic(const std::string& strPublic);
|
||||
void setNodePublic(Blob const& vPublic);
|
||||
bool verifyNodePublic(uint256 const& hash, Blob const& vchSig) const;
|
||||
bool verifyNodePublic(uint256 const& hash, const std::string& strSig) const;
|
||||
bool setNodePublic (const std::string& strPublic);
|
||||
void setNodePublic (Blob const& vPublic);
|
||||
bool verifyNodePublic (uint256 const& hash, Blob const& vchSig) const;
|
||||
bool verifyNodePublic (uint256 const& hash, const std::string& strSig) const;
|
||||
|
||||
static RippleAddress createNodePublic(const RippleAddress& naSeed);
|
||||
static RippleAddress createNodePublic(Blob const& vPublic);
|
||||
static RippleAddress createNodePublic(const std::string& strPublic);
|
||||
static RippleAddress createNodePublic (const RippleAddress& naSeed);
|
||||
static RippleAddress createNodePublic (Blob const& vPublic);
|
||||
static RippleAddress createNodePublic (const std::string& strPublic);
|
||||
|
||||
//
|
||||
// Node Private
|
||||
//
|
||||
Blob const& getNodePrivateData() const;
|
||||
uint256 getNodePrivate() const;
|
||||
//
|
||||
// Node Private
|
||||
//
|
||||
Blob const& getNodePrivateData () const;
|
||||
uint256 getNodePrivate () const;
|
||||
|
||||
std::string humanNodePrivate() const;
|
||||
std::string humanNodePrivate () const;
|
||||
|
||||
bool setNodePrivate(const std::string& strPrivate);
|
||||
void setNodePrivate(Blob const& vPrivate);
|
||||
void setNodePrivate(uint256 hash256);
|
||||
void signNodePrivate(uint256 const& hash, Blob& vchSig) const;
|
||||
bool setNodePrivate (const std::string& strPrivate);
|
||||
void setNodePrivate (Blob const& vPrivate);
|
||||
void setNodePrivate (uint256 hash256);
|
||||
void signNodePrivate (uint256 const& hash, Blob& vchSig) const;
|
||||
|
||||
static RippleAddress createNodePrivate(const RippleAddress& naSeed);
|
||||
static RippleAddress createNodePrivate (const RippleAddress& naSeed);
|
||||
|
||||
//
|
||||
// Accounts IDs
|
||||
//
|
||||
uint160 getAccountID() const;
|
||||
//
|
||||
// Accounts IDs
|
||||
//
|
||||
uint160 getAccountID () const;
|
||||
|
||||
std::string humanAccountID() const;
|
||||
std::string humanAccountID () const;
|
||||
|
||||
bool setAccountID(const std::string& strAccountID, const char* pAlphabet=Base58::getCurrentAlphabet ());
|
||||
void setAccountID(const uint160& hash160In);
|
||||
bool setAccountID (const std::string& strAccountID, const char* pAlphabet = Base58::getCurrentAlphabet ());
|
||||
void setAccountID (const uint160& hash160In);
|
||||
|
||||
static RippleAddress createAccountID(const std::string& strAccountID)
|
||||
{ RippleAddress na; na.setAccountID(strAccountID); return na; }
|
||||
static RippleAddress createAccountID (const std::string& strAccountID)
|
||||
{
|
||||
RippleAddress na;
|
||||
na.setAccountID (strAccountID);
|
||||
return na;
|
||||
}
|
||||
|
||||
static RippleAddress createAccountID(const uint160& uiAccountID);
|
||||
static RippleAddress createAccountID (const uint160& uiAccountID);
|
||||
|
||||
static std::string createHumanAccountID(const uint160& uiAccountID)
|
||||
{ return createAccountID(uiAccountID).humanAccountID(); }
|
||||
static std::string createHumanAccountID (const uint160& uiAccountID)
|
||||
{
|
||||
return createAccountID (uiAccountID).humanAccountID ();
|
||||
}
|
||||
|
||||
static std::string createHumanAccountID(Blob const& vPrivate)
|
||||
{ return createAccountPrivate(vPrivate).humanAccountID(); }
|
||||
static std::string createHumanAccountID (Blob const& vPrivate)
|
||||
{
|
||||
return createAccountPrivate (vPrivate).humanAccountID ();
|
||||
}
|
||||
|
||||
//
|
||||
// Accounts Public
|
||||
//
|
||||
Blob const& getAccountPublic() const;
|
||||
//
|
||||
// Accounts Public
|
||||
//
|
||||
Blob const& getAccountPublic () const;
|
||||
|
||||
std::string humanAccountPublic() const;
|
||||
std::string humanAccountPublic () const;
|
||||
|
||||
bool setAccountPublic(const std::string& strPublic);
|
||||
void setAccountPublic(Blob const& vPublic);
|
||||
void setAccountPublic(const RippleAddress& generator, int seq);
|
||||
bool setAccountPublic (const std::string& strPublic);
|
||||
void setAccountPublic (Blob const& vPublic);
|
||||
void setAccountPublic (const RippleAddress& generator, int seq);
|
||||
|
||||
bool accountPublicVerify(uint256 const& uHash, Blob const& vucSig) const;
|
||||
bool accountPublicVerify (uint256 const& uHash, Blob const& vucSig) const;
|
||||
|
||||
static RippleAddress createAccountPublic(Blob const& vPublic)
|
||||
{
|
||||
RippleAddress naNew;
|
||||
static RippleAddress createAccountPublic (Blob const& vPublic)
|
||||
{
|
||||
RippleAddress naNew;
|
||||
|
||||
naNew.setAccountPublic(vPublic);
|
||||
naNew.setAccountPublic (vPublic);
|
||||
|
||||
return naNew;
|
||||
}
|
||||
return naNew;
|
||||
}
|
||||
|
||||
static std::string createHumanAccountPublic(Blob const& vPublic) {
|
||||
return createAccountPublic(vPublic).humanAccountPublic();
|
||||
}
|
||||
static std::string createHumanAccountPublic (Blob const& vPublic)
|
||||
{
|
||||
return createAccountPublic (vPublic).humanAccountPublic ();
|
||||
}
|
||||
|
||||
// Create a deterministic public key from a public generator.
|
||||
static RippleAddress createAccountPublic(const RippleAddress& naGenerator, int iSeq);
|
||||
// Create a deterministic public key from a public generator.
|
||||
static RippleAddress createAccountPublic (const RippleAddress& naGenerator, int iSeq);
|
||||
|
||||
//
|
||||
// Accounts Private
|
||||
//
|
||||
uint256 getAccountPrivate() const;
|
||||
//
|
||||
// Accounts Private
|
||||
//
|
||||
uint256 getAccountPrivate () const;
|
||||
|
||||
std::string humanAccountPrivate() const;
|
||||
std::string humanAccountPrivate () const;
|
||||
|
||||
bool setAccountPrivate(const std::string& strPrivate);
|
||||
void setAccountPrivate(Blob const& vPrivate);
|
||||
void setAccountPrivate(uint256 hash256);
|
||||
void setAccountPrivate(const RippleAddress& naGenerator, const RippleAddress& naSeed, int seq);
|
||||
bool setAccountPrivate (const std::string& strPrivate);
|
||||
void setAccountPrivate (Blob const& vPrivate);
|
||||
void setAccountPrivate (uint256 hash256);
|
||||
void setAccountPrivate (const RippleAddress& naGenerator, const RippleAddress& naSeed, int seq);
|
||||
|
||||
bool accountPrivateSign(uint256 const& uHash, Blob& vucSig) const;
|
||||
// bool accountPrivateVerify(uint256 const& uHash, Blob const& vucSig) const;
|
||||
bool accountPrivateSign (uint256 const& uHash, Blob& vucSig) const;
|
||||
// bool accountPrivateVerify(uint256 const& uHash, Blob const& vucSig) const;
|
||||
|
||||
// Encrypt a message.
|
||||
Blob accountPrivateEncrypt(const RippleAddress& naPublicTo, Blob const& vucPlainText) const;
|
||||
// Encrypt a message.
|
||||
Blob accountPrivateEncrypt (const RippleAddress& naPublicTo, Blob const& vucPlainText) const;
|
||||
|
||||
// Decrypt a message.
|
||||
Blob accountPrivateDecrypt(const RippleAddress& naPublicFrom, Blob const& vucCipherText) const;
|
||||
// Decrypt a message.
|
||||
Blob accountPrivateDecrypt (const RippleAddress& naPublicFrom, Blob const& vucCipherText) const;
|
||||
|
||||
static RippleAddress createAccountPrivate(const RippleAddress& naGenerator, const RippleAddress& naSeed, int iSeq);
|
||||
static RippleAddress createAccountPrivate (const RippleAddress& naGenerator, const RippleAddress& naSeed, int iSeq);
|
||||
|
||||
static RippleAddress createAccountPrivate(Blob const& vPrivate)
|
||||
{
|
||||
RippleAddress naNew;
|
||||
static RippleAddress createAccountPrivate (Blob const& vPrivate)
|
||||
{
|
||||
RippleAddress naNew;
|
||||
|
||||
naNew.setAccountPrivate(vPrivate);
|
||||
naNew.setAccountPrivate (vPrivate);
|
||||
|
||||
return naNew;
|
||||
}
|
||||
return naNew;
|
||||
}
|
||||
|
||||
static std::string createHumanAccountPrivate(Blob const& vPrivate) {
|
||||
return createAccountPrivate(vPrivate).humanAccountPrivate();
|
||||
}
|
||||
static std::string createHumanAccountPrivate (Blob const& vPrivate)
|
||||
{
|
||||
return createAccountPrivate (vPrivate).humanAccountPrivate ();
|
||||
}
|
||||
|
||||
//
|
||||
// Generators
|
||||
// Use to generate a master or regular family.
|
||||
//
|
||||
BIGNUM* getGeneratorBN() const; // DEPRECATED
|
||||
Blob const& getGenerator() const;
|
||||
//
|
||||
// Generators
|
||||
// Use to generate a master or regular family.
|
||||
//
|
||||
BIGNUM* getGeneratorBN () const; // DEPRECATED
|
||||
Blob const& getGenerator () const;
|
||||
|
||||
std::string humanGenerator() const;
|
||||
std::string humanGenerator () const;
|
||||
|
||||
bool setGenerator(const std::string& strGenerator);
|
||||
void setGenerator(Blob const& vPublic);
|
||||
// void setGenerator(const RippleAddress& seed);
|
||||
bool setGenerator (const std::string& strGenerator);
|
||||
void setGenerator (Blob const& vPublic);
|
||||
// void setGenerator(const RippleAddress& seed);
|
||||
|
||||
// Create generator for making public deterministic keys.
|
||||
static RippleAddress createGeneratorPublic(const RippleAddress& naSeed);
|
||||
// Create generator for making public deterministic keys.
|
||||
static RippleAddress createGeneratorPublic (const RippleAddress& naSeed);
|
||||
|
||||
//
|
||||
// Seeds
|
||||
// Clients must disallow reconizable entries from being seeds.
|
||||
uint128 getSeed() const;
|
||||
//
|
||||
// Seeds
|
||||
// Clients must disallow reconizable entries from being seeds.
|
||||
uint128 getSeed () const;
|
||||
|
||||
std::string humanSeed() const;
|
||||
std::string humanSeed1751() const;
|
||||
std::string humanSeed () const;
|
||||
std::string humanSeed1751 () const;
|
||||
|
||||
bool setSeed(const std::string& strSeed);
|
||||
int setSeed1751(const std::string& strHuman1751);
|
||||
bool setSeedGeneric(const std::string& strText);
|
||||
void setSeed(uint128 hash128);
|
||||
void setSeedRandom();
|
||||
bool setSeed (const std::string& strSeed);
|
||||
int setSeed1751 (const std::string& strHuman1751);
|
||||
bool setSeedGeneric (const std::string& strText);
|
||||
void setSeed (uint128 hash128);
|
||||
void setSeedRandom ();
|
||||
|
||||
static RippleAddress createSeedRandom();
|
||||
static RippleAddress createSeedGeneric(const std::string& strText);
|
||||
static RippleAddress createSeedRandom ();
|
||||
static RippleAddress createSeedGeneric (const std::string& strText);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -33,9 +33,9 @@ public:
|
||||
// the point of call, i.e. "User-agent:" SYSTEM_NAME
|
||||
// It will be necessary to rewrite some of them to use string streams.
|
||||
//
|
||||
#define SYSTEM_NAME "ripple"
|
||||
#define SYSTEM_CURRENCY_CODE "XRP"
|
||||
#define SYSTEM_CURRENCY_PRECISION 6
|
||||
#define SYSTEM_CURRENCY_CODE_RIPPLE "XRR"
|
||||
#define SYSTEM_NAME "ripple"
|
||||
#define SYSTEM_CURRENCY_CODE "XRP"
|
||||
#define SYSTEM_CURRENCY_PRECISION 6
|
||||
#define SYSTEM_CURRENCY_CODE_RIPPLE "XRR"
|
||||
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,324 +1,348 @@
|
||||
|
||||
// CAUTION: This is early code and is *NOT* ready for real use yet.
|
||||
|
||||
static void canonicalizeRound(bool isNative, uint64& value, int& offset, bool roundUp)
|
||||
static void canonicalizeRound (bool isNative, uint64& value, int& offset, bool roundUp)
|
||||
{
|
||||
if (!roundUp) // canonicalize already rounds down
|
||||
return;
|
||||
if (!roundUp) // canonicalize already rounds down
|
||||
return;
|
||||
|
||||
WriteLog (lsTRACE, STAmount) << "canonicalize< " << value << ":" << offset << (roundUp ? " up" : " down");
|
||||
if (isNative)
|
||||
{
|
||||
if (offset < 0)
|
||||
{
|
||||
int loops = 0;
|
||||
while (offset < -1)
|
||||
{
|
||||
value /= 10;
|
||||
++offset;
|
||||
++loops;
|
||||
}
|
||||
value += (loops >= 2) ? 9 : 10; // add before last divide
|
||||
value /= 10;
|
||||
++offset;
|
||||
}
|
||||
}
|
||||
else if (value > STAmount::cMaxValue)
|
||||
{
|
||||
while (value > (10 * STAmount::cMaxValue))
|
||||
{
|
||||
value /= 10;
|
||||
++offset;
|
||||
}
|
||||
value += 9; // add before last divide
|
||||
value /= 10;
|
||||
++offset;
|
||||
}
|
||||
WriteLog (lsTRACE, STAmount) << "canonicalize> " << value << ":" << offset << (roundUp ? " up" : " down");
|
||||
WriteLog (lsTRACE, STAmount) << "canonicalize< " << value << ":" << offset << (roundUp ? " up" : " down");
|
||||
|
||||
if (isNative)
|
||||
{
|
||||
if (offset < 0)
|
||||
{
|
||||
int loops = 0;
|
||||
|
||||
while (offset < -1)
|
||||
{
|
||||
value /= 10;
|
||||
++offset;
|
||||
++loops;
|
||||
}
|
||||
|
||||
value += (loops >= 2) ? 9 : 10; // add before last divide
|
||||
value /= 10;
|
||||
++offset;
|
||||
}
|
||||
}
|
||||
else if (value > STAmount::cMaxValue)
|
||||
{
|
||||
while (value > (10 * STAmount::cMaxValue))
|
||||
{
|
||||
value /= 10;
|
||||
++offset;
|
||||
}
|
||||
|
||||
value += 9; // add before last divide
|
||||
value /= 10;
|
||||
++offset;
|
||||
}
|
||||
|
||||
WriteLog (lsTRACE, STAmount) << "canonicalize> " << value << ":" << offset << (roundUp ? " up" : " down");
|
||||
}
|
||||
|
||||
STAmount STAmount::addRound(const STAmount& v1, const STAmount& v2, bool roundUp)
|
||||
STAmount STAmount::addRound (const STAmount& v1, const STAmount& v2, bool roundUp)
|
||||
{
|
||||
v1.throwComparable(v2);
|
||||
v1.throwComparable (v2);
|
||||
|
||||
if (v2.mValue == 0)
|
||||
return v1;
|
||||
if (v2.mValue == 0)
|
||||
return v1;
|
||||
|
||||
if (v1.mValue == 0)
|
||||
return STAmount(v1.getFName(), v1.mCurrency, v1.mIssuer, v2.mValue, v2.mOffset, v2.mIsNegative);
|
||||
if (v1.mValue == 0)
|
||||
return STAmount (v1.getFName (), v1.mCurrency, v1.mIssuer, v2.mValue, v2.mOffset, v2.mIsNegative);
|
||||
|
||||
if (v1.mIsNative)
|
||||
return STAmount(v1.getFName(), v1.getSNValue() + v2.getSNValue());
|
||||
if (v1.mIsNative)
|
||||
return STAmount (v1.getFName (), v1.getSNValue () + v2.getSNValue ());
|
||||
|
||||
int ov1 = v1.mOffset, ov2 = v2.mOffset;
|
||||
int64 vv1 = static_cast<int64>(v1.mValue), vv2 = static_cast<uint64>(v2.mValue);
|
||||
if (v1.mIsNegative)
|
||||
vv1 = -vv1;
|
||||
if (v2.mIsNegative)
|
||||
vv2 = -vv2;
|
||||
int ov1 = v1.mOffset, ov2 = v2.mOffset;
|
||||
int64 vv1 = static_cast<int64> (v1.mValue), vv2 = static_cast<uint64> (v2.mValue);
|
||||
|
||||
if (ov1 < ov2)
|
||||
{
|
||||
while (ov1 < (ov2 - 1))
|
||||
{
|
||||
vv1 /= 10;
|
||||
++ov1;
|
||||
}
|
||||
if (roundUp)
|
||||
vv1 += 9;
|
||||
vv1 /= 10;
|
||||
++ov1;
|
||||
}
|
||||
if (v1.mIsNegative)
|
||||
vv1 = -vv1;
|
||||
|
||||
if (ov2 < ov1)
|
||||
{
|
||||
while (ov2 < (ov1 - 1))
|
||||
{
|
||||
vv2 /= 10;
|
||||
++ov2;
|
||||
}
|
||||
if (roundUp)
|
||||
vv2 += 9;
|
||||
vv2 /= 10;
|
||||
++ov2;
|
||||
}
|
||||
if (v2.mIsNegative)
|
||||
vv2 = -vv2;
|
||||
|
||||
int64 fv = vv1 + vv2;
|
||||
if ((fv >= -10) && (fv <= 10))
|
||||
return STAmount(v1.getFName(), v1.mCurrency, v1.mIssuer);
|
||||
else if (fv >= 0)
|
||||
{
|
||||
uint64 v = static_cast<uint64>(fv);
|
||||
canonicalizeRound(false, v, ov1, roundUp);
|
||||
return STAmount(v1.getFName(), v1.mCurrency, v1.mIssuer, v, ov1, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint64 v = static_cast<uint64>(-fv);
|
||||
canonicalizeRound(false, v, ov1, !roundUp);
|
||||
return STAmount(v1.getFName(), v1.mCurrency, v1.mIssuer, v, ov1, true);
|
||||
}
|
||||
if (ov1 < ov2)
|
||||
{
|
||||
while (ov1 < (ov2 - 1))
|
||||
{
|
||||
vv1 /= 10;
|
||||
++ov1;
|
||||
}
|
||||
|
||||
if (roundUp)
|
||||
vv1 += 9;
|
||||
|
||||
vv1 /= 10;
|
||||
++ov1;
|
||||
}
|
||||
|
||||
if (ov2 < ov1)
|
||||
{
|
||||
while (ov2 < (ov1 - 1))
|
||||
{
|
||||
vv2 /= 10;
|
||||
++ov2;
|
||||
}
|
||||
|
||||
if (roundUp)
|
||||
vv2 += 9;
|
||||
|
||||
vv2 /= 10;
|
||||
++ov2;
|
||||
}
|
||||
|
||||
int64 fv = vv1 + vv2;
|
||||
|
||||
if ((fv >= -10) && (fv <= 10))
|
||||
return STAmount (v1.getFName (), v1.mCurrency, v1.mIssuer);
|
||||
else if (fv >= 0)
|
||||
{
|
||||
uint64 v = static_cast<uint64> (fv);
|
||||
canonicalizeRound (false, v, ov1, roundUp);
|
||||
return STAmount (v1.getFName (), v1.mCurrency, v1.mIssuer, v, ov1, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint64 v = static_cast<uint64> (-fv);
|
||||
canonicalizeRound (false, v, ov1, !roundUp);
|
||||
return STAmount (v1.getFName (), v1.mCurrency, v1.mIssuer, v, ov1, true);
|
||||
}
|
||||
}
|
||||
|
||||
STAmount STAmount::subRound(const STAmount& v1, const STAmount& v2, bool roundUp)
|
||||
STAmount STAmount::subRound (const STAmount& v1, const STAmount& v2, bool roundUp)
|
||||
{
|
||||
v1.throwComparable(v2);
|
||||
v1.throwComparable (v2);
|
||||
|
||||
if (v2.mValue == 0)
|
||||
return v1;
|
||||
if (v2.mValue == 0)
|
||||
return v1;
|
||||
|
||||
if (v1.mValue == 0)
|
||||
return STAmount(v1.getFName(), v1.mCurrency, v1.mIssuer, v2.mValue, v2.mOffset, !v2.mIsNegative);
|
||||
if (v1.mValue == 0)
|
||||
return STAmount (v1.getFName (), v1.mCurrency, v1.mIssuer, v2.mValue, v2.mOffset, !v2.mIsNegative);
|
||||
|
||||
if (v1.mIsNative)
|
||||
return STAmount(v1.getFName(), v1.getSNValue() - v2.getSNValue());
|
||||
if (v1.mIsNative)
|
||||
return STAmount (v1.getFName (), v1.getSNValue () - v2.getSNValue ());
|
||||
|
||||
int ov1 = v1.mOffset, ov2 = v2.mOffset;
|
||||
int64 vv1 = static_cast<int64>(v1.mValue), vv2 = static_cast<uint64>(v2.mValue);
|
||||
int ov1 = v1.mOffset, ov2 = v2.mOffset;
|
||||
int64 vv1 = static_cast<int64> (v1.mValue), vv2 = static_cast<uint64> (v2.mValue);
|
||||
|
||||
if (v1.mIsNegative)
|
||||
vv1 = -vv1;
|
||||
if (v1.mIsNegative)
|
||||
vv1 = -vv1;
|
||||
|
||||
if (!v2.mIsNegative)
|
||||
vv2 = -vv2;
|
||||
if (!v2.mIsNegative)
|
||||
vv2 = -vv2;
|
||||
|
||||
if (ov1 < ov2)
|
||||
{
|
||||
while (ov1 < (ov2 - 1))
|
||||
{
|
||||
vv1 /= 10;
|
||||
++ov1;
|
||||
}
|
||||
if (roundUp)
|
||||
vv1 += 9;
|
||||
vv1 /= 10;
|
||||
++ov1;
|
||||
}
|
||||
if (ov1 < ov2)
|
||||
{
|
||||
while (ov1 < (ov2 - 1))
|
||||
{
|
||||
vv1 /= 10;
|
||||
++ov1;
|
||||
}
|
||||
|
||||
if (ov2 < ov1)
|
||||
{
|
||||
while (ov2 < (ov1 - 1))
|
||||
{
|
||||
vv2 /= 10;
|
||||
++ov2;
|
||||
}
|
||||
if (roundUp)
|
||||
vv2 += 9;
|
||||
vv2 /= 10;
|
||||
++ov2;
|
||||
}
|
||||
if (roundUp)
|
||||
vv1 += 9;
|
||||
|
||||
int64 fv = vv1 + vv2;
|
||||
if ((fv >= -10) && (fv <= 10))
|
||||
return STAmount(v1.getFName(), v1.mCurrency, v1.mIssuer);
|
||||
else if (fv >= 0)
|
||||
{
|
||||
uint64 v = static_cast<uint64>(fv);
|
||||
canonicalizeRound(false, v, ov1, roundUp);
|
||||
return STAmount(v1.getFName(), v1.mCurrency, v1.mIssuer, v, ov1, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint64 v = static_cast<uint64>(-fv);
|
||||
canonicalizeRound(false, v, ov1, !roundUp);
|
||||
return STAmount(v1.getFName(), v1.mCurrency, v1.mIssuer, v, ov1, true);
|
||||
}
|
||||
vv1 /= 10;
|
||||
++ov1;
|
||||
}
|
||||
|
||||
if (ov2 < ov1)
|
||||
{
|
||||
while (ov2 < (ov1 - 1))
|
||||
{
|
||||
vv2 /= 10;
|
||||
++ov2;
|
||||
}
|
||||
|
||||
if (roundUp)
|
||||
vv2 += 9;
|
||||
|
||||
vv2 /= 10;
|
||||
++ov2;
|
||||
}
|
||||
|
||||
int64 fv = vv1 + vv2;
|
||||
|
||||
if ((fv >= -10) && (fv <= 10))
|
||||
return STAmount (v1.getFName (), v1.mCurrency, v1.mIssuer);
|
||||
else if (fv >= 0)
|
||||
{
|
||||
uint64 v = static_cast<uint64> (fv);
|
||||
canonicalizeRound (false, v, ov1, roundUp);
|
||||
return STAmount (v1.getFName (), v1.mCurrency, v1.mIssuer, v, ov1, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint64 v = static_cast<uint64> (-fv);
|
||||
canonicalizeRound (false, v, ov1, !roundUp);
|
||||
return STAmount (v1.getFName (), v1.mCurrency, v1.mIssuer, v, ov1, true);
|
||||
}
|
||||
}
|
||||
|
||||
STAmount STAmount::mulRound(const STAmount& v1, const STAmount& v2,
|
||||
const uint160& uCurrencyID, const uint160& uIssuerID, bool roundUp)
|
||||
STAmount STAmount::mulRound (const STAmount& v1, const STAmount& v2,
|
||||
const uint160& uCurrencyID, const uint160& uIssuerID, bool roundUp)
|
||||
{
|
||||
if (v1.isZero() || v2.isZero())
|
||||
return STAmount(uCurrencyID, uIssuerID);
|
||||
if (v1.isZero () || v2.isZero ())
|
||||
return STAmount (uCurrencyID, uIssuerID);
|
||||
|
||||
if (v1.mIsNative && v2.mIsNative && uCurrencyID.isZero())
|
||||
{
|
||||
uint64 minV = (v1.getSNValue() < v2.getSNValue()) ? v1.getSNValue() : v2.getSNValue();
|
||||
uint64 maxV = (v1.getSNValue() < v2.getSNValue()) ? v2.getSNValue() : v1.getSNValue();
|
||||
if (minV > 3000000000ull) // sqrt(cMaxNative)
|
||||
throw std::runtime_error("Native value overflow");
|
||||
if (((maxV >> 32) * minV) > 2095475792ull) // cMaxNative / 2^32
|
||||
throw std::runtime_error("Native value overflow");
|
||||
return STAmount(v1.getFName(), minV * maxV);
|
||||
}
|
||||
if (v1.mIsNative && v2.mIsNative && uCurrencyID.isZero ())
|
||||
{
|
||||
uint64 minV = (v1.getSNValue () < v2.getSNValue ()) ? v1.getSNValue () : v2.getSNValue ();
|
||||
uint64 maxV = (v1.getSNValue () < v2.getSNValue ()) ? v2.getSNValue () : v1.getSNValue ();
|
||||
|
||||
uint64 value1 = v1.mValue, value2 = v2.mValue;
|
||||
int offset1 = v1.mOffset, offset2 = v2.mOffset;
|
||||
if (minV > 3000000000ull) // sqrt(cMaxNative)
|
||||
throw std::runtime_error ("Native value overflow");
|
||||
|
||||
if (v1.mIsNative)
|
||||
{
|
||||
while (value1 < STAmount::cMinValue)
|
||||
{
|
||||
value1 *= 10;
|
||||
--offset1;
|
||||
}
|
||||
}
|
||||
if (((maxV >> 32) * minV) > 2095475792ull) // cMaxNative / 2^32
|
||||
throw std::runtime_error ("Native value overflow");
|
||||
|
||||
if (v2.mIsNative)
|
||||
{
|
||||
while (value2 < STAmount::cMinValue)
|
||||
{
|
||||
value2 *= 10;
|
||||
--offset2;
|
||||
}
|
||||
}
|
||||
return STAmount (v1.getFName (), minV * maxV);
|
||||
}
|
||||
|
||||
bool resultNegative = v1.mIsNegative != v2.mIsNegative;
|
||||
// Compute (numerator * denominator) / 10^14 with rounding
|
||||
// 10^16 <= result <= 10^18
|
||||
CBigNum v;
|
||||
if ((BN_add_word64(&v, value1) != 1) || (BN_mul_word64(&v, value2) != 1))
|
||||
throw std::runtime_error("internal bn error");
|
||||
uint64 value1 = v1.mValue, value2 = v2.mValue;
|
||||
int offset1 = v1.mOffset, offset2 = v2.mOffset;
|
||||
|
||||
if (resultNegative != roundUp) // rounding down is automatic when we divide
|
||||
BN_add_word64(&v, tenTo14m1);
|
||||
if (v1.mIsNative)
|
||||
{
|
||||
while (value1 < STAmount::cMinValue)
|
||||
{
|
||||
value1 *= 10;
|
||||
--offset1;
|
||||
}
|
||||
}
|
||||
|
||||
if (BN_div_word64(&v, tenTo14) == ((uint64) -1))
|
||||
throw std::runtime_error("internal bn error");
|
||||
if (v2.mIsNative)
|
||||
{
|
||||
while (value2 < STAmount::cMinValue)
|
||||
{
|
||||
value2 *= 10;
|
||||
--offset2;
|
||||
}
|
||||
}
|
||||
|
||||
// 10^16 <= product <= 10^18
|
||||
assert(BN_num_bytes(&v) <= 64);
|
||||
bool resultNegative = v1.mIsNegative != v2.mIsNegative;
|
||||
// Compute (numerator * denominator) / 10^14 with rounding
|
||||
// 10^16 <= result <= 10^18
|
||||
CBigNum v;
|
||||
|
||||
uint64 amount = v.getuint64();
|
||||
int offset = offset1 + offset2 + 14;
|
||||
canonicalizeRound(uCurrencyID.isZero(), amount, offset, resultNegative != roundUp);
|
||||
return STAmount(uCurrencyID, uIssuerID, amount, offset, resultNegative);
|
||||
if ((BN_add_word64 (&v, value1) != 1) || (BN_mul_word64 (&v, value2) != 1))
|
||||
throw std::runtime_error ("internal bn error");
|
||||
|
||||
if (resultNegative != roundUp) // rounding down is automatic when we divide
|
||||
BN_add_word64 (&v, tenTo14m1);
|
||||
|
||||
if (BN_div_word64 (&v, tenTo14) == ((uint64) - 1))
|
||||
throw std::runtime_error ("internal bn error");
|
||||
|
||||
// 10^16 <= product <= 10^18
|
||||
assert (BN_num_bytes (&v) <= 64);
|
||||
|
||||
uint64 amount = v.getuint64 ();
|
||||
int offset = offset1 + offset2 + 14;
|
||||
canonicalizeRound (uCurrencyID.isZero (), amount, offset, resultNegative != roundUp);
|
||||
return STAmount (uCurrencyID, uIssuerID, amount, offset, resultNegative);
|
||||
}
|
||||
|
||||
STAmount STAmount::divRound(const STAmount& num, const STAmount& den,
|
||||
const uint160& uCurrencyID, const uint160& uIssuerID, bool roundUp)
|
||||
STAmount STAmount::divRound (const STAmount& num, const STAmount& den,
|
||||
const uint160& uCurrencyID, const uint160& uIssuerID, bool roundUp)
|
||||
{
|
||||
if (den.isZero())
|
||||
throw std::runtime_error("division by zero");
|
||||
if (num.isZero())
|
||||
return STAmount(uCurrencyID, uIssuerID);
|
||||
if (den.isZero ())
|
||||
throw std::runtime_error ("division by zero");
|
||||
|
||||
uint64 numVal = num.mValue, denVal = den.mValue;
|
||||
int numOffset = num.mOffset, denOffset = den.mOffset;
|
||||
if (num.isZero ())
|
||||
return STAmount (uCurrencyID, uIssuerID);
|
||||
|
||||
if (num.mIsNative)
|
||||
while (numVal < STAmount::cMinValue)
|
||||
{ // Need to bring into range
|
||||
numVal *= 10;
|
||||
--numOffset;
|
||||
}
|
||||
uint64 numVal = num.mValue, denVal = den.mValue;
|
||||
int numOffset = num.mOffset, denOffset = den.mOffset;
|
||||
|
||||
if (den.mIsNative)
|
||||
while (denVal < STAmount::cMinValue)
|
||||
{
|
||||
denVal *= 10;
|
||||
--denOffset;
|
||||
}
|
||||
if (num.mIsNative)
|
||||
while (numVal < STAmount::cMinValue)
|
||||
{
|
||||
// Need to bring into range
|
||||
numVal *= 10;
|
||||
--numOffset;
|
||||
}
|
||||
|
||||
bool resultNegative = num.mIsNegative != den.mIsNegative;
|
||||
// Compute (numerator * 10^17) / denominator
|
||||
CBigNum v;
|
||||
if ((BN_add_word64(&v, numVal) != 1) || (BN_mul_word64(&v, tenTo17) != 1))
|
||||
throw std::runtime_error("internal bn error");
|
||||
if (den.mIsNative)
|
||||
while (denVal < STAmount::cMinValue)
|
||||
{
|
||||
denVal *= 10;
|
||||
--denOffset;
|
||||
}
|
||||
|
||||
if (resultNegative != roundUp) // Rounding down is automatic when we divide
|
||||
BN_add_word64(&v, denVal - 1);
|
||||
bool resultNegative = num.mIsNegative != den.mIsNegative;
|
||||
// Compute (numerator * 10^17) / denominator
|
||||
CBigNum v;
|
||||
|
||||
if (BN_div_word64(&v, denVal) == ((uint64) -1))
|
||||
throw std::runtime_error("internal bn error");
|
||||
if ((BN_add_word64 (&v, numVal) != 1) || (BN_mul_word64 (&v, tenTo17) != 1))
|
||||
throw std::runtime_error ("internal bn error");
|
||||
|
||||
// 10^16 <= quotient <= 10^18
|
||||
assert(BN_num_bytes(&v) <= 64);
|
||||
if (resultNegative != roundUp) // Rounding down is automatic when we divide
|
||||
BN_add_word64 (&v, denVal - 1);
|
||||
|
||||
uint64 amount = v.getuint64();
|
||||
int offset = numOffset - denOffset - 17;
|
||||
canonicalizeRound(uCurrencyID.isZero(), amount, offset, resultNegative != roundUp);
|
||||
return STAmount(uCurrencyID, uIssuerID, amount, offset, resultNegative);
|
||||
if (BN_div_word64 (&v, denVal) == ((uint64) - 1))
|
||||
throw std::runtime_error ("internal bn error");
|
||||
|
||||
// 10^16 <= quotient <= 10^18
|
||||
assert (BN_num_bytes (&v) <= 64);
|
||||
|
||||
uint64 amount = v.getuint64 ();
|
||||
int offset = numOffset - denOffset - 17;
|
||||
canonicalizeRound (uCurrencyID.isZero (), amount, offset, resultNegative != roundUp);
|
||||
return STAmount (uCurrencyID, uIssuerID, amount, offset, resultNegative);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(amountRound)
|
||||
BOOST_AUTO_TEST_SUITE (amountRound)
|
||||
|
||||
BOOST_AUTO_TEST_CASE( amountRound_test )
|
||||
BOOST_AUTO_TEST_CASE ( amountRound_test )
|
||||
{
|
||||
uint64 value = 25000000000000000ull;
|
||||
int offset = -14;
|
||||
canonicalizeRound(false, value, offset, true);
|
||||
uint64 value = 25000000000000000ull;
|
||||
int offset = -14;
|
||||
canonicalizeRound (false, value, offset, true);
|
||||
|
||||
STAmount one(CURRENCY_ONE, ACCOUNT_ONE, 1);
|
||||
STAmount two(CURRENCY_ONE, ACCOUNT_ONE, 2);
|
||||
STAmount three(CURRENCY_ONE, ACCOUNT_ONE, 3);
|
||||
STAmount one (CURRENCY_ONE, ACCOUNT_ONE, 1);
|
||||
STAmount two (CURRENCY_ONE, ACCOUNT_ONE, 2);
|
||||
STAmount three (CURRENCY_ONE, ACCOUNT_ONE, 3);
|
||||
|
||||
STAmount oneThird1 = STAmount::divRound(one, three, CURRENCY_ONE, ACCOUNT_ONE, false);
|
||||
STAmount oneThird2 = STAmount::divide(one, three, CURRENCY_ONE, ACCOUNT_ONE);
|
||||
STAmount oneThird3 = STAmount::divRound(one, three, CURRENCY_ONE, ACCOUNT_ONE, true);
|
||||
WriteLog (lsINFO, STAmount) << oneThird1;
|
||||
WriteLog (lsINFO, STAmount) << oneThird2;
|
||||
WriteLog (lsINFO, STAmount) << oneThird3;
|
||||
STAmount oneThird1 = STAmount::divRound (one, three, CURRENCY_ONE, ACCOUNT_ONE, false);
|
||||
STAmount oneThird2 = STAmount::divide (one, three, CURRENCY_ONE, ACCOUNT_ONE);
|
||||
STAmount oneThird3 = STAmount::divRound (one, three, CURRENCY_ONE, ACCOUNT_ONE, true);
|
||||
WriteLog (lsINFO, STAmount) << oneThird1;
|
||||
WriteLog (lsINFO, STAmount) << oneThird2;
|
||||
WriteLog (lsINFO, STAmount) << oneThird3;
|
||||
|
||||
STAmount twoThird1 = STAmount::divRound(two, three, CURRENCY_ONE, ACCOUNT_ONE, false);
|
||||
STAmount twoThird2 = STAmount::divide(two, three, CURRENCY_ONE, ACCOUNT_ONE);
|
||||
STAmount twoThird3 = STAmount::divRound(two, three, CURRENCY_ONE, ACCOUNT_ONE, true);
|
||||
WriteLog (lsINFO, STAmount) << twoThird1;
|
||||
WriteLog (lsINFO, STAmount) << twoThird2;
|
||||
WriteLog (lsINFO, STAmount) << twoThird3;
|
||||
STAmount twoThird1 = STAmount::divRound (two, three, CURRENCY_ONE, ACCOUNT_ONE, false);
|
||||
STAmount twoThird2 = STAmount::divide (two, three, CURRENCY_ONE, ACCOUNT_ONE);
|
||||
STAmount twoThird3 = STAmount::divRound (two, three, CURRENCY_ONE, ACCOUNT_ONE, true);
|
||||
WriteLog (lsINFO, STAmount) << twoThird1;
|
||||
WriteLog (lsINFO, STAmount) << twoThird2;
|
||||
WriteLog (lsINFO, STAmount) << twoThird3;
|
||||
|
||||
STAmount oneA = STAmount::mulRound(oneThird1, three, CURRENCY_ONE, ACCOUNT_ONE, false);
|
||||
STAmount oneB = STAmount::multiply(oneThird2, three, CURRENCY_ONE, ACCOUNT_ONE);
|
||||
STAmount oneC = STAmount::mulRound(oneThird3, three, CURRENCY_ONE, ACCOUNT_ONE, true);
|
||||
WriteLog (lsINFO, STAmount) << oneA;
|
||||
WriteLog (lsINFO, STAmount) << oneB;
|
||||
WriteLog (lsINFO, STAmount) << oneC;
|
||||
STAmount oneA = STAmount::mulRound (oneThird1, three, CURRENCY_ONE, ACCOUNT_ONE, false);
|
||||
STAmount oneB = STAmount::multiply (oneThird2, three, CURRENCY_ONE, ACCOUNT_ONE);
|
||||
STAmount oneC = STAmount::mulRound (oneThird3, three, CURRENCY_ONE, ACCOUNT_ONE, true);
|
||||
WriteLog (lsINFO, STAmount) << oneA;
|
||||
WriteLog (lsINFO, STAmount) << oneB;
|
||||
WriteLog (lsINFO, STAmount) << oneC;
|
||||
|
||||
STAmount fourThirdsA = STAmount::addRound(twoThird2, twoThird2, false);
|
||||
STAmount fourThirdsB = twoThird2 + twoThird2;
|
||||
STAmount fourThirdsC = STAmount::addRound(twoThird2, twoThird2, true);
|
||||
WriteLog (lsINFO, STAmount) << fourThirdsA;
|
||||
WriteLog (lsINFO, STAmount) << fourThirdsB;
|
||||
WriteLog (lsINFO, STAmount) << fourThirdsC;
|
||||
STAmount fourThirdsA = STAmount::addRound (twoThird2, twoThird2, false);
|
||||
STAmount fourThirdsB = twoThird2 + twoThird2;
|
||||
STAmount fourThirdsC = STAmount::addRound (twoThird2, twoThird2, true);
|
||||
WriteLog (lsINFO, STAmount) << fourThirdsA;
|
||||
WriteLog (lsINFO, STAmount) << fourThirdsB;
|
||||
WriteLog (lsINFO, STAmount) << fourThirdsC;
|
||||
|
||||
STAmount dripTest1 = STAmount::mulRound(twoThird2, two, uint160(), uint160(), false);
|
||||
STAmount dripTest2 = STAmount::multiply(twoThird2, two, uint160(), uint160());
|
||||
STAmount dripTest3 = STAmount::mulRound(twoThird2, two, uint160(), uint160(), true);
|
||||
WriteLog (lsINFO, STAmount) << dripTest1;
|
||||
WriteLog (lsINFO, STAmount) << dripTest2;
|
||||
WriteLog (lsINFO, STAmount) << dripTest3;
|
||||
STAmount dripTest1 = STAmount::mulRound (twoThird2, two, uint160 (), uint160 (), false);
|
||||
STAmount dripTest2 = STAmount::multiply (twoThird2, two, uint160 (), uint160 ());
|
||||
STAmount dripTest3 = STAmount::mulRound (twoThird2, two, uint160 (), uint160 (), true);
|
||||
WriteLog (lsINFO, STAmount) << dripTest1;
|
||||
WriteLog (lsINFO, STAmount) << dripTest2;
|
||||
WriteLog (lsINFO, STAmount) << dripTest3;
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
BOOST_AUTO_TEST_SUITE_END ()
|
||||
|
||||
// vim:ts=4
|
||||
|
||||
@@ -10,169 +10,169 @@
|
||||
This is done to reduce the average size of the messages.
|
||||
*/
|
||||
|
||||
// types (common)
|
||||
TYPE(Int16, UINT16, 1)
|
||||
TYPE(Int32, UINT32, 2)
|
||||
TYPE(Int64, UINT64, 3)
|
||||
TYPE(Hash128, HASH128, 4)
|
||||
TYPE(Hash256, HASH256, 5)
|
||||
TYPE(Amount, AMOUNT, 6)
|
||||
TYPE(VariableLength, VL, 7)
|
||||
TYPE(Account, ACCOUNT, 8)
|
||||
// 9-13 are reserved
|
||||
TYPE(Object, OBJECT, 14)
|
||||
TYPE(Array, ARRAY, 15)
|
||||
// types (common)
|
||||
TYPE (Int16, UINT16, 1)
|
||||
TYPE (Int32, UINT32, 2)
|
||||
TYPE (Int64, UINT64, 3)
|
||||
TYPE (Hash128, HASH128, 4)
|
||||
TYPE (Hash256, HASH256, 5)
|
||||
TYPE (Amount, AMOUNT, 6)
|
||||
TYPE (VariableLength, VL, 7)
|
||||
TYPE (Account, ACCOUNT, 8)
|
||||
// 9-13 are reserved
|
||||
TYPE (Object, OBJECT, 14)
|
||||
TYPE (Array, ARRAY, 15)
|
||||
|
||||
// types (uncommon)
|
||||
TYPE(Int8, UINT8, 16)
|
||||
TYPE(Hash160, HASH160, 17)
|
||||
TYPE(PathSet, PATHSET, 18)
|
||||
TYPE(Vector256, VECTOR256, 19)
|
||||
// types (uncommon)
|
||||
TYPE (Int8, UINT8, 16)
|
||||
TYPE (Hash160, HASH160, 17)
|
||||
TYPE (PathSet, PATHSET, 18)
|
||||
TYPE (Vector256, VECTOR256, 19)
|
||||
|
||||
|
||||
|
||||
// 8-bit integers
|
||||
FIELD(CloseResolution, UINT8, 1)
|
||||
FIELD(TemplateEntryType, UINT8, 2)
|
||||
FIELD(TransactionResult, UINT8, 3)
|
||||
// 8-bit integers
|
||||
FIELD (CloseResolution, UINT8, 1)
|
||||
FIELD (TemplateEntryType, UINT8, 2)
|
||||
FIELD (TransactionResult, UINT8, 3)
|
||||
|
||||
// 16-bit integers
|
||||
FIELD(LedgerEntryType, UINT16, 1)
|
||||
FIELD(TransactionType, UINT16, 2)
|
||||
// 16-bit integers
|
||||
FIELD (LedgerEntryType, UINT16, 1)
|
||||
FIELD (TransactionType, UINT16, 2)
|
||||
|
||||
// 32-bit integers (common)
|
||||
FIELD(Flags, UINT32, 2)
|
||||
FIELD(SourceTag, UINT32, 3)
|
||||
FIELD(Sequence, UINT32, 4)
|
||||
FIELD(PreviousTxnLgrSeq, UINT32, 5)
|
||||
FIELD(LedgerSequence, UINT32, 6)
|
||||
FIELD(CloseTime, UINT32, 7)
|
||||
FIELD(ParentCloseTime, UINT32, 8)
|
||||
FIELD(SigningTime, UINT32, 9)
|
||||
FIELD(Expiration, UINT32, 10)
|
||||
FIELD(TransferRate, UINT32, 11)
|
||||
FIELD(WalletSize, UINT32, 12)
|
||||
FIELD(OwnerCount, UINT32, 13)
|
||||
FIELD(DestinationTag, UINT32, 14)
|
||||
// 32-bit integers (common)
|
||||
FIELD (Flags, UINT32, 2)
|
||||
FIELD (SourceTag, UINT32, 3)
|
||||
FIELD (Sequence, UINT32, 4)
|
||||
FIELD (PreviousTxnLgrSeq, UINT32, 5)
|
||||
FIELD (LedgerSequence, UINT32, 6)
|
||||
FIELD (CloseTime, UINT32, 7)
|
||||
FIELD (ParentCloseTime, UINT32, 8)
|
||||
FIELD (SigningTime, UINT32, 9)
|
||||
FIELD (Expiration, UINT32, 10)
|
||||
FIELD (TransferRate, UINT32, 11)
|
||||
FIELD (WalletSize, UINT32, 12)
|
||||
FIELD (OwnerCount, UINT32, 13)
|
||||
FIELD (DestinationTag, UINT32, 14)
|
||||
|
||||
// 32-bit integers (uncommon)
|
||||
FIELD(HighQualityIn, UINT32, 16)
|
||||
FIELD(HighQualityOut, UINT32, 17)
|
||||
FIELD(LowQualityIn, UINT32, 18)
|
||||
FIELD(LowQualityOut, UINT32, 19)
|
||||
FIELD(QualityIn, UINT32, 20)
|
||||
FIELD(QualityOut, UINT32, 21)
|
||||
FIELD(StampEscrow, UINT32, 22)
|
||||
FIELD(BondAmount, UINT32, 23)
|
||||
FIELD(LoadFee, UINT32, 24)
|
||||
FIELD(OfferSequence, UINT32, 25)
|
||||
FIELD(FirstLedgerSequence, UINT32, 26) // Deprecated: do not use
|
||||
FIELD(LastLedgerSequence, UINT32, 27)
|
||||
FIELD(TransactionIndex, UINT32, 28)
|
||||
FIELD(OperationLimit, UINT32, 29)
|
||||
FIELD(ReferenceFeeUnits, UINT32, 30)
|
||||
FIELD(ReserveBase, UINT32, 31)
|
||||
FIELD(ReserveIncrement, UINT32, 32)
|
||||
// 32-bit integers (uncommon)
|
||||
FIELD (HighQualityIn, UINT32, 16)
|
||||
FIELD (HighQualityOut, UINT32, 17)
|
||||
FIELD (LowQualityIn, UINT32, 18)
|
||||
FIELD (LowQualityOut, UINT32, 19)
|
||||
FIELD (QualityIn, UINT32, 20)
|
||||
FIELD (QualityOut, UINT32, 21)
|
||||
FIELD (StampEscrow, UINT32, 22)
|
||||
FIELD (BondAmount, UINT32, 23)
|
||||
FIELD (LoadFee, UINT32, 24)
|
||||
FIELD (OfferSequence, UINT32, 25)
|
||||
FIELD (FirstLedgerSequence, UINT32, 26) // Deprecated: do not use
|
||||
FIELD (LastLedgerSequence, UINT32, 27)
|
||||
FIELD (TransactionIndex, UINT32, 28)
|
||||
FIELD (OperationLimit, UINT32, 29)
|
||||
FIELD (ReferenceFeeUnits, UINT32, 30)
|
||||
FIELD (ReserveBase, UINT32, 31)
|
||||
FIELD (ReserveIncrement, UINT32, 32)
|
||||
|
||||
// 64-bit integers
|
||||
FIELD(IndexNext, UINT64, 1)
|
||||
FIELD(IndexPrevious, UINT64, 2)
|
||||
FIELD(BookNode, UINT64, 3)
|
||||
FIELD(OwnerNode, UINT64, 4)
|
||||
FIELD(BaseFee, UINT64, 5)
|
||||
FIELD(ExchangeRate, UINT64, 6)
|
||||
FIELD(LowNode, UINT64, 7)
|
||||
FIELD(HighNode, UINT64, 8)
|
||||
// 64-bit integers
|
||||
FIELD (IndexNext, UINT64, 1)
|
||||
FIELD (IndexPrevious, UINT64, 2)
|
||||
FIELD (BookNode, UINT64, 3)
|
||||
FIELD (OwnerNode, UINT64, 4)
|
||||
FIELD (BaseFee, UINT64, 5)
|
||||
FIELD (ExchangeRate, UINT64, 6)
|
||||
FIELD (LowNode, UINT64, 7)
|
||||
FIELD (HighNode, UINT64, 8)
|
||||
|
||||
|
||||
// 128-bit
|
||||
FIELD(EmailHash, HASH128, 1)
|
||||
// 128-bit
|
||||
FIELD (EmailHash, HASH128, 1)
|
||||
|
||||
// 256-bit (common)
|
||||
FIELD(LedgerHash, HASH256, 1)
|
||||
FIELD(ParentHash, HASH256, 2)
|
||||
FIELD(TransactionHash, HASH256, 3)
|
||||
FIELD(AccountHash, HASH256, 4)
|
||||
FIELD(PreviousTxnID, HASH256, 5)
|
||||
FIELD(LedgerIndex, HASH256, 6)
|
||||
FIELD(WalletLocator, HASH256, 7)
|
||||
FIELD(RootIndex, HASH256, 8)
|
||||
// 256-bit (common)
|
||||
FIELD (LedgerHash, HASH256, 1)
|
||||
FIELD (ParentHash, HASH256, 2)
|
||||
FIELD (TransactionHash, HASH256, 3)
|
||||
FIELD (AccountHash, HASH256, 4)
|
||||
FIELD (PreviousTxnID, HASH256, 5)
|
||||
FIELD (LedgerIndex, HASH256, 6)
|
||||
FIELD (WalletLocator, HASH256, 7)
|
||||
FIELD (RootIndex, HASH256, 8)
|
||||
|
||||
// 256-bit (uncommon)
|
||||
FIELD(BookDirectory, HASH256, 16)
|
||||
FIELD(InvoiceID, HASH256, 17)
|
||||
FIELD(Nickname, HASH256, 18)
|
||||
FIELD(Feature, HASH256, 19)
|
||||
// 256-bit (uncommon)
|
||||
FIELD (BookDirectory, HASH256, 16)
|
||||
FIELD (InvoiceID, HASH256, 17)
|
||||
FIELD (Nickname, HASH256, 18)
|
||||
FIELD (Feature, HASH256, 19)
|
||||
|
||||
// 160-bit (common)
|
||||
FIELD(TakerPaysCurrency, HASH160, 1)
|
||||
FIELD(TakerPaysIssuer, HASH160, 2)
|
||||
FIELD(TakerGetsCurrency, HASH160, 3)
|
||||
FIELD(TakerGetsIssuer, HASH160, 4)
|
||||
// 160-bit (common)
|
||||
FIELD (TakerPaysCurrency, HASH160, 1)
|
||||
FIELD (TakerPaysIssuer, HASH160, 2)
|
||||
FIELD (TakerGetsCurrency, HASH160, 3)
|
||||
FIELD (TakerGetsIssuer, HASH160, 4)
|
||||
|
||||
// currency amount (common)
|
||||
FIELD(Amount, AMOUNT, 1)
|
||||
FIELD(Balance, AMOUNT, 2)
|
||||
FIELD(LimitAmount, AMOUNT, 3)
|
||||
FIELD(TakerPays, AMOUNT, 4)
|
||||
FIELD(TakerGets, AMOUNT, 5)
|
||||
FIELD(LowLimit, AMOUNT, 6)
|
||||
FIELD(HighLimit, AMOUNT, 7)
|
||||
FIELD(Fee, AMOUNT, 8)
|
||||
FIELD(SendMax, AMOUNT, 9)
|
||||
// currency amount (common)
|
||||
FIELD (Amount, AMOUNT, 1)
|
||||
FIELD (Balance, AMOUNT, 2)
|
||||
FIELD (LimitAmount, AMOUNT, 3)
|
||||
FIELD (TakerPays, AMOUNT, 4)
|
||||
FIELD (TakerGets, AMOUNT, 5)
|
||||
FIELD (LowLimit, AMOUNT, 6)
|
||||
FIELD (HighLimit, AMOUNT, 7)
|
||||
FIELD (Fee, AMOUNT, 8)
|
||||
FIELD (SendMax, AMOUNT, 9)
|
||||
|
||||
// currency amount (uncommon)
|
||||
FIELD(MinimumOffer, AMOUNT, 16)
|
||||
FIELD(RippleEscrow, AMOUNT, 17)
|
||||
// currency amount (uncommon)
|
||||
FIELD (MinimumOffer, AMOUNT, 16)
|
||||
FIELD (RippleEscrow, AMOUNT, 17)
|
||||
|
||||
// variable length
|
||||
FIELD(PublicKey, VL, 1)
|
||||
FIELD(MessageKey, VL, 2)
|
||||
FIELD(SigningPubKey, VL, 3)
|
||||
FIELD(TxnSignature, VL, 4)
|
||||
FIELD(Generator, VL, 5)
|
||||
FIELD(Signature, VL, 6)
|
||||
FIELD(Domain, VL, 7)
|
||||
FIELD(FundCode, VL, 8)
|
||||
FIELD(RemoveCode, VL, 9)
|
||||
FIELD(ExpireCode, VL, 10)
|
||||
FIELD(CreateCode, VL, 11)
|
||||
// variable length
|
||||
FIELD (PublicKey, VL, 1)
|
||||
FIELD (MessageKey, VL, 2)
|
||||
FIELD (SigningPubKey, VL, 3)
|
||||
FIELD (TxnSignature, VL, 4)
|
||||
FIELD (Generator, VL, 5)
|
||||
FIELD (Signature, VL, 6)
|
||||
FIELD (Domain, VL, 7)
|
||||
FIELD (FundCode, VL, 8)
|
||||
FIELD (RemoveCode, VL, 9)
|
||||
FIELD (ExpireCode, VL, 10)
|
||||
FIELD (CreateCode, VL, 11)
|
||||
|
||||
// account
|
||||
FIELD(Account, ACCOUNT, 1)
|
||||
FIELD(Owner, ACCOUNT, 2)
|
||||
FIELD(Destination, ACCOUNT, 3)
|
||||
FIELD(Issuer, ACCOUNT, 4)
|
||||
FIELD(Target, ACCOUNT, 7)
|
||||
FIELD(RegularKey, ACCOUNT, 8)
|
||||
// account
|
||||
FIELD (Account, ACCOUNT, 1)
|
||||
FIELD (Owner, ACCOUNT, 2)
|
||||
FIELD (Destination, ACCOUNT, 3)
|
||||
FIELD (Issuer, ACCOUNT, 4)
|
||||
FIELD (Target, ACCOUNT, 7)
|
||||
FIELD (RegularKey, ACCOUNT, 8)
|
||||
|
||||
// path set
|
||||
FIELD(Paths, PATHSET, 1)
|
||||
// path set
|
||||
FIELD (Paths, PATHSET, 1)
|
||||
|
||||
// vector of 256-bit
|
||||
FIELD(Indexes, VECTOR256, 1)
|
||||
FIELD(Hashes, VECTOR256, 2)
|
||||
FIELD(Features, VECTOR256, 3)
|
||||
// vector of 256-bit
|
||||
FIELD (Indexes, VECTOR256, 1)
|
||||
FIELD (Hashes, VECTOR256, 2)
|
||||
FIELD (Features, VECTOR256, 3)
|
||||
|
||||
// inner object
|
||||
// OBJECT/1 is reserved for end of object
|
||||
FIELD(TransactionMetaData, OBJECT, 2)
|
||||
FIELD(CreatedNode, OBJECT, 3)
|
||||
FIELD(DeletedNode, OBJECT, 4)
|
||||
FIELD(ModifiedNode, OBJECT, 5)
|
||||
FIELD(PreviousFields, OBJECT, 6)
|
||||
FIELD(FinalFields, OBJECT, 7)
|
||||
FIELD(NewFields, OBJECT, 8)
|
||||
FIELD(TemplateEntry, OBJECT, 9)
|
||||
// inner object
|
||||
// OBJECT/1 is reserved for end of object
|
||||
FIELD (TransactionMetaData, OBJECT, 2)
|
||||
FIELD (CreatedNode, OBJECT, 3)
|
||||
FIELD (DeletedNode, OBJECT, 4)
|
||||
FIELD (ModifiedNode, OBJECT, 5)
|
||||
FIELD (PreviousFields, OBJECT, 6)
|
||||
FIELD (FinalFields, OBJECT, 7)
|
||||
FIELD (NewFields, OBJECT, 8)
|
||||
FIELD (TemplateEntry, OBJECT, 9)
|
||||
|
||||
// array of objects
|
||||
// ARRAY/1 is reserved for end of array
|
||||
FIELD(SigningAccounts, ARRAY, 2)
|
||||
FIELD(TxnSignatures, ARRAY, 3)
|
||||
FIELD(Signatures, ARRAY, 4)
|
||||
FIELD(Template, ARRAY, 5)
|
||||
FIELD(Necessary, ARRAY, 6)
|
||||
FIELD(Sufficient, ARRAY, 7)
|
||||
FIELD(AffectedNodes, ARRAY, 8)
|
||||
// array of objects
|
||||
// ARRAY/1 is reserved for end of array
|
||||
FIELD (SigningAccounts, ARRAY, 2)
|
||||
FIELD (TxnSignatures, ARRAY, 3)
|
||||
FIELD (Signatures, ARRAY, 4)
|
||||
FIELD (Template, ARRAY, 5)
|
||||
FIELD (Necessary, ARRAY, 6)
|
||||
FIELD (Sufficient, ARRAY, 7)
|
||||
FIELD (AffectedNodes, ARRAY, 8)
|
||||
|
||||
// vim:ts=4
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,256 +1,488 @@
|
||||
#ifndef RIPPLE_SERIALIZEDOBJECT_H
|
||||
#define RIPPLE_SERIALIZEDOBJECT_H
|
||||
|
||||
DEFINE_INSTANCE(SerializedObject);
|
||||
DEFINE_INSTANCE(SerializedArray);
|
||||
DEFINE_INSTANCE (SerializedObject);
|
||||
DEFINE_INSTANCE (SerializedArray);
|
||||
|
||||
class STObject : public SerializedType, private IS_INSTANCE(SerializedObject)
|
||||
class STObject : public SerializedType, private IS_INSTANCE (SerializedObject)
|
||||
{
|
||||
public:
|
||||
STObject() : mType(NULL) { ; }
|
||||
STObject () : mType (NULL)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
explicit STObject(SField::ref name) : SerializedType(name), mType(NULL) { ; }
|
||||
explicit STObject (SField::ref name) : SerializedType (name), mType (NULL)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
STObject (const SOTemplate& type, SField::ref name) : SerializedType(name)
|
||||
{ set(type); }
|
||||
STObject (const SOTemplate & type, SField::ref name) : SerializedType (name)
|
||||
{
|
||||
set (type);
|
||||
}
|
||||
|
||||
STObject (const SOTemplate& type, SerializerIterator& sit, SField::ref name) : SerializedType(name)
|
||||
{ set(sit); setType(type); }
|
||||
STObject (const SOTemplate & type, SerializerIterator & sit, SField::ref name) : SerializedType (name)
|
||||
{
|
||||
set (sit);
|
||||
setType (type);
|
||||
}
|
||||
|
||||
UPTR_T<STObject> oClone() const { return UPTR_T<STObject>(new STObject(*this)); }
|
||||
UPTR_T<STObject> oClone () const
|
||||
{
|
||||
return UPTR_T<STObject> (new STObject (*this));
|
||||
}
|
||||
|
||||
static UPTR_T<STObject> parseJson(const Json::Value& value, SField::ref name = sfGeneric, int depth = 0);
|
||||
static UPTR_T<STObject> parseJson (const Json::Value & value, SField::ref name = sfGeneric, int depth = 0);
|
||||
|
||||
virtual ~STObject() { ; }
|
||||
virtual ~STObject ()
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
static UPTR_T<SerializedType> deserialize(SerializerIterator& sit, SField::ref name);
|
||||
static UPTR_T<SerializedType> deserialize (SerializerIterator & sit, SField::ref name);
|
||||
|
||||
bool setType(const SOTemplate& type);
|
||||
bool isValidForType();
|
||||
bool isFieldAllowed(SField::ref);
|
||||
bool isFree() const { return mType == NULL; }
|
||||
bool setType (const SOTemplate & type);
|
||||
bool isValidForType ();
|
||||
bool isFieldAllowed (SField::ref);
|
||||
bool isFree () const
|
||||
{
|
||||
return mType == NULL;
|
||||
}
|
||||
|
||||
void set(const SOTemplate&);
|
||||
bool set(SerializerIterator& u, int depth = 0);
|
||||
void set (const SOTemplate&);
|
||||
bool set (SerializerIterator & u, int depth = 0);
|
||||
|
||||
virtual SerializedTypeID getSType() const { return STI_OBJECT; }
|
||||
virtual bool isEquivalent(const SerializedType& t) const;
|
||||
virtual bool isDefault() const { return mData.empty(); }
|
||||
virtual SerializedTypeID getSType () const
|
||||
{
|
||||
return STI_OBJECT;
|
||||
}
|
||||
virtual bool isEquivalent (const SerializedType & t) const;
|
||||
virtual bool isDefault () const
|
||||
{
|
||||
return mData.empty ();
|
||||
}
|
||||
|
||||
virtual void add(Serializer& s) const { add(s, true); } // just inner elements
|
||||
virtual void add (Serializer & s) const
|
||||
{
|
||||
add (s, true); // just inner elements
|
||||
}
|
||||
|
||||
void add(Serializer& s, bool withSignature) const;
|
||||
void add (Serializer & s, bool withSignature) const;
|
||||
|
||||
// VFALCO NOTE does this return an expensive copy of an object with a dynamic buffer?
|
||||
// VFALCO TODO Remove this function and fix the few callers.
|
||||
Serializer getSerializer() const { Serializer s; add(s); return s; }
|
||||
Serializer getSerializer () const
|
||||
{
|
||||
Serializer s;
|
||||
add (s);
|
||||
return s;
|
||||
}
|
||||
|
||||
std::string getFullText() const;
|
||||
std::string getText() const;
|
||||
virtual Json::Value getJson(int options) const;
|
||||
std::string getFullText () const;
|
||||
std::string getText () const;
|
||||
virtual Json::Value getJson (int options) const;
|
||||
|
||||
int addObject(const SerializedType& t) { mData.push_back(t.clone().release()); return mData.size() - 1; }
|
||||
int giveObject(UPTR_T<SerializedType> t) { mData.push_back(t.release()); return mData.size() - 1; }
|
||||
int giveObject(SerializedType* t) { mData.push_back(t); return mData.size() - 1; }
|
||||
const boost::ptr_vector<SerializedType>& peekData() const { return mData; }
|
||||
boost::ptr_vector<SerializedType>& peekData() { return mData; }
|
||||
SerializedType& front() { return mData.front(); }
|
||||
const SerializedType& front() const { return mData.front(); }
|
||||
SerializedType& back() { return mData.back(); }
|
||||
const SerializedType& back() const { return mData.back(); }
|
||||
int addObject (const SerializedType & t)
|
||||
{
|
||||
mData.push_back (t.clone ().release ());
|
||||
return mData.size () - 1;
|
||||
}
|
||||
int giveObject (UPTR_T<SerializedType> t)
|
||||
{
|
||||
mData.push_back (t.release ());
|
||||
return mData.size () - 1;
|
||||
}
|
||||
int giveObject (SerializedType * t)
|
||||
{
|
||||
mData.push_back (t);
|
||||
return mData.size () - 1;
|
||||
}
|
||||
const boost::ptr_vector<SerializedType>& peekData () const
|
||||
{
|
||||
return mData;
|
||||
}
|
||||
boost::ptr_vector<SerializedType>& peekData ()
|
||||
{
|
||||
return mData;
|
||||
}
|
||||
SerializedType& front ()
|
||||
{
|
||||
return mData.front ();
|
||||
}
|
||||
const SerializedType& front () const
|
||||
{
|
||||
return mData.front ();
|
||||
}
|
||||
SerializedType& back ()
|
||||
{
|
||||
return mData.back ();
|
||||
}
|
||||
const SerializedType& back () const
|
||||
{
|
||||
return mData.back ();
|
||||
}
|
||||
|
||||
int getCount() const { return mData.size(); }
|
||||
int getCount () const
|
||||
{
|
||||
return mData.size ();
|
||||
}
|
||||
|
||||
bool setFlag(uint32);
|
||||
bool clearFlag(uint32);
|
||||
uint32 getFlags() const;
|
||||
bool setFlag (uint32);
|
||||
bool clearFlag (uint32);
|
||||
uint32 getFlags () const;
|
||||
|
||||
uint256 getHash(uint32 prefix) const;
|
||||
uint256 getSigningHash(uint32 prefix) const;
|
||||
uint256 getHash (uint32 prefix) const;
|
||||
uint256 getSigningHash (uint32 prefix) const;
|
||||
|
||||
const SerializedType& peekAtIndex(int offset) const { return mData[offset]; }
|
||||
SerializedType& getIndex(int offset) { return mData[offset]; }
|
||||
const SerializedType* peekAtPIndex(int offset) const { return &(mData[offset]); }
|
||||
SerializedType* getPIndex(int offset) { return &(mData[offset]); }
|
||||
const SerializedType& peekAtIndex (int offset) const
|
||||
{
|
||||
return mData[offset];
|
||||
}
|
||||
SerializedType& getIndex (int offset)
|
||||
{
|
||||
return mData[offset];
|
||||
}
|
||||
const SerializedType* peekAtPIndex (int offset) const
|
||||
{
|
||||
return & (mData[offset]);
|
||||
}
|
||||
SerializedType* getPIndex (int offset)
|
||||
{
|
||||
return & (mData[offset]);
|
||||
}
|
||||
|
||||
int getFieldIndex(SField::ref field) const;
|
||||
SField::ref getFieldSType(int index) const;
|
||||
int getFieldIndex (SField::ref field) const;
|
||||
SField::ref getFieldSType (int index) const;
|
||||
|
||||
const SerializedType& peekAtField(SField::ref field) const;
|
||||
SerializedType& getField(SField::ref field);
|
||||
const SerializedType* peekAtPField(SField::ref field) const;
|
||||
SerializedType* getPField(SField::ref field, bool createOkay = false);
|
||||
const SerializedType& peekAtField (SField::ref field) const;
|
||||
SerializedType& getField (SField::ref field);
|
||||
const SerializedType* peekAtPField (SField::ref field) const;
|
||||
SerializedType* getPField (SField::ref field, bool createOkay = false);
|
||||
|
||||
// these throw if the field type doesn't match, or return default values if the
|
||||
// field is optional but not present
|
||||
std::string getFieldString(SField::ref field) const;
|
||||
unsigned char getFieldU8(SField::ref field) const;
|
||||
uint16 getFieldU16(SField::ref field) const;
|
||||
uint32 getFieldU32(SField::ref field) const;
|
||||
uint64 getFieldU64(SField::ref field) const;
|
||||
uint128 getFieldH128(SField::ref field) const;
|
||||
uint160 getFieldH160(SField::ref field) const;
|
||||
uint256 getFieldH256(SField::ref field) const;
|
||||
RippleAddress getFieldAccount(SField::ref field) const;
|
||||
uint160 getFieldAccount160(SField::ref field) const;
|
||||
Blob getFieldVL(SField::ref field) const;
|
||||
const STAmount& getFieldAmount(SField::ref field) const;
|
||||
const STPathSet& getFieldPathSet(SField::ref field) const;
|
||||
const STVector256& getFieldV256(SField::ref field) const;
|
||||
// these throw if the field type doesn't match, or return default values if the
|
||||
// field is optional but not present
|
||||
std::string getFieldString (SField::ref field) const;
|
||||
unsigned char getFieldU8 (SField::ref field) const;
|
||||
uint16 getFieldU16 (SField::ref field) const;
|
||||
uint32 getFieldU32 (SField::ref field) const;
|
||||
uint64 getFieldU64 (SField::ref field) const;
|
||||
uint128 getFieldH128 (SField::ref field) const;
|
||||
uint160 getFieldH160 (SField::ref field) const;
|
||||
uint256 getFieldH256 (SField::ref field) const;
|
||||
RippleAddress getFieldAccount (SField::ref field) const;
|
||||
uint160 getFieldAccount160 (SField::ref field) const;
|
||||
Blob getFieldVL (SField::ref field) const;
|
||||
const STAmount& getFieldAmount (SField::ref field) const;
|
||||
const STPathSet& getFieldPathSet (SField::ref field) const;
|
||||
const STVector256& getFieldV256 (SField::ref field) const;
|
||||
|
||||
void setFieldU8(SField::ref field, unsigned char);
|
||||
void setFieldU16(SField::ref field, uint16);
|
||||
void setFieldU32(SField::ref field, uint32);
|
||||
void setFieldU64(SField::ref field, uint64);
|
||||
void setFieldH128(SField::ref field, const uint128&);
|
||||
void setFieldH160(SField::ref field, const uint160&);
|
||||
void setFieldH256(SField::ref field, uint256 const& );
|
||||
void setFieldVL(SField::ref field, Blob const&);
|
||||
void setFieldAccount(SField::ref field, const uint160&);
|
||||
void setFieldAccount(SField::ref field, const RippleAddress& addr)
|
||||
{ setFieldAccount(field, addr.getAccountID()); }
|
||||
void setFieldAmount(SField::ref field, const STAmount&);
|
||||
void setFieldPathSet(SField::ref field, const STPathSet&);
|
||||
void setFieldV256(SField::ref field, const STVector256& v);
|
||||
void setFieldU8 (SField::ref field, unsigned char);
|
||||
void setFieldU16 (SField::ref field, uint16);
|
||||
void setFieldU32 (SField::ref field, uint32);
|
||||
void setFieldU64 (SField::ref field, uint64);
|
||||
void setFieldH128 (SField::ref field, const uint128&);
|
||||
void setFieldH160 (SField::ref field, const uint160&);
|
||||
void setFieldH256 (SField::ref field, uint256 const& );
|
||||
void setFieldVL (SField::ref field, Blob const&);
|
||||
void setFieldAccount (SField::ref field, const uint160&);
|
||||
void setFieldAccount (SField::ref field, const RippleAddress & addr)
|
||||
{
|
||||
setFieldAccount (field, addr.getAccountID ());
|
||||
}
|
||||
void setFieldAmount (SField::ref field, const STAmount&);
|
||||
void setFieldPathSet (SField::ref field, const STPathSet&);
|
||||
void setFieldV256 (SField::ref field, const STVector256 & v);
|
||||
|
||||
STObject& peekFieldObject(SField::ref field);
|
||||
STObject& peekFieldObject (SField::ref field);
|
||||
|
||||
bool isFieldPresent(SField::ref field) const;
|
||||
SerializedType* makeFieldPresent(SField::ref field);
|
||||
void makeFieldAbsent(SField::ref field);
|
||||
bool delField(SField::ref field);
|
||||
void delField(int index);
|
||||
bool isFieldPresent (SField::ref field) const;
|
||||
SerializedType* makeFieldPresent (SField::ref field);
|
||||
void makeFieldAbsent (SField::ref field);
|
||||
bool delField (SField::ref field);
|
||||
void delField (int index);
|
||||
|
||||
static UPTR_T <SerializedType> makeDefaultObject(SerializedTypeID id, SField::ref name);
|
||||
static UPTR_T <SerializedType> makeDefaultObject (SerializedTypeID id, SField::ref name);
|
||||
|
||||
// VFALCO TODO remove the 'depth' parameter
|
||||
static UPTR_T<SerializedType> makeDeserializedObject (
|
||||
SerializedTypeID id,
|
||||
SField::ref name,
|
||||
SerializerIterator &,
|
||||
SerializerIterator&,
|
||||
int depth);
|
||||
|
||||
static UPTR_T<SerializedType> makeNonPresentObject (SField::ref name)
|
||||
{
|
||||
return makeDefaultObject(STI_NOTPRESENT, name);
|
||||
static UPTR_T<SerializedType> makeNonPresentObject (SField::ref name)
|
||||
{
|
||||
return makeDefaultObject (STI_NOTPRESENT, name);
|
||||
}
|
||||
|
||||
static UPTR_T<SerializedType> makeDefaultObject (SField::ref name)
|
||||
{
|
||||
return makeDefaultObject(name.fieldType, name);
|
||||
{
|
||||
return makeDefaultObject (name.fieldType, name);
|
||||
}
|
||||
|
||||
// field iterator stuff
|
||||
typedef boost::ptr_vector<SerializedType>::iterator iterator;
|
||||
typedef boost::ptr_vector<SerializedType>::const_iterator const_iterator;
|
||||
iterator begin() { return mData.begin(); }
|
||||
iterator end() { return mData.end(); }
|
||||
const_iterator begin() const { return mData.begin(); }
|
||||
const_iterator end() const { return mData.end(); }
|
||||
bool empty() const { return mData.empty(); }
|
||||
// field iterator stuff
|
||||
typedef boost::ptr_vector<SerializedType>::iterator iterator;
|
||||
typedef boost::ptr_vector<SerializedType>::const_iterator const_iterator;
|
||||
iterator begin ()
|
||||
{
|
||||
return mData.begin ();
|
||||
}
|
||||
iterator end ()
|
||||
{
|
||||
return mData.end ();
|
||||
}
|
||||
const_iterator begin () const
|
||||
{
|
||||
return mData.begin ();
|
||||
}
|
||||
const_iterator end () const
|
||||
{
|
||||
return mData.end ();
|
||||
}
|
||||
bool empty () const
|
||||
{
|
||||
return mData.empty ();
|
||||
}
|
||||
|
||||
bool hasMatchingEntry(const SerializedType&);
|
||||
bool hasMatchingEntry (const SerializedType&);
|
||||
|
||||
bool operator==(const STObject& o) const;
|
||||
bool operator!=(const STObject& o) const { return ! (*this == o); }
|
||||
bool operator== (const STObject & o) const;
|
||||
bool operator!= (const STObject & o) const
|
||||
{
|
||||
return ! (*this == o);
|
||||
}
|
||||
|
||||
private:
|
||||
boost::ptr_vector<SerializedType> mData;
|
||||
const SOTemplate* mType;
|
||||
boost::ptr_vector<SerializedType> mData;
|
||||
const SOTemplate* mType;
|
||||
|
||||
STObject* duplicate() const { return new STObject(*this); }
|
||||
STObject(SField::ref name, boost::ptr_vector<SerializedType>& data) : SerializedType(name), mType(NULL)
|
||||
{ mData.swap(data); }
|
||||
STObject* duplicate () const
|
||||
{
|
||||
return new STObject (*this);
|
||||
}
|
||||
STObject (SField::ref name, boost::ptr_vector<SerializedType>& data) : SerializedType (name), mType (NULL)
|
||||
{
|
||||
mData.swap (data);
|
||||
}
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
inline STObject::iterator range_begin(STObject& x) { return x.begin(); }
|
||||
inline STObject::iterator range_end(STObject &x) { return x.end(); }
|
||||
inline STObject::iterator range_begin (STObject& x)
|
||||
{
|
||||
return x.begin ();
|
||||
}
|
||||
inline STObject::iterator range_end (STObject& x)
|
||||
{
|
||||
return x.end ();
|
||||
}
|
||||
namespace boost
|
||||
{
|
||||
template<> struct range_mutable_iterator<STObject> { typedef STObject::iterator type; };
|
||||
template<> struct range_const_iterator<STObject> { typedef STObject::const_iterator type; };
|
||||
template<> struct range_mutable_iterator<STObject>
|
||||
{
|
||||
typedef STObject::iterator type;
|
||||
};
|
||||
template<> struct range_const_iterator<STObject>
|
||||
{
|
||||
typedef STObject::const_iterator type;
|
||||
};
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
class STArray : public SerializedType, private IS_INSTANCE(SerializedArray)
|
||||
class STArray : public SerializedType, private IS_INSTANCE (SerializedArray)
|
||||
{
|
||||
public:
|
||||
typedef boost::ptr_vector<STObject> vector;
|
||||
typedef boost::ptr_vector<STObject>::iterator iterator;
|
||||
typedef boost::ptr_vector<STObject>::const_iterator const_iterator;
|
||||
typedef boost::ptr_vector<STObject>::reverse_iterator reverse_iterator;
|
||||
typedef boost::ptr_vector<STObject>::const_reverse_iterator const_reverse_iterator;
|
||||
typedef boost::ptr_vector<STObject>::size_type size_type;
|
||||
typedef boost::ptr_vector<STObject> vector;
|
||||
typedef boost::ptr_vector<STObject>::iterator iterator;
|
||||
typedef boost::ptr_vector<STObject>::const_iterator const_iterator;
|
||||
typedef boost::ptr_vector<STObject>::reverse_iterator reverse_iterator;
|
||||
typedef boost::ptr_vector<STObject>::const_reverse_iterator const_reverse_iterator;
|
||||
typedef boost::ptr_vector<STObject>::size_type size_type;
|
||||
|
||||
public:
|
||||
STArray () { ; }
|
||||
explicit STArray(int n) { value.reserve(n); }
|
||||
explicit STArray(SField::ref f) : SerializedType(f) { ; }
|
||||
STArray(SField::ref f, int n) : SerializedType(f) { value.reserve(n); }
|
||||
STArray(SField::ref f, const vector& v) : SerializedType(f), value(v) { ; }
|
||||
explicit STArray(vector& v) : value(v) { ; }
|
||||
STArray ()
|
||||
{
|
||||
;
|
||||
}
|
||||
explicit STArray (int n)
|
||||
{
|
||||
value.reserve (n);
|
||||
}
|
||||
explicit STArray (SField::ref f) : SerializedType (f)
|
||||
{
|
||||
;
|
||||
}
|
||||
STArray (SField::ref f, int n) : SerializedType (f)
|
||||
{
|
||||
value.reserve (n);
|
||||
}
|
||||
STArray (SField::ref f, const vector & v) : SerializedType (f), value (v)
|
||||
{
|
||||
;
|
||||
}
|
||||
explicit STArray (vector & v) : value (v)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
static UPTR_T<SerializedType> deserialize(SerializerIterator& sit, SField::ref name)
|
||||
{ return UPTR_T<SerializedType>(construct(sit, name)); }
|
||||
static UPTR_T<SerializedType> deserialize (SerializerIterator & sit, SField::ref name)
|
||||
{
|
||||
return UPTR_T<SerializedType> (construct (sit, name));
|
||||
}
|
||||
|
||||
const vector& getValue() const { return value; }
|
||||
vector& getValue() { return value; }
|
||||
const vector& getValue () const
|
||||
{
|
||||
return value;
|
||||
}
|
||||
vector& getValue ()
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
// VFALCO NOTE as long as we're married to boost why not use boost::iterator_facade?
|
||||
//
|
||||
// vector-like functions
|
||||
void push_back(const STObject& object) { value.push_back(object.oClone().release()); }
|
||||
STObject& operator[](int j) { return value[j]; }
|
||||
const STObject& operator[](int j) const { return value[j]; }
|
||||
iterator begin() { return value.begin(); }
|
||||
const_iterator begin() const { return value.begin(); }
|
||||
iterator end() { return value.end(); }
|
||||
const_iterator end() const { return value.end(); }
|
||||
size_type size() const { return value.size(); }
|
||||
reverse_iterator rbegin() { return value.rbegin(); }
|
||||
const_reverse_iterator rbegin() const { return value.rbegin(); }
|
||||
reverse_iterator rend() { return value.rend(); }
|
||||
const_reverse_iterator rend() const { return value.rend(); }
|
||||
iterator erase(iterator pos) { return value.erase(pos); }
|
||||
STObject& front() { return value.front(); }
|
||||
const STObject& front() const { return value.front(); }
|
||||
STObject& back() { return value.back(); }
|
||||
const STObject& back() const { return value.back(); }
|
||||
void pop_back() { value.pop_back(); }
|
||||
bool empty() const { return value.empty(); }
|
||||
void clear() { value.clear(); }
|
||||
void swap(STArray& a) { value.swap(a.value); }
|
||||
void push_back (const STObject & object)
|
||||
{
|
||||
value.push_back (object.oClone ().release ());
|
||||
}
|
||||
STObject& operator[] (int j)
|
||||
{
|
||||
return value[j];
|
||||
}
|
||||
const STObject& operator[] (int j) const
|
||||
{
|
||||
return value[j];
|
||||
}
|
||||
iterator begin ()
|
||||
{
|
||||
return value.begin ();
|
||||
}
|
||||
const_iterator begin () const
|
||||
{
|
||||
return value.begin ();
|
||||
}
|
||||
iterator end ()
|
||||
{
|
||||
return value.end ();
|
||||
}
|
||||
const_iterator end () const
|
||||
{
|
||||
return value.end ();
|
||||
}
|
||||
size_type size () const
|
||||
{
|
||||
return value.size ();
|
||||
}
|
||||
reverse_iterator rbegin ()
|
||||
{
|
||||
return value.rbegin ();
|
||||
}
|
||||
const_reverse_iterator rbegin () const
|
||||
{
|
||||
return value.rbegin ();
|
||||
}
|
||||
reverse_iterator rend ()
|
||||
{
|
||||
return value.rend ();
|
||||
}
|
||||
const_reverse_iterator rend () const
|
||||
{
|
||||
return value.rend ();
|
||||
}
|
||||
iterator erase (iterator pos)
|
||||
{
|
||||
return value.erase (pos);
|
||||
}
|
||||
STObject& front ()
|
||||
{
|
||||
return value.front ();
|
||||
}
|
||||
const STObject& front () const
|
||||
{
|
||||
return value.front ();
|
||||
}
|
||||
STObject& back ()
|
||||
{
|
||||
return value.back ();
|
||||
}
|
||||
const STObject& back () const
|
||||
{
|
||||
return value.back ();
|
||||
}
|
||||
void pop_back ()
|
||||
{
|
||||
value.pop_back ();
|
||||
}
|
||||
bool empty () const
|
||||
{
|
||||
return value.empty ();
|
||||
}
|
||||
void clear ()
|
||||
{
|
||||
value.clear ();
|
||||
}
|
||||
void swap (STArray & a)
|
||||
{
|
||||
value.swap (a.value);
|
||||
}
|
||||
|
||||
virtual std::string getFullText() const;
|
||||
virtual std::string getText() const;
|
||||
virtual Json::Value getJson(int) const;
|
||||
virtual void add(Serializer& s) const;
|
||||
virtual std::string getFullText () const;
|
||||
virtual std::string getText () const;
|
||||
virtual Json::Value getJson (int) const;
|
||||
virtual void add (Serializer & s) const;
|
||||
|
||||
void sort(bool (*compare)(const STObject& o1, const STObject& o2));
|
||||
void sort (bool (*compare) (const STObject & o1, const STObject & o2));
|
||||
|
||||
bool operator==(const STArray &s) { return value == s.value; }
|
||||
bool operator!=(const STArray &s) { return value != s.value; }
|
||||
bool operator== (const STArray & s)
|
||||
{
|
||||
return value == s.value;
|
||||
}
|
||||
bool operator!= (const STArray & s)
|
||||
{
|
||||
return value != s.value;
|
||||
}
|
||||
|
||||
virtual SerializedTypeID getSType() const { return STI_ARRAY; }
|
||||
virtual bool isEquivalent(const SerializedType& t) const;
|
||||
virtual bool isDefault() const { return value.empty(); }
|
||||
virtual SerializedTypeID getSType () const
|
||||
{
|
||||
return STI_ARRAY;
|
||||
}
|
||||
virtual bool isEquivalent (const SerializedType & t) const;
|
||||
virtual bool isDefault () const
|
||||
{
|
||||
return value.empty ();
|
||||
}
|
||||
|
||||
private:
|
||||
vector value;
|
||||
vector value;
|
||||
|
||||
STArray* duplicate() const { return new STArray(*this); }
|
||||
static STArray* construct(SerializerIterator&, SField::ref);
|
||||
STArray* duplicate () const
|
||||
{
|
||||
return new STArray (*this);
|
||||
}
|
||||
static STArray* construct (SerializerIterator&, SField::ref);
|
||||
};
|
||||
|
||||
inline STArray::iterator range_begin(STArray& x) { return x.begin(); }
|
||||
inline STArray::iterator range_end(STArray &x) { return x.end(); }
|
||||
inline STArray::iterator range_begin (STArray& x)
|
||||
{
|
||||
return x.begin ();
|
||||
}
|
||||
inline STArray::iterator range_end (STArray& x)
|
||||
{
|
||||
return x.end ();
|
||||
}
|
||||
namespace boost
|
||||
{
|
||||
template<> struct range_mutable_iterator<STArray> { typedef STArray::iterator type; };
|
||||
template<> struct range_const_iterator<STArray> { typedef STArray::const_iterator type; };
|
||||
template<> struct range_mutable_iterator<STArray>
|
||||
{
|
||||
typedef STArray::iterator type;
|
||||
};
|
||||
template<> struct range_const_iterator<STArray>
|
||||
{
|
||||
typedef STArray::const_iterator type;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -8,24 +8,24 @@ void SOTemplate::push_back (SOElement const& r)
|
||||
// Ensure there is the enough space in the index mapping
|
||||
// table for all possible fields.
|
||||
//
|
||||
if (mIndex.empty())
|
||||
if (mIndex.empty ())
|
||||
{
|
||||
// Unmapped indices will be set to -1
|
||||
//
|
||||
mIndex.resize (SField::getNumFields() + 1, -1);
|
||||
mIndex.resize (SField::getNumFields () + 1, -1);
|
||||
}
|
||||
|
||||
// Make sure the field's index is in range
|
||||
//
|
||||
assert (r.e_field.getNum() < mIndex.size());
|
||||
assert (r.e_field.getNum () < mIndex.size ());
|
||||
|
||||
// Make sure that this field hasn't already been assigned
|
||||
//
|
||||
assert(getIndex(r.e_field) == -1);
|
||||
|
||||
assert (getIndex (r.e_field) == -1);
|
||||
|
||||
// Add the field to the index mapping table
|
||||
//
|
||||
mIndex [r.e_field.getNum ()] = mTypes.size();
|
||||
mIndex [r.e_field.getNum ()] = mTypes.size ();
|
||||
|
||||
// Append the new element.
|
||||
//
|
||||
@@ -36,7 +36,7 @@ int SOTemplate::getIndex (SField::ref f) const
|
||||
{
|
||||
// The mapping table should be large enough for any possible field
|
||||
//
|
||||
assert (f.getNum() < mIndex.size());
|
||||
assert (f.getNum () < mIndex.size ());
|
||||
|
||||
return mIndex[f.getNum()];
|
||||
return mIndex[f.getNum ()];
|
||||
}
|
||||
|
||||
@@ -8,10 +8,10 @@
|
||||
// VFALCO NOTE these don't look like bit-flags...
|
||||
enum SOE_Flags
|
||||
{
|
||||
SOE_INVALID = -1,
|
||||
SOE_REQUIRED = 0, // required
|
||||
SOE_OPTIONAL = 1, // optional, may be present with default value
|
||||
SOE_DEFAULT = 2, // optional, if present, must not have default value
|
||||
SOE_INVALID = -1,
|
||||
SOE_REQUIRED = 0, // required
|
||||
SOE_OPTIONAL = 1, // optional, may be present with default value
|
||||
SOE_DEFAULT = 2, // optional, if present, must not have default value
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@@ -21,10 +21,10 @@ enum SOE_Flags
|
||||
class SOElement
|
||||
{
|
||||
public:
|
||||
SField::ref const e_field;
|
||||
SOE_Flags const flags;
|
||||
SField::ref const e_field;
|
||||
SOE_Flags const flags;
|
||||
|
||||
SOElement (SField::ref fieldName, SOE_Flags flags)
|
||||
SOElement (SField::ref fieldName, SOE_Flags flags)
|
||||
: e_field (fieldName)
|
||||
, flags (flags)
|
||||
{
|
||||
@@ -48,12 +48,12 @@ public:
|
||||
|
||||
@see push_back
|
||||
*/
|
||||
SOTemplate ();
|
||||
SOTemplate ();
|
||||
|
||||
// VFALCO NOTE Why do we even bother with the 'private' keyword if
|
||||
// this function is present?
|
||||
//
|
||||
std::vector <SOElement const*> const& peek() const
|
||||
std::vector <SOElement const*> const& peek () const
|
||||
{
|
||||
return mTypes;
|
||||
}
|
||||
@@ -61,15 +61,15 @@ public:
|
||||
/** Add an element to the template.
|
||||
*/
|
||||
void push_back (SOElement const& r);
|
||||
|
||||
|
||||
/** Retrieve the position of a named field.
|
||||
*/
|
||||
int getIndex (SField::ref) const;
|
||||
|
||||
private:
|
||||
std::vector <SOElement const*> mTypes;
|
||||
std::vector <SOElement const*> mTypes;
|
||||
|
||||
std::vector <int> mIndex; // field num -> index
|
||||
std::vector <int> mIndex; // field num -> index
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,265 +1,291 @@
|
||||
|
||||
SETUP_LOG (SerializedType)
|
||||
|
||||
const STAmount saZero(CURRENCY_ONE, ACCOUNT_ONE, 0);
|
||||
const STAmount saOne(CURRENCY_ONE, ACCOUNT_ONE, 1);
|
||||
const STAmount saZero (CURRENCY_ONE, ACCOUNT_ONE, 0);
|
||||
const STAmount saOne (CURRENCY_ONE, ACCOUNT_ONE, 1);
|
||||
|
||||
SerializedType& SerializedType::operator=(const SerializedType& t)
|
||||
SerializedType& SerializedType::operator= (const SerializedType& t)
|
||||
{
|
||||
if ((t.fName != fName) && fName->isUseful() && t.fName->isUseful())
|
||||
{
|
||||
WriteLog ((t.getSType() == STI_AMOUNT) ? lsDEBUG : lsWARNING, SerializedType) // This is common for amounts
|
||||
<< "Caution: " << t.fName->getName() << " not replacing " << fName->getName();
|
||||
}
|
||||
if (!fName->isUseful()) fName = t.fName;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
void STPathSet::printDebug() {
|
||||
for (int i = 0; i < value.size(); i++) {
|
||||
std::cerr << i << ": ";
|
||||
for (int j = 0; j < value[i].mPath.size(); j++) {
|
||||
//STPathElement pe = value[i].mPath[j];
|
||||
RippleAddress nad;
|
||||
nad.setAccountID(value[i].mPath[j].mAccountID);
|
||||
std::cerr << " " << nad.humanAccountID();
|
||||
//std::cerr << " " << pe.mAccountID.GetHex();
|
||||
if ((t.fName != fName) && fName->isUseful () && t.fName->isUseful ())
|
||||
{
|
||||
WriteLog ((t.getSType () == STI_AMOUNT) ? lsDEBUG : lsWARNING, SerializedType) // This is common for amounts
|
||||
<< "Caution: " << t.fName->getName () << " not replacing " << fName->getName ();
|
||||
}
|
||||
std::cerr << std::endl;
|
||||
}
|
||||
|
||||
if (!fName->isUseful ()) fName = t.fName;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
void STPath::printDebug() {
|
||||
std::cerr << "STPath:" << std::endl;
|
||||
for(int i =0; i < mPath.size(); i++) {
|
||||
RippleAddress nad;
|
||||
nad.setAccountID(mPath[i].mAccountID);
|
||||
std::cerr << " " << i << ": " << nad.humanAccountID() << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
std::string SerializedType::getFullText() const
|
||||
void STPathSet::printDebug ()
|
||||
{
|
||||
std::string ret;
|
||||
if (getSType() != STI_NOTPRESENT)
|
||||
{
|
||||
if(fName->hasName())
|
||||
{
|
||||
ret = fName->fieldName;
|
||||
ret += " = ";
|
||||
}
|
||||
ret += getText();
|
||||
}
|
||||
return ret;
|
||||
for (int i = 0; i < value.size (); i++)
|
||||
{
|
||||
std::cerr << i << ": ";
|
||||
|
||||
for (int j = 0; j < value[i].mPath.size (); j++)
|
||||
{
|
||||
//STPathElement pe = value[i].mPath[j];
|
||||
RippleAddress nad;
|
||||
nad.setAccountID (value[i].mPath[j].mAccountID);
|
||||
std::cerr << " " << nad.humanAccountID ();
|
||||
//std::cerr << " " << pe.mAccountID.GetHex();
|
||||
}
|
||||
|
||||
std::cerr << std::endl;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
STUInt8* STUInt8::construct(SerializerIterator& u, SField::ref name)
|
||||
void STPath::printDebug ()
|
||||
{
|
||||
return new STUInt8(name, u.get8());
|
||||
std::cerr << "STPath:" << std::endl;
|
||||
|
||||
for (int i = 0; i < mPath.size (); i++)
|
||||
{
|
||||
RippleAddress nad;
|
||||
nad.setAccountID (mPath[i].mAccountID);
|
||||
std::cerr << " " << i << ": " << nad.humanAccountID () << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
std::string STUInt8::getText() const
|
||||
std::string SerializedType::getFullText () const
|
||||
{
|
||||
if (getFName() == sfTransactionResult)
|
||||
{
|
||||
std::string token, human;
|
||||
if (transResultInfo(static_cast<TER>(value), token, human))
|
||||
return human;
|
||||
}
|
||||
return boost::lexical_cast<std::string>(value);
|
||||
std::string ret;
|
||||
|
||||
if (getSType () != STI_NOTPRESENT)
|
||||
{
|
||||
if (fName->hasName ())
|
||||
{
|
||||
ret = fName->fieldName;
|
||||
ret += " = ";
|
||||
}
|
||||
|
||||
ret += getText ();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
Json::Value STUInt8::getJson(int) const
|
||||
STUInt8* STUInt8::construct (SerializerIterator& u, SField::ref name)
|
||||
{
|
||||
if (getFName() == sfTransactionResult)
|
||||
{
|
||||
std::string token, human;
|
||||
if (transResultInfo(static_cast<TER>(value), token, human))
|
||||
return token;
|
||||
else
|
||||
WriteLog (lsWARNING, SerializedType) << "Unknown result code in metadata: " << value;
|
||||
}
|
||||
return value;
|
||||
return new STUInt8 (name, u.get8 ());
|
||||
}
|
||||
|
||||
bool STUInt8::isEquivalent(const SerializedType& t) const
|
||||
std::string STUInt8::getText () const
|
||||
{
|
||||
const STUInt8* v = dynamic_cast<const STUInt8*>(&t);
|
||||
return v && (value == v->value);
|
||||
if (getFName () == sfTransactionResult)
|
||||
{
|
||||
std::string token, human;
|
||||
|
||||
if (transResultInfo (static_cast<TER> (value), token, human))
|
||||
return human;
|
||||
}
|
||||
|
||||
return boost::lexical_cast<std::string> (value);
|
||||
}
|
||||
|
||||
STUInt16* STUInt16::construct(SerializerIterator& u, SField::ref name)
|
||||
Json::Value STUInt8::getJson (int) const
|
||||
{
|
||||
return new STUInt16(name, u.get16());
|
||||
if (getFName () == sfTransactionResult)
|
||||
{
|
||||
std::string token, human;
|
||||
|
||||
if (transResultInfo (static_cast<TER> (value), token, human))
|
||||
return token;
|
||||
else
|
||||
WriteLog (lsWARNING, SerializedType) << "Unknown result code in metadata: " << value;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
std::string STUInt16::getText() const
|
||||
bool STUInt8::isEquivalent (const SerializedType& t) const
|
||||
{
|
||||
if (getFName() == sfLedgerEntryType)
|
||||
{
|
||||
LedgerEntryFormat *f = LedgerEntryFormat::getLgrFormat(value);
|
||||
if (f != NULL)
|
||||
return f->t_name;
|
||||
}
|
||||
if (getFName() == sfTransactionType)
|
||||
{
|
||||
TransactionFormat *f = TransactionFormat::getTxnFormat(value);
|
||||
if (f != NULL)
|
||||
return f->t_name;
|
||||
}
|
||||
return boost::lexical_cast<std::string>(value);
|
||||
const STUInt8* v = dynamic_cast<const STUInt8*> (&t);
|
||||
return v && (value == v->value);
|
||||
}
|
||||
|
||||
Json::Value STUInt16::getJson(int) const
|
||||
STUInt16* STUInt16::construct (SerializerIterator& u, SField::ref name)
|
||||
{
|
||||
if (getFName() == sfLedgerEntryType)
|
||||
{
|
||||
LedgerEntryFormat *f = LedgerEntryFormat::getLgrFormat(value);
|
||||
if (f != NULL)
|
||||
return f->t_name;
|
||||
}
|
||||
if (getFName() == sfTransactionType)
|
||||
{
|
||||
TransactionFormat *f = TransactionFormat::getTxnFormat(value);
|
||||
if (f != NULL)
|
||||
return f->t_name;
|
||||
}
|
||||
return value;
|
||||
return new STUInt16 (name, u.get16 ());
|
||||
}
|
||||
|
||||
bool STUInt16::isEquivalent(const SerializedType& t) const
|
||||
std::string STUInt16::getText () const
|
||||
{
|
||||
const STUInt16* v = dynamic_cast<const STUInt16*>(&t);
|
||||
return v && (value == v->value);
|
||||
if (getFName () == sfLedgerEntryType)
|
||||
{
|
||||
LedgerEntryFormat* f = LedgerEntryFormat::getLgrFormat (value);
|
||||
|
||||
if (f != NULL)
|
||||
return f->t_name;
|
||||
}
|
||||
|
||||
if (getFName () == sfTransactionType)
|
||||
{
|
||||
TransactionFormat* f = TransactionFormat::getTxnFormat (value);
|
||||
|
||||
if (f != NULL)
|
||||
return f->t_name;
|
||||
}
|
||||
|
||||
return boost::lexical_cast<std::string> (value);
|
||||
}
|
||||
|
||||
STUInt32* STUInt32::construct(SerializerIterator& u, SField::ref name)
|
||||
{
|
||||
return new STUInt32(name, u.get32());
|
||||
}
|
||||
|
||||
std::string STUInt32::getText() const
|
||||
Json::Value STUInt16::getJson (int) const
|
||||
{
|
||||
return boost::lexical_cast<std::string>(value);
|
||||
if (getFName () == sfLedgerEntryType)
|
||||
{
|
||||
LedgerEntryFormat* f = LedgerEntryFormat::getLgrFormat (value);
|
||||
|
||||
if (f != NULL)
|
||||
return f->t_name;
|
||||
}
|
||||
|
||||
if (getFName () == sfTransactionType)
|
||||
{
|
||||
TransactionFormat* f = TransactionFormat::getTxnFormat (value);
|
||||
|
||||
if (f != NULL)
|
||||
return f->t_name;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
Json::Value STUInt32::getJson(int) const
|
||||
bool STUInt16::isEquivalent (const SerializedType& t) const
|
||||
{
|
||||
return value;
|
||||
const STUInt16* v = dynamic_cast<const STUInt16*> (&t);
|
||||
return v && (value == v->value);
|
||||
}
|
||||
|
||||
bool STUInt32::isEquivalent(const SerializedType& t) const
|
||||
STUInt32* STUInt32::construct (SerializerIterator& u, SField::ref name)
|
||||
{
|
||||
const STUInt32* v = dynamic_cast<const STUInt32*>(&t);
|
||||
return v && (value == v->value);
|
||||
return new STUInt32 (name, u.get32 ());
|
||||
}
|
||||
|
||||
STUInt64* STUInt64::construct(SerializerIterator& u, SField::ref name)
|
||||
std::string STUInt32::getText () const
|
||||
{
|
||||
return new STUInt64(name, u.get64());
|
||||
return boost::lexical_cast<std::string> (value);
|
||||
}
|
||||
|
||||
std::string STUInt64::getText() const
|
||||
Json::Value STUInt32::getJson (int) const
|
||||
{
|
||||
return boost::lexical_cast<std::string>(value);
|
||||
return value;
|
||||
}
|
||||
|
||||
Json::Value STUInt64::getJson(int) const
|
||||
bool STUInt32::isEquivalent (const SerializedType& t) const
|
||||
{
|
||||
return strHex(value);
|
||||
const STUInt32* v = dynamic_cast<const STUInt32*> (&t);
|
||||
return v && (value == v->value);
|
||||
}
|
||||
|
||||
bool STUInt64::isEquivalent(const SerializedType& t) const
|
||||
STUInt64* STUInt64::construct (SerializerIterator& u, SField::ref name)
|
||||
{
|
||||
const STUInt64* v = dynamic_cast<const STUInt64*>(&t);
|
||||
return v && (value == v->value);
|
||||
return new STUInt64 (name, u.get64 ());
|
||||
}
|
||||
|
||||
STHash128* STHash128::construct(SerializerIterator& u, SField::ref name)
|
||||
std::string STUInt64::getText () const
|
||||
{
|
||||
return new STHash128(name, u.get128());
|
||||
return boost::lexical_cast<std::string> (value);
|
||||
}
|
||||
|
||||
std::string STHash128::getText() const
|
||||
Json::Value STUInt64::getJson (int) const
|
||||
{
|
||||
return value.GetHex();
|
||||
return strHex (value);
|
||||
}
|
||||
|
||||
bool STHash128::isEquivalent(const SerializedType& t) const
|
||||
bool STUInt64::isEquivalent (const SerializedType& t) const
|
||||
{
|
||||
const STHash128* v = dynamic_cast<const STHash128*>(&t);
|
||||
return v && (value == v->value);
|
||||
const STUInt64* v = dynamic_cast<const STUInt64*> (&t);
|
||||
return v && (value == v->value);
|
||||
}
|
||||
|
||||
STHash160* STHash160::construct(SerializerIterator& u, SField::ref name)
|
||||
STHash128* STHash128::construct (SerializerIterator& u, SField::ref name)
|
||||
{
|
||||
return new STHash160(name, u.get160());
|
||||
return new STHash128 (name, u.get128 ());
|
||||
}
|
||||
|
||||
std::string STHash160::getText() const
|
||||
std::string STHash128::getText () const
|
||||
{
|
||||
return value.GetHex();
|
||||
return value.GetHex ();
|
||||
}
|
||||
|
||||
bool STHash160::isEquivalent(const SerializedType& t) const
|
||||
bool STHash128::isEquivalent (const SerializedType& t) const
|
||||
{
|
||||
const STHash160* v = dynamic_cast<const STHash160*>(&t);
|
||||
return v && (value == v->value);
|
||||
const STHash128* v = dynamic_cast<const STHash128*> (&t);
|
||||
return v && (value == v->value);
|
||||
}
|
||||
|
||||
STHash256* STHash256::construct(SerializerIterator& u, SField::ref name)
|
||||
STHash160* STHash160::construct (SerializerIterator& u, SField::ref name)
|
||||
{
|
||||
return new STHash256(name, u.get256());
|
||||
return new STHash160 (name, u.get160 ());
|
||||
}
|
||||
|
||||
std::string STHash256::getText() const
|
||||
std::string STHash160::getText () const
|
||||
{
|
||||
return value.GetHex();
|
||||
return value.GetHex ();
|
||||
}
|
||||
|
||||
bool STHash256::isEquivalent(const SerializedType& t) const
|
||||
bool STHash160::isEquivalent (const SerializedType& t) const
|
||||
{
|
||||
const STHash256* v = dynamic_cast<const STHash256*>(&t);
|
||||
return v && (value == v->value);
|
||||
const STHash160* v = dynamic_cast<const STHash160*> (&t);
|
||||
return v && (value == v->value);
|
||||
}
|
||||
|
||||
STVariableLength::STVariableLength(SerializerIterator& st, SField::ref name) : SerializedType(name)
|
||||
STHash256* STHash256::construct (SerializerIterator& u, SField::ref name)
|
||||
{
|
||||
value = st.getVL();
|
||||
return new STHash256 (name, u.get256 ());
|
||||
}
|
||||
|
||||
std::string STVariableLength::getText() const
|
||||
std::string STHash256::getText () const
|
||||
{
|
||||
return strHex(value);
|
||||
return value.GetHex ();
|
||||
}
|
||||
|
||||
STVariableLength* STVariableLength::construct(SerializerIterator& u, SField::ref name)
|
||||
bool STHash256::isEquivalent (const SerializedType& t) const
|
||||
{
|
||||
return new STVariableLength(name, u.getVL());
|
||||
const STHash256* v = dynamic_cast<const STHash256*> (&t);
|
||||
return v && (value == v->value);
|
||||
}
|
||||
|
||||
bool STVariableLength::isEquivalent(const SerializedType& t) const
|
||||
STVariableLength::STVariableLength (SerializerIterator& st, SField::ref name) : SerializedType (name)
|
||||
{
|
||||
const STVariableLength* v = dynamic_cast<const STVariableLength*>(&t);
|
||||
return v && (value == v->value);
|
||||
value = st.getVL ();
|
||||
}
|
||||
|
||||
std::string STAccount::getText() const
|
||||
std::string STVariableLength::getText () const
|
||||
{
|
||||
uint160 u;
|
||||
RippleAddress a;
|
||||
|
||||
if (!getValueH160(u))
|
||||
return STVariableLength::getText();
|
||||
a.setAccountID(u);
|
||||
return a.humanAccountID();
|
||||
return strHex (value);
|
||||
}
|
||||
|
||||
STAccount* STAccount::construct(SerializerIterator& u, SField::ref name)
|
||||
STVariableLength* STVariableLength::construct (SerializerIterator& u, SField::ref name)
|
||||
{
|
||||
return new STAccount(name, u.getVL());
|
||||
return new STVariableLength (name, u.getVL ());
|
||||
}
|
||||
|
||||
bool STVariableLength::isEquivalent (const SerializedType& t) const
|
||||
{
|
||||
const STVariableLength* v = dynamic_cast<const STVariableLength*> (&t);
|
||||
return v && (value == v->value);
|
||||
}
|
||||
|
||||
std::string STAccount::getText () const
|
||||
{
|
||||
uint160 u;
|
||||
RippleAddress a;
|
||||
|
||||
if (!getValueH160 (u))
|
||||
return STVariableLength::getText ();
|
||||
|
||||
a.setAccountID (u);
|
||||
return a.humanAccountID ();
|
||||
}
|
||||
|
||||
STAccount* STAccount::construct (SerializerIterator& u, SField::ref name)
|
||||
{
|
||||
return new STAccount (name, u.getVL ());
|
||||
}
|
||||
|
||||
//
|
||||
@@ -267,287 +293,298 @@ STAccount* STAccount::construct(SerializerIterator& u, SField::ref name)
|
||||
//
|
||||
|
||||
// Return a new object from a SerializerIterator.
|
||||
STVector256* STVector256::construct(SerializerIterator& u, SField::ref name)
|
||||
STVector256* STVector256::construct (SerializerIterator& u, SField::ref name)
|
||||
{
|
||||
Blob data = u.getVL();
|
||||
Blob ::iterator begin = data.begin();
|
||||
Blob data = u.getVL ();
|
||||
Blob ::iterator begin = data.begin ();
|
||||
|
||||
UPTR_T<STVector256> vec(new STVector256(name));
|
||||
UPTR_T<STVector256> vec (new STVector256 (name));
|
||||
|
||||
int count = data.size() / (256 / 8);
|
||||
vec->mValue.reserve(count);
|
||||
int count = data.size () / (256 / 8);
|
||||
vec->mValue.reserve (count);
|
||||
|
||||
unsigned int uStart = 0;
|
||||
for (unsigned int i = 0; i != count; i++)
|
||||
{
|
||||
unsigned int uEnd = uStart + (256 / 8);
|
||||
unsigned int uStart = 0;
|
||||
|
||||
// This next line could be optimized to construct a default uint256 in the vector and then copy into it
|
||||
vec->mValue.push_back(uint256(Blob (begin + uStart, begin + uEnd)));
|
||||
uStart = uEnd;
|
||||
}
|
||||
for (unsigned int i = 0; i != count; i++)
|
||||
{
|
||||
unsigned int uEnd = uStart + (256 / 8);
|
||||
|
||||
return vec.release();
|
||||
// This next line could be optimized to construct a default uint256 in the vector and then copy into it
|
||||
vec->mValue.push_back (uint256 (Blob (begin + uStart, begin + uEnd)));
|
||||
uStart = uEnd;
|
||||
}
|
||||
|
||||
return vec.release ();
|
||||
}
|
||||
|
||||
void STVector256::add(Serializer& s) const
|
||||
void STVector256::add (Serializer& s) const
|
||||
{
|
||||
s.addVL(mValue.empty() ? NULL : mValue[0].begin(), mValue.size() * (256 / 8));
|
||||
s.addVL (mValue.empty () ? NULL : mValue[0].begin (), mValue.size () * (256 / 8));
|
||||
}
|
||||
|
||||
bool STVector256::isEquivalent(const SerializedType& t) const
|
||||
bool STVector256::isEquivalent (const SerializedType& t) const
|
||||
{
|
||||
const STVector256* v = dynamic_cast<const STVector256*>(&t);
|
||||
return v && (mValue == v->mValue);
|
||||
const STVector256* v = dynamic_cast<const STVector256*> (&t);
|
||||
return v && (mValue == v->mValue);
|
||||
}
|
||||
|
||||
bool STVector256::hasValue(uint256 const& v) const
|
||||
bool STVector256::hasValue (uint256 const& v) const
|
||||
{
|
||||
BOOST_FOREACH(uint256 const& hash, mValue)
|
||||
{
|
||||
if (hash == v)
|
||||
return true;
|
||||
}
|
||||
BOOST_FOREACH (uint256 const & hash, mValue)
|
||||
{
|
||||
if (hash == v)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
//
|
||||
// STAccount
|
||||
//
|
||||
|
||||
STAccount::STAccount(SField::ref n, const uint160& v) : STVariableLength(n)
|
||||
STAccount::STAccount (SField::ref n, const uint160& v) : STVariableLength (n)
|
||||
{
|
||||
peekValue().insert(peekValue().end(), v.begin(), v.end());
|
||||
peekValue ().insert (peekValue ().end (), v.begin (), v.end ());
|
||||
}
|
||||
|
||||
bool STAccount::isValueH160() const
|
||||
bool STAccount::isValueH160 () const
|
||||
{
|
||||
return peekValue().size() == (160 / 8);
|
||||
return peekValue ().size () == (160 / 8);
|
||||
}
|
||||
|
||||
void STAccount::setValueH160(const uint160& v)
|
||||
void STAccount::setValueH160 (const uint160& v)
|
||||
{
|
||||
peekValue().clear();
|
||||
peekValue().insert(peekValue().end(), v.begin(), v.end());
|
||||
assert(peekValue().size() == (160/8));
|
||||
peekValue ().clear ();
|
||||
peekValue ().insert (peekValue ().end (), v.begin (), v.end ());
|
||||
assert (peekValue ().size () == (160 / 8));
|
||||
}
|
||||
|
||||
bool STAccount::getValueH160(uint160& v) const
|
||||
bool STAccount::getValueH160 (uint160& v) const
|
||||
{
|
||||
if (!isValueH160()) return false;
|
||||
memcpy(v.begin(), &(peekValue().front()), (160/8));
|
||||
return true;
|
||||
if (!isValueH160 ()) return false;
|
||||
|
||||
memcpy (v.begin (), & (peekValue ().front ()), (160 / 8));
|
||||
return true;
|
||||
}
|
||||
|
||||
RippleAddress STAccount::getValueNCA() const
|
||||
RippleAddress STAccount::getValueNCA () const
|
||||
{
|
||||
RippleAddress a;
|
||||
uint160 v;
|
||||
if (getValueH160(v))
|
||||
a.setAccountID(v);
|
||||
return a;
|
||||
RippleAddress a;
|
||||
uint160 v;
|
||||
|
||||
if (getValueH160 (v))
|
||||
a.setAccountID (v);
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
void STAccount::setValueNCA(const RippleAddress& nca)
|
||||
void STAccount::setValueNCA (const RippleAddress& nca)
|
||||
{
|
||||
setValueH160(nca.getAccountID());
|
||||
setValueH160 (nca.getAccountID ());
|
||||
}
|
||||
|
||||
STPathSet* STPathSet::construct(SerializerIterator& s, SField::ref name)
|
||||
STPathSet* STPathSet::construct (SerializerIterator& s, SField::ref name)
|
||||
{
|
||||
std::vector<STPath> paths;
|
||||
std::vector<STPathElement> path;
|
||||
std::vector<STPath> paths;
|
||||
std::vector<STPathElement> path;
|
||||
|
||||
do
|
||||
{
|
||||
int iType = s.get8();
|
||||
do
|
||||
{
|
||||
int iType = s.get8 ();
|
||||
|
||||
if (iType == STPathElement::typeEnd || iType == STPathElement::typeBoundary)
|
||||
{
|
||||
if (path.empty())
|
||||
{
|
||||
WriteLog (lsINFO, SerializedType) << "STPathSet: Empty path.";
|
||||
if (iType == STPathElement::typeEnd || iType == STPathElement::typeBoundary)
|
||||
{
|
||||
if (path.empty ())
|
||||
{
|
||||
WriteLog (lsINFO, SerializedType) << "STPathSet: Empty path.";
|
||||
|
||||
throw std::runtime_error("empty path");
|
||||
}
|
||||
throw std::runtime_error ("empty path");
|
||||
}
|
||||
|
||||
paths.push_back(path);
|
||||
path.clear();
|
||||
paths.push_back (path);
|
||||
path.clear ();
|
||||
|
||||
if (iType == STPathElement::typeEnd)
|
||||
{
|
||||
return new STPathSet(name, paths);
|
||||
}
|
||||
}
|
||||
else if (iType & ~STPathElement::typeValidBits)
|
||||
{
|
||||
WriteLog (lsINFO, SerializedType) << "STPathSet: Bad path element: " << iType;
|
||||
if (iType == STPathElement::typeEnd)
|
||||
{
|
||||
return new STPathSet (name, paths);
|
||||
}
|
||||
}
|
||||
else if (iType & ~STPathElement::typeValidBits)
|
||||
{
|
||||
WriteLog (lsINFO, SerializedType) << "STPathSet: Bad path element: " << iType;
|
||||
|
||||
throw std::runtime_error("bad path element");
|
||||
}
|
||||
else
|
||||
{
|
||||
const bool bAccount = !!(iType & STPathElement::typeAccount);
|
||||
const bool bCurrency = !!(iType & STPathElement::typeCurrency);
|
||||
const bool bIssuer = !!(iType & STPathElement::typeIssuer);
|
||||
throw std::runtime_error ("bad path element");
|
||||
}
|
||||
else
|
||||
{
|
||||
const bool bAccount = !! (iType & STPathElement::typeAccount);
|
||||
const bool bCurrency = !! (iType & STPathElement::typeCurrency);
|
||||
const bool bIssuer = !! (iType & STPathElement::typeIssuer);
|
||||
|
||||
uint160 uAccountID;
|
||||
uint160 uCurrency;
|
||||
uint160 uIssuerID;
|
||||
uint160 uAccountID;
|
||||
uint160 uCurrency;
|
||||
uint160 uIssuerID;
|
||||
|
||||
if (bAccount)
|
||||
uAccountID = s.get160();
|
||||
if (bAccount)
|
||||
uAccountID = s.get160 ();
|
||||
|
||||
if (bCurrency)
|
||||
uCurrency = s.get160();
|
||||
if (bCurrency)
|
||||
uCurrency = s.get160 ();
|
||||
|
||||
if (bIssuer)
|
||||
uIssuerID = s.get160();
|
||||
if (bIssuer)
|
||||
uIssuerID = s.get160 ();
|
||||
|
||||
path.push_back(STPathElement(uAccountID, uCurrency, uIssuerID, bCurrency));
|
||||
}
|
||||
} while(1);
|
||||
path.push_back (STPathElement (uAccountID, uCurrency, uIssuerID, bCurrency));
|
||||
}
|
||||
}
|
||||
while (1);
|
||||
}
|
||||
|
||||
bool STPathSet::isEquivalent(const SerializedType& t) const
|
||||
bool STPathSet::isEquivalent (const SerializedType& t) const
|
||||
{
|
||||
const STPathSet* v = dynamic_cast<const STPathSet*>(&t);
|
||||
return v && (value == v->value);
|
||||
const STPathSet* v = dynamic_cast<const STPathSet*> (&t);
|
||||
return v && (value == v->value);
|
||||
}
|
||||
|
||||
bool STPath::hasSeen(const uint160 &uAccountId, const uint160& uCurrencyID, const uint160& uIssuerID)
|
||||
bool STPath::hasSeen (const uint160& uAccountId, const uint160& uCurrencyID, const uint160& uIssuerID)
|
||||
{
|
||||
for (int i = 0; i < mPath.size(); ++i)
|
||||
{
|
||||
const STPathElement& ele = getElement(i);
|
||||
if (ele.getAccountID() == uAccountId
|
||||
&& ele.getCurrency() == uCurrencyID
|
||||
&& ele.getIssuerID() == uIssuerID)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
for (int i = 0; i < mPath.size (); ++i)
|
||||
{
|
||||
const STPathElement& ele = getElement (i);
|
||||
|
||||
if (ele.getAccountID () == uAccountId
|
||||
&& ele.getCurrency () == uCurrencyID
|
||||
&& ele.getIssuerID () == uIssuerID)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
Json::Value STPath::getJson(int) const
|
||||
Json::Value STPath::getJson (int) const
|
||||
{
|
||||
Json::Value ret(Json::arrayValue);
|
||||
Json::Value ret (Json::arrayValue);
|
||||
|
||||
BOOST_FOREACH(std::vector<STPathElement>::const_iterator::value_type it, mPath)
|
||||
{
|
||||
Json::Value elem(Json::objectValue);
|
||||
int iType = it.getNodeType();
|
||||
BOOST_FOREACH (std::vector<STPathElement>::const_iterator::value_type it, mPath)
|
||||
{
|
||||
Json::Value elem (Json::objectValue);
|
||||
int iType = it.getNodeType ();
|
||||
|
||||
elem["type"] = iType;
|
||||
elem["type_hex"] = strHex(iType);
|
||||
elem["type"] = iType;
|
||||
elem["type_hex"] = strHex (iType);
|
||||
|
||||
if (iType & STPathElement::typeAccount)
|
||||
elem["account"] = RippleAddress::createHumanAccountID(it.getAccountID());
|
||||
if (iType & STPathElement::typeAccount)
|
||||
elem["account"] = RippleAddress::createHumanAccountID (it.getAccountID ());
|
||||
|
||||
if (iType & STPathElement::typeCurrency)
|
||||
elem["currency"] = STAmount::createHumanCurrency(it.getCurrency());
|
||||
if (iType & STPathElement::typeCurrency)
|
||||
elem["currency"] = STAmount::createHumanCurrency (it.getCurrency ());
|
||||
|
||||
if (iType & STPathElement::typeIssuer)
|
||||
elem["issuer"] = RippleAddress::createHumanAccountID(it.getIssuerID());
|
||||
if (iType & STPathElement::typeIssuer)
|
||||
elem["issuer"] = RippleAddress::createHumanAccountID (it.getIssuerID ());
|
||||
|
||||
ret.append(elem);
|
||||
}
|
||||
ret.append (elem);
|
||||
}
|
||||
|
||||
return ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
Json::Value STPathSet::getJson(int options) const
|
||||
Json::Value STPathSet::getJson (int options) const
|
||||
{
|
||||
Json::Value ret(Json::arrayValue);
|
||||
Json::Value ret (Json::arrayValue);
|
||||
|
||||
BOOST_FOREACH(std::vector<STPath>::const_iterator::value_type it, value)
|
||||
ret.append(it.getJson(options));
|
||||
BOOST_FOREACH (std::vector<STPath>::const_iterator::value_type it, value)
|
||||
ret.append (it.getJson (options));
|
||||
|
||||
return ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if 0
|
||||
std::string STPath::getText() const
|
||||
std::string STPath::getText () const
|
||||
{
|
||||
std::string ret("[");
|
||||
bool first = true;
|
||||
std::string ret ("[");
|
||||
bool first = true;
|
||||
|
||||
BOOST_FOREACH(const STPathElement& it, mPath)
|
||||
{
|
||||
if (!first) ret += ", ";
|
||||
switch (it.getNodeType())
|
||||
{
|
||||
case STPathElement::typeAccount:
|
||||
{
|
||||
ret += RippleAddress::createHumanAccountID(it.getNode());
|
||||
break;
|
||||
}
|
||||
BOOST_FOREACH (const STPathElement & it, mPath)
|
||||
{
|
||||
if (!first) ret += ", ";
|
||||
|
||||
case STPathElement::typeOffer:
|
||||
{
|
||||
ret += "Offer(";
|
||||
ret += it.getNode().GetHex();
|
||||
ret += ")";
|
||||
break;
|
||||
}
|
||||
switch (it.getNodeType ())
|
||||
{
|
||||
case STPathElement::typeAccount:
|
||||
{
|
||||
ret += RippleAddress::createHumanAccountID (it.getNode ());
|
||||
break;
|
||||
}
|
||||
|
||||
default: throw std::runtime_error("Unknown path element");
|
||||
}
|
||||
first = false;
|
||||
}
|
||||
case STPathElement::typeOffer:
|
||||
{
|
||||
ret += "Offer(";
|
||||
ret += it.getNode ().GetHex ();
|
||||
ret += ")";
|
||||
break;
|
||||
}
|
||||
|
||||
return ret + "]";
|
||||
default:
|
||||
throw std::runtime_error ("Unknown path element");
|
||||
}
|
||||
|
||||
first = false;
|
||||
}
|
||||
|
||||
return ret + "]";
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
std::string STPathSet::getText() const
|
||||
std::string STPathSet::getText () const
|
||||
{
|
||||
std::string ret("{");
|
||||
bool firstPath = true;
|
||||
std::string ret ("{");
|
||||
bool firstPath = true;
|
||||
|
||||
BOOST_FOREACH(std::vector<STPath>::const_iterator::value_type it, value)
|
||||
{
|
||||
if (!firstPath)
|
||||
{
|
||||
ret += ", ";
|
||||
firstPath = false;
|
||||
}
|
||||
ret += it.getText();
|
||||
}
|
||||
return ret + "}";
|
||||
BOOST_FOREACH (std::vector<STPath>::const_iterator::value_type it, value)
|
||||
{
|
||||
if (!firstPath)
|
||||
{
|
||||
ret += ", ";
|
||||
firstPath = false;
|
||||
}
|
||||
|
||||
ret += it.getText ();
|
||||
}
|
||||
return ret + "}";
|
||||
}
|
||||
#endif
|
||||
|
||||
void STPathSet::add(Serializer& s) const
|
||||
void STPathSet::add (Serializer& s) const
|
||||
{
|
||||
bool bFirst = true;
|
||||
bool bFirst = true;
|
||||
|
||||
BOOST_FOREACH(const STPath& spPath, value)
|
||||
{
|
||||
if (!bFirst)
|
||||
{
|
||||
s.add8(STPathElement::typeBoundary);
|
||||
}
|
||||
BOOST_FOREACH (const STPath & spPath, value)
|
||||
{
|
||||
if (!bFirst)
|
||||
{
|
||||
s.add8 (STPathElement::typeBoundary);
|
||||
}
|
||||
|
||||
BOOST_FOREACH(const STPathElement& speElement, spPath)
|
||||
{
|
||||
int iType = speElement.getNodeType();
|
||||
BOOST_FOREACH (const STPathElement & speElement, spPath)
|
||||
{
|
||||
int iType = speElement.getNodeType ();
|
||||
|
||||
s.add8(iType);
|
||||
s.add8 (iType);
|
||||
|
||||
if (iType & STPathElement::typeAccount)
|
||||
s.add160(speElement.getAccountID());
|
||||
if (iType & STPathElement::typeAccount)
|
||||
s.add160 (speElement.getAccountID ());
|
||||
|
||||
if (iType & STPathElement::typeCurrency)
|
||||
s.add160(speElement.getCurrency());
|
||||
if (iType & STPathElement::typeCurrency)
|
||||
s.add160 (speElement.getCurrency ());
|
||||
|
||||
if (iType & STPathElement::typeIssuer)
|
||||
s.add160(speElement.getIssuerID());
|
||||
}
|
||||
if (iType & STPathElement::typeIssuer)
|
||||
s.add160 (speElement.getIssuerID ());
|
||||
}
|
||||
|
||||
bFirst = false;
|
||||
}
|
||||
s.add8(STPathElement::typeEnd);
|
||||
bFirst = false;
|
||||
}
|
||||
s.add8 (STPathElement::typeEnd);
|
||||
}
|
||||
// vim:ts=4
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -6,155 +6,270 @@ class CKey; // forward declaration
|
||||
class Serializer
|
||||
{
|
||||
public:
|
||||
typedef boost::shared_ptr<Serializer> pointer;
|
||||
typedef boost::shared_ptr<Serializer> pointer;
|
||||
|
||||
protected:
|
||||
Blob mData;
|
||||
Blob mData;
|
||||
|
||||
public:
|
||||
Serializer(int n = 256) { mData.reserve(n); }
|
||||
Serializer(Blob const& data) : mData(data) { ; }
|
||||
Serializer(const std::string& data) : mData(data.data(), (data.data()) + data.size()) { ; }
|
||||
Serializer(Blob ::iterator begin, Blob ::iterator end) :
|
||||
mData(begin, end) { ; }
|
||||
Serializer(Blob ::const_iterator begin, Blob ::const_iterator end) :
|
||||
mData(begin, end) { ; }
|
||||
Serializer (int n = 256)
|
||||
{
|
||||
mData.reserve (n);
|
||||
}
|
||||
Serializer (Blob const& data) : mData (data)
|
||||
{
|
||||
;
|
||||
}
|
||||
Serializer (const std::string& data) : mData (data.data (), (data.data ()) + data.size ())
|
||||
{
|
||||
;
|
||||
}
|
||||
Serializer (Blob ::iterator begin, Blob ::iterator end) :
|
||||
mData (begin, end)
|
||||
{
|
||||
;
|
||||
}
|
||||
Serializer (Blob ::const_iterator begin, Blob ::const_iterator end) :
|
||||
mData (begin, end)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
// assemble functions
|
||||
int add8(unsigned char byte);
|
||||
int add16(uint16);
|
||||
int add32(uint32); // ledger indexes, account sequence, timestamps
|
||||
int add64(uint64); // native currency amounts
|
||||
int add128(const uint128&); // private key generators
|
||||
int add160(const uint160&); // account names, hankos
|
||||
int add256(uint256 const& ); // transaction and ledger hashes
|
||||
int addRaw(Blob const& vector);
|
||||
int addRaw(const void *ptr, int len);
|
||||
int addRaw(const Serializer& s);
|
||||
int addZeros(size_t uBytes);
|
||||
// assemble functions
|
||||
int add8 (unsigned char byte);
|
||||
int add16 (uint16);
|
||||
int add32 (uint32); // ledger indexes, account sequence, timestamps
|
||||
int add64 (uint64); // native currency amounts
|
||||
int add128 (const uint128&); // private key generators
|
||||
int add160 (const uint160&); // account names, hankos
|
||||
int add256 (uint256 const& ); // transaction and ledger hashes
|
||||
int addRaw (Blob const& vector);
|
||||
int addRaw (const void* ptr, int len);
|
||||
int addRaw (const Serializer& s);
|
||||
int addZeros (size_t uBytes);
|
||||
|
||||
int addVL(Blob const& vector);
|
||||
int addVL(const std::string& string);
|
||||
int addVL(const void *ptr, int len);
|
||||
int addVL (Blob const& vector);
|
||||
int addVL (const std::string& string);
|
||||
int addVL (const void* ptr, int len);
|
||||
|
||||
// disassemble functions
|
||||
bool get8(int&, int offset) const;
|
||||
bool get8(unsigned char&, int offset) const;
|
||||
bool get16(uint16&, int offset) const;
|
||||
bool get32(uint32&, int offset) const;
|
||||
bool get64(uint64&, int offset) const;
|
||||
bool get128(uint128&, int offset) const;
|
||||
bool get160(uint160&, int offset) const;
|
||||
bool get256(uint256&, int offset) const;
|
||||
uint256 get256(int offset) const;
|
||||
bool getRaw(Blob&, int offset, int length) const;
|
||||
Blob getRaw(int offset, int length) const;
|
||||
// disassemble functions
|
||||
bool get8 (int&, int offset) const;
|
||||
bool get8 (unsigned char&, int offset) const;
|
||||
bool get16 (uint16&, int offset) const;
|
||||
bool get32 (uint32&, int offset) const;
|
||||
bool get64 (uint64&, int offset) const;
|
||||
bool get128 (uint128&, int offset) const;
|
||||
bool get160 (uint160&, int offset) const;
|
||||
bool get256 (uint256&, int offset) const;
|
||||
uint256 get256 (int offset) const;
|
||||
bool getRaw (Blob&, int offset, int length) const;
|
||||
Blob getRaw (int offset, int length) const;
|
||||
|
||||
bool getVL(Blob& objectVL, int offset, int& length) const;
|
||||
bool getVLLength(int& length, int offset) const;
|
||||
bool getVL (Blob& objectVL, int offset, int& length) const;
|
||||
bool getVLLength (int& length, int offset) const;
|
||||
|
||||
bool getFieldID(int& type, int& name, int offset) const;
|
||||
int addFieldID(int type, int name);
|
||||
int addFieldID(SerializedTypeID type, int name) { return addFieldID(static_cast<int>(type), name); }
|
||||
bool getFieldID (int& type, int& name, int offset) const;
|
||||
int addFieldID (int type, int name);
|
||||
int addFieldID (SerializedTypeID type, int name)
|
||||
{
|
||||
return addFieldID (static_cast<int> (type), name);
|
||||
}
|
||||
|
||||
// normal hash functions
|
||||
uint160 getRIPEMD160(int size=-1) const;
|
||||
uint256 getSHA256(int size=-1) const;
|
||||
uint256 getSHA512Half(int size=-1) const;
|
||||
static uint256 getSHA512Half(Blob const& data, int size=-1);
|
||||
static uint256 getSHA512Half(const unsigned char *data, int len);
|
||||
static uint256 getSHA512Half(const std::string& strData);
|
||||
// normal hash functions
|
||||
uint160 getRIPEMD160 (int size = -1) const;
|
||||
uint256 getSHA256 (int size = -1) const;
|
||||
uint256 getSHA512Half (int size = -1) const;
|
||||
static uint256 getSHA512Half (Blob const& data, int size = -1);
|
||||
static uint256 getSHA512Half (const unsigned char* data, int len);
|
||||
static uint256 getSHA512Half (const std::string& strData);
|
||||
|
||||
// prefix hash functions
|
||||
static uint256 getPrefixHash(uint32 prefix, const unsigned char *data, int len);
|
||||
uint256 getPrefixHash(uint32 prefix) const
|
||||
{ return getPrefixHash(prefix, &(mData.front()), mData.size()); }
|
||||
static uint256 getPrefixHash(uint32 prefix, Blob const& data)
|
||||
{ return getPrefixHash(prefix, &(data.front()), data.size()); }
|
||||
static uint256 getPrefixHash(uint32 prefix, const std::string& strData)
|
||||
{ return getPrefixHash(prefix, reinterpret_cast<const unsigned char *>(strData.data()), strData.size()); }
|
||||
// prefix hash functions
|
||||
static uint256 getPrefixHash (uint32 prefix, const unsigned char* data, int len);
|
||||
uint256 getPrefixHash (uint32 prefix) const
|
||||
{
|
||||
return getPrefixHash (prefix, & (mData.front ()), mData.size ());
|
||||
}
|
||||
static uint256 getPrefixHash (uint32 prefix, Blob const& data)
|
||||
{
|
||||
return getPrefixHash (prefix, & (data.front ()), data.size ());
|
||||
}
|
||||
static uint256 getPrefixHash (uint32 prefix, const std::string& strData)
|
||||
{
|
||||
return getPrefixHash (prefix, reinterpret_cast<const unsigned char*> (strData.data ()), strData.size ());
|
||||
}
|
||||
|
||||
// totality functions
|
||||
Blob const& peekData() const { return mData; }
|
||||
Blob getData() const { return mData; }
|
||||
Blob& modData() { return mData; }
|
||||
int getCapacity() const { return mData.capacity(); }
|
||||
int getDataLength() const { return mData.size(); }
|
||||
const void* getDataPtr() const { return &mData.front(); }
|
||||
void* getDataPtr() { return &mData.front(); }
|
||||
int getLength() const { return mData.size(); }
|
||||
std::string getString() const { return std::string(static_cast<const char *>(getDataPtr()), size()); }
|
||||
void secureErase() { memset(&(mData.front()), 0, mData.size()); erase(); }
|
||||
void erase() { mData.clear(); }
|
||||
int removeLastByte();
|
||||
bool chop(int num);
|
||||
// totality functions
|
||||
Blob const& peekData () const
|
||||
{
|
||||
return mData;
|
||||
}
|
||||
Blob getData () const
|
||||
{
|
||||
return mData;
|
||||
}
|
||||
Blob& modData ()
|
||||
{
|
||||
return mData;
|
||||
}
|
||||
int getCapacity () const
|
||||
{
|
||||
return mData.capacity ();
|
||||
}
|
||||
int getDataLength () const
|
||||
{
|
||||
return mData.size ();
|
||||
}
|
||||
const void* getDataPtr () const
|
||||
{
|
||||
return &mData.front ();
|
||||
}
|
||||
void* getDataPtr ()
|
||||
{
|
||||
return &mData.front ();
|
||||
}
|
||||
int getLength () const
|
||||
{
|
||||
return mData.size ();
|
||||
}
|
||||
std::string getString () const
|
||||
{
|
||||
return std::string (static_cast<const char*> (getDataPtr ()), size ());
|
||||
}
|
||||
void secureErase ()
|
||||
{
|
||||
memset (& (mData.front ()), 0, mData.size ());
|
||||
erase ();
|
||||
}
|
||||
void erase ()
|
||||
{
|
||||
mData.clear ();
|
||||
}
|
||||
int removeLastByte ();
|
||||
bool chop (int num);
|
||||
|
||||
// vector-like functions
|
||||
Blob ::iterator begin() { return mData.begin(); }
|
||||
Blob ::iterator end() { return mData.end(); }
|
||||
Blob ::const_iterator begin() const { return mData.begin(); }
|
||||
Blob ::const_iterator end() const { return mData.end(); }
|
||||
Blob ::size_type size() const { return mData.size(); }
|
||||
void reserve(size_t n) { mData.reserve(n); }
|
||||
void resize(size_t n) { mData.resize(n); }
|
||||
size_t capacity() const { return mData.capacity(); }
|
||||
// vector-like functions
|
||||
Blob ::iterator begin ()
|
||||
{
|
||||
return mData.begin ();
|
||||
}
|
||||
Blob ::iterator end ()
|
||||
{
|
||||
return mData.end ();
|
||||
}
|
||||
Blob ::const_iterator begin () const
|
||||
{
|
||||
return mData.begin ();
|
||||
}
|
||||
Blob ::const_iterator end () const
|
||||
{
|
||||
return mData.end ();
|
||||
}
|
||||
Blob ::size_type size () const
|
||||
{
|
||||
return mData.size ();
|
||||
}
|
||||
void reserve (size_t n)
|
||||
{
|
||||
mData.reserve (n);
|
||||
}
|
||||
void resize (size_t n)
|
||||
{
|
||||
mData.resize (n);
|
||||
}
|
||||
size_t capacity () const
|
||||
{
|
||||
return mData.capacity ();
|
||||
}
|
||||
|
||||
bool operator==(Blob const& v) { return v == mData; }
|
||||
bool operator!=(Blob const& v) { return v != mData; }
|
||||
bool operator==(const Serializer& v) { return v.mData == mData; }
|
||||
bool operator!=(const Serializer& v) { return v.mData != mData; }
|
||||
bool operator== (Blob const& v)
|
||||
{
|
||||
return v == mData;
|
||||
}
|
||||
bool operator!= (Blob const& v)
|
||||
{
|
||||
return v != mData;
|
||||
}
|
||||
bool operator== (const Serializer& v)
|
||||
{
|
||||
return v.mData == mData;
|
||||
}
|
||||
bool operator!= (const Serializer& v)
|
||||
{
|
||||
return v.mData != mData;
|
||||
}
|
||||
|
||||
// signature functions
|
||||
bool checkSignature(int pubkeyOffset, int signatureOffset) const;
|
||||
bool checkSignature(Blob const& signature, CKey& rkey) const;
|
||||
bool makeSignature(Blob& signature, CKey& rkey) const;
|
||||
bool addSignature(CKey& rkey);
|
||||
// signature functions
|
||||
bool checkSignature (int pubkeyOffset, int signatureOffset) const;
|
||||
bool checkSignature (Blob const& signature, CKey& rkey) const;
|
||||
bool makeSignature (Blob& signature, CKey& rkey) const;
|
||||
bool addSignature (CKey& rkey);
|
||||
|
||||
// low-level VL length encode/decode functions
|
||||
static Blob encodeVL(int length);
|
||||
static int lengthVL(int length) { return length + encodeLengthLength(length); }
|
||||
static int encodeLengthLength(int length); // length to encode length
|
||||
static int decodeLengthLength(int b1);
|
||||
static int decodeVLLength(int b1);
|
||||
static int decodeVLLength(int b1, int b2);
|
||||
static int decodeVLLength(int b1, int b2, int b3);
|
||||
// low-level VL length encode/decode functions
|
||||
static Blob encodeVL (int length);
|
||||
static int lengthVL (int length)
|
||||
{
|
||||
return length + encodeLengthLength (length);
|
||||
}
|
||||
static int encodeLengthLength (int length); // length to encode length
|
||||
static int decodeLengthLength (int b1);
|
||||
static int decodeVLLength (int b1);
|
||||
static int decodeVLLength (int b1, int b2);
|
||||
static int decodeVLLength (int b1, int b2, int b3);
|
||||
|
||||
static void TestSerializer();
|
||||
static void TestSerializer ();
|
||||
};
|
||||
|
||||
class SerializerIterator
|
||||
{
|
||||
protected:
|
||||
const Serializer& mSerializer;
|
||||
int mPos;
|
||||
const Serializer& mSerializer;
|
||||
int mPos;
|
||||
|
||||
public:
|
||||
|
||||
// Reference is not const because we don't want to bind to a temporary
|
||||
SerializerIterator(Serializer& s) : mSerializer(s), mPos(0) { ; }
|
||||
// Reference is not const because we don't want to bind to a temporary
|
||||
SerializerIterator (Serializer& s) : mSerializer (s), mPos (0)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
const Serializer& operator*(void) { return mSerializer; }
|
||||
void reset(void) { mPos = 0; }
|
||||
void setPos(int p) { mPos = p; }
|
||||
const Serializer& operator* (void)
|
||||
{
|
||||
return mSerializer;
|
||||
}
|
||||
void reset (void)
|
||||
{
|
||||
mPos = 0;
|
||||
}
|
||||
void setPos (int p)
|
||||
{
|
||||
mPos = p;
|
||||
}
|
||||
|
||||
int getPos(void) { return mPos; }
|
||||
bool empty() { return mPos == mSerializer.getLength(); }
|
||||
int getBytesLeft();
|
||||
int getPos (void)
|
||||
{
|
||||
return mPos;
|
||||
}
|
||||
bool empty ()
|
||||
{
|
||||
return mPos == mSerializer.getLength ();
|
||||
}
|
||||
int getBytesLeft ();
|
||||
|
||||
// get functions throw on error
|
||||
unsigned char get8();
|
||||
uint16 get16();
|
||||
uint32 get32();
|
||||
uint64 get64();
|
||||
uint128 get128();
|
||||
uint160 get160();
|
||||
uint256 get256();
|
||||
// get functions throw on error
|
||||
unsigned char get8 ();
|
||||
uint16 get16 ();
|
||||
uint32 get32 ();
|
||||
uint64 get64 ();
|
||||
uint128 get128 ();
|
||||
uint160 get160 ();
|
||||
uint256 get256 ();
|
||||
|
||||
void getFieldID(int& type, int& field);
|
||||
void getFieldID (int& type, int& field);
|
||||
|
||||
Blob getRaw(int iLength);
|
||||
Blob getRaw (int iLength);
|
||||
|
||||
Blob getVL();
|
||||
Blob getVL ();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,125 +1,127 @@
|
||||
|
||||
bool transResultInfo(TER terCode, std::string& strToken, std::string& strHuman)
|
||||
bool transResultInfo (TER terCode, std::string& strToken, std::string& strHuman)
|
||||
{
|
||||
static struct {
|
||||
TER terCode;
|
||||
const char* cpToken;
|
||||
const char* cpHuman;
|
||||
} transResultInfoA[] = {
|
||||
{ tecCLAIM, "tecCLAIM", "Fee claimed. Sequence used. No action." },
|
||||
{ tecDIR_FULL, "tecDIR_FULL", "Can not add entry to full directory." },
|
||||
{ tecFAILED_PROCESSING, "tecFAILED_PROCESSING", "Failed to correctly process transaction." },
|
||||
{ tecINSUF_RESERVE_LINE, "tecINSUF_RESERVE_LINE", "Insufficient reserve to add trust line." },
|
||||
{ tecINSUF_RESERVE_OFFER, "tecINSUF_RESERVE_OFFER", "Insufficient reserve to create offer." },
|
||||
{ tecNO_DST, "tecNO_DST", "Destination does not exist. Send XRP to create it." },
|
||||
{ tecNO_DST_INSUF_XRP, "tecNO_DST_INSUF_XRP", "Destination does not exist. Too little XRP sent to create it." },
|
||||
{ tecNO_LINE_INSUF_RESERVE, "tecNO_LINE_INSUF_RESERVE", "No such line. Too little reserve to create it." },
|
||||
{ tecNO_LINE_REDUNDANT, "tecNO_LINE_REDUNDANT", "Can't set non-existant line to default." },
|
||||
{ tecPATH_DRY, "tecPATH_DRY", "Path could not send partial amount." },
|
||||
{ tecPATH_PARTIAL, "tecPATH_PARTIAL", "Path could not send full amount." },
|
||||
static struct
|
||||
{
|
||||
TER terCode;
|
||||
const char* cpToken;
|
||||
const char* cpHuman;
|
||||
} transResultInfoA[] =
|
||||
{
|
||||
{ tecCLAIM, "tecCLAIM", "Fee claimed. Sequence used. No action." },
|
||||
{ tecDIR_FULL, "tecDIR_FULL", "Can not add entry to full directory." },
|
||||
{ tecFAILED_PROCESSING, "tecFAILED_PROCESSING", "Failed to correctly process transaction." },
|
||||
{ tecINSUF_RESERVE_LINE, "tecINSUF_RESERVE_LINE", "Insufficient reserve to add trust line." },
|
||||
{ tecINSUF_RESERVE_OFFER, "tecINSUF_RESERVE_OFFER", "Insufficient reserve to create offer." },
|
||||
{ tecNO_DST, "tecNO_DST", "Destination does not exist. Send XRP to create it." },
|
||||
{ tecNO_DST_INSUF_XRP, "tecNO_DST_INSUF_XRP", "Destination does not exist. Too little XRP sent to create it." },
|
||||
{ tecNO_LINE_INSUF_RESERVE, "tecNO_LINE_INSUF_RESERVE", "No such line. Too little reserve to create it." },
|
||||
{ tecNO_LINE_REDUNDANT, "tecNO_LINE_REDUNDANT", "Can't set non-existant line to default." },
|
||||
{ tecPATH_DRY, "tecPATH_DRY", "Path could not send partial amount." },
|
||||
{ tecPATH_PARTIAL, "tecPATH_PARTIAL", "Path could not send full amount." },
|
||||
|
||||
{ tecUNFUNDED, "tecUNFUNDED", "One of _ADD, _OFFER, or _SEND. Deprecated." },
|
||||
{ tecUNFUNDED_ADD, "tecUNFUNDED_ADD", "Insufficient XRP balance for WalletAdd." },
|
||||
{ tecUNFUNDED_OFFER, "tecUNFUNDED_OFFER", "Insufficient balance to fund created offer." },
|
||||
{ tecUNFUNDED_PAYMENT, "tecUNFUNDED_PAYMENT", "Insufficient XRP balance to send." },
|
||||
{ tecUNFUNDED, "tecUNFUNDED", "One of _ADD, _OFFER, or _SEND. Deprecated." },
|
||||
{ tecUNFUNDED_ADD, "tecUNFUNDED_ADD", "Insufficient XRP balance for WalletAdd." },
|
||||
{ tecUNFUNDED_OFFER, "tecUNFUNDED_OFFER", "Insufficient balance to fund created offer." },
|
||||
{ tecUNFUNDED_PAYMENT, "tecUNFUNDED_PAYMENT", "Insufficient XRP balance to send." },
|
||||
|
||||
{ tefFAILURE, "tefFAILURE", "Failed to apply." },
|
||||
{ tefALREADY, "tefALREADY", "The exact transaction was already in this ledger." },
|
||||
{ tefBAD_ADD_AUTH, "tefBAD_ADD_AUTH", "Not authorized to add account." },
|
||||
{ tefBAD_AUTH, "tefBAD_AUTH", "Transaction's public key is not authorized." },
|
||||
{ tefBAD_CLAIM_ID, "tefBAD_CLAIM_ID", "Malformed: Bad claim id." },
|
||||
{ tefBAD_GEN_AUTH, "tefBAD_GEN_AUTH", "Not authorized to claim generator." },
|
||||
{ tefBAD_LEDGER, "tefBAD_LEDGER", "Ledger in unexpected state." },
|
||||
{ tefCLAIMED, "tefCLAIMED", "Can not claim a previously claimed account." },
|
||||
{ tefCREATED, "tefCREATED", "Can't add an already created account." },
|
||||
{ tefDST_TAG_NEEDED, "tefDST_TAG_NEEDED", "Destination tag required." },
|
||||
{ tefEXCEPTION, "tefEXCEPTION", "Unexpected program state." },
|
||||
{ tefGEN_IN_USE, "tefGEN_IN_USE", "Generator already in use." },
|
||||
{ tefINTERNAL, "tefINTERNAL", "Internal error." },
|
||||
{ tefNO_AUTH_REQUIRED, "tefNO_AUTH_REQUIRED", "Auth is not required." },
|
||||
{ tefPAST_SEQ, "tefPAST_SEQ", "This sequence number has already past." },
|
||||
{ tefWRONG_PRIOR, "tefWRONG_PRIOR", "This previous transaction does not match." },
|
||||
{ tefFAILURE, "tefFAILURE", "Failed to apply." },
|
||||
{ tefALREADY, "tefALREADY", "The exact transaction was already in this ledger." },
|
||||
{ tefBAD_ADD_AUTH, "tefBAD_ADD_AUTH", "Not authorized to add account." },
|
||||
{ tefBAD_AUTH, "tefBAD_AUTH", "Transaction's public key is not authorized." },
|
||||
{ tefBAD_CLAIM_ID, "tefBAD_CLAIM_ID", "Malformed: Bad claim id." },
|
||||
{ tefBAD_GEN_AUTH, "tefBAD_GEN_AUTH", "Not authorized to claim generator." },
|
||||
{ tefBAD_LEDGER, "tefBAD_LEDGER", "Ledger in unexpected state." },
|
||||
{ tefCLAIMED, "tefCLAIMED", "Can not claim a previously claimed account." },
|
||||
{ tefCREATED, "tefCREATED", "Can't add an already created account." },
|
||||
{ tefDST_TAG_NEEDED, "tefDST_TAG_NEEDED", "Destination tag required." },
|
||||
{ tefEXCEPTION, "tefEXCEPTION", "Unexpected program state." },
|
||||
{ tefGEN_IN_USE, "tefGEN_IN_USE", "Generator already in use." },
|
||||
{ tefINTERNAL, "tefINTERNAL", "Internal error." },
|
||||
{ tefNO_AUTH_REQUIRED, "tefNO_AUTH_REQUIRED", "Auth is not required." },
|
||||
{ tefPAST_SEQ, "tefPAST_SEQ", "This sequence number has already past." },
|
||||
{ tefWRONG_PRIOR, "tefWRONG_PRIOR", "This previous transaction does not match." },
|
||||
|
||||
{ telLOCAL_ERROR, "telLOCAL_ERROR", "Local failure." },
|
||||
{ telBAD_DOMAIN, "telBAD_DOMAIN", "Domain too long." },
|
||||
{ telBAD_PATH_COUNT, "telBAD_PATH_COUNT", "Malformed: Too many paths." },
|
||||
{ telBAD_PUBLIC_KEY, "telBAD_PUBLIC_KEY", "Public key too long." },
|
||||
{ telFAILED_PROCESSING, "telFAILED_PROCESSING", "Failed to correctly process transaction." },
|
||||
{ telINSUF_FEE_P, "telINSUF_FEE_P", "Fee insufficient." },
|
||||
{ telNO_DST_PARTIAL, "telNO_DST_PARTIAL", "Partial payment to create account not allowed." },
|
||||
{ telLOCAL_ERROR, "telLOCAL_ERROR", "Local failure." },
|
||||
{ telBAD_DOMAIN, "telBAD_DOMAIN", "Domain too long." },
|
||||
{ telBAD_PATH_COUNT, "telBAD_PATH_COUNT", "Malformed: Too many paths." },
|
||||
{ telBAD_PUBLIC_KEY, "telBAD_PUBLIC_KEY", "Public key too long." },
|
||||
{ telFAILED_PROCESSING, "telFAILED_PROCESSING", "Failed to correctly process transaction." },
|
||||
{ telINSUF_FEE_P, "telINSUF_FEE_P", "Fee insufficient." },
|
||||
{ telNO_DST_PARTIAL, "telNO_DST_PARTIAL", "Partial payment to create account not allowed." },
|
||||
|
||||
{ temMALFORMED, "temMALFORMED", "Malformed transaction." },
|
||||
{ temBAD_AMOUNT, "temBAD_AMOUNT", "Can only send positive amounts." },
|
||||
{ temBAD_AUTH_MASTER, "temBAD_AUTH_MASTER", "Auth for unclaimed account needs correct master key." },
|
||||
{ temBAD_CURRENCY, "temBAD_CURRENCY", "Malformed: Bad currency." },
|
||||
{ temBAD_FEE, "temBAD_FEE", "Invalid fee, negative or not XRP." },
|
||||
{ temBAD_EXPIRATION, "temBAD_EXPIRATION", "Malformed: Bad expiration." },
|
||||
{ temBAD_ISSUER, "temBAD_ISSUER", "Malformed: Bad issuer." },
|
||||
{ temBAD_LIMIT, "temBAD_LIMIT", "Limits must be non-negative." },
|
||||
{ temBAD_OFFER, "temBAD_OFFER", "Malformed: Bad offer." },
|
||||
{ temBAD_PATH, "temBAD_PATH", "Malformed: Bad path." },
|
||||
{ temBAD_PATH_LOOP, "temBAD_PATH_LOOP", "Malformed: Loop in path." },
|
||||
{ temBAD_PUBLISH, "temBAD_PUBLISH", "Malformed: Bad publish." },
|
||||
{ temBAD_SIGNATURE, "temBAD_SIGNATURE", "Malformed: Bad signature." },
|
||||
{ temBAD_SRC_ACCOUNT, "temBAD_SRC_ACCOUNT", "Malformed: Bad source account." },
|
||||
{ temBAD_TRANSFER_RATE, "temBAD_TRANSFER_RATE", "Malformed: Transfer rate must be >= 1.0" },
|
||||
{ temBAD_SEQUENCE, "temBAD_SEQUENCE", "Malformed: Sequence is not in the past." },
|
||||
{ temBAD_SEND_XRP_LIMIT, "temBAD_SEND_XRP_LIMIT", "Malformed: Limit quality is not allowed for XRP to XRP." },
|
||||
{ temBAD_SEND_XRP_MAX, "temBAD_SEND_XRP_MAX", "Malformed: Send max is not allowed for XRP to XRP." },
|
||||
{ temBAD_SEND_XRP_NO_DIRECT, "temBAD_SEND_XRP_NO_DIRECT", "Malformed: No Ripple direct is not allowed for XRP to XRP." },
|
||||
{ temBAD_SEND_XRP_PARTIAL, "temBAD_SEND_XRP_PARTIAL", "Malformed: Partial payment is not allowed for XRP to XRP." },
|
||||
{ temBAD_SEND_XRP_PATHS, "temBAD_SEND_XRP_PATHS", "Malformed: Paths are not allowed for XRP to XRP." },
|
||||
{ temDST_IS_SRC, "temDST_IS_SRC", "Destination may not be source." },
|
||||
{ temDST_NEEDED, "temDST_NEEDED", "Destination not specified." },
|
||||
{ temINVALID, "temINVALID", "The transaction is ill-formed." },
|
||||
{ temINVALID_FLAG, "temINVALID_FLAG", "The transaction has an invalid flag." },
|
||||
{ temREDUNDANT, "temREDUNDANT", "Sends same currency to self." },
|
||||
{ temREDUNDANT_SEND_MAX, "temREDUNDANT_SEND_MAX", "Send max is redundant." },
|
||||
{ temRIPPLE_EMPTY, "temRIPPLE_EMPTY", "PathSet with no paths." },
|
||||
{ temUNCERTAIN, "temUNCERTAIN", "In process of determining result. Never returned." },
|
||||
{ temUNKNOWN, "temUNKNOWN", "The transactions requires logic not implemented yet." },
|
||||
{ temMALFORMED, "temMALFORMED", "Malformed transaction." },
|
||||
{ temBAD_AMOUNT, "temBAD_AMOUNT", "Can only send positive amounts." },
|
||||
{ temBAD_AUTH_MASTER, "temBAD_AUTH_MASTER", "Auth for unclaimed account needs correct master key." },
|
||||
{ temBAD_CURRENCY, "temBAD_CURRENCY", "Malformed: Bad currency." },
|
||||
{ temBAD_FEE, "temBAD_FEE", "Invalid fee, negative or not XRP." },
|
||||
{ temBAD_EXPIRATION, "temBAD_EXPIRATION", "Malformed: Bad expiration." },
|
||||
{ temBAD_ISSUER, "temBAD_ISSUER", "Malformed: Bad issuer." },
|
||||
{ temBAD_LIMIT, "temBAD_LIMIT", "Limits must be non-negative." },
|
||||
{ temBAD_OFFER, "temBAD_OFFER", "Malformed: Bad offer." },
|
||||
{ temBAD_PATH, "temBAD_PATH", "Malformed: Bad path." },
|
||||
{ temBAD_PATH_LOOP, "temBAD_PATH_LOOP", "Malformed: Loop in path." },
|
||||
{ temBAD_PUBLISH, "temBAD_PUBLISH", "Malformed: Bad publish." },
|
||||
{ temBAD_SIGNATURE, "temBAD_SIGNATURE", "Malformed: Bad signature." },
|
||||
{ temBAD_SRC_ACCOUNT, "temBAD_SRC_ACCOUNT", "Malformed: Bad source account." },
|
||||
{ temBAD_TRANSFER_RATE, "temBAD_TRANSFER_RATE", "Malformed: Transfer rate must be >= 1.0" },
|
||||
{ temBAD_SEQUENCE, "temBAD_SEQUENCE", "Malformed: Sequence is not in the past." },
|
||||
{ temBAD_SEND_XRP_LIMIT, "temBAD_SEND_XRP_LIMIT", "Malformed: Limit quality is not allowed for XRP to XRP." },
|
||||
{ temBAD_SEND_XRP_MAX, "temBAD_SEND_XRP_MAX", "Malformed: Send max is not allowed for XRP to XRP." },
|
||||
{ temBAD_SEND_XRP_NO_DIRECT, "temBAD_SEND_XRP_NO_DIRECT", "Malformed: No Ripple direct is not allowed for XRP to XRP." },
|
||||
{ temBAD_SEND_XRP_PARTIAL, "temBAD_SEND_XRP_PARTIAL", "Malformed: Partial payment is not allowed for XRP to XRP." },
|
||||
{ temBAD_SEND_XRP_PATHS, "temBAD_SEND_XRP_PATHS", "Malformed: Paths are not allowed for XRP to XRP." },
|
||||
{ temDST_IS_SRC, "temDST_IS_SRC", "Destination may not be source." },
|
||||
{ temDST_NEEDED, "temDST_NEEDED", "Destination not specified." },
|
||||
{ temINVALID, "temINVALID", "The transaction is ill-formed." },
|
||||
{ temINVALID_FLAG, "temINVALID_FLAG", "The transaction has an invalid flag." },
|
||||
{ temREDUNDANT, "temREDUNDANT", "Sends same currency to self." },
|
||||
{ temREDUNDANT_SEND_MAX, "temREDUNDANT_SEND_MAX", "Send max is redundant." },
|
||||
{ temRIPPLE_EMPTY, "temRIPPLE_EMPTY", "PathSet with no paths." },
|
||||
{ temUNCERTAIN, "temUNCERTAIN", "In process of determining result. Never returned." },
|
||||
{ temUNKNOWN, "temUNKNOWN", "The transactions requires logic not implemented yet." },
|
||||
|
||||
{ terRETRY, "terRETRY", "Retry transaction." },
|
||||
{ terFUNDS_SPENT, "terFUNDS_SPENT", "Can't set password, password set funds already spent." },
|
||||
{ terINSUF_FEE_B, "terINSUF_FEE_B", "Account balance can't pay fee." },
|
||||
{ terLAST, "terLAST", "Process last." },
|
||||
{ terNO_ACCOUNT, "terNO_ACCOUNT", "The source account does not exist." },
|
||||
{ terNO_AUTH, "terNO_AUTH", "Not authorized to hold IOUs." },
|
||||
{ terNO_LINE, "terNO_LINE", "No such line." },
|
||||
{ terPRE_SEQ, "terPRE_SEQ", "Missing/inapplicable prior transaction." },
|
||||
{ terOWNERS, "terOWNERS", "Non-zero owner count." },
|
||||
{ terRETRY, "terRETRY", "Retry transaction." },
|
||||
{ terFUNDS_SPENT, "terFUNDS_SPENT", "Can't set password, password set funds already spent." },
|
||||
{ terINSUF_FEE_B, "terINSUF_FEE_B", "Account balance can't pay fee." },
|
||||
{ terLAST, "terLAST", "Process last." },
|
||||
{ terNO_ACCOUNT, "terNO_ACCOUNT", "The source account does not exist." },
|
||||
{ terNO_AUTH, "terNO_AUTH", "Not authorized to hold IOUs." },
|
||||
{ terNO_LINE, "terNO_LINE", "No such line." },
|
||||
{ terPRE_SEQ, "terPRE_SEQ", "Missing/inapplicable prior transaction." },
|
||||
{ terOWNERS, "terOWNERS", "Non-zero owner count." },
|
||||
|
||||
{ tesSUCCESS, "tesSUCCESS", "The transaction was applied." },
|
||||
};
|
||||
{ tesSUCCESS, "tesSUCCESS", "The transaction was applied." },
|
||||
};
|
||||
|
||||
int iIndex = NUMBER(transResultInfoA);
|
||||
int iIndex = NUMBER (transResultInfoA);
|
||||
|
||||
while (iIndex-- && transResultInfoA[iIndex].terCode != terCode)
|
||||
;
|
||||
while (iIndex-- && transResultInfoA[iIndex].terCode != terCode)
|
||||
;
|
||||
|
||||
if (iIndex >= 0)
|
||||
{
|
||||
strToken = transResultInfoA[iIndex].cpToken;
|
||||
strHuman = transResultInfoA[iIndex].cpHuman;
|
||||
}
|
||||
if (iIndex >= 0)
|
||||
{
|
||||
strToken = transResultInfoA[iIndex].cpToken;
|
||||
strHuman = transResultInfoA[iIndex].cpHuman;
|
||||
}
|
||||
|
||||
return iIndex >= 0;
|
||||
return iIndex >= 0;
|
||||
}
|
||||
|
||||
std::string transToken(TER terCode)
|
||||
std::string transToken (TER terCode)
|
||||
{
|
||||
std::string strToken;
|
||||
std::string strHuman;
|
||||
std::string strToken;
|
||||
std::string strHuman;
|
||||
|
||||
return transResultInfo(terCode, strToken, strHuman) ? strToken : "-";
|
||||
return transResultInfo (terCode, strToken, strHuman) ? strToken : "-";
|
||||
}
|
||||
|
||||
std::string transHuman(TER terCode)
|
||||
std::string transHuman (TER terCode)
|
||||
{
|
||||
std::string strToken;
|
||||
std::string strHuman;
|
||||
std::string strToken;
|
||||
std::string strHuman;
|
||||
|
||||
return transResultInfo(terCode, strToken, strHuman) ? strHuman : "-";
|
||||
return transResultInfo (terCode, strToken, strHuman) ? strHuman : "-";
|
||||
}
|
||||
|
||||
// vim:ts=4
|
||||
|
||||
@@ -7,149 +7,149 @@
|
||||
//
|
||||
// VFALCO TODO consider renaming TER to TxErr or TxResult for clarity.
|
||||
//
|
||||
enum TER // aka TransactionEngineResult
|
||||
enum TER // aka TransactionEngineResult
|
||||
{
|
||||
// Note: Range is stable. Exact numbers are currently unstable. Use tokens.
|
||||
// Note: Range is stable. Exact numbers are currently unstable. Use tokens.
|
||||
|
||||
// -399 .. -300: L Local error (transaction fee inadequate, exceeds local limit)
|
||||
// Only valid during non-consensus processing.
|
||||
// Implications:
|
||||
// - Not forwarded
|
||||
// - No fee check
|
||||
telLOCAL_ERROR = -399,
|
||||
telBAD_DOMAIN, // VFALCO TODO should read "telBAD_DOMAIN = -398," etc...
|
||||
telBAD_PATH_COUNT,
|
||||
telBAD_PUBLIC_KEY,
|
||||
telFAILED_PROCESSING,
|
||||
telINSUF_FEE_P,
|
||||
telNO_DST_PARTIAL,
|
||||
// -399 .. -300: L Local error (transaction fee inadequate, exceeds local limit)
|
||||
// Only valid during non-consensus processing.
|
||||
// Implications:
|
||||
// - Not forwarded
|
||||
// - No fee check
|
||||
telLOCAL_ERROR = -399,
|
||||
telBAD_DOMAIN, // VFALCO TODO should read "telBAD_DOMAIN = -398," etc...
|
||||
telBAD_PATH_COUNT,
|
||||
telBAD_PUBLIC_KEY,
|
||||
telFAILED_PROCESSING,
|
||||
telINSUF_FEE_P,
|
||||
telNO_DST_PARTIAL,
|
||||
|
||||
// -299 .. -200: M Malformed (bad signature)
|
||||
// Causes:
|
||||
// - Transaction corrupt.
|
||||
// Implications:
|
||||
// - Not applied
|
||||
// - Not forwarded
|
||||
// - Reject
|
||||
// - Can not succeed in any imagined ledger.
|
||||
temMALFORMED = -299,
|
||||
temBAD_AMOUNT,
|
||||
temBAD_AUTH_MASTER,
|
||||
temBAD_CURRENCY,
|
||||
temBAD_FEE,
|
||||
temBAD_EXPIRATION,
|
||||
temBAD_ISSUER,
|
||||
temBAD_LIMIT,
|
||||
temBAD_OFFER,
|
||||
temBAD_PATH,
|
||||
temBAD_PATH_LOOP,
|
||||
temBAD_PUBLISH,
|
||||
temBAD_TRANSFER_RATE,
|
||||
temBAD_SEND_XRP_LIMIT,
|
||||
temBAD_SEND_XRP_MAX,
|
||||
temBAD_SEND_XRP_NO_DIRECT,
|
||||
temBAD_SEND_XRP_PARTIAL,
|
||||
temBAD_SEND_XRP_PATHS,
|
||||
temBAD_SIGNATURE,
|
||||
temBAD_SRC_ACCOUNT,
|
||||
temBAD_SEQUENCE,
|
||||
temDST_IS_SRC,
|
||||
temDST_NEEDED,
|
||||
temINVALID,
|
||||
temINVALID_FLAG,
|
||||
temREDUNDANT,
|
||||
temREDUNDANT_SEND_MAX,
|
||||
temRIPPLE_EMPTY,
|
||||
temUNCERTAIN, // An intermediate result used internally, should never be returned.
|
||||
temUNKNOWN,
|
||||
// -299 .. -200: M Malformed (bad signature)
|
||||
// Causes:
|
||||
// - Transaction corrupt.
|
||||
// Implications:
|
||||
// - Not applied
|
||||
// - Not forwarded
|
||||
// - Reject
|
||||
// - Can not succeed in any imagined ledger.
|
||||
temMALFORMED = -299,
|
||||
temBAD_AMOUNT,
|
||||
temBAD_AUTH_MASTER,
|
||||
temBAD_CURRENCY,
|
||||
temBAD_FEE,
|
||||
temBAD_EXPIRATION,
|
||||
temBAD_ISSUER,
|
||||
temBAD_LIMIT,
|
||||
temBAD_OFFER,
|
||||
temBAD_PATH,
|
||||
temBAD_PATH_LOOP,
|
||||
temBAD_PUBLISH,
|
||||
temBAD_TRANSFER_RATE,
|
||||
temBAD_SEND_XRP_LIMIT,
|
||||
temBAD_SEND_XRP_MAX,
|
||||
temBAD_SEND_XRP_NO_DIRECT,
|
||||
temBAD_SEND_XRP_PARTIAL,
|
||||
temBAD_SEND_XRP_PATHS,
|
||||
temBAD_SIGNATURE,
|
||||
temBAD_SRC_ACCOUNT,
|
||||
temBAD_SEQUENCE,
|
||||
temDST_IS_SRC,
|
||||
temDST_NEEDED,
|
||||
temINVALID,
|
||||
temINVALID_FLAG,
|
||||
temREDUNDANT,
|
||||
temREDUNDANT_SEND_MAX,
|
||||
temRIPPLE_EMPTY,
|
||||
temUNCERTAIN, // An intermediate result used internally, should never be returned.
|
||||
temUNKNOWN,
|
||||
|
||||
// -199 .. -100: F Failure (sequence number previously used)
|
||||
// Causes:
|
||||
// - Transaction cannot succeed because of ledger state.
|
||||
// - Unexpected ledger state.
|
||||
// - C++ exception.
|
||||
// Implications:
|
||||
// - Not applied
|
||||
// - Not forwarded
|
||||
// - Could succeed in an imagined ledger.
|
||||
tefFAILURE = -199,
|
||||
tefALREADY,
|
||||
tefBAD_ADD_AUTH,
|
||||
tefBAD_AUTH,
|
||||
tefBAD_CLAIM_ID,
|
||||
tefBAD_GEN_AUTH,
|
||||
tefBAD_LEDGER,
|
||||
tefCLAIMED,
|
||||
tefCREATED,
|
||||
tefDST_TAG_NEEDED,
|
||||
tefEXCEPTION,
|
||||
tefGEN_IN_USE,
|
||||
tefINTERNAL,
|
||||
tefNO_AUTH_REQUIRED, // Can't set auth if auth is not required.
|
||||
tefPAST_SEQ,
|
||||
tefWRONG_PRIOR,
|
||||
// -199 .. -100: F Failure (sequence number previously used)
|
||||
// Causes:
|
||||
// - Transaction cannot succeed because of ledger state.
|
||||
// - Unexpected ledger state.
|
||||
// - C++ exception.
|
||||
// Implications:
|
||||
// - Not applied
|
||||
// - Not forwarded
|
||||
// - Could succeed in an imagined ledger.
|
||||
tefFAILURE = -199,
|
||||
tefALREADY,
|
||||
tefBAD_ADD_AUTH,
|
||||
tefBAD_AUTH,
|
||||
tefBAD_CLAIM_ID,
|
||||
tefBAD_GEN_AUTH,
|
||||
tefBAD_LEDGER,
|
||||
tefCLAIMED,
|
||||
tefCREATED,
|
||||
tefDST_TAG_NEEDED,
|
||||
tefEXCEPTION,
|
||||
tefGEN_IN_USE,
|
||||
tefINTERNAL,
|
||||
tefNO_AUTH_REQUIRED, // Can't set auth if auth is not required.
|
||||
tefPAST_SEQ,
|
||||
tefWRONG_PRIOR,
|
||||
|
||||
// -99 .. -1: R Retry (sequence too high, no funds for txn fee, originating account non-existent)
|
||||
// Causes:
|
||||
// - Prior application of another, possibly non-existant, another transaction could allow this transaction to succeed.
|
||||
// Implications:
|
||||
// - Not applied
|
||||
// - Not forwarded
|
||||
// - Might succeed later
|
||||
// - Hold
|
||||
// - Makes hole in sequence which jams transactions.
|
||||
terRETRY = -99,
|
||||
terFUNDS_SPENT, // This is a free transaction, therefore don't burden network.
|
||||
terINSUF_FEE_B, // Can't pay fee, therefore don't burden network.
|
||||
terNO_ACCOUNT, // Can't pay fee, therefore don't burden network.
|
||||
terNO_AUTH, // Not authorized to hold IOUs.
|
||||
terNO_LINE, // Internal flag.
|
||||
terOWNERS, // Can't succeed with non-zero owner count.
|
||||
terPRE_SEQ, // Can't pay fee, no point in forwarding, therefore don't burden network.
|
||||
terLAST, // Process after all other transactions
|
||||
// -99 .. -1: R Retry (sequence too high, no funds for txn fee, originating account non-existent)
|
||||
// Causes:
|
||||
// - Prior application of another, possibly non-existant, another transaction could allow this transaction to succeed.
|
||||
// Implications:
|
||||
// - Not applied
|
||||
// - Not forwarded
|
||||
// - Might succeed later
|
||||
// - Hold
|
||||
// - Makes hole in sequence which jams transactions.
|
||||
terRETRY = -99,
|
||||
terFUNDS_SPENT, // This is a free transaction, therefore don't burden network.
|
||||
terINSUF_FEE_B, // Can't pay fee, therefore don't burden network.
|
||||
terNO_ACCOUNT, // Can't pay fee, therefore don't burden network.
|
||||
terNO_AUTH, // Not authorized to hold IOUs.
|
||||
terNO_LINE, // Internal flag.
|
||||
terOWNERS, // Can't succeed with non-zero owner count.
|
||||
terPRE_SEQ, // Can't pay fee, no point in forwarding, therefore don't burden network.
|
||||
terLAST, // Process after all other transactions
|
||||
|
||||
// 0: S Success (success)
|
||||
// Causes:
|
||||
// - Success.
|
||||
// Implications:
|
||||
// - Applied
|
||||
// - Forwarded
|
||||
tesSUCCESS = 0,
|
||||
// 0: S Success (success)
|
||||
// Causes:
|
||||
// - Success.
|
||||
// Implications:
|
||||
// - Applied
|
||||
// - Forwarded
|
||||
tesSUCCESS = 0,
|
||||
|
||||
// 100 .. 129 C Claim fee only (ripple transaction with no good paths, pay to non-existent account, no path)
|
||||
// Causes:
|
||||
// - Success, but does not achieve optimal result.
|
||||
// - Invalid transaction or no effect, but claim fee to use the sequence number.
|
||||
// Implications:
|
||||
// - Applied
|
||||
// - Forwarded
|
||||
// Only allowed as a return code of appliedTransaction when !tapRetry. Otherwise, treated as terRETRY.
|
||||
//
|
||||
// DO NOT CHANGE THESE NUMBERS: They appear in ledger meta data.
|
||||
tecCLAIM = 100,
|
||||
tecPATH_PARTIAL = 101,
|
||||
tecUNFUNDED_ADD = 102,
|
||||
tecUNFUNDED_OFFER = 103,
|
||||
tecUNFUNDED_PAYMENT = 104,
|
||||
tecFAILED_PROCESSING = 105,
|
||||
tecDIR_FULL = 121,
|
||||
tecINSUF_RESERVE_LINE = 122,
|
||||
tecINSUF_RESERVE_OFFER = 123,
|
||||
tecNO_DST = 124,
|
||||
tecNO_DST_INSUF_XRP = 125,
|
||||
tecNO_LINE_INSUF_RESERVE = 126,
|
||||
tecNO_LINE_REDUNDANT = 127,
|
||||
tecPATH_DRY = 128,
|
||||
tecUNFUNDED = 129, // Deprecated, old ambiguous unfunded.
|
||||
// 100 .. 129 C Claim fee only (ripple transaction with no good paths, pay to non-existent account, no path)
|
||||
// Causes:
|
||||
// - Success, but does not achieve optimal result.
|
||||
// - Invalid transaction or no effect, but claim fee to use the sequence number.
|
||||
// Implications:
|
||||
// - Applied
|
||||
// - Forwarded
|
||||
// Only allowed as a return code of appliedTransaction when !tapRetry. Otherwise, treated as terRETRY.
|
||||
//
|
||||
// DO NOT CHANGE THESE NUMBERS: They appear in ledger meta data.
|
||||
tecCLAIM = 100,
|
||||
tecPATH_PARTIAL = 101,
|
||||
tecUNFUNDED_ADD = 102,
|
||||
tecUNFUNDED_OFFER = 103,
|
||||
tecUNFUNDED_PAYMENT = 104,
|
||||
tecFAILED_PROCESSING = 105,
|
||||
tecDIR_FULL = 121,
|
||||
tecINSUF_RESERVE_LINE = 122,
|
||||
tecINSUF_RESERVE_OFFER = 123,
|
||||
tecNO_DST = 124,
|
||||
tecNO_DST_INSUF_XRP = 125,
|
||||
tecNO_LINE_INSUF_RESERVE = 126,
|
||||
tecNO_LINE_REDUNDANT = 127,
|
||||
tecPATH_DRY = 128,
|
||||
tecUNFUNDED = 129, // Deprecated, old ambiguous unfunded.
|
||||
};
|
||||
|
||||
// VFALCO TODO change these to normal functions.
|
||||
#define isTelLocal(x) ((x) >= telLOCAL_ERROR && (x) < temMALFORMED)
|
||||
#define isTemMalformed(x) ((x) >= temMALFORMED && (x) < tefFAILURE)
|
||||
#define isTefFailure(x) ((x) >= tefFAILURE && (x) < terRETRY)
|
||||
#define isTerRetry(x) ((x) >= terRETRY && (x) < tesSUCCESS)
|
||||
#define isTesSuccess(x) ((x) == tesSUCCESS)
|
||||
#define isTecClaim(x) ((x) >= tecCLAIM)
|
||||
#define isTelLocal(x) ((x) >= telLOCAL_ERROR && (x) < temMALFORMED)
|
||||
#define isTemMalformed(x) ((x) >= temMALFORMED && (x) < tefFAILURE)
|
||||
#define isTefFailure(x) ((x) >= tefFAILURE && (x) < terRETRY)
|
||||
#define isTerRetry(x) ((x) >= terRETRY && (x) < tesSUCCESS)
|
||||
#define isTesSuccess(x) ((x) == tesSUCCESS)
|
||||
#define isTecClaim(x) ((x) >= tecCLAIM)
|
||||
|
||||
// VFALCO TODO group these into a shell class along with the defines above.
|
||||
extern bool transResultInfo (TER terCode, std::string& strToken, std::string& strHuman);
|
||||
|
||||
@@ -4,111 +4,117 @@ std::map<int, TransactionFormat*> TransactionFormat::byType;
|
||||
std::map<std::string, TransactionFormat*> TransactionFormat::byName;
|
||||
|
||||
// VFALCO TODO surely we can think of a better way than to use macros??
|
||||
#define TF_BASE \
|
||||
<< SOElement(sfTransactionType, SOE_REQUIRED) \
|
||||
<< SOElement(sfFlags, SOE_OPTIONAL) \
|
||||
<< SOElement(sfSourceTag, SOE_OPTIONAL) \
|
||||
<< SOElement(sfAccount, SOE_REQUIRED) \
|
||||
<< SOElement(sfSequence, SOE_REQUIRED) \
|
||||
<< SOElement(sfPreviousTxnID, SOE_OPTIONAL) \
|
||||
<< SOElement(sfFee, SOE_REQUIRED) \
|
||||
<< SOElement(sfOperationLimit, SOE_OPTIONAL) \
|
||||
<< SOElement(sfSigningPubKey, SOE_REQUIRED) \
|
||||
<< SOElement(sfTxnSignature, SOE_OPTIONAL)
|
||||
#define TF_BASE \
|
||||
<< SOElement(sfTransactionType, SOE_REQUIRED) \
|
||||
<< SOElement(sfFlags, SOE_OPTIONAL) \
|
||||
<< SOElement(sfSourceTag, SOE_OPTIONAL) \
|
||||
<< SOElement(sfAccount, SOE_REQUIRED) \
|
||||
<< SOElement(sfSequence, SOE_REQUIRED) \
|
||||
<< SOElement(sfPreviousTxnID, SOE_OPTIONAL) \
|
||||
<< SOElement(sfFee, SOE_REQUIRED) \
|
||||
<< SOElement(sfOperationLimit, SOE_OPTIONAL) \
|
||||
<< SOElement(sfSigningPubKey, SOE_REQUIRED) \
|
||||
<< SOElement(sfTxnSignature, SOE_OPTIONAL)
|
||||
|
||||
#define DECLARE_TF(name, type) tf = new TransactionFormat(#name, type); (*tf) TF_BASE
|
||||
|
||||
void TFInit()
|
||||
void TFInit ()
|
||||
{
|
||||
TransactionFormat* tf;
|
||||
TransactionFormat* tf;
|
||||
|
||||
DECLARE_TF(AccountSet, ttACCOUNT_SET)
|
||||
<< SOElement(sfEmailHash, SOE_OPTIONAL)
|
||||
<< SOElement(sfWalletLocator, SOE_OPTIONAL)
|
||||
<< SOElement(sfWalletSize, SOE_OPTIONAL)
|
||||
<< SOElement(sfMessageKey, SOE_OPTIONAL)
|
||||
<< SOElement(sfDomain, SOE_OPTIONAL)
|
||||
<< SOElement(sfTransferRate, SOE_OPTIONAL)
|
||||
;
|
||||
DECLARE_TF (AccountSet, ttACCOUNT_SET)
|
||||
<< SOElement (sfEmailHash, SOE_OPTIONAL)
|
||||
<< SOElement (sfWalletLocator, SOE_OPTIONAL)
|
||||
<< SOElement (sfWalletSize, SOE_OPTIONAL)
|
||||
<< SOElement (sfMessageKey, SOE_OPTIONAL)
|
||||
<< SOElement (sfDomain, SOE_OPTIONAL)
|
||||
<< SOElement (sfTransferRate, SOE_OPTIONAL)
|
||||
;
|
||||
|
||||
DECLARE_TF(TrustSet, ttTRUST_SET)
|
||||
<< SOElement(sfLimitAmount, SOE_OPTIONAL)
|
||||
<< SOElement(sfQualityIn, SOE_OPTIONAL)
|
||||
<< SOElement(sfQualityOut, SOE_OPTIONAL)
|
||||
;
|
||||
DECLARE_TF (TrustSet, ttTRUST_SET)
|
||||
<< SOElement (sfLimitAmount, SOE_OPTIONAL)
|
||||
<< SOElement (sfQualityIn, SOE_OPTIONAL)
|
||||
<< SOElement (sfQualityOut, SOE_OPTIONAL)
|
||||
;
|
||||
|
||||
DECLARE_TF(OfferCreate, ttOFFER_CREATE)
|
||||
<< SOElement(sfTakerPays, SOE_REQUIRED)
|
||||
<< SOElement(sfTakerGets, SOE_REQUIRED)
|
||||
<< SOElement(sfExpiration, SOE_OPTIONAL)
|
||||
;
|
||||
DECLARE_TF (OfferCreate, ttOFFER_CREATE)
|
||||
<< SOElement (sfTakerPays, SOE_REQUIRED)
|
||||
<< SOElement (sfTakerGets, SOE_REQUIRED)
|
||||
<< SOElement (sfExpiration, SOE_OPTIONAL)
|
||||
;
|
||||
|
||||
DECLARE_TF(OfferCancel, ttOFFER_CANCEL)
|
||||
<< SOElement(sfOfferSequence, SOE_REQUIRED)
|
||||
;
|
||||
DECLARE_TF (OfferCancel, ttOFFER_CANCEL)
|
||||
<< SOElement (sfOfferSequence, SOE_REQUIRED)
|
||||
;
|
||||
|
||||
DECLARE_TF(SetRegularKey, ttREGULAR_KEY_SET)
|
||||
<< SOElement(sfRegularKey, SOE_REQUIRED)
|
||||
;
|
||||
DECLARE_TF (SetRegularKey, ttREGULAR_KEY_SET)
|
||||
<< SOElement (sfRegularKey, SOE_REQUIRED)
|
||||
;
|
||||
|
||||
DECLARE_TF(Payment, ttPAYMENT)
|
||||
<< SOElement(sfDestination, SOE_REQUIRED)
|
||||
<< SOElement(sfAmount, SOE_REQUIRED)
|
||||
<< SOElement(sfSendMax, SOE_OPTIONAL)
|
||||
<< SOElement(sfPaths, SOE_DEFAULT)
|
||||
<< SOElement(sfInvoiceID, SOE_OPTIONAL)
|
||||
<< SOElement(sfDestinationTag, SOE_OPTIONAL)
|
||||
;
|
||||
DECLARE_TF (Payment, ttPAYMENT)
|
||||
<< SOElement (sfDestination, SOE_REQUIRED)
|
||||
<< SOElement (sfAmount, SOE_REQUIRED)
|
||||
<< SOElement (sfSendMax, SOE_OPTIONAL)
|
||||
<< SOElement (sfPaths, SOE_DEFAULT)
|
||||
<< SOElement (sfInvoiceID, SOE_OPTIONAL)
|
||||
<< SOElement (sfDestinationTag, SOE_OPTIONAL)
|
||||
;
|
||||
|
||||
DECLARE_TF(Contract, ttCONTRACT)
|
||||
<< SOElement(sfExpiration, SOE_REQUIRED)
|
||||
<< SOElement(sfBondAmount, SOE_REQUIRED)
|
||||
<< SOElement(sfStampEscrow, SOE_REQUIRED)
|
||||
<< SOElement(sfRippleEscrow, SOE_REQUIRED)
|
||||
<< SOElement(sfCreateCode, SOE_OPTIONAL)
|
||||
<< SOElement(sfFundCode, SOE_OPTIONAL)
|
||||
<< SOElement(sfRemoveCode, SOE_OPTIONAL)
|
||||
<< SOElement(sfExpireCode, SOE_OPTIONAL)
|
||||
;
|
||||
DECLARE_TF (Contract, ttCONTRACT)
|
||||
<< SOElement (sfExpiration, SOE_REQUIRED)
|
||||
<< SOElement (sfBondAmount, SOE_REQUIRED)
|
||||
<< SOElement (sfStampEscrow, SOE_REQUIRED)
|
||||
<< SOElement (sfRippleEscrow, SOE_REQUIRED)
|
||||
<< SOElement (sfCreateCode, SOE_OPTIONAL)
|
||||
<< SOElement (sfFundCode, SOE_OPTIONAL)
|
||||
<< SOElement (sfRemoveCode, SOE_OPTIONAL)
|
||||
<< SOElement (sfExpireCode, SOE_OPTIONAL)
|
||||
;
|
||||
|
||||
DECLARE_TF(RemoveContract, ttCONTRACT_REMOVE)
|
||||
<< SOElement(sfTarget, SOE_REQUIRED)
|
||||
;
|
||||
DECLARE_TF (RemoveContract, ttCONTRACT_REMOVE)
|
||||
<< SOElement (sfTarget, SOE_REQUIRED)
|
||||
;
|
||||
|
||||
DECLARE_TF(EnableFeature, ttFEATURE)
|
||||
<< SOElement(sfFeature, SOE_REQUIRED)
|
||||
;
|
||||
DECLARE_TF (EnableFeature, ttFEATURE)
|
||||
<< SOElement (sfFeature, SOE_REQUIRED)
|
||||
;
|
||||
|
||||
DECLARE_TF(SetFee, ttFEE)
|
||||
<< SOElement(sfBaseFee, SOE_REQUIRED)
|
||||
<< SOElement(sfReferenceFeeUnits, SOE_REQUIRED)
|
||||
<< SOElement(sfReserveBase, SOE_REQUIRED)
|
||||
<< SOElement(sfReserveIncrement, SOE_REQUIRED)
|
||||
;
|
||||
DECLARE_TF (SetFee, ttFEE)
|
||||
<< SOElement (sfBaseFee, SOE_REQUIRED)
|
||||
<< SOElement (sfReferenceFeeUnits, SOE_REQUIRED)
|
||||
<< SOElement (sfReserveBase, SOE_REQUIRED)
|
||||
<< SOElement (sfReserveIncrement, SOE_REQUIRED)
|
||||
;
|
||||
}
|
||||
|
||||
TransactionFormat* TransactionFormat::getTxnFormat(TransactionType t)
|
||||
TransactionFormat* TransactionFormat::getTxnFormat (TransactionType t)
|
||||
{
|
||||
std::map<int, TransactionFormat*>::iterator it = byType.find(static_cast<int>(t));
|
||||
if (it == byType.end())
|
||||
return NULL;
|
||||
return it->second;
|
||||
std::map<int, TransactionFormat*>::iterator it = byType.find (static_cast<int> (t));
|
||||
|
||||
if (it == byType.end ())
|
||||
return NULL;
|
||||
|
||||
return it->second;
|
||||
}
|
||||
|
||||
TransactionFormat* TransactionFormat::getTxnFormat(int t)
|
||||
TransactionFormat* TransactionFormat::getTxnFormat (int t)
|
||||
{
|
||||
std::map<int, TransactionFormat*>::iterator it = byType.find((t));
|
||||
if (it == byType.end())
|
||||
return NULL;
|
||||
return it->second;
|
||||
std::map<int, TransactionFormat*>::iterator it = byType.find ((t));
|
||||
|
||||
if (it == byType.end ())
|
||||
return NULL;
|
||||
|
||||
return it->second;
|
||||
}
|
||||
|
||||
TransactionFormat* TransactionFormat::getTxnFormat(const std::string& t)
|
||||
TransactionFormat* TransactionFormat::getTxnFormat (const std::string& t)
|
||||
{
|
||||
std::map<std::string, TransactionFormat*>::iterator it = byName.find((t));
|
||||
if (it == byName.end())
|
||||
return NULL;
|
||||
return it->second;
|
||||
std::map<std::string, TransactionFormat*>::iterator it = byName.find ((t));
|
||||
|
||||
if (it == byName.end ())
|
||||
return NULL;
|
||||
|
||||
return it->second;
|
||||
}
|
||||
|
||||
// vim:ts=4
|
||||
// vim:ts=4
|
||||
|
||||
@@ -3,86 +3,86 @@
|
||||
|
||||
enum TransactionType
|
||||
{
|
||||
ttINVALID = -1,
|
||||
ttINVALID = -1,
|
||||
|
||||
ttPAYMENT = 0,
|
||||
ttCLAIM = 1, // open
|
||||
ttWALLET_ADD = 2,
|
||||
ttACCOUNT_SET = 3,
|
||||
ttPASSWORD_FUND = 4, // open
|
||||
ttREGULAR_KEY_SET = 5,
|
||||
ttNICKNAME_SET = 6, // open
|
||||
ttOFFER_CREATE = 7,
|
||||
ttOFFER_CANCEL = 8,
|
||||
ttCONTRACT = 9,
|
||||
ttCONTRACT_REMOVE = 10, // can we use the same msg as offer cancel
|
||||
ttPAYMENT = 0,
|
||||
ttCLAIM = 1, // open
|
||||
ttWALLET_ADD = 2,
|
||||
ttACCOUNT_SET = 3,
|
||||
ttPASSWORD_FUND = 4, // open
|
||||
ttREGULAR_KEY_SET = 5,
|
||||
ttNICKNAME_SET = 6, // open
|
||||
ttOFFER_CREATE = 7,
|
||||
ttOFFER_CANCEL = 8,
|
||||
ttCONTRACT = 9,
|
||||
ttCONTRACT_REMOVE = 10, // can we use the same msg as offer cancel
|
||||
|
||||
ttTRUST_SET = 20,
|
||||
ttTRUST_SET = 20,
|
||||
|
||||
ttFEATURE = 100,
|
||||
ttFEE = 101,
|
||||
ttFEATURE = 100,
|
||||
ttFEE = 101,
|
||||
};
|
||||
|
||||
class TransactionFormat
|
||||
{
|
||||
public:
|
||||
std::string t_name;
|
||||
TransactionType t_type;
|
||||
SOTemplate elements;
|
||||
std::string t_name;
|
||||
TransactionType t_type;
|
||||
SOTemplate elements;
|
||||
|
||||
static std::map<int, TransactionFormat*> byType;
|
||||
static std::map<std::string, TransactionFormat*> byName;
|
||||
static std::map<int, TransactionFormat*> byType;
|
||||
static std::map<std::string, TransactionFormat*> byName;
|
||||
|
||||
TransactionFormat(const char *name, TransactionType type) : t_name(name), t_type(type)
|
||||
TransactionFormat (const char* name, TransactionType type) : t_name (name), t_type (type)
|
||||
{
|
||||
byName[name] = this;
|
||||
byType[type] = this;
|
||||
byName[name] = this;
|
||||
byType[type] = this;
|
||||
}
|
||||
TransactionFormat& operator<<(const SOElement& el)
|
||||
TransactionFormat& operator<< (const SOElement& el)
|
||||
{
|
||||
elements.push_back(el);
|
||||
return *this;
|
||||
elements.push_back (el);
|
||||
return *this;
|
||||
}
|
||||
|
||||
static TransactionFormat* getTxnFormat(TransactionType t);
|
||||
static TransactionFormat* getTxnFormat(const std::string& t);
|
||||
static TransactionFormat* getTxnFormat(int t);
|
||||
static TransactionFormat* getTxnFormat (TransactionType t);
|
||||
static TransactionFormat* getTxnFormat (const std::string& t);
|
||||
static TransactionFormat* getTxnFormat (int t);
|
||||
};
|
||||
|
||||
const int TransactionMinLen = 32;
|
||||
const int TransactionMaxLen = 1048576;
|
||||
const int TransactionMinLen = 32;
|
||||
const int TransactionMaxLen = 1048576;
|
||||
|
||||
//
|
||||
// Transaction flags.
|
||||
//
|
||||
|
||||
// AccountSet flags:
|
||||
const uint32 tfRequireDestTag = 0x00010000;
|
||||
const uint32 tfOptionalDestTag = 0x00020000;
|
||||
const uint32 tfRequireAuth = 0x00040000;
|
||||
const uint32 tfOptionalAuth = 0x00080000;
|
||||
const uint32 tfDisallowXRP = 0x00100000;
|
||||
const uint32 tfAllowXRP = 0x00200000;
|
||||
const uint32 tfAccountSetMask = ~(tfRequireDestTag|tfOptionalDestTag
|
||||
|tfRequireAuth|tfOptionalAuth
|
||||
|tfDisallowXRP|tfAllowXRP);
|
||||
const uint32 tfRequireDestTag = 0x00010000;
|
||||
const uint32 tfOptionalDestTag = 0x00020000;
|
||||
const uint32 tfRequireAuth = 0x00040000;
|
||||
const uint32 tfOptionalAuth = 0x00080000;
|
||||
const uint32 tfDisallowXRP = 0x00100000;
|
||||
const uint32 tfAllowXRP = 0x00200000;
|
||||
const uint32 tfAccountSetMask = ~ (tfRequireDestTag | tfOptionalDestTag
|
||||
| tfRequireAuth | tfOptionalAuth
|
||||
| tfDisallowXRP | tfAllowXRP);
|
||||
|
||||
// OfferCreate flags:
|
||||
const uint32 tfPassive = 0x00010000;
|
||||
const uint32 tfImmediateOrCancel = 0x00020000;
|
||||
const uint32 tfFillOrKill = 0x00040000;
|
||||
const uint32 tfSell = 0x00080000;
|
||||
const uint32 tfOfferCreateMask = ~(tfPassive|tfImmediateOrCancel|tfFillOrKill|tfSell);
|
||||
const uint32 tfPassive = 0x00010000;
|
||||
const uint32 tfImmediateOrCancel = 0x00020000;
|
||||
const uint32 tfFillOrKill = 0x00040000;
|
||||
const uint32 tfSell = 0x00080000;
|
||||
const uint32 tfOfferCreateMask = ~ (tfPassive | tfImmediateOrCancel | tfFillOrKill | tfSell);
|
||||
|
||||
// Payment flags:
|
||||
const uint32 tfNoRippleDirect = 0x00010000;
|
||||
const uint32 tfPartialPayment = 0x00020000;
|
||||
const uint32 tfLimitQuality = 0x00040000;
|
||||
const uint32 tfPaymentMask = ~(tfPartialPayment|tfLimitQuality|tfNoRippleDirect);
|
||||
const uint32 tfNoRippleDirect = 0x00010000;
|
||||
const uint32 tfPartialPayment = 0x00020000;
|
||||
const uint32 tfLimitQuality = 0x00040000;
|
||||
const uint32 tfPaymentMask = ~ (tfPartialPayment | tfLimitQuality | tfNoRippleDirect);
|
||||
|
||||
// TrustSet flags:
|
||||
const uint32 tfSetfAuth = 0x00010000;
|
||||
const uint32 tfTrustSetMask = ~(tfSetfAuth);
|
||||
const uint32 tfSetfAuth = 0x00010000;
|
||||
const uint32 tfTrustSetMask = ~ (tfSetfAuth);
|
||||
|
||||
#endif
|
||||
// vim:ts=4
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
Copyright (c) 2011-2013, OpenCoin, Inc.
|
||||
Copyright (c) 2011-2013, OpenCoin, Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
/** Add this to get the @ref ripple_data module.
|
||||
/** Add this to get the @ref ripple_data module.
|
||||
|
||||
@file ripple_data.cpp
|
||||
@ingroup ripple_data
|
||||
|
||||
@@ -1,32 +1,32 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
Copyright (c) 2011-2013, OpenCoin, Inc.
|
||||
Copyright (c) 2011-2013, OpenCoin, Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
/** Include this to get the @ref ripple_data module.
|
||||
/** Include this to get the @ref ripple_data module.
|
||||
|
||||
@file ripple_data.h
|
||||
@ingroup ripple_data
|
||||
*/
|
||||
|
||||
/** Ripple specific data representation and manipulation.
|
||||
/** Ripple specific data representation and manipulation.
|
||||
|
||||
These form the building blocks of Ripple data.
|
||||
These form the building blocks of Ripple data.
|
||||
|
||||
@defgroup ripple_data
|
||||
@defgroup ripple_data
|
||||
*/
|
||||
|
||||
#ifndef RIPPLE_DATA_H
|
||||
|
||||
@@ -10,29 +10,55 @@ JSONCache::Key::Key (int op, uint256 const& ledger, uint160 const& object, int l
|
||||
mHash = static_cast <std::size_t> (mOperation);
|
||||
|
||||
mLedger.hash_combine (mHash);
|
||||
|
||||
|
||||
mObject.hash_combine (mHash);
|
||||
}
|
||||
|
||||
int JSONCache::Key::compare (Key const& other) const
|
||||
{
|
||||
if (mHash < other.mHash) return -1;
|
||||
|
||||
if (mHash > other.mHash) return 1;
|
||||
|
||||
if (mOperation < other.mOperation) return -1;
|
||||
|
||||
if (mOperation > other.mOperation) return 1;
|
||||
|
||||
if (mLedger < other.mLedger) return -1;
|
||||
|
||||
if (mLedger > other.mLedger) return 1;
|
||||
|
||||
if (mObject < other.mObject) return -1;
|
||||
|
||||
if (mObject > other.mObject) return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool JSONCache::Key::operator< (Key const& rhs) const { return compare (rhs) < 0; }
|
||||
bool JSONCache::Key::operator> (Key const& rhs) const { return compare (rhs) > 0; }
|
||||
bool JSONCache::Key::operator<= (Key const& rhs) const { return compare (rhs) <= 0; }
|
||||
bool JSONCache::Key::operator>= (Key const& rhs) const { return compare (rhs) >= 0; }
|
||||
bool JSONCache::Key::operator!= (Key const& rhs) const { return compare (rhs) != 0; }
|
||||
bool JSONCache::Key::operator== (Key const& rhs) const { return compare (rhs) == 0; }
|
||||
bool JSONCache::Key::operator< (Key const& rhs) const
|
||||
{
|
||||
return compare (rhs) < 0;
|
||||
}
|
||||
bool JSONCache::Key::operator> (Key const& rhs) const
|
||||
{
|
||||
return compare (rhs) > 0;
|
||||
}
|
||||
bool JSONCache::Key::operator<= (Key const& rhs) const
|
||||
{
|
||||
return compare (rhs) <= 0;
|
||||
}
|
||||
bool JSONCache::Key::operator>= (Key const& rhs) const
|
||||
{
|
||||
return compare (rhs) >= 0;
|
||||
}
|
||||
bool JSONCache::Key::operator!= (Key const& rhs) const
|
||||
{
|
||||
return compare (rhs) != 0;
|
||||
}
|
||||
bool JSONCache::Key::operator== (Key const& rhs) const
|
||||
{
|
||||
return compare (rhs) == 0;
|
||||
}
|
||||
|
||||
void JSONCache::Key::touch (Key const& key) const
|
||||
{
|
||||
@@ -85,10 +111,10 @@ JSONCache::data_t JSONCache::getEntry (Kind kind, LedgerHash const& ledger, uint
|
||||
Key key (kind, ledger, object, getUptime ());
|
||||
|
||||
{
|
||||
boost::recursive_mutex::scoped_lock sl(m_lock);
|
||||
boost::recursive_mutex::scoped_lock sl (m_lock);
|
||||
|
||||
boost::unordered_map <Key, data_t>::iterator it = m_cache.find (key);
|
||||
|
||||
|
||||
if (it != m_cache.end ())
|
||||
{
|
||||
++mHits;
|
||||
@@ -113,7 +139,7 @@ void JSONCache::storeEntry (Kind kind, uint256 const& ledger, uint160 const& obj
|
||||
Key key (kind, ledger, object, getUptime ());
|
||||
|
||||
{
|
||||
boost::recursive_mutex::scoped_lock sl(m_lock);
|
||||
boost::recursive_mutex::scoped_lock sl (m_lock);
|
||||
|
||||
m_cache.insert (std::pair <Key, data_t> (key, data));
|
||||
}
|
||||
@@ -130,15 +156,15 @@ void JSONCache::sweep ()
|
||||
sweepTime -= m_expirationTime;
|
||||
|
||||
{
|
||||
boost::recursive_mutex::scoped_lock sl(m_lock);
|
||||
|
||||
boost::unordered_map <Key, data_t>::iterator it = m_cache.begin();
|
||||
boost::recursive_mutex::scoped_lock sl (m_lock);
|
||||
|
||||
boost::unordered_map <Key, data_t>::iterator it = m_cache.begin ();
|
||||
|
||||
while (it != m_cache.end ())
|
||||
{
|
||||
if (it->first.isExpired (sweepTime))
|
||||
{
|
||||
it = m_cache.erase(it);
|
||||
it = m_cache.erase (it);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -153,5 +179,5 @@ void JSONCache::sweep ()
|
||||
|
||||
int JSONCache::getUptime () const
|
||||
{
|
||||
return UptimeTimer::getInstance().getElapsedSeconds();
|
||||
return UptimeTimer::getInstance ().getElapsedSeconds ();
|
||||
}
|
||||
|
||||
@@ -12,13 +12,13 @@ public:
|
||||
{
|
||||
public:
|
||||
Key (int op, const uint256& ledger, const uint160& object, int lastUse);
|
||||
int compare(const Key& k) const;
|
||||
bool operator<(const Key &k) const;
|
||||
bool operator>(const Key &k) const;
|
||||
bool operator<=(const Key &k) const;
|
||||
bool operator>=(const Key &k) const;
|
||||
bool operator!=(const Key &k) const;
|
||||
bool operator==(const Key &k) const;
|
||||
int compare (const Key& k) const;
|
||||
bool operator< (const Key& k) const;
|
||||
bool operator> (const Key& k) const;
|
||||
bool operator<= (const Key& k) const;
|
||||
bool operator>= (const Key& k) const;
|
||||
bool operator!= (const Key& k) const;
|
||||
bool operator== (const Key& k) const;
|
||||
|
||||
void touch (Key const& key) const;
|
||||
bool isExpired (int expireTime) const;
|
||||
|
||||
@@ -5,10 +5,10 @@
|
||||
*/
|
||||
struct UptimeTimerAdapter
|
||||
{
|
||||
inline static int getElapsedSeconds ()
|
||||
{
|
||||
return UptimeTimer::getInstance().getElapsedSeconds ();
|
||||
}
|
||||
inline static int getElapsedSeconds ()
|
||||
{
|
||||
return UptimeTimer::getInstance ().getElapsedSeconds ();
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user