mirror of
https://github.com/Xahau/xahaud.git
synced 2025-11-29 15:05:50 +00:00
New Resource::Manager for controlling access to server resources
This commit is contained in:
@@ -68,6 +68,7 @@ SOURCES += \
|
||||
../../src/ripple/http/ripple_http.cpp \
|
||||
../../src/ripple/json/ripple_json.cpp \
|
||||
../../src/ripple/peerfinder/ripple_peerfinder.cpp \
|
||||
../../src/ripple/resource/ripple_resource.cpp \
|
||||
../../src/ripple/rpc/ripple_rpc.cpp \
|
||||
../../src/ripple/sophia/ripple_sophia.c \
|
||||
../../src/ripple/sslutil/ripple_sslutil.cpp \
|
||||
|
||||
@@ -121,6 +121,43 @@
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\ripple\peerfinder\ripple_peerfinder.cpp" />
|
||||
<ClCompile Include="..\..\src\ripple\resource\impl\Charge.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\resource\impl\Consumer.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\resource\impl\Fees.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\resource\impl\LegacyFees.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\resource\impl\Manager.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\resource\impl\Tests.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\resource\ripple_resource.cpp" />
|
||||
<ClCompile Include="..\..\src\ripple\rpc\impl\Handler.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
@@ -1656,6 +1693,24 @@
|
||||
<ClInclude Include="..\..\src\ripple\peerfinder\impl\StoreSqdb.h" />
|
||||
<ClInclude Include="..\..\src\ripple\peerfinder\impl\Tuning.h" />
|
||||
<ClInclude Include="..\..\src\ripple\peerfinder\ripple_peerfinder.h" />
|
||||
<ClInclude Include="..\..\src\ripple\resource\api\Charge.h" />
|
||||
<ClInclude Include="..\..\src\ripple\resource\api\Consumer.h" />
|
||||
<ClInclude Include="..\..\src\ripple\resource\api\Disposition.h" />
|
||||
<ClInclude Include="..\..\src\ripple\resource\api\Gossip.h" />
|
||||
<ClInclude Include="..\..\src\ripple\resource\api\Fees.h" />
|
||||
<ClInclude Include="..\..\src\ripple\resource\api\LegacyFees.h" />
|
||||
<ClInclude Include="..\..\src\ripple\resource\api\Manager.h" />
|
||||
<ClInclude Include="..\..\src\ripple\resource\api\Types.h" />
|
||||
<ClInclude Include="..\..\src\ripple\resource\impl\DecayingSample.h" />
|
||||
<ClInclude Include="..\..\src\ripple\resource\impl\Entry.h" />
|
||||
<ClInclude Include="..\..\src\ripple\resource\impl\Import.h" />
|
||||
<ClInclude Include="..\..\src\ripple\resource\impl\Key.h" />
|
||||
<ClInclude Include="..\..\src\ripple\resource\impl\Kind.h" />
|
||||
<ClInclude Include="..\..\src\ripple\resource\impl\Logic.h" />
|
||||
<ClInclude Include="..\..\src\ripple\resource\impl\LogicType.h" />
|
||||
<ClInclude Include="..\..\src\ripple\resource\impl\SimpleMonotonicClock.h" />
|
||||
<ClInclude Include="..\..\src\ripple\resource\impl\Tuning.h" />
|
||||
<ClInclude Include="..\..\src\ripple\resource\ripple_resource.h" />
|
||||
<ClInclude Include="..\..\src\ripple\rpc\api\Handler.h" />
|
||||
<ClInclude Include="..\..\src\ripple\rpc\api\Manager.h" />
|
||||
<ClInclude Include="..\..\src\ripple\rpc\api\Service.h" />
|
||||
@@ -1836,7 +1891,6 @@
|
||||
<ClInclude Include="..\..\src\ripple_basics\utility\Time.h" />
|
||||
<ClInclude Include="..\..\src\ripple_basics\utility\UptimeTimer.h" />
|
||||
<ClInclude Include="..\..\src\ripple_core\functional\LoadSource.h" />
|
||||
<ClInclude Include="..\..\src\ripple_core\functional\LoadType.h" />
|
||||
<ClInclude Include="..\..\src\ripple_core\functional\Config.h" />
|
||||
<ClInclude Include="..\..\src\ripple_core\functional\ConfigSections.h" />
|
||||
<ClInclude Include="..\..\src\ripple_core\functional\LoadFeeTrack.h" />
|
||||
|
||||
@@ -238,6 +238,15 @@
|
||||
<Filter Include="[1] Ripple\peerfinder\impl">
|
||||
<UniqueIdentifier>{cd1585a6-bc32-477d-88cd-275159dafa83}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="[1] Ripple\resource">
|
||||
<UniqueIdentifier>{ec26c9d0-ff17-466b-bf23-a36b8aa60717}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="[1] Ripple\resource\api">
|
||||
<UniqueIdentifier>{555d2128-108e-4afa-abe5-48d1508edb1e}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="[1] Ripple\resource\impl">
|
||||
<UniqueIdentifier>{28a8ede0-743b-4a9a-bae1-5b2bc03ee44e}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\src\ripple_basics\containers\RangeSet.cpp">
|
||||
@@ -1092,6 +1101,30 @@
|
||||
<ClCompile Include="..\..\src\ripple\types\impl\JsonPropertyStream.cpp">
|
||||
<Filter>[1] Ripple\types\impl</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\ripple_app\main\BlackList.cpp">
|
||||
<Filter>[2] Old Ripple\ripple_app\main</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\ripple\resource\ripple_resource.cpp">
|
||||
<Filter>[1] Ripple\resource</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\ripple\resource\impl\Charge.cpp">
|
||||
<Filter>[1] Ripple\resource\impl</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\ripple\resource\impl\Consumer.cpp">
|
||||
<Filter>[1] Ripple\resource\impl</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\ripple\resource\impl\Manager.cpp">
|
||||
<Filter>[1] Ripple\resource\impl</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\ripple\resource\impl\Tests.cpp">
|
||||
<Filter>[1] Ripple\resource\impl</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\ripple\resource\impl\Fees.cpp">
|
||||
<Filter>[1] Ripple\resource\impl</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\ripple\resource\impl\LegacyFees.cpp">
|
||||
<Filter>[1] Ripple\resource\impl</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\src\ripple_basics\containers\KeyCache.h">
|
||||
@@ -1649,9 +1682,6 @@
|
||||
<ClInclude Include="..\..\src\ripple_core\functional\LoadSource.h">
|
||||
<Filter>[2] Old Ripple\ripple_core\functional</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ripple_core\functional\LoadType.h">
|
||||
<Filter>[2] Old Ripple\ripple_core\functional</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ripple_app\main\LoadManager.h">
|
||||
<Filter>[2] Old Ripple\ripple_app\main</Filter>
|
||||
</ClInclude>
|
||||
@@ -2220,6 +2250,63 @@
|
||||
<ClInclude Include="..\..\src\ripple\types\api\JsonPropertyStream.h">
|
||||
<Filter>[1] Ripple\types\api</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ripple_app\main\BlackList.h">
|
||||
<Filter>[2] Old Ripple\ripple_app\main</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ripple\resource\ripple_resource.h">
|
||||
<Filter>[1] Ripple\resource</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ripple\resource\api\Disposition.h">
|
||||
<Filter>[1] Ripple\resource\api</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ripple\resource\api\Types.h">
|
||||
<Filter>[1] Ripple\resource\api</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ripple\resource\api\Charge.h">
|
||||
<Filter>[1] Ripple\resource\api</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ripple\resource\api\Consumer.h">
|
||||
<Filter>[1] Ripple\resource\api</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ripple\resource\api\Manager.h">
|
||||
<Filter>[1] Ripple\resource\api</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ripple\resource\impl\DecayingSample.h">
|
||||
<Filter>[1] Ripple\resource\impl</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ripple\resource\impl\Kind.h">
|
||||
<Filter>[1] Ripple\resource\impl</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ripple\resource\impl\Key.h">
|
||||
<Filter>[1] Ripple\resource\impl</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ripple\resource\impl\Entry.h">
|
||||
<Filter>[1] Ripple\resource\impl</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ripple\resource\impl\SimpleMonotonicClock.h">
|
||||
<Filter>[1] Ripple\resource\impl</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ripple\resource\api\Fees.h">
|
||||
<Filter>[1] Ripple\resource\api</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ripple\resource\impl\Tuning.h">
|
||||
<Filter>[1] Ripple\resource\impl</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ripple\resource\impl\Logic.h">
|
||||
<Filter>[1] Ripple\resource\impl</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ripple\resource\impl\LogicType.h">
|
||||
<Filter>[1] Ripple\resource\impl</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ripple\resource\api\Gossip.h">
|
||||
<Filter>[1] Ripple\resource\api</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ripple\resource\impl\Import.h">
|
||||
<Filter>[1] Ripple\resource\impl</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ripple\resource\api\LegacyFees.h">
|
||||
<Filter>[1] Ripple\resource\api</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<CustomBuild Include="..\..\src\ripple_data\protocol\ripple.proto">
|
||||
|
||||
@@ -159,6 +159,7 @@ COMPILED_FILES.extend([
|
||||
'src/ripple/http/ripple_http.cpp',
|
||||
'src/ripple/json/ripple_json.cpp',
|
||||
'src/ripple/peerfinder/ripple_peerfinder.cpp',
|
||||
'src/ripple/resource/ripple_resource.cpp',
|
||||
'src/ripple/rpc/ripple_rpc.cpp',
|
||||
'src/ripple/sophia/ripple_sophia.c',
|
||||
'src/ripple/sslutil/ripple_sslutil.cpp',
|
||||
|
||||
@@ -178,4 +178,11 @@
|
||||
#define RIPPLE_USE_RPC_SERVICE_MANAGER 0
|
||||
#endif
|
||||
|
||||
// Here temporarily
|
||||
// Controls whether or not the new Resource manager replaces the BlackList
|
||||
// and LoadManager for measuring and controlling access to the server
|
||||
#ifndef RIPPLE_USE_RESOURCE_MANAGER
|
||||
#define RIPPLE_USE_RESOURCE_MANAGER 0
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
60
src/ripple/resource/api/Charge.h
Normal file
60
src/ripple/resource/api/Charge.h
Normal file
@@ -0,0 +1,60 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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_RESOURCE_CHARGE_H_INCLUDED
|
||||
#define RIPPLE_RESOURCE_CHARGE_H_INCLUDED
|
||||
|
||||
#include <ios>
|
||||
|
||||
namespace ripple {
|
||||
namespace Resource {
|
||||
|
||||
/** A consumption charge. */
|
||||
class Charge
|
||||
{
|
||||
public:
|
||||
/** The type used to hold a consumption charge. */
|
||||
typedef int value_type;
|
||||
|
||||
/** Create a new charge with no cost (yet). */
|
||||
Charge ();
|
||||
|
||||
/** Create a charge with the specified cost and name. */
|
||||
Charge (value_type cost, std::string const& label = std::string());
|
||||
|
||||
/** Return the human readable label associated with the charge. */
|
||||
std::string const& label() const;
|
||||
|
||||
/** Return the cost of the charge in Resource::Manager units. */
|
||||
value_type cost () const;
|
||||
|
||||
/** Converts this charge into a human readable string. */
|
||||
std::string to_string () const;
|
||||
|
||||
private:
|
||||
value_type m_cost;
|
||||
std::string m_label;
|
||||
};
|
||||
|
||||
std::ostream& operator<< (std::ostream& os, Charge const& v);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
83
src/ripple/resource/api/Consumer.h
Normal file
83
src/ripple/resource/api/Consumer.h
Normal file
@@ -0,0 +1,83 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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_RESOURCE_CONSUMER_H_INCLUDED
|
||||
#define RIPPLE_RESOURCE_CONSUMER_H_INCLUDED
|
||||
|
||||
namespace ripple {
|
||||
namespace Resource {
|
||||
|
||||
class Logic;
|
||||
|
||||
/** An endpoint that consumes resources. */
|
||||
class Consumer
|
||||
{
|
||||
private:
|
||||
friend class Logic;
|
||||
Consumer (Logic& logic, Entry& entry);
|
||||
|
||||
public:
|
||||
Consumer ();
|
||||
~Consumer ();
|
||||
Consumer (Consumer const& other);
|
||||
Consumer& operator= (Consumer const& other);
|
||||
|
||||
/** Return a human readable string uniquely identifying this consumer. */
|
||||
std::string label ();
|
||||
|
||||
/** Returns `true` if this is a privileged endpoint. */
|
||||
bool admin () const;
|
||||
|
||||
/** Raise the Consumer's privilege level to a Named endpoint.
|
||||
The reference to the original endpoint descriptor is released.
|
||||
*/
|
||||
void elevate (std::string const& name);
|
||||
|
||||
/** Returns the current disposition of this consumer.
|
||||
This should be checked upon creation to determine if the consumer
|
||||
should be disconnected immediately.
|
||||
*/
|
||||
Disposition disposition() const;
|
||||
|
||||
/** Apply a load charge to the consumer. */
|
||||
Disposition charge (Charge const& fee);
|
||||
|
||||
/** Returns `true` if the consumer should be warned.
|
||||
This consumes the warning.
|
||||
*/
|
||||
bool warn();
|
||||
|
||||
/** Returns `true` if the consumer should be disconnected. */
|
||||
bool disconnect();
|
||||
|
||||
/** Returns the credit balance representing consumption. */
|
||||
int balance();
|
||||
|
||||
// Private: Retrieve the entry associated with the consumer
|
||||
Entry& entry();
|
||||
|
||||
private:
|
||||
Logic* m_logic;
|
||||
Entry* m_entry;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
42
src/ripple/resource/api/Disposition.h
Normal file
42
src/ripple/resource/api/Disposition.h
Normal file
@@ -0,0 +1,42 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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_RESOURCE_DISPOSITION_H_INCLUDED
|
||||
#define RIPPLE_RESOURCE_DISPOSITION_H_INCLUDED
|
||||
|
||||
namespace ripple {
|
||||
namespace Resource {
|
||||
|
||||
/** The disposition of a consumer after applying a load charge. */
|
||||
enum Disposition
|
||||
{
|
||||
/** No action required. */
|
||||
ok
|
||||
|
||||
/** Consumer should be warned that consumption is high. */
|
||||
,warn
|
||||
|
||||
/** Consumer should be disconnected for excess consumption. */
|
||||
,drop
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
64
src/ripple/resource/api/Fees.h
Normal file
64
src/ripple/resource/api/Fees.h
Normal file
@@ -0,0 +1,64 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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_RESOURCE_FEES_H_INCLUDED
|
||||
#define RIPPLE_RESOURCE_FEES_H_INCLUDED
|
||||
|
||||
namespace ripple {
|
||||
namespace Resource {
|
||||
|
||||
/** Schedule of fees charged for imposing load on the server. */
|
||||
/** @{ */
|
||||
extern Charge const feeInvalidRequest; // A request that we can immediately tell is invalid
|
||||
extern Charge const feeRequestNoReply; // A request that we cannot satisfy
|
||||
extern Charge const feeInvalidSignature; // An object whose signature we had to check and it failed
|
||||
extern Charge const feeUnwantedData; // Data we have no use for
|
||||
extern Charge const feeBadProofOfWork; // Proof of work not valid
|
||||
extern Charge const feeBadData; // Data we have to verify before rejecting
|
||||
|
||||
// RPC loads
|
||||
extern Charge const feeInvalidRPC; // An RPC request that we can immediately tell is invalid.
|
||||
extern Charge const feeReferenceRPC; // A default "reference" unspecified load
|
||||
extern Charge const feeExceptionRPC; // An RPC load that causes an exception
|
||||
extern Charge const feeLightRPC; // A normal RPC command
|
||||
extern Charge const feeLowBurdenRPC; // A slightly burdensome RPC load
|
||||
extern Charge const feeMediumBurdenRPC; // A somewhat burdensome RPC load
|
||||
extern Charge const feeHighBurdenRPC; // A very burdensome RPC load
|
||||
|
||||
// Good things
|
||||
extern Charge const feeNewTrustedNote; // A new transaction/validation/proposal we trust
|
||||
extern Charge const feeNewValidTx; // A new, valid transaction
|
||||
extern Charge const feeSatisfiedRequest; // Data we requested
|
||||
|
||||
// Requests
|
||||
extern Charge const feeRequestedData; // A request that is hard to satisfy, disk access
|
||||
extern Charge const feeCheapQuery; // A query that is trivial, cached data
|
||||
|
||||
// Administrative
|
||||
extern Charge const feeWarning; // The cost of receiving a warning
|
||||
extern Charge const feeDrop; // The cost of being dropped for excess load
|
||||
/** @} */
|
||||
|
||||
/** Returns an appropriate Charge based on the legacy LoadType. */
|
||||
extern Charge legacyFee (LoadType t);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
42
src/ripple/resource/api/Gossip.h
Normal file
42
src/ripple/resource/api/Gossip.h
Normal file
@@ -0,0 +1,42 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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_RESOURCE_GOSSIP_H_INCLUDED
|
||||
#define RIPPLE_RESOURCE_GOSSIP_H_INCLUDED
|
||||
|
||||
namespace ripple {
|
||||
namespace Resource {
|
||||
|
||||
/** Data format for exchanging consumption information across peers. */
|
||||
struct Gossip
|
||||
{
|
||||
/** Describes a single consumer. */
|
||||
struct Item
|
||||
{
|
||||
int balance;
|
||||
IPEndpoint address;
|
||||
};
|
||||
|
||||
std::vector <Item> items;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -17,36 +17,11 @@
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_RESOURCE_LEGACYFEES_H_INCLUDED
|
||||
#define RIPPLE_RESOURCE_LEGACYFEES_H_INCLUDED
|
||||
|
||||
#ifndef RIPPLE_CORE_FUNCTIONAL_LOADTYPE_H_INCLUDED
|
||||
#define RIPPLE_CORE_FUNCTIONAL_LOADTYPE_H_INCLUDED
|
||||
namespace ripple {
|
||||
|
||||
// types of load that can be placed on the server
|
||||
/** The type of load placed on the server.
|
||||
*/
|
||||
/* VFALCO TODO
|
||||
- Remove LT_ from each enum
|
||||
- Put LoadType into a struct like this:
|
||||
(Note this is modeled after boost::system::error_code::err_c)
|
||||
|
||||
struct LoadType
|
||||
{
|
||||
enum load_c
|
||||
{
|
||||
invalidRequest,
|
||||
//...
|
||||
}
|
||||
};
|
||||
|
||||
// For parameters
|
||||
typedef LoadType::load_c LoadTypeParam;
|
||||
|
||||
// Example of passing a LoadType:
|
||||
peer->applyLoadCharge (LoadType::newTransaction);
|
||||
|
||||
// Example function prototype
|
||||
void applyLoadCharge (LoadTypeParam loadType);
|
||||
*/
|
||||
enum LoadType
|
||||
{
|
||||
// Bad things
|
||||
@@ -75,4 +50,6 @@ enum LoadType
|
||||
LT_MAX // MUST BE LAST
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
58
src/ripple/resource/api/Manager.h
Normal file
58
src/ripple/resource/api/Manager.h
Normal file
@@ -0,0 +1,58 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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_RESOURCE_MANAGER_H_INCLUDED
|
||||
#define RIPPLE_RESOURCE_MANAGER_H_INCLUDED
|
||||
|
||||
namespace ripple {
|
||||
namespace Resource {
|
||||
|
||||
/** Tracks load and resource consumption. */
|
||||
class Manager : public PropertyStream::Source
|
||||
{
|
||||
protected:
|
||||
Manager ();
|
||||
|
||||
public:
|
||||
static Manager* New (Journal journal);
|
||||
|
||||
virtual ~Manager() { }
|
||||
|
||||
/** Create a new endpoint keyed by inbound IP address. */
|
||||
virtual Consumer newInboundEndpoint (IPEndpoint const& address) = 0;
|
||||
|
||||
/** Create a new endpoint keyed by outbound IP address and port. */
|
||||
virtual Consumer newOutboundEndpoint (IPEndpoint const& address) = 0;
|
||||
|
||||
/** Create a new endpoint keyed by name. */
|
||||
virtual Consumer newAdminEndpoint (std::string const& name) = 0;
|
||||
|
||||
/** Extract packaged consumer information for export. */
|
||||
virtual Gossip exportConsumers () = 0;
|
||||
|
||||
/** Import packaged consumer information.
|
||||
@param origin An identifier that unique labels the origin.
|
||||
*/
|
||||
virtual void importConsumers (std::string const& origin, Gossip const& gossip) = 0;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
35
src/ripple/resource/api/Types.h
Normal file
35
src/ripple/resource/api/Types.h
Normal file
@@ -0,0 +1,35 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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_RESOURCE_TYPES_H_INCLUDED
|
||||
#define RIPPLE_RESOURCE_TYPES_H_INCLUDED
|
||||
|
||||
namespace ripple {
|
||||
namespace Resource {
|
||||
|
||||
struct Key;
|
||||
struct Entry;
|
||||
|
||||
/** Measures seconds from an unspecified fixed reference event in the past. */
|
||||
typedef int DiscreteTime;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
60
src/ripple/resource/impl/Charge.cpp
Normal file
60
src/ripple/resource/impl/Charge.cpp
Normal file
@@ -0,0 +1,60 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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 <sstream>
|
||||
|
||||
namespace ripple {
|
||||
namespace Resource {
|
||||
|
||||
Charge::Charge ()
|
||||
: m_cost (0)
|
||||
{
|
||||
}
|
||||
|
||||
Charge::Charge (value_type cost, std::string const& label)
|
||||
: m_cost (cost)
|
||||
, m_label (label)
|
||||
{
|
||||
}
|
||||
|
||||
std::string const& Charge::label () const
|
||||
{
|
||||
return m_label;
|
||||
}
|
||||
|
||||
Charge::value_type Charge::cost() const
|
||||
{
|
||||
return m_cost;
|
||||
}
|
||||
|
||||
std::string Charge::to_string () const
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << m_label << " ($" << m_cost << ")";
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
std::ostream& operator<< (std::ostream& os, Charge const& v)
|
||||
{
|
||||
os << v.to_string();
|
||||
return os;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
129
src/ripple/resource/impl/Consumer.cpp
Normal file
129
src/ripple/resource/impl/Consumer.cpp
Normal file
@@ -0,0 +1,129 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
namespace ripple {
|
||||
namespace Resource {
|
||||
|
||||
Consumer::Consumer (Logic& logic, Entry& entry)
|
||||
: m_logic (&logic)
|
||||
, m_entry (&entry)
|
||||
{
|
||||
}
|
||||
|
||||
Consumer::Consumer ()
|
||||
: m_logic (nullptr)
|
||||
, m_entry (nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
Consumer::Consumer (Consumer const& other)
|
||||
: m_logic (other.m_logic)
|
||||
, m_entry (nullptr)
|
||||
{
|
||||
if (m_logic != nullptr)
|
||||
{
|
||||
if (other.m_entry != nullptr)
|
||||
{
|
||||
m_entry = other.m_entry;
|
||||
m_logic->acquire (*m_entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Consumer::~Consumer()
|
||||
{
|
||||
if (m_logic != nullptr)
|
||||
{
|
||||
if (m_entry != nullptr)
|
||||
m_logic->release (*m_entry);
|
||||
}
|
||||
}
|
||||
|
||||
Consumer& Consumer::operator= (Consumer const& other)
|
||||
{
|
||||
// remove old ref
|
||||
if (m_logic != nullptr)
|
||||
{
|
||||
if (m_entry != nullptr)
|
||||
m_logic->release (*m_entry);
|
||||
}
|
||||
|
||||
m_logic = other.m_logic;
|
||||
m_entry = other.m_entry;
|
||||
|
||||
// add new ref
|
||||
if (m_logic != nullptr)
|
||||
{
|
||||
if (m_entry != nullptr)
|
||||
m_logic->acquire (*m_entry);
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
std::string Consumer::label ()
|
||||
{
|
||||
if (m_logic == nullptr)
|
||||
return "(none)";
|
||||
|
||||
return m_entry->label();
|
||||
}
|
||||
|
||||
bool Consumer::admin () const
|
||||
{
|
||||
return m_entry->admin();
|
||||
}
|
||||
|
||||
void Consumer::elevate (std::string const& name)
|
||||
{
|
||||
m_entry = &m_logic->elevateToAdminEndpoint (*m_entry, name);
|
||||
}
|
||||
|
||||
Disposition Consumer::disposition() const
|
||||
{
|
||||
return ok;
|
||||
}
|
||||
|
||||
Disposition Consumer::charge (Charge const& what)
|
||||
{
|
||||
return m_logic->charge (*m_entry, what);
|
||||
}
|
||||
|
||||
bool Consumer::warn ()
|
||||
{
|
||||
return m_logic->warn (*m_entry);
|
||||
}
|
||||
|
||||
bool Consumer::disconnect ()
|
||||
{
|
||||
return m_logic->disconnect (*m_entry);
|
||||
}
|
||||
|
||||
int Consumer::balance()
|
||||
{
|
||||
return m_logic->balance (*m_entry);
|
||||
}
|
||||
|
||||
Entry& Consumer::entry()
|
||||
{
|
||||
return *m_entry;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
99
src/ripple/resource/impl/DecayingSample.h
Normal file
99
src/ripple/resource/impl/DecayingSample.h
Normal file
@@ -0,0 +1,99 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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_RESOURCE_DECAYINGSAMPLE_H_INCLUDED
|
||||
#define RIPPLE_RESOURCE_DECAYINGSAMPLE_H_INCLUDED
|
||||
|
||||
namespace ripple {
|
||||
namespace Resource {
|
||||
|
||||
/** Sampling function using exponential decay to provide a continuous value. */
|
||||
template <int Window,
|
||||
typename Value = int,
|
||||
typename Elapsed = int>
|
||||
class DecayingSample
|
||||
{
|
||||
public:
|
||||
typedef Value value_type;
|
||||
typedef Elapsed elapsed_type;
|
||||
|
||||
/** Create a default constructed sample. */
|
||||
DecayingSample ()
|
||||
: m_value (value_type())
|
||||
, m_when (elapsed_type())
|
||||
{
|
||||
}
|
||||
|
||||
/** Add a new sample.
|
||||
The value is first aged according to the specified time.
|
||||
*/
|
||||
Value add (value_type value, elapsed_type now)
|
||||
{
|
||||
decay (now);
|
||||
m_value += value;
|
||||
return m_value / Window;
|
||||
}
|
||||
|
||||
/** Retrieve the current value in normalized units.
|
||||
The samples are first aged according to the specified time.
|
||||
*/
|
||||
Value value (elapsed_type now)
|
||||
{
|
||||
decay (now);
|
||||
return m_value / Window;
|
||||
}
|
||||
|
||||
private:
|
||||
// Apply exponential decay based on the specified time.
|
||||
void decay (elapsed_type now)
|
||||
{
|
||||
if (m_value == value_type())
|
||||
return;
|
||||
|
||||
elapsed_type n (now - m_when);
|
||||
|
||||
if (n == 0)
|
||||
return;
|
||||
|
||||
// A span larger than four times the window decays the
|
||||
// value to an insignificant amount so just reset it.
|
||||
//
|
||||
if (n > 4 * Window)
|
||||
{
|
||||
m_value = value_type();
|
||||
return;
|
||||
}
|
||||
|
||||
while (n--)
|
||||
m_value -= (m_value + Window - 1) / Window;
|
||||
|
||||
m_when = now;
|
||||
}
|
||||
|
||||
// Current value in exponential units
|
||||
value_type m_value;
|
||||
|
||||
// Last time the aging function was applied
|
||||
elapsed_type m_when;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
97
src/ripple/resource/impl/Entry.h
Normal file
97
src/ripple/resource/impl/Entry.h
Normal file
@@ -0,0 +1,97 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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_RESOURCE_ENTRY_H_INCLUDED
|
||||
#define RIPPLE_RESOURCE_ENTRY_H_INCLUDED
|
||||
|
||||
namespace ripple {
|
||||
namespace Resource {
|
||||
|
||||
// An entry in the table
|
||||
struct Entry : public List <Entry>::Node
|
||||
{
|
||||
// Dummy argument is necessary for zero-copy construction of elements
|
||||
Entry (int)
|
||||
: refcount (0)
|
||||
, remote_balance (0)
|
||||
, disposition (ok)
|
||||
, lastWarningTime (0)
|
||||
, whenExpires (0)
|
||||
{
|
||||
}
|
||||
|
||||
std::string label() const
|
||||
{
|
||||
switch (key->kind)
|
||||
{
|
||||
case kindInbound: return key->address.to_string();
|
||||
case kindOutbound: return key->address.to_string();
|
||||
case kindAdmin: return key->name;
|
||||
default:
|
||||
bassertfalse;
|
||||
}
|
||||
|
||||
return "(undefined)";
|
||||
}
|
||||
|
||||
// Returns `true` if this connection is privileged
|
||||
bool admin () const
|
||||
{
|
||||
return key->kind == kindAdmin;
|
||||
}
|
||||
|
||||
// Balance including remote contributions
|
||||
int balance (DiscreteTime const now)
|
||||
{
|
||||
return local_balance.value (now) + remote_balance;
|
||||
}
|
||||
|
||||
// Add a charge and return normalized balance
|
||||
// including contributions from imports.
|
||||
int add (int charge, DiscreteTime const now)
|
||||
{
|
||||
return local_balance.add (charge, now) + remote_balance;
|
||||
}
|
||||
|
||||
// Back pointer to the map key (bit of a hack here)
|
||||
Key const* key;
|
||||
|
||||
// Number of Consumer references
|
||||
int refcount;
|
||||
|
||||
// Exponentially decaying balance of resource consumption
|
||||
DecayingSample <decayWindowSeconds> local_balance;
|
||||
|
||||
// Normalized balance contribution from imports
|
||||
int remote_balance;
|
||||
|
||||
// Disposition
|
||||
Disposition disposition;
|
||||
|
||||
// Time of the last warning
|
||||
DiscreteTime lastWarningTime;
|
||||
|
||||
// For inactive entries, time after which this entry will be erased
|
||||
DiscreteTime whenExpires;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
49
src/ripple/resource/impl/Fees.cpp
Normal file
49
src/ripple/resource/impl/Fees.cpp
Normal file
@@ -0,0 +1,49 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
namespace ripple {
|
||||
namespace Resource {
|
||||
|
||||
Charge const feeInvalidRequest ( 10, "malformed request" );
|
||||
Charge const feeRequestNoReply ( 1, "unsatisfiable request" );
|
||||
Charge const feeInvalidSignature ( 100, "invalid signature" );
|
||||
Charge const feeUnwantedData ( 5, "useless data" );
|
||||
Charge const feeBadProofOfWork ( 250, "incorrect proof of work"); // DAVID: Check the cost
|
||||
Charge const feeBadData ( 20, "invalid data" );
|
||||
|
||||
Charge const feeInvalidRPC ( 10, "malformed RPC" );
|
||||
Charge const feeReferenceRPC ( 2, "reference RPC" );
|
||||
Charge const feeExceptionRPC ( 10, "exceptioned RPC" );
|
||||
Charge const feeLightRPC ( 5, "light RPC" ); // DAVID: Check the cost
|
||||
Charge const feeLowBurdenRPC ( 10, "low RPC" );
|
||||
Charge const feeMediumBurdenRPC ( 20, "medium RPC" );
|
||||
Charge const feeHighBurdenRPC ( 50, "heavy RPC" );
|
||||
|
||||
Charge const feeNewTrustedNote ( 10, "trusted note" );
|
||||
Charge const feeNewValidTx ( 2, "valid tx" );
|
||||
Charge const feeSatisfiedRequest ( 10, "needed data" );
|
||||
|
||||
Charge const feeRequestedData ( 5, "costly request" );
|
||||
Charge const feeCheapQuery ( 1, "trivial query" );
|
||||
|
||||
Charge const feeWarning ( 10, "received warning" ); // DAVID: Check the cost
|
||||
Charge const feeDrop ( 100, "dropped" ); // DAVID: Check the cost
|
||||
|
||||
}
|
||||
}
|
||||
51
src/ripple/resource/impl/Import.h
Normal file
51
src/ripple/resource/impl/Import.h
Normal file
@@ -0,0 +1,51 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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_RESOURCE_IMPORT_H_INCLUDED
|
||||
#define RIPPLE_RESOURCE_IMPORT_H_INCLUDED
|
||||
|
||||
namespace ripple {
|
||||
namespace Resource {
|
||||
|
||||
/** A set of imported consumer data from a gossip origin. */
|
||||
struct Import
|
||||
{
|
||||
struct Item
|
||||
{
|
||||
int balance;
|
||||
Consumer consumer;
|
||||
};
|
||||
|
||||
// Dummy argument required for zero-copy construction
|
||||
Import (int = 0)
|
||||
: whenExpires (0)
|
||||
{
|
||||
}
|
||||
|
||||
// When the imported data expires
|
||||
DiscreteTime whenExpires;
|
||||
|
||||
// List of remote entries
|
||||
std::vector <Item> items;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
88
src/ripple/resource/impl/Key.h
Normal file
88
src/ripple/resource/impl/Key.h
Normal file
@@ -0,0 +1,88 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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_RESOURCE_KEY_H_INCLUDED
|
||||
#define RIPPLE_RESOURCE_KEY_H_INCLUDED
|
||||
|
||||
namespace ripple {
|
||||
namespace Resource {
|
||||
|
||||
// The consumer key
|
||||
struct Key
|
||||
{
|
||||
Kind kind;
|
||||
IPEndpoint address;
|
||||
std::string name;
|
||||
|
||||
struct hasher
|
||||
{
|
||||
std::size_t operator() (Key const& v) const
|
||||
{
|
||||
switch (v.kind)
|
||||
{
|
||||
case kindInbound:
|
||||
case kindOutbound:
|
||||
return m_addr_hash (v.address);
|
||||
|
||||
case kindAdmin:
|
||||
return m_name_hash (v.name);
|
||||
|
||||
default:
|
||||
bassertfalse;
|
||||
};
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
private:
|
||||
IPEndpoint::hasher m_addr_hash;
|
||||
boost::hash <std::string> m_name_hash;
|
||||
};
|
||||
|
||||
struct key_equal
|
||||
{
|
||||
bool operator() (Key const& lhs, Key const& rhs) const
|
||||
{
|
||||
if (lhs.kind != rhs.kind)
|
||||
return false;
|
||||
|
||||
switch (lhs.kind)
|
||||
{
|
||||
case kindInbound:
|
||||
case kindOutbound:
|
||||
return lhs.address == rhs.address;
|
||||
|
||||
case kindAdmin:
|
||||
return lhs.name == rhs.name;
|
||||
|
||||
default:
|
||||
bassertfalse;
|
||||
};
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
37
src/ripple/resource/impl/Kind.h
Normal file
37
src/ripple/resource/impl/Kind.h
Normal file
@@ -0,0 +1,37 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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_RESOURCE_KIND_H_INCLUDED
|
||||
#define RIPPLE_RESOURCE_KIND_H_INCLUDED
|
||||
|
||||
namespace ripple {
|
||||
namespace Resource {
|
||||
|
||||
// Kind of consumer
|
||||
enum Kind
|
||||
{
|
||||
kindInbound
|
||||
,kindOutbound
|
||||
,kindAdmin
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
60
src/ripple/resource/impl/LegacyFees.cpp
Normal file
60
src/ripple/resource/impl/LegacyFees.cpp
Normal file
@@ -0,0 +1,60 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
namespace ripple {
|
||||
namespace Resource {
|
||||
|
||||
Charge legacyFee (LoadType t)
|
||||
{
|
||||
switch (t)
|
||||
{
|
||||
case LT_InvalidRequest: return feeInvalidRequest;
|
||||
case LT_RequestNoReply: return feeRequestNoReply;
|
||||
case LT_InvalidSignature: return feeInvalidSignature;
|
||||
case LT_UnwantedData: return feeUnwantedData;
|
||||
case LT_BadPoW: return feeBadProofOfWork;
|
||||
case LT_BadData: return feeBadData;
|
||||
|
||||
case LT_RPCInvalid: return feeInvalidRPC;
|
||||
case LT_RPCReference: return feeReferenceRPC;
|
||||
case LT_RPCException: return feeExceptionRPC;
|
||||
|
||||
#if 0
|
||||
case LT_RPCLight: return feeLightRPC;
|
||||
case LT_RPCBurdenLow: return feeLowBurdenRPC;
|
||||
case LT_RPCBurdenMedium: return feeMediumBurdenRPC;
|
||||
case LT_RPCBurdenHigh: return feeHighBurdenRPC;
|
||||
#endif
|
||||
|
||||
case LT_NewTrusted: return feeNewTrustedNote;
|
||||
case LT_NewTransaction: return feeNewValidTx;
|
||||
case LT_NeededData: return feeSatisfiedRequest;
|
||||
|
||||
case LT_RequestData: return feeRequestedData;
|
||||
|
||||
default:
|
||||
bassertfalse;
|
||||
case LT_CheapQuery: return feeCheapQuery;
|
||||
};
|
||||
|
||||
return feeInvalidRequest;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
543
src/ripple/resource/impl/Logic.h
Normal file
543
src/ripple/resource/impl/Logic.h
Normal file
@@ -0,0 +1,543 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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_RESOURCE_LOGIC_H_INCLUDED
|
||||
#define RIPPLE_RESOURCE_LOGIC_H_INCLUDED
|
||||
|
||||
namespace ripple {
|
||||
namespace Resource {
|
||||
|
||||
class Logic
|
||||
{
|
||||
public:
|
||||
typedef boost::unordered_map <std::string, Import> Imports;
|
||||
typedef boost::unordered_map <Key, Entry, Key::hasher, Key::key_equal> Table;
|
||||
|
||||
struct State
|
||||
{
|
||||
// Table of all entries
|
||||
Table table;
|
||||
|
||||
// List of all active inbound entries
|
||||
List <Entry> inbound;
|
||||
|
||||
// List of all active outbound entries
|
||||
List <Entry> outbound;
|
||||
|
||||
// List of all active admin entries
|
||||
List <Entry> admin;
|
||||
|
||||
// List of all inactve entries
|
||||
List <Entry> inactive;
|
||||
|
||||
// All imported gossip data
|
||||
Imports import_table;
|
||||
};
|
||||
|
||||
typedef SharedData <State> SharedState;
|
||||
|
||||
SharedState m_state;
|
||||
Journal m_journal;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
Logic (Journal journal)
|
||||
: m_journal (journal)
|
||||
{
|
||||
#if 1
|
||||
#if BEAST_MSVC
|
||||
if (beast_isRunningUnderDebugger())
|
||||
{
|
||||
m_journal.sink().set_console (true);
|
||||
m_journal.sink().set_severity (Journal::kLowestSeverity);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
virtual ~Logic ()
|
||||
{
|
||||
// These have to be cleared before the Logic is destroyed
|
||||
// since their destructors call back into the class.
|
||||
// Order matters here as well, the import table has to be
|
||||
// destroyed before the consumer table.
|
||||
//
|
||||
SharedState::UnlockedAccess state (m_state);
|
||||
state->import_table.clear();
|
||||
state->table.clear();
|
||||
}
|
||||
|
||||
virtual DiscreteTime get_now ()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
Consumer newInboundEndpoint (IPEndpoint const& address)
|
||||
{
|
||||
if (isWhitelisted (address))
|
||||
return newAdminEndpoint (address.to_string());
|
||||
|
||||
Key key;
|
||||
key.kind = kindInbound;
|
||||
key.address = address;
|
||||
|
||||
Entry* entry (nullptr);
|
||||
|
||||
{
|
||||
SharedState::Access state (m_state);
|
||||
std::pair <Table::iterator, bool> result (
|
||||
state->table.emplace (key, 0));
|
||||
entry = &result.first->second;
|
||||
entry->key = &result.first->first;
|
||||
++entry->refcount;
|
||||
if (entry->refcount == 1)
|
||||
{
|
||||
if (! result.second)
|
||||
state->inactive.erase (
|
||||
state->inactive.iterator_to (*entry));
|
||||
state->inbound.push_back (*entry);
|
||||
}
|
||||
}
|
||||
|
||||
m_journal.debug << "New inbound endpoint " << entry->label();
|
||||
|
||||
return Consumer (*this, *entry);
|
||||
}
|
||||
|
||||
Consumer newOutboundEndpoint (IPEndpoint const& address)
|
||||
{
|
||||
if (isWhitelisted (address))
|
||||
return newAdminEndpoint (address.to_string());
|
||||
|
||||
Key key;
|
||||
key.kind = kindOutbound;
|
||||
key.address = address;
|
||||
|
||||
Entry* entry (nullptr);
|
||||
|
||||
{
|
||||
SharedState::Access state (m_state);
|
||||
std::pair <Table::iterator, bool> result (
|
||||
state->table.emplace (key, 0));
|
||||
entry = &result.first->second;
|
||||
entry->key = &result.first->first;
|
||||
++entry->refcount;
|
||||
if (entry->refcount == 1)
|
||||
{
|
||||
if (! result.second)
|
||||
state->inactive.erase (
|
||||
state->inactive.iterator_to (*entry));
|
||||
state->outbound.push_back (*entry);
|
||||
}
|
||||
}
|
||||
|
||||
m_journal.debug << "New outbound endpoint " << entry->label();
|
||||
|
||||
return Consumer (*this, *entry);
|
||||
}
|
||||
|
||||
Consumer newAdminEndpoint (std::string const& name)
|
||||
{
|
||||
Key key;
|
||||
key.kind = kindAdmin;
|
||||
key.name = name;
|
||||
|
||||
Entry* entry (nullptr);
|
||||
|
||||
{
|
||||
SharedState::Access state (m_state);
|
||||
std::pair <Table::iterator, bool> result (
|
||||
state->table.emplace (key, 0));
|
||||
entry = &result.first->second;
|
||||
entry->key = &result.first->first;
|
||||
++entry->refcount;
|
||||
if (entry->refcount == 1)
|
||||
{
|
||||
if (! result.second)
|
||||
state->inactive.erase (
|
||||
state->inactive.iterator_to (*entry));
|
||||
state->admin.push_back (*entry);
|
||||
}
|
||||
}
|
||||
|
||||
m_journal.debug << "New admin endpoint " << entry->label();
|
||||
|
||||
return Consumer (*this, *entry);
|
||||
}
|
||||
|
||||
Entry& elevateToAdminEndpoint (Entry& prior, std::string const& name)
|
||||
{
|
||||
Key key;
|
||||
key.kind = kindAdmin;
|
||||
key.name = name;
|
||||
|
||||
m_journal.info << "Elevate " << prior.label() << " to " << name;
|
||||
|
||||
Entry* entry (nullptr);
|
||||
|
||||
{
|
||||
SharedState::Access state (m_state);
|
||||
Table::iterator iter (
|
||||
state->table.find (*prior.key));
|
||||
std::pair <Table::iterator, bool> result (
|
||||
state->table.emplace (key, 0));
|
||||
entry = &result.first->second;
|
||||
entry->key = &result.first->first;
|
||||
++entry->refcount;
|
||||
if (entry->refcount == 1)
|
||||
{
|
||||
if (! result.second)
|
||||
state->inactive.erase (
|
||||
state->inactive.iterator_to (*entry));
|
||||
state->admin.push_back (*entry);
|
||||
}
|
||||
|
||||
release (prior, state);
|
||||
}
|
||||
|
||||
return *entry;
|
||||
}
|
||||
|
||||
Gossip exportConsumers ()
|
||||
{
|
||||
DiscreteTime const now (get_now());
|
||||
|
||||
Gossip gossip;
|
||||
SharedState::Access state (m_state);
|
||||
|
||||
gossip.items.reserve (state->inbound.size());
|
||||
|
||||
for (List <Entry>::iterator iter (state->inbound.begin());
|
||||
iter != state->inbound.end(); ++iter)
|
||||
{
|
||||
Gossip::Item item;
|
||||
item.balance = iter->local_balance.value (now);
|
||||
if (item.balance >= minimumGossipBalance)
|
||||
{
|
||||
item.address = iter->key->address;
|
||||
gossip.items.push_back (item);
|
||||
}
|
||||
}
|
||||
|
||||
return gossip;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void importConsumers (std::string const& origin, Gossip const& gossip)
|
||||
{
|
||||
DiscreteTime const now (get_now());
|
||||
|
||||
{
|
||||
SharedState::Access state (m_state);
|
||||
std::pair <Imports::iterator, bool> result (
|
||||
state->import_table.emplace (origin, 0));
|
||||
|
||||
if (result.second)
|
||||
{
|
||||
// This is a new import
|
||||
Import& next (result.first->second);
|
||||
next.whenExpires = now + gossipExpirationSeconds;
|
||||
next.items.reserve (gossip.items.size());
|
||||
for (std::vector <Gossip::Item>::const_iterator iter (gossip.items.begin());
|
||||
iter != gossip.items.end(); ++iter)
|
||||
{
|
||||
Import::Item item;
|
||||
item.balance = iter->balance;
|
||||
item.consumer = newInboundEndpoint (iter->address);
|
||||
item.consumer.entry().remote_balance += item.balance;
|
||||
next.items.push_back (item);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Previous import exists so add the new remote
|
||||
// balances and then deduct the old remote balances.
|
||||
|
||||
Import next;
|
||||
next.whenExpires = now + gossipExpirationSeconds;
|
||||
next.items.reserve (gossip.items.size());
|
||||
for (std::vector <Gossip::Item>::const_iterator iter (gossip.items.begin());
|
||||
iter != gossip.items.end(); ++iter)
|
||||
{
|
||||
Import::Item item;
|
||||
item.balance = iter->balance;
|
||||
item.consumer = newInboundEndpoint (iter->address);
|
||||
item.consumer.entry().remote_balance += item.balance;
|
||||
next.items.push_back (item);
|
||||
}
|
||||
|
||||
Import& prev (result.first->second);
|
||||
for (std::vector <Import::Item>::iterator iter (prev.items.begin());
|
||||
iter != prev.items.end(); ++iter)
|
||||
{
|
||||
iter->consumer.entry().remote_balance -= iter->balance;
|
||||
}
|
||||
|
||||
std::swap (next, prev);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
bool isWhitelisted (IPEndpoint const& address)
|
||||
{
|
||||
if (! address.isPublic())
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Called periodically to expire entries and groom the table.
|
||||
//
|
||||
void periodicActivity ()
|
||||
{
|
||||
SharedState::Access state (m_state);
|
||||
|
||||
DiscreteTime const now (get_now());
|
||||
|
||||
for (List <Entry>::iterator iter (
|
||||
state->inactive.begin()); iter != state->inactive.end();)
|
||||
{
|
||||
if (iter->whenExpires <= now)
|
||||
{
|
||||
m_journal.debug << "Expired " << iter->label();
|
||||
Table::iterator table_iter (
|
||||
state->table.find (*iter->key));
|
||||
++iter;
|
||||
erase (table_iter, state);
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (Imports::iterator iter (state->import_table.begin());
|
||||
iter != state->import_table.end(); ++iter)
|
||||
{
|
||||
Import& import (iter->second);
|
||||
if (iter->second.whenExpires <= now)
|
||||
{
|
||||
for (std::vector <Import::Item>::iterator item_iter (import.items.begin());
|
||||
item_iter != import.items.end(); ++item_iter)
|
||||
{
|
||||
item_iter->consumer.entry().remote_balance -= item_iter->balance;
|
||||
}
|
||||
|
||||
iter = state->import_table.erase (iter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
// Returns the disposition based on the balance and thresholds
|
||||
static Disposition disposition (int balance)
|
||||
{
|
||||
if (balance >= dropThreshold)
|
||||
return Disposition::drop;
|
||||
|
||||
if (balance >= warningThreshold)
|
||||
return Disposition::warn;
|
||||
|
||||
return Disposition::ok;
|
||||
}
|
||||
|
||||
void acquire (Entry& entry, SharedState::Access& state)
|
||||
{
|
||||
++entry.refcount;
|
||||
}
|
||||
|
||||
void release (Entry& entry, SharedState::Access& state)
|
||||
{
|
||||
if (--entry.refcount == 0)
|
||||
{
|
||||
m_journal.debug << "Inactive " << entry.label();
|
||||
switch (entry.key->kind)
|
||||
{
|
||||
case kindInbound:
|
||||
state->inbound.erase (
|
||||
state->inbound.iterator_to (entry));
|
||||
break;
|
||||
case kindOutbound:
|
||||
state->outbound.erase (
|
||||
state->outbound.iterator_to (entry));
|
||||
break;
|
||||
case kindAdmin:
|
||||
state->admin.erase (
|
||||
state->admin.iterator_to (entry));
|
||||
break;
|
||||
default:
|
||||
bassertfalse;
|
||||
break;
|
||||
}
|
||||
state->inactive.push_back (entry);
|
||||
entry.whenExpires = get_now() + secondsUntilExpiration;
|
||||
}
|
||||
}
|
||||
|
||||
void erase (Table::iterator iter, SharedState::Access& state)
|
||||
{
|
||||
Entry& entry (iter->second);
|
||||
bassert (entry.refcount == 0);
|
||||
state->inactive.erase (
|
||||
state->inactive.iterator_to (entry));
|
||||
state->table.erase (iter);
|
||||
}
|
||||
|
||||
Disposition charge (Entry& entry, Charge const& fee, SharedState::Access& state)
|
||||
{
|
||||
DiscreteTime const now (get_now());
|
||||
int const balance (entry.add (fee.cost(), now));
|
||||
m_journal.info << "Charging " << entry.label() << " for " << fee;
|
||||
return disposition (balance);
|
||||
}
|
||||
|
||||
bool warn (Entry& entry, SharedState::Access& state)
|
||||
{
|
||||
bool notify (false);
|
||||
DiscreteTime const now (get_now());
|
||||
if (entry.balance (now) >= warningThreshold && now != entry.lastWarningTime)
|
||||
{
|
||||
charge (entry, feeWarning, state);
|
||||
notify = true;
|
||||
entry.lastWarningTime = now;
|
||||
}
|
||||
|
||||
if (notify)
|
||||
m_journal.info << "Load warning: " << entry.label();
|
||||
|
||||
return notify;
|
||||
}
|
||||
|
||||
bool disconnect (Entry& entry, SharedState::Access& state)
|
||||
{
|
||||
bool drop (false);
|
||||
DiscreteTime const now (get_now());
|
||||
if (entry.balance (now) >= dropThreshold)
|
||||
{
|
||||
charge (entry, feeDrop, state);
|
||||
drop = true;
|
||||
}
|
||||
return drop;
|
||||
}
|
||||
|
||||
int balance (Entry& entry, SharedState::Access& state)
|
||||
{
|
||||
return entry.balance (get_now());
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void acquire (Entry& entry)
|
||||
{
|
||||
SharedState::Access state (m_state);
|
||||
acquire (entry, state);
|
||||
}
|
||||
|
||||
void release (Entry& entry)
|
||||
{
|
||||
SharedState::Access state (m_state);
|
||||
release (entry, state);
|
||||
}
|
||||
|
||||
Disposition charge (Entry& entry, Charge const& fee)
|
||||
{
|
||||
SharedState::Access state (m_state);
|
||||
return charge (entry, fee, state);
|
||||
}
|
||||
|
||||
bool warn (Entry& entry)
|
||||
{
|
||||
if (entry.admin())
|
||||
return false;
|
||||
|
||||
SharedState::Access state (m_state);
|
||||
return warn (entry, state);
|
||||
}
|
||||
|
||||
bool disconnect (Entry& entry)
|
||||
{
|
||||
if (entry.admin())
|
||||
return false;
|
||||
|
||||
SharedState::Access state (m_state);
|
||||
return disconnect (entry, state);
|
||||
}
|
||||
|
||||
int balance (Entry& entry)
|
||||
{
|
||||
SharedState::Access state (m_state);
|
||||
return balance (entry, state);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void writeList (
|
||||
DiscreteTime const now,
|
||||
PropertyStream::Set& items,
|
||||
List <Entry>& list)
|
||||
{
|
||||
for (List <Entry>::iterator iter (list.begin());
|
||||
iter != list.end(); ++iter)
|
||||
{
|
||||
PropertyStream::Map item (items);
|
||||
if (iter->refcount != 0)
|
||||
item ["count"] = iter->refcount;
|
||||
item ["name"] = iter->label();
|
||||
item ["balance"] = iter->balance(now);
|
||||
if (iter->remote_balance != 0)
|
||||
item ["remote_balance"] = iter->remote_balance;
|
||||
}
|
||||
}
|
||||
|
||||
void onWrite (PropertyStream::Map& map)
|
||||
{
|
||||
DiscreteTime const now (get_now());
|
||||
|
||||
SharedState::Access state (m_state);
|
||||
|
||||
{
|
||||
PropertyStream::Set s ("inbound", map);
|
||||
writeList (now, s, state->inbound);
|
||||
}
|
||||
|
||||
{
|
||||
PropertyStream::Set s ("outbound", map);
|
||||
writeList (now, s, state->outbound);
|
||||
}
|
||||
|
||||
{
|
||||
PropertyStream::Set s ("admin", map);
|
||||
writeList (now, s, state->admin);
|
||||
}
|
||||
|
||||
{
|
||||
PropertyStream::Set s ("inactive", map);
|
||||
writeList (now, s, state->inactive);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
50
src/ripple/resource/impl/LogicType.h
Normal file
50
src/ripple/resource/impl/LogicType.h
Normal file
@@ -0,0 +1,50 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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_RESOURCE_LOGICTYPE_H_INCLUDED
|
||||
#define RIPPLE_RESOURCE_LOGICTYPE_H_INCLUDED
|
||||
|
||||
namespace ripple {
|
||||
namespace Resource {
|
||||
|
||||
/** Provides the Clock required by Logic's get_now().
|
||||
This allows the unit tests to provide its own manual clock.
|
||||
*/
|
||||
template <typename Clock>
|
||||
class LogicType : public Logic
|
||||
{
|
||||
public:
|
||||
explicit LogicType (Journal journal)
|
||||
: Logic (journal)
|
||||
{
|
||||
}
|
||||
|
||||
DiscreteTime get_now ()
|
||||
{
|
||||
return m_clock();
|
||||
}
|
||||
|
||||
private:
|
||||
Clock m_clock;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
105
src/ripple/resource/impl/Manager.cpp
Normal file
105
src/ripple/resource/impl/Manager.cpp
Normal file
@@ -0,0 +1,105 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
namespace ripple {
|
||||
namespace Resource {
|
||||
|
||||
class ManagerImp
|
||||
: public Manager
|
||||
, public Thread
|
||||
{
|
||||
public:
|
||||
Journal m_journal;
|
||||
LogicType <SimpleMonotonicClock> m_logic;
|
||||
|
||||
ManagerImp (Journal journal)
|
||||
: Thread ("Resource::Manager")
|
||||
,
|
||||
m_journal (journal)
|
||||
, m_logic (journal)
|
||||
{
|
||||
startThread ();
|
||||
}
|
||||
|
||||
~ManagerImp ()
|
||||
{
|
||||
stopThread ();
|
||||
}
|
||||
|
||||
Consumer newInboundEndpoint (IPEndpoint const& address)
|
||||
{
|
||||
return m_logic.newInboundEndpoint (address);
|
||||
}
|
||||
|
||||
Consumer newOutboundEndpoint (IPEndpoint const& address)
|
||||
{
|
||||
return m_logic.newOutboundEndpoint (address);
|
||||
}
|
||||
|
||||
Consumer newAdminEndpoint (std::string const& name)
|
||||
{
|
||||
return m_logic.newAdminEndpoint (name);
|
||||
}
|
||||
|
||||
Gossip exportConsumers ()
|
||||
{
|
||||
return m_logic.exportConsumers();
|
||||
}
|
||||
|
||||
void importConsumers (std::string const& origin, Gossip const& gossip)
|
||||
{
|
||||
m_logic.importConsumers (origin, gossip);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void onWrite (PropertyStream::Map& map)
|
||||
{
|
||||
m_logic.onWrite (map);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void run ()
|
||||
{
|
||||
do
|
||||
{
|
||||
m_logic.periodicActivity();
|
||||
wait (1000);
|
||||
}
|
||||
while (! threadShouldExit ());
|
||||
}
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
Manager::Manager ()
|
||||
: PropertyStream::Source ("resource")
|
||||
{
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
Manager* Manager::New (Journal journal)
|
||||
{
|
||||
return new ManagerImp (journal);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
40
src/ripple/resource/impl/SimpleMonotonicClock.h
Normal file
40
src/ripple/resource/impl/SimpleMonotonicClock.h
Normal file
@@ -0,0 +1,40 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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_RESOURCE_SIMPLEMONOTONICCLOCK_H_INCLUDED
|
||||
#define RIPPLE_RESOURCE_SIMPLEMONOTONICCLOCK_H_INCLUDED
|
||||
|
||||
namespace ripple {
|
||||
namespace Resource {
|
||||
|
||||
/** Monotonically increasing time value. */
|
||||
struct SimpleMonotonicClock
|
||||
{
|
||||
typedef int value_type;
|
||||
|
||||
value_type operator() () const
|
||||
{
|
||||
return value_type (RelativeTime::fromStartup().inSeconds());
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
145
src/ripple/resource/impl/Tests.cpp
Normal file
145
src/ripple/resource/impl/Tests.cpp
Normal file
@@ -0,0 +1,145 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
namespace ripple {
|
||||
namespace Resource {
|
||||
|
||||
class Tests : public UnitTest
|
||||
{
|
||||
public:
|
||||
// A manually operated clock
|
||||
class TestClock
|
||||
{
|
||||
public:
|
||||
static int& now()
|
||||
{
|
||||
static int when (0);
|
||||
return when;
|
||||
}
|
||||
|
||||
int operator() () const
|
||||
{
|
||||
return now();
|
||||
}
|
||||
};
|
||||
|
||||
void createGossip (Gossip& gossip)
|
||||
{
|
||||
int const v (10 + random().nextInt (10));
|
||||
int const n (10 + random().nextInt (10));
|
||||
gossip.items.reserve (n);
|
||||
for (int i = 0; i < n; ++i)
|
||||
{
|
||||
Gossip::Item item;
|
||||
item.balance = 100 + random().nextInt (500);
|
||||
item.address = IPEndpoint (IPEndpoint::V4 (
|
||||
207, 127, 82, v + i));
|
||||
gossip.items.push_back (item);
|
||||
}
|
||||
}
|
||||
|
||||
void testImports ()
|
||||
{
|
||||
beginTestCase ("Imports");
|
||||
|
||||
ScopedPointer <Logic> logic (
|
||||
new LogicType <TestClock> (journal()));
|
||||
|
||||
Gossip g[5];
|
||||
|
||||
for (int i = 0; i < 5; ++i)
|
||||
createGossip (g[i]);
|
||||
|
||||
for (int i = 0; i < 5; ++i)
|
||||
logic->importConsumers (String::fromNumber (i).toStdString(), g[i]);
|
||||
|
||||
pass();
|
||||
}
|
||||
|
||||
void testImport ()
|
||||
{
|
||||
beginTestCase ("Import");
|
||||
|
||||
ScopedPointer <Logic> logic (
|
||||
new LogicType <TestClock> (journal()));
|
||||
|
||||
Gossip g;
|
||||
Gossip::Item item;
|
||||
item.balance = 100;
|
||||
item.address = IPEndpoint (IPEndpoint::V4 (207, 127, 82, 1));
|
||||
g.items.push_back (item);
|
||||
|
||||
logic->importConsumers ("g", g);
|
||||
|
||||
pass();
|
||||
}
|
||||
|
||||
void testCharges ()
|
||||
{
|
||||
beginTestCase ("Charge");
|
||||
ScopedPointer <Logic> logic (
|
||||
new LogicType <TestClock> (journal()));
|
||||
|
||||
{
|
||||
IPEndpoint address (IPEndpoint::from_string ("207.127.82.1"));
|
||||
Consumer c (logic->newInboundEndpoint (address));
|
||||
logMessage ("Charging " + c.label() + " 10,000 units");
|
||||
c.charge (10000);
|
||||
for (int i = 0; i < 128; ++i)
|
||||
{
|
||||
logMessage (
|
||||
"Time = " + String::fromNumber (TestClock::now()) +
|
||||
", Balance = " + String::fromNumber (c.balance()));
|
||||
++TestClock::now();
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
IPEndpoint address (IPEndpoint::from_string ("207.127.82.2"));
|
||||
Consumer c (logic->newInboundEndpoint (address));
|
||||
logMessage ("Charging " + c.label() + " 1000 units per second");
|
||||
for (int i = 0; i < 128; ++i)
|
||||
{
|
||||
c.charge (1000);
|
||||
logMessage (
|
||||
"Time = " + String::fromNumber (TestClock::now()) +
|
||||
", Balance = " + String::fromNumber (c.balance()));
|
||||
++TestClock::now();
|
||||
}
|
||||
}
|
||||
|
||||
pass();
|
||||
}
|
||||
|
||||
void runTest ()
|
||||
{
|
||||
//testCharges();
|
||||
testImports();
|
||||
//testImport();
|
||||
}
|
||||
|
||||
Tests () : UnitTest ("ResourceManager", "ripple", runManual)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
static Tests tests;
|
||||
|
||||
}
|
||||
}
|
||||
52
src/ripple/resource/impl/Tuning.h
Normal file
52
src/ripple/resource/impl/Tuning.h
Normal file
@@ -0,0 +1,52 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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_RESOURCE_TUNING_H_INCLUDED
|
||||
#define RIPPLE_RESOURCE_TUNING_H_INCLUDED
|
||||
|
||||
namespace ripple {
|
||||
namespace Resource {
|
||||
|
||||
/** Tunable constants. */
|
||||
enum
|
||||
{
|
||||
// Balance at which a warning is issued
|
||||
warningThreshold = 1000
|
||||
|
||||
// Balance at which the consumer is disconnected
|
||||
,dropThreshold = 5000
|
||||
|
||||
// The number of seconds until an inactive table item is removed
|
||||
,secondsUntilExpiration = 300
|
||||
|
||||
// The number of seconds in the exponential decay window
|
||||
// (This should be a power of two)
|
||||
,decayWindowSeconds = 32
|
||||
|
||||
// The minimum balance required in order to include a load source in gossip
|
||||
,minimumGossipBalance = 100
|
||||
|
||||
// Number of seconds until imported gossip expires
|
||||
,gossipExpirationSeconds = 30
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
41
src/ripple/resource/ripple_resource.cpp
Normal file
41
src/ripple/resource/ripple_resource.cpp
Normal file
@@ -0,0 +1,41 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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 "BeastConfig.h"
|
||||
|
||||
#include "ripple_resource.h"
|
||||
|
||||
#include "beast/modules/beast_core/system/BeforeBoost.h"
|
||||
#include <boost/unordered_map.hpp>
|
||||
|
||||
#include "impl/Fees.cpp"
|
||||
# include "impl/Kind.h"
|
||||
# include "impl/Key.h"
|
||||
# include "impl/DecayingSample.h"
|
||||
# include "impl/Tuning.h"
|
||||
# include "impl/Entry.h"
|
||||
# include "impl/Import.h"
|
||||
#include "impl/SimpleMonotonicClock.h"
|
||||
#include "impl/Charge.cpp"
|
||||
# include "impl/Logic.h"
|
||||
# include "impl/LogicType.h"
|
||||
#include "impl/Consumer.cpp"
|
||||
#include "impl/LegacyFees.cpp"
|
||||
#include "impl/Manager.cpp"
|
||||
#include "impl/Tests.cpp"
|
||||
38
src/ripple/resource/ripple_resource.h
Normal file
38
src/ripple/resource/ripple_resource.h
Normal file
@@ -0,0 +1,38 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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_RESOURCE_H_INCLUDED
|
||||
#define RIPPLE_RESOURCE_H_INCLUDED
|
||||
|
||||
#include "beast/modules/beast_core/beast_core.h"
|
||||
|
||||
namespace ripple {
|
||||
using namespace beast;
|
||||
}
|
||||
|
||||
# include "api/Types.h"
|
||||
# include "api/Disposition.h"
|
||||
# include "api/Charge.h"
|
||||
# include "api/LegacyFees.h"
|
||||
# include "api/Fees.h"
|
||||
# include "api/Consumer.h"
|
||||
# include "api/Gossip.h"
|
||||
#include "api/Manager.h"
|
||||
|
||||
#endif
|
||||
@@ -17,13 +17,11 @@
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
|
||||
#include "BeastConfig.h"
|
||||
|
||||
#include "ripple_testoverlay.h"
|
||||
|
||||
namespace ripple
|
||||
{
|
||||
namespace ripple {
|
||||
|
||||
#include "impl/TestOverlay.cpp"
|
||||
|
||||
|
||||
@@ -128,7 +128,10 @@ void InboundLedgers::gotLedgerData (Job&, LedgerHash hash,
|
||||
WriteLog (lsTRACE, InboundLedger) << "Got data for ledger we're not acquiring";
|
||||
|
||||
if (peer)
|
||||
{
|
||||
peer->charge (Resource::feeInvalidRequest);
|
||||
peer->applyLoadCharge (LT_InvalidRequest);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -143,6 +146,7 @@ void InboundLedgers::gotLedgerData (Job&, LedgerHash hash,
|
||||
if (packet.nodes_size () < 1)
|
||||
{
|
||||
WriteLog (lsWARNING, InboundLedger) << "Got empty base data";
|
||||
peer->charge (Resource::feeInvalidRequest);
|
||||
peer->applyLoadCharge (LT_InvalidRequest);
|
||||
return;
|
||||
}
|
||||
@@ -150,6 +154,7 @@ void InboundLedgers::gotLedgerData (Job&, LedgerHash hash,
|
||||
if (!ledger->takeBase (packet.nodes (0).nodedata ()))
|
||||
{
|
||||
WriteLog (lsWARNING, InboundLedger) << "Got invalid base data";
|
||||
peer->charge (Resource::feeInvalidRequest);
|
||||
peer->applyLoadCharge (LT_InvalidRequest);
|
||||
return;
|
||||
}
|
||||
@@ -185,6 +190,7 @@ void InboundLedgers::gotLedgerData (Job&, LedgerHash hash,
|
||||
if (packet.nodes ().size () <= 0)
|
||||
{
|
||||
WriteLog (lsINFO, InboundLedger) << "Got response with no nodes";
|
||||
peer->charge (Resource::feeInvalidRequest);
|
||||
peer->applyLoadCharge (LT_InvalidRequest);
|
||||
return;
|
||||
}
|
||||
@@ -196,6 +202,7 @@ void InboundLedgers::gotLedgerData (Job&, LedgerHash hash,
|
||||
if (!node.has_nodeid () || !node.has_nodedata ())
|
||||
{
|
||||
WriteLog (lsWARNING, InboundLedger) << "Got bad node";
|
||||
peer->charge (Resource::feeInvalidRequest);
|
||||
peer->applyLoadCharge (LT_InvalidRequest);
|
||||
return;
|
||||
}
|
||||
@@ -223,6 +230,7 @@ void InboundLedgers::gotLedgerData (Job&, LedgerHash hash,
|
||||
}
|
||||
|
||||
WriteLog (lsWARNING, InboundLedger) << "Not sure what ledger data we got";
|
||||
peer->charge (Resource::feeInvalidRequest);
|
||||
peer->applyLoadCharge (LT_InvalidRequest);
|
||||
}
|
||||
|
||||
|
||||
@@ -42,6 +42,8 @@ class HTTPServerLog;
|
||||
template <> char const* LogPartition::getPartitionName <HTTPServerLog> () { return "RPCServer"; }
|
||||
class LoadManagerLog;
|
||||
template <> char const* LogPartition::getPartitionName <LoadManagerLog> () { return "LoadManager"; }
|
||||
class ResourceManagerLog;
|
||||
template <> char const* LogPartition::getPartitionName <ResourceManagerLog> () { return "ResourceManager"; }
|
||||
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
@@ -71,6 +73,9 @@ public:
|
||||
, m_tempNodeCache ("NodeCache", 16384, 90)
|
||||
, m_sleCache ("LedgerEntryCache", 4096, 120)
|
||||
|
||||
, m_resourceManager (add (Resource::Manager::New (
|
||||
LogJournal::get <ResourceManagerLog> ())))
|
||||
|
||||
, m_rpcServiceManager (RPC::Manager::New (
|
||||
LogJournal::get <RPCServiceManagerLog> ()))
|
||||
|
||||
@@ -472,7 +477,8 @@ public:
|
||||
// the creation of the peer SSL context and Peers object into
|
||||
// the conditional.
|
||||
//
|
||||
m_peers = add (Peers::New (m_mainIoPool, m_mainIoPool, m_peerSSLContext->get ()));
|
||||
m_peers = add (Peers::New (m_mainIoPool, *m_resourceManager,
|
||||
m_mainIoPool, m_peerSSLContext->get ()));
|
||||
|
||||
// If we're not in standalone mode,
|
||||
// prepare ourselves for networking
|
||||
@@ -483,6 +489,7 @@ public:
|
||||
//
|
||||
m_peerDoors.add (PeerDoor::New (
|
||||
m_mainIoPool,
|
||||
*m_resourceManager,
|
||||
PeerDoor::sslRequired,
|
||||
getConfig ().PEER_IP,
|
||||
getConfig ().peerListeningPort,
|
||||
@@ -494,6 +501,7 @@ public:
|
||||
// Also listen on a PROXY-only port.
|
||||
m_peerDoors.add (PeerDoor::New (
|
||||
m_mainIoPool,
|
||||
*m_resourceManager,
|
||||
PeerDoor::sslAndPROXYRequired,
|
||||
getConfig ().PEER_IP,
|
||||
getConfig ().peerPROXYListeningPort,
|
||||
@@ -523,8 +531,10 @@ public:
|
||||
//
|
||||
if (!getConfig ().WEBSOCKET_IP.empty () && getConfig ().WEBSOCKET_PORT)
|
||||
{
|
||||
m_wsPrivateDoor = WSDoor::New (getOPs(), getConfig ().WEBSOCKET_IP,
|
||||
getConfig ().WEBSOCKET_PORT, false, m_wsSSLContext->get ());
|
||||
m_wsPrivateDoor = WSDoor::New (*m_resourceManager,
|
||||
getOPs(), getConfig ().WEBSOCKET_IP,
|
||||
getConfig ().WEBSOCKET_PORT, false,
|
||||
m_wsSSLContext->get ());
|
||||
|
||||
if (m_wsPrivateDoor == nullptr)
|
||||
{
|
||||
@@ -541,8 +551,10 @@ public:
|
||||
//
|
||||
if (!getConfig ().WEBSOCKET_PUBLIC_IP.empty () && getConfig ().WEBSOCKET_PUBLIC_PORT)
|
||||
{
|
||||
m_wsPublicDoor = WSDoor::New (getOPs(), getConfig ().WEBSOCKET_PUBLIC_IP,
|
||||
getConfig ().WEBSOCKET_PUBLIC_PORT, true, m_wsSSLContext->get ());
|
||||
m_wsPublicDoor = WSDoor::New (*m_resourceManager,
|
||||
getOPs(), getConfig ().WEBSOCKET_PUBLIC_IP,
|
||||
getConfig ().WEBSOCKET_PUBLIC_PORT, true,
|
||||
m_wsSSLContext->get ());
|
||||
|
||||
if (m_wsPublicDoor == nullptr)
|
||||
{
|
||||
@@ -839,6 +851,7 @@ private:
|
||||
LocalCredentials m_localCredentials;
|
||||
TransactionMaster m_txMaster;
|
||||
|
||||
ScopedPointer <Resource::Manager> m_resourceManager;
|
||||
ScopedPointer <RPC::Manager> m_rpcServiceManager;
|
||||
|
||||
// These are Stoppable-related
|
||||
|
||||
@@ -102,6 +102,16 @@ public:
|
||||
, mDeadLock (0)
|
||||
, mCosts (LT_MAX)
|
||||
{
|
||||
#if 0
|
||||
#if BEAST_MSVC
|
||||
if (beast_isRunningUnderDebugger())
|
||||
{
|
||||
m_journal.sink().set_console (true);
|
||||
m_journal.sink().set_severity (Journal::kLowestSeverity);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/** Flags indicating the type of load.
|
||||
|
||||
Utilization may include any combination of:
|
||||
|
||||
@@ -17,9 +17,8 @@
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
|
||||
#ifndef RIPPLE_LOADMANAGER_H_INCLUDEd
|
||||
#define RIPPLE_LOADMANAGER_H_INCLUDEd
|
||||
#ifndef RIPPLE_LOADMANAGER_H_INCLUDED
|
||||
#define RIPPLE_LOADMANAGER_H_INCLUDED
|
||||
|
||||
/** Manages load sources.
|
||||
|
||||
|
||||
@@ -35,8 +35,9 @@ class PeerImp : public Peer
|
||||
, public CountedObject <PeerImp>
|
||||
{
|
||||
private:
|
||||
// This is up here to prevent warnings about order of initializations
|
||||
// These is up here to prevent warnings about order of initializations
|
||||
//
|
||||
Resource::Manager& m_resourceManager;
|
||||
bool m_isInbound;
|
||||
|
||||
public:
|
||||
@@ -59,12 +60,13 @@ public:
|
||||
return *m_socket;
|
||||
}
|
||||
|
||||
PeerImp (boost::asio::io_service& io_service,
|
||||
boost::asio::ssl::context& ssl_context,
|
||||
uint64 peerID,
|
||||
bool inbound,
|
||||
MultiSocket::Flag flags)
|
||||
: m_isInbound (inbound)
|
||||
PeerImp (Resource::Manager& resourceManager,
|
||||
boost::asio::io_service& io_service,
|
||||
boost::asio::ssl::context& ssl_context,
|
||||
uint64 peerID, bool inbound,
|
||||
MultiSocket::Flag flags)
|
||||
: m_resourceManager (resourceManager)
|
||||
, m_isInbound (inbound)
|
||||
, m_socket (MultiSocket::New (
|
||||
io_service, ssl_context, flags.asBits ()))
|
||||
, m_strand (io_service)
|
||||
@@ -118,7 +120,8 @@ private:
|
||||
|
||||
bool m_remoteAddressSet;
|
||||
IPEndpoint m_remoteAddress;
|
||||
|
||||
Resource::Consumer m_usage;
|
||||
|
||||
public:
|
||||
static char const* getCountedObjectName () { return "Peer"; }
|
||||
|
||||
@@ -160,6 +163,11 @@ public:
|
||||
|
||||
void sendGetPeers ();
|
||||
|
||||
void charge (Resource::Charge const& fee)
|
||||
{
|
||||
m_usage.charge (fee);
|
||||
}
|
||||
|
||||
void applyLoadCharge (LoadType);
|
||||
|
||||
Json::Value getJson ();
|
||||
@@ -300,24 +308,6 @@ private:
|
||||
}
|
||||
else
|
||||
{
|
||||
boost::asio::ip::address addr (getNativeSocket().remote_endpoint().address());
|
||||
|
||||
if (addr.is_v4())
|
||||
{
|
||||
boost::asio::ip::address_v4::bytes_type bytes (addr.to_v4().to_bytes());
|
||||
m_remoteAddress = IPEndpoint (IPEndpoint::V4 (
|
||||
bytes[0], bytes[1], bytes[2], bytes[3]), 0);
|
||||
if (! m_isInbound)
|
||||
m_remoteAddress = m_remoteAddress.withPort (
|
||||
getNativeSocket().remote_endpoint().port());
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO: Support ipv6
|
||||
bassertfalse;
|
||||
}
|
||||
m_remoteAddressSet = true;
|
||||
|
||||
if (m_socket->getFlags ().set (MultiSocket::Flag::proxy) && m_isInbound)
|
||||
{
|
||||
MultiSocket::ProxyInfo const proxyInfo (m_socket->getProxyInfo ());
|
||||
@@ -336,6 +326,11 @@ private:
|
||||
mIpPort.first = proxyInfo.sourceAddress.toString ().toStdString ();
|
||||
mIpPort.second = proxyInfo.sourcePort;
|
||||
|
||||
if (m_isInbound)
|
||||
m_usage = m_resourceManager.newInboundEndpoint (m_remoteAddress);
|
||||
else
|
||||
m_usage = m_resourceManager.newOutboundEndpoint (m_remoteAddress);
|
||||
|
||||
// Must compute mCookieHash before receiving a hello.
|
||||
sendHello ();
|
||||
startReadHeader ();
|
||||
@@ -359,6 +354,29 @@ private:
|
||||
}
|
||||
else
|
||||
{
|
||||
boost::asio::ip::address addr (getNativeSocket().remote_endpoint().address());
|
||||
|
||||
if (addr.is_v4())
|
||||
{
|
||||
boost::asio::ip::address_v4::bytes_type bytes (addr.to_v4().to_bytes());
|
||||
m_remoteAddress = IPEndpoint (IPEndpoint::V4 (
|
||||
bytes[0], bytes[1], bytes[2], bytes[3]), 0);
|
||||
if (! m_isInbound)
|
||||
m_remoteAddress = m_remoteAddress.withPort (
|
||||
getNativeSocket().remote_endpoint().port());
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO: Support ipv6
|
||||
bassertfalse;
|
||||
}
|
||||
m_remoteAddressSet = true;
|
||||
|
||||
if (m_isInbound)
|
||||
m_usage = m_resourceManager.newInboundEndpoint (m_remoteAddress);
|
||||
else
|
||||
m_usage = m_resourceManager.newOutboundEndpoint (m_remoteAddress);
|
||||
|
||||
// Must compute mCookieHash before receiving a hello.
|
||||
sendHello ();
|
||||
startReadHeader ();
|
||||
@@ -1221,6 +1239,7 @@ static void checkTransaction (Job&, int flags, SerializedTransaction::pointer st
|
||||
if (tx->getStatus () == INVALID)
|
||||
{
|
||||
getApp().getHashRouter ().setFlag (stx->getTransactionID (), SF_BAD);
|
||||
Peer::charge (peer, Resource::feeInvalidSignature);
|
||||
Peer::applyLoadCharge (peer, LT_InvalidSignature);
|
||||
return;
|
||||
}
|
||||
@@ -1234,6 +1253,7 @@ static void checkTransaction (Job&, int flags, SerializedTransaction::pointer st
|
||||
catch (...)
|
||||
{
|
||||
getApp().getHashRouter ().setFlag (stx->getTransactionID (), SF_BAD);
|
||||
Peer::charge (peer, Resource::feeInvalidRequest);
|
||||
Peer::applyLoadCharge (peer, LT_InvalidRequest);
|
||||
}
|
||||
|
||||
@@ -1261,6 +1281,7 @@ void PeerImp::recvTransaction (protocol::TMTransaction& packet, Application::Sco
|
||||
// we have seen this transaction recently
|
||||
if (isSetBit (flags, SF_BAD))
|
||||
{
|
||||
charge (Resource::feeInvalidSignature);
|
||||
applyLoadCharge (LT_InvalidSignature);
|
||||
return;
|
||||
}
|
||||
@@ -1325,6 +1346,7 @@ static void checkPropose (Job& job, boost::shared_ptr<protocol::TMProposeSet> pa
|
||||
Peer::pointer p = peer.lock ();
|
||||
WriteLog (lsWARNING, Peer) << "proposal with previous ledger fails signature check: " <<
|
||||
(p ? p->getIP () : std::string ("???"));
|
||||
Peer::charge (peer, Resource::feeInvalidSignature);
|
||||
Peer::applyLoadCharge (peer, LT_InvalidSignature);
|
||||
return;
|
||||
}
|
||||
@@ -1369,6 +1391,7 @@ void PeerImp::recvPropose (const boost::shared_ptr<protocol::TMProposeSet>& pack
|
||||
(set.signature ().size () < 56) || (set.nodepubkey ().size () > 128) || (set.signature ().size () > 128))
|
||||
{
|
||||
WriteLog (lsWARNING, Peer) << "Received proposal is malformed";
|
||||
charge (Resource::feeInvalidSignature);
|
||||
applyLoadCharge (LT_InvalidSignature);
|
||||
return;
|
||||
}
|
||||
@@ -1376,6 +1399,7 @@ void PeerImp::recvPropose (const boost::shared_ptr<protocol::TMProposeSet>& pack
|
||||
if (set.has_previousledger () && (set.previousledger ().size () != 32))
|
||||
{
|
||||
WriteLog (lsWARNING, Peer) << "Received proposal is malformed";
|
||||
charge (Resource::feeInvalidRequest);
|
||||
applyLoadCharge (LT_InvalidRequest);
|
||||
return;
|
||||
}
|
||||
@@ -1437,6 +1461,7 @@ void PeerImp::recvHaveTxSet (protocol::TMHaveTransactionSet& packet)
|
||||
|
||||
if (packet.hash ().size () != (256 / 8))
|
||||
{
|
||||
charge (Resource::feeInvalidRequest);
|
||||
applyLoadCharge (LT_InvalidRequest);
|
||||
return;
|
||||
}
|
||||
@@ -1452,7 +1477,10 @@ void PeerImp::recvHaveTxSet (protocol::TMHaveTransactionSet& packet)
|
||||
addTxSet (hash);
|
||||
|
||||
if (!getApp().getOPs ().hasTXSet (shared_from_this (), hash, packet.status ()))
|
||||
{
|
||||
charge (Resource::feeUnwantedData);
|
||||
applyLoadCharge (LT_UnwantedData);
|
||||
}
|
||||
}
|
||||
|
||||
static void checkValidation (Job&, SerializedValidation::pointer val, bool isTrusted, bool isCluster,
|
||||
@@ -1467,6 +1495,7 @@ static void checkValidation (Job&, SerializedValidation::pointer val, bool isTru
|
||||
if (!isCluster && !val->isValid (signingHash))
|
||||
{
|
||||
WriteLog (lsWARNING, Peer) << "Validation is invalid";
|
||||
Peer::charge (peer, Resource::feeInvalidRequest);
|
||||
Peer::applyLoadCharge (peer, LT_InvalidRequest);
|
||||
return;
|
||||
}
|
||||
@@ -1505,6 +1534,7 @@ static void checkValidation (Job&, SerializedValidation::pointer val, bool isTru
|
||||
catch (...)
|
||||
{
|
||||
WriteLog (lsWARNING, Peer) << "Exception processing validation";
|
||||
Peer::charge (peer, Resource::feeInvalidRequest);
|
||||
Peer::applyLoadCharge (peer, LT_InvalidRequest);
|
||||
}
|
||||
|
||||
@@ -1519,6 +1549,7 @@ void PeerImp::recvValidation (const boost::shared_ptr<protocol::TMValidation>& p
|
||||
if (packet->validation ().size () < 50)
|
||||
{
|
||||
WriteLog (lsWARNING, Peer) << "Too small validation from peer";
|
||||
charge (Resource::feeInvalidRequest);
|
||||
applyLoadCharge (LT_InvalidRequest);
|
||||
return;
|
||||
}
|
||||
@@ -1535,6 +1566,7 @@ void PeerImp::recvValidation (const boost::shared_ptr<protocol::TMValidation>& p
|
||||
if (closeTime > (120 + val->getFieldU32(sfSigningTime)))
|
||||
{
|
||||
WriteLog (lsTRACE, Peer) << "Validation is more than two minutes old";
|
||||
charge (Resource::feeUnwantedData);
|
||||
applyLoadCharge (LT_UnwantedData);
|
||||
return;
|
||||
}
|
||||
@@ -1558,6 +1590,7 @@ void PeerImp::recvValidation (const boost::shared_ptr<protocol::TMValidation>& p
|
||||
catch (...)
|
||||
{
|
||||
WriteLog (lsWARNING, Peer) << "Exception processing validation";
|
||||
charge (Resource::feeInvalidRequest);
|
||||
applyLoadCharge (LT_InvalidRequest);
|
||||
}
|
||||
|
||||
@@ -1568,6 +1601,7 @@ void PeerImp::recvCluster (protocol::TMCluster& packet)
|
||||
{
|
||||
if (!mCluster)
|
||||
{
|
||||
charge (Resource::feeUnwantedData);
|
||||
applyLoadCharge(LT_UnwantedData);
|
||||
return;
|
||||
}
|
||||
@@ -1863,6 +1897,7 @@ void PeerImp::recvProofWork (protocol::TMProofWork& packet)
|
||||
// this is an answer to a proof of work we requested
|
||||
if (packet.response ().size () != (256 / 8))
|
||||
{
|
||||
charge (Resource::feeInvalidRequest);
|
||||
applyLoadCharge (LT_InvalidRequest);
|
||||
return;
|
||||
}
|
||||
@@ -1881,7 +1916,10 @@ void PeerImp::recvProofWork (protocol::TMProofWork& packet)
|
||||
// return error message
|
||||
// WRITEME
|
||||
if (r != powTOOEASY)
|
||||
{
|
||||
charge (Resource::feeBadProofOfWork);
|
||||
applyLoadCharge (LT_BadPoW);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -1901,6 +1939,7 @@ void PeerImp::recvProofWork (protocol::TMProofWork& packet)
|
||||
|
||||
if ((packet.challenge ().size () != (256 / 8)) || (packet.target ().size () != (256 / 8)))
|
||||
{
|
||||
charge (Resource::feeInvalidRequest);
|
||||
applyLoadCharge (LT_InvalidRequest);
|
||||
return;
|
||||
}
|
||||
@@ -1912,6 +1951,7 @@ void PeerImp::recvProofWork (protocol::TMProofWork& packet)
|
||||
|
||||
if (!pow->isValid ())
|
||||
{
|
||||
charge (Resource::feeInvalidRequest);
|
||||
applyLoadCharge (LT_InvalidRequest);
|
||||
return;
|
||||
}
|
||||
@@ -2009,6 +2049,7 @@ void PeerImp::recvGetLedger (protocol::TMGetLedger& packet, Application::ScopedL
|
||||
|
||||
if ((!packet.has_ledgerhash () || packet.ledgerhash ().size () != 32))
|
||||
{
|
||||
charge (Resource::feeInvalidRequest);
|
||||
applyLoadCharge (LT_InvalidRequest);
|
||||
WriteLog (lsWARNING, Peer) << "invalid request for TX candidate set data";
|
||||
return;
|
||||
@@ -2045,6 +2086,7 @@ void PeerImp::recvGetLedger (protocol::TMGetLedger& packet, Application::ScopedL
|
||||
}
|
||||
|
||||
WriteLog (lsERROR, Peer) << "We do not have the map our peer wants " << getIP ();
|
||||
charge (Resource::feeInvalidRequest);
|
||||
applyLoadCharge (LT_InvalidRequest);
|
||||
return;
|
||||
}
|
||||
@@ -2073,6 +2115,7 @@ void PeerImp::recvGetLedger (protocol::TMGetLedger& packet, Application::ScopedL
|
||||
|
||||
if (packet.ledgerhash ().size () != 32)
|
||||
{
|
||||
charge (Resource::feeInvalidRequest);
|
||||
applyLoadCharge (LT_InvalidRequest);
|
||||
WriteLog (lsWARNING, Peer) << "Invalid request";
|
||||
return;
|
||||
@@ -2129,6 +2172,7 @@ void PeerImp::recvGetLedger (protocol::TMGetLedger& packet, Application::ScopedL
|
||||
}
|
||||
else
|
||||
{
|
||||
charge (Resource::feeInvalidRequest);
|
||||
applyLoadCharge (LT_InvalidRequest);
|
||||
WriteLog (lsWARNING, Peer) << "Can't figure out what ledger they want";
|
||||
return;
|
||||
@@ -2136,6 +2180,7 @@ void PeerImp::recvGetLedger (protocol::TMGetLedger& packet, Application::ScopedL
|
||||
|
||||
if ((!ledger) || (packet.has_ledgerseq () && (packet.ledgerseq () != ledger->getLedgerSeq ())))
|
||||
{
|
||||
charge (Resource::feeInvalidRequest);
|
||||
applyLoadCharge (LT_InvalidRequest);
|
||||
|
||||
if (ShouldLog (lsWARNING, Peer))
|
||||
@@ -2216,6 +2261,7 @@ void PeerImp::recvGetLedger (protocol::TMGetLedger& packet, Application::ScopedL
|
||||
if ((!map) || (packet.nodeids_size () == 0))
|
||||
{
|
||||
WriteLog (lsWARNING, Peer) << "Can't find map or empty request";
|
||||
charge (Resource::feeInvalidRequest);
|
||||
applyLoadCharge (LT_InvalidRequest);
|
||||
return;
|
||||
}
|
||||
@@ -2229,6 +2275,7 @@ void PeerImp::recvGetLedger (protocol::TMGetLedger& packet, Application::ScopedL
|
||||
if (!mn.isValid ())
|
||||
{
|
||||
WriteLog (lsWARNING, Peer) << "Request for invalid node: " << logMe;
|
||||
charge (Resource::feeInvalidRequest);
|
||||
applyLoadCharge (LT_InvalidRequest);
|
||||
return;
|
||||
}
|
||||
@@ -2290,6 +2337,7 @@ void PeerImp::recvLedger (const boost::shared_ptr<protocol::TMLedgerData>& packe
|
||||
if (packet.nodes ().size () <= 0)
|
||||
{
|
||||
WriteLog (lsWARNING, Peer) << "Ledger/TXset data with no nodes";
|
||||
charge (Resource::feeInvalidRequest);
|
||||
applyLoadCharge (LT_InvalidRequest);
|
||||
return;
|
||||
}
|
||||
@@ -2306,6 +2354,7 @@ void PeerImp::recvLedger (const boost::shared_ptr<protocol::TMLedgerData>& packe
|
||||
else
|
||||
{
|
||||
WriteLog (lsINFO, Peer) << "Unable to route TX/ledger data reply";
|
||||
charge (Resource::feeUnwantedData);
|
||||
applyLoadCharge (LT_UnwantedData);
|
||||
}
|
||||
|
||||
@@ -2317,6 +2366,7 @@ void PeerImp::recvLedger (const boost::shared_ptr<protocol::TMLedgerData>& packe
|
||||
if (packet.ledgerhash ().size () != 32)
|
||||
{
|
||||
WriteLog (lsWARNING, Peer) << "TX candidate reply with invalid hash size";
|
||||
charge (Resource::feeInvalidRequest);
|
||||
applyLoadCharge (LT_InvalidRequest);
|
||||
return;
|
||||
}
|
||||
@@ -2336,6 +2386,7 @@ void PeerImp::recvLedger (const boost::shared_ptr<protocol::TMLedgerData>& packe
|
||||
if (!node.has_nodeid () || !node.has_nodedata () || (node.nodeid ().size () != 33))
|
||||
{
|
||||
WriteLog (lsWARNING, Peer) << "LedgerData request with invalid node ID";
|
||||
charge (Resource::feeInvalidRequest);
|
||||
applyLoadCharge (LT_InvalidRequest);
|
||||
return;
|
||||
}
|
||||
@@ -2347,17 +2398,25 @@ void PeerImp::recvLedger (const boost::shared_ptr<protocol::TMLedgerData>& packe
|
||||
SHAMapAddNode san = getApp().getOPs ().gotTXData (shared_from_this (), hash, nodeIDs, nodeData);
|
||||
|
||||
if (san.isInvalid ())
|
||||
{
|
||||
charge (Resource::feeUnwantedData);
|
||||
applyLoadCharge (LT_UnwantedData);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (getApp().getInboundLedgers ().awaitLedgerData (hash))
|
||||
{
|
||||
getApp().getJobQueue ().addJob (jtLEDGER_DATA, "gotLedgerData",
|
||||
BIND_TYPE (&InboundLedgers::gotLedgerData, &getApp().getInboundLedgers (),
|
||||
P_1, hash, packet_ptr, boost::weak_ptr<Peer> (shared_from_this ())));
|
||||
}
|
||||
else
|
||||
{
|
||||
charge (Resource::feeUnwantedData);
|
||||
applyLoadCharge (LT_UnwantedData);
|
||||
}
|
||||
}
|
||||
|
||||
void PeerImp::ledgerRange (uint32& minSeq, uint32& maxSeq) const
|
||||
@@ -2570,6 +2629,7 @@ void PeerImp::doFetchPack (const boost::shared_ptr<protocol::TMGetObjectByHash>&
|
||||
if (packet->ledgerhash ().size () != 32)
|
||||
{
|
||||
WriteLog (lsWARNING, Peer) << "FetchPack hash size malformed";
|
||||
charge (Resource::feeInvalidRequest);
|
||||
applyLoadCharge (LT_InvalidRequest);
|
||||
return;
|
||||
}
|
||||
@@ -2582,6 +2642,7 @@ void PeerImp::doFetchPack (const boost::shared_ptr<protocol::TMGetObjectByHash>&
|
||||
if (!haveLedger)
|
||||
{
|
||||
WriteLog (lsINFO, Peer) << "Peer requests fetch pack for ledger we don't have: " << hash;
|
||||
charge (Resource::feeRequestNoReply);
|
||||
applyLoadCharge (LT_RequestNoReply);
|
||||
return;
|
||||
}
|
||||
@@ -2589,6 +2650,7 @@ void PeerImp::doFetchPack (const boost::shared_ptr<protocol::TMGetObjectByHash>&
|
||||
if (!haveLedger->isClosed ())
|
||||
{
|
||||
WriteLog (lsWARNING, Peer) << "Peer requests fetch pack from open ledger: " << hash;
|
||||
charge (Resource::feeInvalidRequest);
|
||||
applyLoadCharge (LT_InvalidRequest);
|
||||
return;
|
||||
}
|
||||
@@ -2598,6 +2660,7 @@ void PeerImp::doFetchPack (const boost::shared_ptr<protocol::TMGetObjectByHash>&
|
||||
if (!wantLedger)
|
||||
{
|
||||
WriteLog (lsINFO, Peer) << "Peer requests fetch pack for ledger whose predecessor we don't have: " << hash;
|
||||
charge (Resource::feeRequestNoReply);
|
||||
applyLoadCharge (LT_RequestNoReply);
|
||||
return;
|
||||
}
|
||||
@@ -2692,9 +2755,10 @@ Json::Value PeerImp::getJson ()
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
Peer::pointer Peer::New (boost::asio::io_service& io_service,
|
||||
boost::asio::ssl::context& ssl_context, uint64 id,
|
||||
bool inbound, bool requirePROXYHandshake)
|
||||
Peer::pointer Peer::New (Resource::Manager& resourceManager,
|
||||
boost::asio::io_service& io_service,
|
||||
boost::asio::ssl::context& ssl_context, uint64 id,
|
||||
bool inbound, bool requirePROXYHandshake)
|
||||
{
|
||||
MultiSocket::Flag flags;
|
||||
|
||||
@@ -2714,12 +2778,19 @@ Peer::pointer Peer::New (boost::asio::io_service& io_service,
|
||||
bassert (! requirePROXYHandshake);
|
||||
}
|
||||
|
||||
return Peer::pointer (new PeerImp (
|
||||
return Peer::pointer (new PeerImp (resourceManager,
|
||||
io_service, ssl_context, id, inbound, flags));
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
void Peer::charge (boost::weak_ptr <Peer>& peer, Resource::Charge const& fee)
|
||||
{
|
||||
Peer::pointer p (peer.lock());
|
||||
if (p != nullptr)
|
||||
p->charge (fee);
|
||||
}
|
||||
|
||||
void Peer::applyLoadCharge (boost::weak_ptr <Peer>& peerToPunish,
|
||||
LoadType loadThatWasImposed)
|
||||
{
|
||||
@@ -2730,3 +2801,4 @@ void Peer::applyLoadCharge (boost::weak_ptr <Peer>& peerToPunish,
|
||||
p->applyLoadCharge (loadThatWasImposed);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,10 +17,14 @@
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
|
||||
#ifndef RIPPLE_PEER_H_INCLUDED
|
||||
#define RIPPLE_PEER_H_INCLUDED
|
||||
|
||||
namespace Resource {
|
||||
class Charge;
|
||||
class Manager;
|
||||
}
|
||||
|
||||
// VFALCO TODO Couldn't this be a struct?
|
||||
typedef std::pair <std::string, int> IPAndPortNumber;
|
||||
|
||||
@@ -35,7 +39,8 @@ public:
|
||||
typedef pointer const& ref;
|
||||
|
||||
public:
|
||||
static pointer New (boost::asio::io_service& io_service,
|
||||
static pointer New (Resource::Manager& resourceManager,
|
||||
boost::asio::io_service& io_service,
|
||||
boost::asio::ssl::context& ctx,
|
||||
uint64 id,
|
||||
bool inbound,
|
||||
@@ -63,14 +68,15 @@ public:
|
||||
|
||||
virtual void sendGetPeers () = 0;
|
||||
|
||||
virtual void applyLoadCharge (LoadType) = 0;
|
||||
|
||||
// VFALCO NOTE what's with this odd parameter passing? Why the static member?
|
||||
//
|
||||
/** Adjust this peer's load balance based on the type of load imposed.
|
||||
|
||||
@note Formerly named punishPeer
|
||||
*/
|
||||
virtual void charge (Resource::Charge const& fee) = 0;
|
||||
static void charge (boost::weak_ptr <Peer>& peer, Resource::Charge const& fee);
|
||||
virtual void applyLoadCharge (LoadType) = 0;
|
||||
static void applyLoadCharge (boost::weak_ptr <Peer>& peerTOCharge, LoadType loadThatWasImposed);
|
||||
|
||||
virtual Json::Value getJson () = 0;
|
||||
|
||||
@@ -25,9 +25,11 @@ class PeerDoorImp
|
||||
, public LeakChecked <PeerDoorImp>
|
||||
{
|
||||
public:
|
||||
PeerDoorImp (Stoppable& parent, Kind kind, std::string const& ip, int port,
|
||||
boost::asio::io_service& io_service, boost::asio::ssl::context& ssl_context)
|
||||
PeerDoorImp (Stoppable& parent, Resource::Manager& resourceManager,
|
||||
Kind kind, std::string const& ip, int port,
|
||||
boost::asio::io_service& io_service, boost::asio::ssl::context& ssl_context)
|
||||
: PeerDoor (parent)
|
||||
, m_resourceManager (resourceManager)
|
||||
, m_kind (kind)
|
||||
, m_ssl_context (ssl_context)
|
||||
, mAcceptor (io_service, boost::asio::ip::tcp::endpoint (
|
||||
@@ -56,8 +58,8 @@ public:
|
||||
bool const requirePROXYHandshake (m_kind == sslAndPROXYRequired);
|
||||
|
||||
Peer::pointer new_connection (Peer::New (
|
||||
mAcceptor.get_io_service (), m_ssl_context,
|
||||
getApp().getPeers ().assignPeerId (),
|
||||
m_resourceManager, mAcceptor.get_io_service (),
|
||||
m_ssl_context, getApp().getPeers ().assignPeerId (),
|
||||
isInbound, requirePROXYHandshake));
|
||||
|
||||
mAcceptor.async_accept (new_connection->getNativeSocket (),
|
||||
@@ -123,6 +125,7 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
Resource::Manager& m_resourceManager;
|
||||
Kind m_kind;
|
||||
boost::asio::ssl::context& m_ssl_context;
|
||||
boost::asio::ip::tcp::acceptor mAcceptor;
|
||||
@@ -138,8 +141,12 @@ PeerDoor::PeerDoor (Stoppable& parent)
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
PeerDoor* PeerDoor::New (Stoppable& parent, Kind kind, std::string const& ip, int port,
|
||||
boost::asio::io_service& io_service, boost::asio::ssl::context& ssl_context)
|
||||
PeerDoor* PeerDoor::New (Stoppable& parent,
|
||||
Resource::Manager& resourceManager,
|
||||
Kind kind, std::string const& ip, int port,
|
||||
boost::asio::io_service& io_service,
|
||||
boost::asio::ssl::context& ssl_context)
|
||||
{
|
||||
return new PeerDoorImp (parent, kind, ip, port, io_service, ssl_context);
|
||||
return new PeerDoorImp (parent, resourceManager,
|
||||
kind, ip, port, io_service, ssl_context);
|
||||
}
|
||||
|
||||
@@ -17,10 +17,13 @@
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
|
||||
#ifndef RIPPLE_PEERDOOR_H_INCLUDED
|
||||
#define RIPPLE_PEERDOOR_H_INCLUDED
|
||||
|
||||
namespace Resource {
|
||||
class Manager;
|
||||
}
|
||||
|
||||
/** Handles incoming connections from peers. */
|
||||
class PeerDoor : public Stoppable
|
||||
{
|
||||
@@ -36,8 +39,11 @@ public:
|
||||
sslAndPROXYRequired
|
||||
};
|
||||
|
||||
static PeerDoor* New (Stoppable& parent, Kind kind, std::string const& ip, int port,
|
||||
boost::asio::io_service& io_service, boost::asio::ssl::context& ssl_context);
|
||||
static PeerDoor* New (Stoppable& parent,
|
||||
Resource::Manager& resourceManager,
|
||||
Kind kind, std::string const& ip, int port,
|
||||
boost::asio::io_service& io_service,
|
||||
boost::asio::ssl::context& ssl_context);
|
||||
|
||||
//virtual boost::asio::ssl::context& getSSLContext () = 0;
|
||||
};
|
||||
|
||||
@@ -42,6 +42,7 @@ public:
|
||||
typedef std::map<IPAndPortNumber, Peer::pointer>::value_type vtPeer;
|
||||
typedef boost::unordered_map<RippleAddress, Peer::pointer>::value_type vtConMap;
|
||||
|
||||
Resource::Manager& m_resourceManager;
|
||||
ScopedPointer <PeerFinder::Manager> m_peerFinder;
|
||||
|
||||
boost::asio::io_service& m_io_service;
|
||||
@@ -88,9 +89,11 @@ public:
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
PeersImp (Stoppable& parent,
|
||||
boost::asio::io_service& io_service,
|
||||
boost::asio::ssl::context& ssl_context)
|
||||
Resource::Manager& resourceManager,
|
||||
boost::asio::io_service& io_service,
|
||||
boost::asio::ssl::context& ssl_context)
|
||||
: Stoppable ("Peers", parent)
|
||||
, m_resourceManager (resourceManager)
|
||||
, m_peerFinder (add (PeerFinder::Manager::New (
|
||||
*this, *this, LogJournal::get <PeerFinderLog> ())))
|
||||
, m_io_service (io_service)
|
||||
@@ -193,6 +196,7 @@ public:
|
||||
if (peer->isConnected() &&
|
||||
PeerFinder::PeerID (peer->getNodePublic()) == id)
|
||||
{
|
||||
peer->charge (Resource::feeUnwantedData);
|
||||
peer->applyLoadCharge (LT_UnwantedData);
|
||||
break;
|
||||
}
|
||||
@@ -639,7 +643,7 @@ Peer::pointer PeersImp::peerConnect (const std::string& strIp, int iPort)
|
||||
bool const isInbound (false);
|
||||
bool const requirePROXYHandshake (false);
|
||||
|
||||
ppResult = Peer::New (m_io_service, m_ssl_context,
|
||||
ppResult = Peer::New (m_resourceManager, m_io_service, m_ssl_context,
|
||||
++mLastPeer, isInbound, requirePROXYHandshake);
|
||||
|
||||
mIpMap [pipPeer] = ppResult;
|
||||
@@ -1093,9 +1097,10 @@ Peers::Peers ()
|
||||
}
|
||||
|
||||
Peers* Peers::New (Stoppable& parent,
|
||||
Resource::Manager& resourceManager,
|
||||
boost::asio::io_service& io_service,
|
||||
boost::asio::ssl::context& ssl_context)
|
||||
{
|
||||
return new PeersImp (parent, io_service, ssl_context);
|
||||
return new PeersImp (parent, resourceManager, io_service, ssl_context);
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,10 @@
|
||||
#ifndef RIPPLE_PEERS_H_INCLUDED
|
||||
#define RIPPLE_PEERS_H_INCLUDED
|
||||
|
||||
namespace Resource {
|
||||
class Manager;
|
||||
}
|
||||
|
||||
namespace PeerFinder {
|
||||
class Manager;
|
||||
}
|
||||
@@ -29,8 +33,9 @@ class Peers : public PropertyStream::Source
|
||||
{
|
||||
public:
|
||||
static Peers* New (Stoppable& parent,
|
||||
boost::asio::io_service& io_service,
|
||||
boost::asio::ssl::context& context);
|
||||
Resource::Manager& resourceManager,
|
||||
boost::asio::io_service& io_service,
|
||||
boost::asio::ssl::context& context);
|
||||
|
||||
Peers ();
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
// material in Ripple since it holds the Application object.
|
||||
|
||||
#include "../ripple/http/ripple_http.h"
|
||||
#include "../ripple/resource/ripple_resource.h"
|
||||
#include "../ripple/rpc/ripple_rpc.h"
|
||||
#include "../ripple/validators/ripple_validators.h"
|
||||
|
||||
|
||||
@@ -62,8 +62,7 @@
|
||||
//
|
||||
#include "peers/PackedMessage.h"
|
||||
|
||||
namespace ripple
|
||||
{
|
||||
namespace ripple {
|
||||
|
||||
// Order matters here. If you get compile errors,
|
||||
// reorder the include lines until the order is correct.
|
||||
|
||||
@@ -22,8 +22,7 @@
|
||||
|
||||
#include "ripple_app.h"
|
||||
|
||||
namespace ripple
|
||||
{
|
||||
namespace ripple {
|
||||
|
||||
#include "shamap/SHAMap.cpp" // Uses theApp
|
||||
#include "shamap/SHAMapItem.cpp"
|
||||
|
||||
@@ -24,10 +24,10 @@
|
||||
#include "../ripple_net/ripple_net.h"
|
||||
|
||||
#include "../ripple/peerfinder/ripple_peerfinder.h"
|
||||
#include "../ripple/resource/ripple_resource.h"
|
||||
#include "../ripple/validators/ripple_validators.h"
|
||||
|
||||
namespace ripple
|
||||
{
|
||||
namespace ripple {
|
||||
|
||||
#include "ledger/LedgerTiming.cpp"
|
||||
#include "ledger/AcceptedLedgerTx.cpp"
|
||||
|
||||
@@ -22,6 +22,8 @@
|
||||
|
||||
#include "ripple_app.h"
|
||||
|
||||
#include "../ripple/resource/ripple_resource.h"
|
||||
|
||||
namespace ripple
|
||||
{
|
||||
|
||||
|
||||
@@ -28,9 +28,12 @@ static std::string trimIP(const std::string& ip)
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
WSConnection::WSConnection (InfoSub::Source& source, bool isPublic,
|
||||
std::string const& remoteIP, boost::asio::io_service& io_service)
|
||||
WSConnection::WSConnection (Resource::Manager& resourceManager,
|
||||
Resource::Consumer usage, InfoSub::Source& source, bool isPublic,
|
||||
std::string const& remoteIP, boost::asio::io_service& io_service)
|
||||
: InfoSub (source)
|
||||
, m_resourceManager (resourceManager)
|
||||
, m_usage (usage)
|
||||
, m_isPublic (isPublic)
|
||||
, m_remoteIP (remoteIP)
|
||||
, m_receiveQueueMutex (this, "WSConnection", __FILE__, __LINE__)
|
||||
@@ -110,12 +113,19 @@ void WSConnection::returnMessage (message_ptr ptr)
|
||||
|
||||
Json::Value WSConnection::invokeCommand (Json::Value& jvRequest)
|
||||
{
|
||||
// VFALCO TODO Make LoadManager a ctor argument
|
||||
#if RIPPLE_USE_RESOURCE_MANAGER
|
||||
if (m_usage.disconnect ())
|
||||
{
|
||||
disconnect ();
|
||||
return rpcError (rpcSLOW_DOWN);
|
||||
}
|
||||
#else
|
||||
if (getApp().getLoadManager ().shouldCutoff (m_loadSource))
|
||||
{
|
||||
disconnect ();
|
||||
return rpcError (rpcSLOW_DOWN);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Requests without "command" are invalid.
|
||||
//
|
||||
@@ -133,7 +143,11 @@ Json::Value WSConnection::invokeCommand (Json::Value& jvRequest)
|
||||
jvResult["id"] = jvRequest["id"];
|
||||
}
|
||||
|
||||
#if RIPPLE_USE_RESOURCE_MANAGER
|
||||
m_usage.charge (Resource::feeInvalidRPC);
|
||||
#else
|
||||
getApp().getLoadManager ().applyLoadCharge (m_loadSource, LT_RPCInvalid);
|
||||
#endif
|
||||
|
||||
return jvResult;
|
||||
}
|
||||
@@ -155,6 +169,13 @@ Json::Value WSConnection::invokeCommand (Json::Value& jvRequest)
|
||||
jvResult["result"] = mRPCHandler.doCommand (jvRequest, role, &loadType);
|
||||
}
|
||||
|
||||
#if RIPPLE_USE_RESOURCE_MANAGER
|
||||
m_usage.charge (Resource::legacyFee (loadType));
|
||||
if (m_usage.warn ())
|
||||
{
|
||||
jvResult["warning"] = "load";
|
||||
}
|
||||
#else
|
||||
// Debit/credit the load and see if we should include a warning.
|
||||
//
|
||||
if (getApp().getLoadManager ().applyLoadCharge (m_loadSource, loadType) &&
|
||||
@@ -162,6 +183,7 @@ Json::Value WSConnection::invokeCommand (Json::Value& jvRequest)
|
||||
{
|
||||
jvResult["warning"] = "load";
|
||||
}
|
||||
#endif
|
||||
|
||||
// Currently we will simply unwrap errors returned by the RPC
|
||||
// API, in the future maybe we can make the responses
|
||||
|
||||
@@ -38,8 +38,9 @@ public:
|
||||
protected:
|
||||
typedef websocketpp::message::data::ptr message_ptr;
|
||||
|
||||
WSConnection (InfoSub::Source& source, bool isPublic,
|
||||
std::string const& remoteIP, boost::asio::io_service& io_service);
|
||||
WSConnection (Resource::Manager& resourceManager,
|
||||
Resource::Consumer usage, InfoSub::Source& source, bool isPublic,
|
||||
std::string const& remoteIP, boost::asio::io_service& io_service);
|
||||
|
||||
virtual ~WSConnection ();
|
||||
|
||||
@@ -54,6 +55,8 @@ public:
|
||||
Json::Value invokeCommand (Json::Value& jvRequest);
|
||||
|
||||
protected:
|
||||
Resource::Manager& m_resourceManager;
|
||||
Resource::Consumer m_usage;
|
||||
bool const m_isPublic;
|
||||
std::string const m_remoteIP;
|
||||
LockType m_receiveQueueMutex;
|
||||
@@ -89,9 +92,21 @@ public:
|
||||
typedef WSServerHandler <endpoint_type> server_type;
|
||||
|
||||
public:
|
||||
WSConnectionType (InfoSub::Source& source, server_type& serverHandler,
|
||||
connection_ptr const& cpConnection)
|
||||
: WSConnection (source,
|
||||
static IPEndpoint from_address (boost::asio::ip::address const& addr)
|
||||
{
|
||||
boost::asio::ip::address_v4::bytes_type bytes (addr.to_v4().to_bytes());
|
||||
IPEndpoint ep (IPEndpoint::V4 (bytes[0], bytes[1], bytes[2], bytes[3]), 0);
|
||||
return ep;
|
||||
}
|
||||
|
||||
WSConnectionType (Resource::Manager& resourceManager,
|
||||
InfoSub::Source& source, server_type& serverHandler,
|
||||
connection_ptr const& cpConnection)
|
||||
: WSConnection (
|
||||
resourceManager,
|
||||
resourceManager.newInboundEndpoint (from_address (
|
||||
cpConnection->get_socket ().lowest_layer ().remote_endpoint ().address ())),
|
||||
source,
|
||||
serverHandler.getPublic (),
|
||||
cpConnection->get_socket ().lowest_layer ().remote_endpoint ().address ().to_string (),
|
||||
cpConnection->get_io_service ())
|
||||
|
||||
@@ -39,11 +39,12 @@ SETUP_LOG (WSDoor)
|
||||
class WSDoorImp : public WSDoor, protected Thread, LeakChecked <WSDoorImp>
|
||||
{
|
||||
public:
|
||||
WSDoorImp (InfoSub::Source& source,
|
||||
std::string const& strIp, int iPort, bool bPublic,
|
||||
boost::asio::ssl::context& ssl_context)
|
||||
WSDoorImp (Resource::Manager& resourceManager,
|
||||
InfoSub::Source& source, std::string const& strIp,
|
||||
int iPort, bool bPublic, boost::asio::ssl::context& ssl_context)
|
||||
: WSDoor (source)
|
||||
, Thread ("websocket")
|
||||
, m_resourceManager (resourceManager)
|
||||
, m_source (source)
|
||||
, m_ssl_context (ssl_context)
|
||||
, m_endpointLock (this, "WSDoor", __FILE__, __LINE__)
|
||||
@@ -67,8 +68,8 @@ private:
|
||||
(mPublic ? "Public" : "Private") % mIp % mPort);
|
||||
|
||||
websocketpp::server_autotls::handler::ptr handler (
|
||||
new WSServerHandler <websocketpp::server_autotls> (m_source,
|
||||
m_ssl_context, mPublic));
|
||||
new WSServerHandler <websocketpp::server_autotls> (
|
||||
m_resourceManager, m_source, m_ssl_context, mPublic));
|
||||
|
||||
{
|
||||
ScopedLockType lock (m_endpointLock, __FILE__, __LINE__);
|
||||
@@ -130,7 +131,8 @@ private:
|
||||
private:
|
||||
typedef RippleRecursiveMutex LockType;
|
||||
typedef LockType::ScopedLockType ScopedLockType;
|
||||
|
||||
|
||||
Resource::Manager& m_resourceManager;
|
||||
InfoSub::Source& m_source;
|
||||
boost::asio::ssl::context& m_ssl_context;
|
||||
LockType m_endpointLock;
|
||||
@@ -150,14 +152,16 @@ WSDoor::WSDoor (Stoppable& parent)
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
WSDoor* WSDoor::New (InfoSub::Source& source, std::string const& strIp,
|
||||
int iPort, bool bPublic, boost::asio::ssl::context& ssl_context)
|
||||
WSDoor* WSDoor::New (Resource::Manager& resourceManager,
|
||||
InfoSub::Source& source, std::string const& strIp,
|
||||
int iPort, bool bPublic, boost::asio::ssl::context& ssl_context)
|
||||
{
|
||||
ScopedPointer <WSDoor> door;
|
||||
|
||||
try
|
||||
{
|
||||
door = new WSDoorImp (source, strIp, iPort, bPublic, ssl_context);
|
||||
door = new WSDoorImp (resourceManager,
|
||||
source, strIp, iPort, bPublic, ssl_context);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
|
||||
@@ -30,8 +30,9 @@ protected:
|
||||
public:
|
||||
virtual ~WSDoor () { }
|
||||
|
||||
static WSDoor* New (InfoSub::Source& source, std::string const& strIp,
|
||||
int iPort, bool bPublic, boost::asio::ssl::context& ssl_context);
|
||||
static WSDoor* New (Resource::Manager& resourceManager,
|
||||
InfoSub::Source& source, std::string const& strIp,
|
||||
int iPort, bool bPublic, boost::asio::ssl::context& ssl_context);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -56,6 +56,7 @@ public:
|
||||
};
|
||||
|
||||
private:
|
||||
Resource::Manager& m_resourceManager;
|
||||
InfoSub::Source& m_source;
|
||||
|
||||
protected:
|
||||
@@ -74,8 +75,10 @@ protected:
|
||||
bool const mPublic;
|
||||
|
||||
public:
|
||||
WSServerHandler (InfoSub::Source& source, boost::asio::ssl::context& ssl_context, bool bPublic)
|
||||
: m_source (source)
|
||||
WSServerHandler (Resource::Manager& resourceManager,
|
||||
InfoSub::Source& source, boost::asio::ssl::context& ssl_context, bool bPublic)
|
||||
: m_resourceManager (resourceManager)
|
||||
, m_source (source)
|
||||
, mLock (static_cast <WSServerHandlerBase*> (this), "WSServerHandler", __FILE__, __LINE__)
|
||||
, m_ssl_context (ssl_context)
|
||||
, mPublic (bPublic)
|
||||
@@ -181,7 +184,9 @@ public:
|
||||
{
|
||||
mMap [cpClient] = boost::make_shared <
|
||||
WSConnectionType <endpoint_type>
|
||||
> (boost::ref (m_source), boost::ref(*this), boost::cref(cpClient));
|
||||
> (boost::ref(m_resourceManager),
|
||||
boost::ref (m_source),
|
||||
boost::ref(*this), boost::cref(cpClient));
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
|
||||
@@ -47,16 +47,6 @@
|
||||
class LoadSource
|
||||
{
|
||||
public:
|
||||
// VFALCO TODO Use these dispositions
|
||||
/*
|
||||
enum Disposition
|
||||
{
|
||||
none,
|
||||
shouldWarn,
|
||||
shouldDrop,
|
||||
};
|
||||
*/
|
||||
|
||||
/** Construct a load source.
|
||||
|
||||
Sources with admin privileges have relaxed or no restrictions
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
|
||||
#include "beast/beast/http/URL.h" // for Config
|
||||
|
||||
#include "../ripple/resource/api/LegacyFees.h"
|
||||
|
||||
#include "nodestore/NodeStore.h"
|
||||
|
||||
@@ -41,7 +42,6 @@ namespace ripple
|
||||
# include "functional/LoadMonitor.h"
|
||||
# include "functional/Job.h"
|
||||
#include "functional/JobQueue.h"
|
||||
# include "functional/LoadType.h"
|
||||
#include "functional/LoadSource.h"
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user