Add RippleAsset types

Conflicts:
	Builds/VisualStudio2012/RippleD.vcxproj.filters
This commit is contained in:
Vinnie Falco
2013-12-18 15:53:13 -08:00
parent b2dbe8ef83
commit 6527cdfa97
12 changed files with 780 additions and 126 deletions

View File

@@ -685,6 +685,12 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\ripple\types\impl\RippleAssets.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\ripple\types\impl\RippleIdentifierTests.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
@@ -2314,6 +2320,7 @@
<ClInclude Include="..\..\src\ripple\types\api\RippleAccountPrivateKey.h" />
<ClInclude Include="..\..\src\ripple\types\api\RippleAccountPublicKey.h" />
<ClInclude Include="..\..\src\ripple\types\api\CryptoIdentifier.h" />
<ClInclude Include="..\..\src\ripple\types\api\RippleAssets.h" />
<ClInclude Include="..\..\src\ripple\types\api\RippleLedgerHash.h" />
<ClInclude Include="..\..\src\ripple\types\api\RipplePrivateKey.h" />
<ClInclude Include="..\..\src\ripple\types\api\RipplePublicKey.h" />

View File

@@ -1398,6 +1398,12 @@
<ClCompile Include="..\..\src\ripple_app\shamap\RadixMapTest.cpp">
<Filter>[2] Old Ripple\ripple_app\shamap</Filter>
</ClCompile>
<ClCompile Include="..\..\src\ripple\types\impl\RippleAssets.cpp">
<Filter>[1] Ripple\types\impl</Filter>
</ClCompile>
<ClCompile Include="..\..\src\ripple\types\impl\RippleAssets.h">
<Filter>[1] Ripple\types\impl</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\src\ripple_basics\containers\KeyCache.h">
@@ -2871,6 +2877,9 @@
<ClInclude Include="..\..\src\ripple_app\shamap\RadixMapTest.h">
<Filter>[2] Old Ripple\ripple_app\shamap</Filter>
</ClInclude>
<ClInclude Include="..\..\src\ripple\types\api\RippleAssets.h">
<Filter>[1] Ripple\types\api</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<CustomBuild Include="..\..\src\ripple_data\protocol\ripple.proto">

View File

@@ -0,0 +1,399 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2012, 2013 Ripple Labs 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.
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.
*/
//==============================================================================
#ifndef RIPPLE_TYPES_RIPPLEASSETS_H_INCLUDED
#define RIPPLE_TYPES_RIPPLEASSETS_H_INCLUDED
#ifndef RIPPLE_USE_C11
#define RIPPLE_USE_C11 1
#endif
#if RIPPLE_USE_C11
# include <type_traits>
#else
# include "beast/beast/mpl/IfCond.h"
#endif
namespace ripple {
/** Identifies a currency in the payment network.
Currencies are associated with issuers.
@see RippleIssuer
*/
typedef uint160 RippleCurrency;
/** Identifies the account of a currency issuer.
Currency IOUs are issued by account holders.
@see RippleCurrency
*/
typedef uint160 RippleIssuer;
//------------------------------------------------------------------------------
/** Ripple asset specifier, expressed as a currency issuer pair.
When ByValue is `false`, this only stores references, and the caller
is responsible for managing object lifetime.
@see RippleCurrency, RippleIssuer, RippleAssset, RippleAssetRef
*/
template <bool ByValue>
class RippleAssetType
{
public:
#if RIPPLE_USE_C11
typedef typename std::conditional <ByValue,
RippleCurrency, RippleCurrency const&>::type Currency;
typedef typename std::conditional <ByValue,
RippleIssuer, RippleIssuer const&>::type Issuer;
#else
typedef typename mpl::IfCond <ByValue,
RippleCurrency, RippleCurrency const&>::type Currency;
typedef typename mpl::IfCond <ByValue,
RippleIssuer, RippleIssuer const&>::type Issuer;
#endif
Currency currency;
Issuer issuer;
RippleAssetType ()
{
}
RippleAssetType (RippleCurrency const& currency_,
RippleIssuer const& issuer_)
: currency (currency_)
, issuer (issuer_)
{
}
template <bool OtherByValue>
RippleAssetType (RippleAssetType <OtherByValue> const& other)
: currency (other.currency)
, issuer (other.issuer)
{
}
/** Assignment.
This is only valid when ByValue == `true`
*/
template <bool OtherByValue>
RippleAssetType& operator= (RippleAssetType <OtherByValue> const& other)
{
currency = other.currency;
issuer = other.issuer;
return *this;
}
bool is_xrp () const
{
if (currency.isZero ())
{
//check_invariant (issuer == ACCOUNT_ONE);
return true;
}
return false;
}
};
/** Ordered comparison.
The assets are ordered first by currency and then by issuer,
if the currency is not XRP.
*/
template <bool LhsByValue, bool RhsByValue>
int compare (RippleAssetType <LhsByValue> const& lhs,
RippleAssetType <RhsByValue> const& rhs)
{
int const diff (compare (lhs.currency, rhs.currency));
if (diff != 0)
return diff;
if (lhs.is_xrp ())
return 0;
return compare (lhs.issuer, rhs.issuer);
}
/** Equality comparison. */
/** @{ */
template <bool LhsByValue, bool RhsByValue>
bool operator== (RippleAssetType <LhsByValue> const& lhs,
RippleAssetType <RhsByValue> const& rhs)
{
return compare (lhs, rhs) == 0;
}
template <bool LhsByValue, bool RhsByValue>
bool operator!= (RippleAssetType <LhsByValue> const& lhs,
RippleAssetType <RhsByValue> const& rhs)
{
return ! (lhs == rhs);
}
/** @} */
/** Strict weak ordering. */
/** @{ */
template <bool LhsByValue, bool RhsByValue>
bool operator< (RippleAssetType <LhsByValue> const& lhs,
RippleAssetType <RhsByValue> const& rhs)
{
return compare (lhs, rhs) < 0;
}
template <bool LhsByValue, bool RhsByValue>
bool operator> (RippleAssetType <LhsByValue> const& lhs,
RippleAssetType <RhsByValue> const& rhs)
{
return rhs < lhs;
}
template <bool LhsByValue, bool RhsByValue>
bool operator>= (RippleAssetType <LhsByValue> const& lhs,
RippleAssetType <RhsByValue> const& rhs)
{
return ! (lhs < rhs);
}
template <bool LhsByValue, bool RhsByValue>
bool operator<= (RippleAssetType <LhsByValue> const& lhs,
RippleAssetType <RhsByValue> const& rhs)
{
return ! (rhs < lhs);
}
/** @} */
//------------------------------------------------------------------------------
typedef RippleAssetType <false> RippleAssetRef;
typedef RippleAssetType <true> RippleAsset;
/** Create an asset specifier by parsing the given JSON.
Errors, if any, will be returned or injected into the specified result
JSON object using the JSON-RPC error specification interface.
@param currency_field The JSON field name of the currency specifier
@param issuer_field The JSON field name of the issuer specifier
@param result The JSON in which to store any errors.
#return An asset representing the parsed JSON if no errors occurred.
*/
RippleAsset make_asset (Json::Value json,
std::string const& currency_field, std::string const& issuer_field,
Json::Value* result);
//------------------------------------------------------------------------------
/** Returns an asset specifier that represents XRP. */
inline RippleAssetRef xrp_asset ()
{
static RippleAsset asset (RippleCurrency (0), RippleIssuer (0));
return asset;
}
//------------------------------------------------------------------------------
/** Specifies an order book.
The order book is defined by the input asset ('in') and output
asset ('out').
*/
template <bool ByValue>
class RippleBookType
{
public:
typedef RippleAssetType <ByValue> AssetType;
AssetType in;
AssetType out;
RippleBookType ()
{
}
RippleBookType (AssetType const& in_, AssetType const& out_)
: in (in_)
, out (out_)
{
}
template <bool OtherByValue>
RippleBookType (RippleBookType <OtherByValue> const& other)
: in (other.in)
, out (other.out)
{
}
/** Assignment.
This is only valid when ByValue == `true`
*/
template <bool OtherByValue>
RippleBookType& operator= (RippleBookType <OtherByValue> const& other)
{
in = other.in;
out = other.out;
return *this;
}
};
/** Ordered comparison. */
template <bool LhsByValue, bool RhsByValue>
int compare (RippleBookType <LhsByValue> const& lhs,
RippleBookType <RhsByValue> const& rhs)
{
int const diff (compare (lhs.in, rhs.in));
if (diff != 0)
return diff;
return compare (lhs.out, rhs.out);
}
/** Equality comparison. */
/** @{ */
template <bool LhsByValue, bool RhsByValue>
bool operator== (RippleBookType <LhsByValue> const& lhs,
RippleBookType <RhsByValue> const& rhs)
{
return (lhs.in == rhs.in) &&
(lhs.out == rhs.out);
}
template <bool LhsByValue, bool RhsByValue>
bool operator!= (RippleBookType <LhsByValue> const& lhs,
RippleBookType <RhsByValue> const& rhs)
{
return (lhs.in != rhs.in) ||
(lhs.out != rhs.out);
}
/** @} */
/** Strict weak ordering. */
/** @{ */
template <bool LhsByValue, bool RhsByValue>
bool operator< (RippleBookType <LhsByValue> const& lhs,
RippleBookType <RhsByValue> const& rhs)
{
int const diff (compare (lhs.in, rhs.in));
if (diff != 0 || lhs.in.is_xrp ())
return diff < 0;
return lhs.out < rhs.out;
}
template <bool LhsByValue, bool RhsByValue>
bool operator> (RippleBookType <LhsByValue> const& lhs,
RippleBookType <RhsByValue> const& rhs)
{
return rhs < lhs;
}
template <bool LhsByValue, bool RhsByValue>
bool operator>= (RippleBookType <LhsByValue> const& lhs,
RippleBookType <RhsByValue> const& rhs)
{
return ! (lhs < rhs);
}
template <bool LhsByValue, bool RhsByValue>
bool operator<= (RippleBookType <LhsByValue> const& lhs,
RippleBookType <RhsByValue> const& rhs)
{
return ! (rhs < lhs);
}
/** @} */
//------------------------------------------------------------------------------
typedef RippleBookType <false> RippleBook;
typedef RippleBookType <true> RippleBookRef;
}
//------------------------------------------------------------------------------
namespace std {
template <bool ByValue>
struct hash <ripple::RippleAssetType <ByValue>>
: private boost::base_from_member <std::hash <ripple::RippleCurrency>, 0>
, private boost::base_from_member <std::hash <ripple::RippleIssuer>, 1>
{
private:
typedef boost::base_from_member <
std::hash <ripple::RippleCurrency>, 0> currency_hash_type;
typedef boost::base_from_member <
std::hash <ripple::RippleIssuer>, 1> issuer_hash_type;
public:
typedef std::size_t value_type;
typedef ripple::RippleAssetType <ByValue> argument_type;
value_type operator() (argument_type const& value) const
{
value_type result (currency_hash_type::member (value.currency));
if (! value.is_xrp ())
boost::hash_combine (result,
issuer_hash_type::member (value.issuer));
return result;
}
};
//------------------------------------------------------------------------------
template <bool ByValue>
struct hash <ripple::RippleBookType <ByValue>>
{
private:
typedef std::hash <ripple::RippleAssetType <ByValue>> hasher;
hasher m_hasher;
public:
typedef std::size_t value_type;
typedef ripple::RippleBookType <ByValue> argument_type;
value_type operator() (argument_type const& value) const
{
value_type result (m_hasher (value.in));
boost::hash_combine (result, m_hasher (value.out));
return result;
}
};
}
//------------------------------------------------------------------------------
namespace boost {
template <bool ByValue>
struct hash <ripple::RippleAssetType <ByValue>>
: std::hash <ripple::RippleAssetType <ByValue>>
{
typedef std::hash <ripple::RippleAssetType <ByValue>> Base;
// VFALCO NOTE broken in vs2012
//using Base::Base; // inherit ctors
};
template <bool ByValue>
struct hash <ripple::RippleBookType <ByValue>>
: std::hash <ripple::RippleBookType <ByValue>>
{
typedef std::hash <ripple::RippleBookType <ByValue>> Base;
// VFALCO NOTE broken in vs2012
//using Base::Base; // inherit ctors
};
}
#endif

View File

@@ -190,4 +190,36 @@ extern std::size_t hash_value (const uint160&);
}
//------------------------------------------------------------------------------
namespace std {
template <class>
struct hash;
template <>
struct hash <ripple::uint160> : ripple::uint160::hasher
{
// VFALCO NOTE broken in vs2012
//using ripple::uint160::hasher::hasher; // inherit ctors
};
}
//------------------------------------------------------------------------------
namespace boost {
template <class>
struct hash;
template <>
struct hash <ripple::uint160> : ripple::uint160::hasher
{
// VFALCO NOTE broken in vs2012
//using ripple::uint160::hasher::hasher; // inherit ctors
};
}
#endif

View File

@@ -0,0 +1,251 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2012, 2013 Ripple Labs 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.
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 <set>
#include <unordered_set>
#include <boost/unordered_set.hpp>
#if BEAST_MSVC
# define STL_SET_HAS_EMPLACE 1
#else
# define STL_SET_HAS_EMPLACE 0
#endif
namespace ripple {
class RippleAssetTests : public UnitTest
{
public:
template <class Set>
void testAssetSet ()
{
RippleCurrency const c1 (1);
RippleIssuer const i1 (1);
RippleCurrency const c2 (2);
RippleIssuer const i2 (2);
RippleAssetRef const a1 (c1, i1);
RippleAssetRef const a2 (c2, i2);
Set c;
c.insert (a1);
c.insert (a2);
expect (c.erase (RippleAsset (c1, i2)) == 0);
expect (c.erase (RippleAsset (c1, i1)) == 1);
expect (c.erase (RippleAsset (c2, i2)) == 1);
expect (c.empty ());
c.insert (a1);
c.insert (a2);
expect (c.erase (RippleAssetRef (c1, i2)) == 0);
expect (c.erase (RippleAssetRef (c1, i1)) == 1);
expect (c.erase (RippleAssetRef (c2, i2)) == 1);
expect (c.empty ());
#if STL_SET_HAS_EMPLACE
c.emplace (c1, i1);
c.emplace (c2, i2);
expect (c.size() == 2);
#endif
}
template <class Map>
void testAssetMap ()
{
RippleCurrency const c1 (1);
RippleIssuer const i1 (1);
RippleCurrency const c2 (2);
RippleIssuer const i2 (2);
RippleAssetRef const a1 (c1, i1);
RippleAssetRef const a2 (c2, i2);
Map c;
c.insert (std::make_pair (a1, 1));
c.insert (std::make_pair (a2, 2));
expect (c.erase (RippleAsset (c1, i2)) == 0);
expect (c.erase (RippleAsset (c1, i1)) == 1);
expect (c.erase (RippleAsset (c2, i2)) == 1);
expect (c.empty ());
c.insert (std::make_pair (a1, 1));
c.insert (std::make_pair (a2, 2));
expect (c.erase (RippleAssetRef (c1, i2)) == 0);
expect (c.erase (RippleAssetRef (c1, i1)) == 1);
expect (c.erase (RippleAssetRef (c2, i2)) == 1);
expect (c.empty ());
}
void testAssets ()
{
beginTestCase ("assets");
RippleCurrency const c1 (1);
RippleIssuer const i1 (1);
RippleCurrency const c2 (2);
RippleIssuer const i2 (2);
{
RippleAssetRef a0 (xrp_asset ());
expect (a0 == xrp_asset());
RippleAssetRef a1 (c1, i1);
RippleAssetRef a2 (a1);
expect (a1 == a2);
}
{
// VFALCO NOTE this should be uninitialized
RippleAsset uninitialized_asset;
}
{
RippleAsset a1 (c1, i1);
RippleAsset a2 (a1);
expect (a1 == a2);
expect (a1 != xrp_asset());
a2 = RippleAsset (c2, i2);
expect (a1 < a2);
}
testAssetSet <std::set <RippleAsset>> ();
testAssetSet <std::set <RippleAssetRef>> ();
testAssetSet <std::unordered_set <RippleAsset>> ();
testAssetSet <std::unordered_set <RippleAssetRef>> ();
testAssetSet <boost::unordered_set <RippleAsset>> ();
testAssetSet <boost::unordered_set <RippleAssetRef>> ();
testAssetMap <std::map <RippleAsset, int>> ();
testAssetMap <std::map <RippleAssetRef, int>> ();
testAssetMap <std::unordered_map <RippleAsset, int>> ();
testAssetMap <std::unordered_map <RippleAssetRef, int>> ();
testAssetMap <boost::unordered_map <RippleAsset, int>> ();
testAssetMap <boost::unordered_map <RippleAssetRef, int>> ();
}
template <class Set>
void testBookSet ()
{
RippleCurrency const c1 (1);
RippleIssuer const i1 (1);
RippleCurrency const c2 (2);
RippleIssuer const i2 (2);
RippleAssetRef const a1 (c1, i1);
RippleAssetRef const a2 (c2, i2);
RippleBookRef const b1 (a1, a2);
RippleBookRef const b2 (a2, a1);
Set c;
c.insert (b1);
c.insert (b2);
expect (c.erase (RippleBook (a1, a1)) == 0);
expect (c.erase (RippleBook (a1, a2)) == 1);
expect (c.erase (RippleBook (a2, a1)) == 1);
expect (c.empty ());
c.insert (b1);
c.insert (b2);
expect (c.erase (RippleBookRef (a1, a1)) == 0);
expect (c.erase (RippleBookRef (a1, a2)) == 1);
expect (c.erase (RippleBookRef (a2, a1)) == 1);
expect (c.empty ());
#if STL_SET_HAS_EMPLACE
c.emplace (a1, a2);
c.emplace (a2, a1);
expect (c.size() == 2);
#endif
}
template <class Map>
void testBookMap ()
{
RippleCurrency const c1 (1);
RippleIssuer const i1 (1);
RippleCurrency const c2 (2);
RippleIssuer const i2 (2);
RippleAssetRef const a1 (c1, i1);
RippleAssetRef const a2 (c2, i2);
RippleBookRef const b1 (a1, a2);
RippleBookRef const b2 (a2, a1);
Map c;
c.insert (std::make_pair (b1, 1));
c.insert (std::make_pair (b2, 2));
expect (c.erase (RippleBook (a1, a1)) == 0);
expect (c.erase (RippleBook (a1, a2)) == 1);
expect (c.erase (RippleBook (a2, a1)) == 1);
expect (c.empty ());
c.insert (std::make_pair (b1, 1));
c.insert (std::make_pair (b2, 2));
expect (c.erase (RippleBookRef (a1, a1)) == 0);
expect (c.erase (RippleBookRef (a1, a2)) == 1);
expect (c.erase (RippleBookRef (a2, a1)) == 1);
expect (c.empty ());
}
void testBooks ()
{
beginTestCase ("books");
RippleAsset a1 (RippleCurrency (1), RippleIssuer (1));
RippleAsset a2 (RippleCurrency (2), RippleIssuer (2));
RippleBook b1 (a1, a2);
RippleBook b2 (a2, a1);
expect (b1 != b2);
expect (b1 < b2);
testBookSet <std::set <RippleBook>> ();
testBookSet <std::set <RippleBookRef>> ();
testBookSet <std::unordered_set <RippleBook>> ();
testBookSet <std::unordered_set <RippleBookRef>> ();
testBookSet <boost::unordered_set <RippleBook>> ();
testBookSet <boost::unordered_set <RippleBookRef>> ();
testBookMap <std::map <RippleBook, int>> ();
testBookMap <std::map <RippleBookRef, int>> ();
testBookMap <std::unordered_map <RippleBook, int>> ();
testBookMap <std::unordered_map <RippleBookRef, int>> ();
testBookMap <boost::unordered_map <RippleBook, int>> ();
testBookMap <boost::unordered_map <RippleBookRef, int>> ();
}
void runTest ()
{
testAssets ();
testBooks ();
}
RippleAssetTests () : UnitTest ("RippleAsset", "ripple")
{
}
};
static RippleAssetTests rippleAssetTests;
}

View File

@@ -30,6 +30,13 @@
# endif
#endif
#include <set>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <boost/unordered_map.hpp>
#include <boost/unordered_set.hpp>
#include "impl/Base58.cpp"
#include "impl/ByteOrder.cpp"
#include "impl/RandomNumbers.cpp"
@@ -38,4 +45,5 @@
#include "impl/UInt160.cpp"
#include "impl/UInt256.cpp"
#include "impl/RippleIdentifierTests.cpp"
#include "impl/RippleAssets.cpp"
#include "impl/JsonPropertyStream.cpp"

View File

@@ -26,6 +26,7 @@
#include "beast/modules/beast_crypto/beast_crypto.h" // for UnsignedInteger, Remove ASAP!
#include "beast/modules/beast_core/system/BeforeBoost.h"
#include <boost/utility/base_from_member.hpp>
#include <boost/functional/hash.hpp>
#include <boost/unordered_set.hpp>
@@ -61,6 +62,7 @@ using namespace beast;
#include "api/RippleAccountID.h"
#include "api/RippleAccountPublicKey.h"
#include "api/RippleAccountPrivateKey.h"
#include "api/RippleAssets.h"
#include "api/RipplePublicKey.h"
#include "api/RipplePrivateKey.h"
# include "api/SimpleIdentifier.h"

View File

@@ -63,9 +63,9 @@ void OrderBookDB::setup (Ledger::ref ledger)
static void updateHelper (SLE::ref entry,
boost::unordered_set< uint256 >& seen,
boost::unordered_map< currencyIssuer_t, std::vector<OrderBook::pointer> >& destMap,
boost::unordered_map< currencyIssuer_t, std::vector<OrderBook::pointer> >& sourceMap,
boost::unordered_set< currencyIssuer_t >& XRPBooks,
boost::unordered_map< RippleAsset, std::vector<OrderBook::pointer> >& destMap,
boost::unordered_map< RippleAsset, std::vector<OrderBook::pointer> >& sourceMap,
boost::unordered_set< RippleAsset >& XRPBooks,
int& books)
{
if ((entry->getType () == ltDIR_NODE) && (entry->isFieldPresent (sfExchangeRate)) &&
@@ -84,10 +84,10 @@ static void updateHelper (SLE::ref entry,
OrderBook::pointer book = boost::make_shared<OrderBook> (boost::cref (index),
boost::cref (ci), boost::cref (co), boost::cref (ii), boost::cref (io));
sourceMap[currencyIssuer_ct (ci, ii)].push_back (book);
destMap[currencyIssuer_ct (co, io)].push_back (book);
sourceMap[RippleAssetRef (ci, ii)].push_back (book);
destMap[RippleAssetRef (co, io)].push_back (book);
if (co.isZero())
XRPBooks.insert(currencyIssuer_ct (ci, ii));
XRPBooks.insert(RippleAssetRef (ci, ii));
++books;
}
}
@@ -96,9 +96,9 @@ static void updateHelper (SLE::ref entry,
void OrderBookDB::update (Ledger::pointer ledger)
{
boost::unordered_set< uint256 > seen;
boost::unordered_map< currencyIssuer_t, std::vector<OrderBook::pointer> > destMap;
boost::unordered_map< currencyIssuer_t, std::vector<OrderBook::pointer> > sourceMap;
boost::unordered_set< currencyIssuer_t > XRPBooks;
boost::unordered_map< RippleAsset, std::vector<OrderBook::pointer> > destMap;
boost::unordered_map< RippleAsset, std::vector<OrderBook::pointer> > sourceMap;
boost::unordered_set< RippleAsset > XRPBooks;
WriteLog (lsDEBUG, OrderBookDB) << "OrderBookDB::update>";
@@ -137,7 +137,7 @@ void OrderBookDB::addOrderBook(const uint160& ci, const uint160& co,
if (toXRP)
{ // We don't want to search through all the to-XRP or from-XRP order books!
BOOST_FOREACH(OrderBook::ref ob, mSourceMap[currencyIssuer_ct(ci, ii)])
BOOST_FOREACH(OrderBook::ref ob, mSourceMap[RippleAssetRef(ci, ii)])
{
if ((ob->getCurrencyOut() == co) && (ob->getIssuerOut() == io))
return;
@@ -145,7 +145,7 @@ void OrderBookDB::addOrderBook(const uint160& ci, const uint160& co,
}
else
{
BOOST_FOREACH(OrderBook::ref ob, mDestMap[currencyIssuer_ct(co, io)])
BOOST_FOREACH(OrderBook::ref ob, mDestMap[RippleAssetRef(co, io)])
{
if ((ob->getCurrencyIn() == ci) && (ob->getIssuerIn() == ii))
return;
@@ -156,19 +156,19 @@ void OrderBookDB::addOrderBook(const uint160& ci, const uint160& co,
OrderBook::pointer book = boost::make_shared<OrderBook> (boost::cref (index),
boost::cref (ci), boost::cref (co), boost::cref (ii), boost::cref (io));
mSourceMap[currencyIssuer_ct (ci, ii)].push_back (book);
mDestMap[currencyIssuer_ct (co, io)].push_back (book);
mSourceMap[RippleAssetRef (ci, ii)].push_back (book);
mDestMap[RippleAssetRef (co, io)].push_back (book);
if (toXRP)
mXRPBooks.insert(currencyIssuer_ct (ci, ii));
mXRPBooks.insert(RippleAssetRef (ci, ii));
}
// return list of all orderbooks that want this issuerID and currencyID
void OrderBookDB::getBooksByTakerPays (const uint160& issuerID, const uint160& currencyID,
void OrderBookDB::getBooksByTakerPays (RippleIssuer const& issuerID, RippleCurrency const& currencyID,
std::vector<OrderBook::pointer>& bookRet)
{
ScopedLockType sl (mLock, __FILE__, __LINE__);
boost::unordered_map< currencyIssuer_t, std::vector<OrderBook::pointer> >::const_iterator
it = mSourceMap.find (currencyIssuer_ct (currencyID, issuerID));
boost::unordered_map< RippleAsset, std::vector<OrderBook::pointer> >::const_iterator
it = mSourceMap.find (RippleAssetRef (currencyID, issuerID));
if (it != mSourceMap.end ())
bookRet = it->second;
@@ -176,20 +176,20 @@ void OrderBookDB::getBooksByTakerPays (const uint160& issuerID, const uint160& c
bookRet.clear ();
}
bool OrderBookDB::isBookToXRP(const uint160& issuerID, const uint160& currencyID)
bool OrderBookDB::isBookToXRP(RippleIssuer const& issuerID, RippleCurrency const& currencyID)
{
ScopedLockType sl (mLock, __FILE__, __LINE__);
return mXRPBooks.count(currencyIssuer_ct(currencyID, issuerID)) > 0;
return mXRPBooks.count(RippleAssetRef(currencyID, issuerID)) > 0;
}
// return list of all orderbooks that give this issuerID and currencyID
void OrderBookDB::getBooksByTakerGets (const uint160& issuerID, const uint160& currencyID,
void OrderBookDB::getBooksByTakerGets (RippleIssuer const& issuerID, RippleCurrency const& currencyID,
std::vector<OrderBook::pointer>& bookRet)
{
ScopedLockType sl (mLock, __FILE__, __LINE__);
boost::unordered_map< currencyIssuer_t, std::vector<OrderBook::pointer> >::const_iterator
it = mDestMap.find (currencyIssuer_ct (currencyID, issuerID));
boost::unordered_map< RippleAsset, std::vector<OrderBook::pointer> >::const_iterator
it = mDestMap.find (RippleAssetRef (currencyID, issuerID));
if (it != mDestMap.end ())
bookRet = it->second;
@@ -197,8 +197,8 @@ void OrderBookDB::getBooksByTakerGets (const uint160& issuerID, const uint160& c
bookRet.clear ();
}
BookListeners::pointer OrderBookDB::makeBookListeners (const uint160& currencyPays, const uint160& currencyGets,
const uint160& issuerPays, const uint160& issuerGets)
BookListeners::pointer OrderBookDB::makeBookListeners (RippleCurrency const& currencyPays, RippleCurrency const& currencyGets,
RippleIssuer const& issuerPays, RippleIssuer const& issuerGets)
{
ScopedLockType sl (mLock, __FILE__, __LINE__);
BookListeners::pointer ret = getBookListeners (currencyPays, currencyGets, issuerPays, issuerGets);
@@ -206,41 +206,29 @@ BookListeners::pointer OrderBookDB::makeBookListeners (const uint160& currencyPa
if (!ret)
{
ret = boost::make_shared<BookListeners> ();
mListeners[issuerPays][issuerGets][currencyPays][currencyGets] = ret;
mListeners [RippleBookRef (
RippleAssetRef (currencyPays, issuerPays),
RippleAssetRef (currencyGets, issuerGets))] = ret;
}
return ret;
}
BookListeners::pointer OrderBookDB::getBookListeners (const uint160& currencyPays, const uint160& currencyGets,
const uint160& issuerPays, const uint160& issuerGets)
BookListeners::pointer OrderBookDB::getBookListeners (RippleCurrency const& currencyPays, RippleCurrency const& currencyGets,
RippleIssuer const& issuerPays, RippleIssuer const& issuerGets)
{
BookListeners::pointer ret;
ScopedLockType sl (mLock, __FILE__, __LINE__);
std::map<uint160, std::map<uint160, std::map<uint160, std::map<uint160, BookListeners::pointer> > > >::iterator
it0 = mListeners.find (issuerPays);
MapType::iterator it0 (mListeners.find (RippleBookRef (
RippleAssetRef (currencyPays, issuerPays),
RippleAssetRef (currencyGets, issuerGets))));
if (it0 == mListeners.end ())
return ret;
if (it0 != mListeners.end ())
ret = it0->second;
std::map<uint160, std::map<uint160, std::map<uint160, BookListeners::pointer> > >::iterator
it1 = (*it0).second.find (issuerGets);
if (it1 == (*it0).second.end ())
return ret;
std::map<uint160, std::map<uint160, BookListeners::pointer> >::iterator it2 = (*it1).second.find (currencyPays);
if (it2 == (*it1).second.end ())
return ret;
std::map<uint160, BookListeners::pointer>::iterator it3 = (*it2).second.find (currencyGets);
if (it3 == (*it2).second.end ())
return ret;
return (*it3).second;
return ret;;
}
// Based on the meta, send the meta to the streams that are listening
@@ -281,12 +269,12 @@ void OrderBookDB::processTxn (Ledger::ref ledger, const AcceptedLedgerTx& alTx,
if (data)
{
const STAmount& takerGets = data->getFieldAmount (sfTakerGets);
const uint160& currencyGets = takerGets.getCurrency ();
const uint160& issuerGets = takerGets.getIssuer ();
RippleCurrency const& currencyGets = takerGets.getCurrency ();
RippleIssuer const& issuerGets = takerGets.getIssuer ();
const STAmount& takerPays = data->getFieldAmount (sfTakerPays);
const uint160& currencyPays = takerPays.getCurrency ();
const uint160& issuerPays = takerPays.getIssuer ();
RippleCurrency const& currencyPays = takerPays.getCurrency ();
RippleIssuer const& issuerPays = takerPays.getIssuer ();
// determine the OrderBook
BookListeners::pointer book =

View File

@@ -20,55 +20,6 @@
#ifndef RIPPLE_ORDERBOOKDB_H_INCLUDED
#define RIPPLE_ORDERBOOKDB_H_INCLUDED
/*
TODO
----
- Add typedefs (in src/ripple/types) for usage of the following primitives:
* uint64
* uint160
* uint256
Each typedef should make it clear what the semantics of the value are,
and have a javadoc comment. Examples:
RippleCurrencyHash
RippleIssuerHash
- Add a new struct OrderBookKey with these fields:
* issuerPays
* issuerGets
* currencyPays
* currencyGets
Use this struct as the key to map order books to the book listeners,
instead of passing the four parameters around everywhere. Change
all function signatures and container types to use this key instead
of the four parameters.
- Add typedefs for all containers, choose a descriptive name that follows
the coding style, add a Javadoc comment explaining what it holds.
- Rename currencyIssuer_ct to follow the coding style. e.g. CurrencyPair
- Replace C11X with a suitable Beast macro
- Move BookListeners to its own header file
- Add documentation explaining what each class does
*/
// VFALCO TODO Rename this type and give the key and value typedefs.
typedef std::pair<uint160, uint160> currencyIssuer_t;
// VFALCO TODO Replace C11X with a suitable Beast macro
#ifdef C11X
typedef std::pair<const uint160&, const uint160&> currencyIssuer_ct;
#else
typedef std::pair<uint160, uint160> currencyIssuer_ct; // C++ defect 106
#endif
//------------------------------------------------------------------------------
// VFALCO TODO Add Javadoc comment explaining what this class does
class BookListeners
{
@@ -108,34 +59,41 @@ public:
const uint160& takerPaysIssuer, const uint160& takerGetsIssuer);
// return list of all orderbooks that want this issuerID and currencyID
void getBooksByTakerPays (const uint160& issuerID, const uint160& currencyID,
void getBooksByTakerPays (RippleIssuer const& issuerID, RippleCurrency const& currencyID,
std::vector<OrderBook::pointer>& bookRet);
void getBooksByTakerGets (const uint160& issuerID, const uint160& currencyID,
void getBooksByTakerGets (RippleIssuer const& issuerID, RippleCurrency const& currencyID,
std::vector<OrderBook::pointer>& bookRet);
bool isBookToXRP (const uint160& issuerID, const uint160& currencyID);
bool isBookToXRP (RippleIssuer const& issuerID, RippleCurrency const& currencyID);
BookListeners::pointer getBookListeners (const uint160& currencyPays, const uint160& currencyGets,
const uint160& issuerPays, const uint160& issuerGets);
BookListeners::pointer getBookListeners (RippleCurrency const& currencyPays, RippleCurrency const& currencyGets,
RippleIssuer const& issuerPays, RippleIssuer const& issuerGets);
BookListeners::pointer makeBookListeners (const uint160& currencyPays, const uint160& currencyGets,
const uint160& issuerPays, const uint160& issuerGets);
BookListeners::pointer makeBookListeners (RippleCurrency const& currencyPays, RippleCurrency const& currencyGets,
RippleIssuer const& issuerPays, RippleIssuer const& issuerGets);
// see if this txn effects any orderbook
void processTxn (Ledger::ref ledger, const AcceptedLedgerTx& alTx, Json::Value& jvObj);
private:
boost::unordered_map< currencyIssuer_t, std::vector<OrderBook::pointer> > mSourceMap; // by ci/ii
boost::unordered_map< currencyIssuer_t, std::vector<OrderBook::pointer> > mDestMap; // by co/io
boost::unordered_set< currencyIssuer_t > mXRPBooks; // does an order book to XRP exist
// by ci/ii
boost::unordered_map <RippleAsset,
std::vector <OrderBook::pointer>> mSourceMap;
// by co/io
boost::unordered_map <RippleAsset,
std::vector<OrderBook::pointer>> mDestMap;
// does an order book to XRP exist
boost::unordered_set <RippleAsset> mXRPBooks;
typedef RippleRecursiveMutex LockType;
typedef LockType::ScopedLockType ScopedLockType;
LockType mLock;
typedef boost::unordered_map <RippleBook, BookListeners::pointer> MapType;
// VFALCO TODO Replace with just one map / unordered_map with a struct for the key
// issuerPays, issuerGets, currencyPays, currencyGets
std::map<uint160, std::map<uint160, std::map<uint160, std::map<uint160, BookListeners::pointer> > > > mListeners;
MapType mListeners;
uint32 mSeq;

View File

@@ -356,10 +356,10 @@ public:
bool subServer (InfoSub::ref ispListener, Json::Value& jvResult);
bool unsubServer (uint64 uListener);
bool subBook (InfoSub::ref ispListener, const uint160& currencyPays, const uint160& currencyGets,
const uint160& issuerPays, const uint160& issuerGets);
bool unsubBook (uint64 uListener, const uint160& currencyPays, const uint160& currencyGets,
const uint160& issuerPays, const uint160& issuerGets);
bool subBook (InfoSub::ref ispListener, RippleCurrency const& currencyPays, RippleCurrency const& currencyGets,
RippleIssuer const& issuerPays, RippleIssuer const& issuerGets);
bool unsubBook (uint64 uListener, RippleCurrency const& currencyPays, RippleCurrency const& currencyGets,
RippleIssuer const& issuerPays, RippleIssuer const& issuerGets);
bool subTransactions (InfoSub::ref ispListener);
bool unsubTransactions (uint64 uListener);
@@ -2605,8 +2605,8 @@ void NetworkOPsImp::unsubAccount (uint64 uSeq, const boost::unordered_set<Ripple
}
}
bool NetworkOPsImp::subBook (InfoSub::ref isrListener, const uint160& currencyPays, const uint160& currencyGets,
const uint160& issuerPays, const uint160& issuerGets)
bool NetworkOPsImp::subBook (InfoSub::ref isrListener, RippleCurrency const& currencyPays, RippleCurrency const& currencyGets,
RippleIssuer const& issuerPays, RippleIssuer const& issuerGets)
{
BookListeners::pointer listeners =
getApp().getOrderBookDB ().makeBookListeners (currencyPays, currencyGets, issuerPays, issuerGets);
@@ -2618,7 +2618,7 @@ bool NetworkOPsImp::subBook (InfoSub::ref isrListener, const uint160& currencyPa
}
bool NetworkOPsImp::unsubBook (uint64 uSeq,
const uint160& currencyPays, const uint160& currencyGets, const uint160& issuerPays, const uint160& issuerGets)
RippleCurrency const& currencyPays, RippleCurrency const& currencyGets, RippleIssuer const& issuerPays, RippleIssuer const& issuerGets)
{
BookListeners::pointer listeners =
getApp().getOrderBookDB ().getBookListeners (currencyPays, currencyGets, issuerPays, issuerGets);

View File

@@ -453,7 +453,7 @@ bool Pathfinder::matchesOrigin (const uint160& currency, const uint160& issuer)
return (issuer == mSrcIssuerID) || (issuer == mSrcAccountID);
}
int Pathfinder::getPathsOut (const uint160& currencyID, const uint160& accountID,
int Pathfinder::getPathsOut (RippleCurrency const& currencyID, const uint160& accountID,
bool isDstCurrency, const uint160& dstAccount)
{
#ifdef C11X

View File

@@ -72,12 +72,12 @@ public:
virtual bool unsubServer (uint64 uListener) = 0;
virtual bool subBook (ref ispListener,
const uint160& currencyPays, const uint160& currencyGets,
const uint160& issuerPays, const uint160& issuerGets) = 0;
RippleCurrency const& currencyPays, RippleCurrency const& currencyGets,
RippleIssuer const& issuerPays, RippleIssuer const& issuerGets) = 0;
virtual bool unsubBook (uint64 uListener,
const uint160& currencyPays, const uint160& currencyGets,
const uint160& issuerPays, const uint160& issuerGets) = 0;
RippleCurrency const& currencyPays, RippleCurrency const& currencyGets,
RippleIssuer const& issuerPays, RippleIssuer const& issuerGets) = 0;
virtual bool subTransactions (ref ispListener) = 0;