mirror of
https://github.com/XRPLF/rippled.git
synced 2025-12-06 17:27:55 +00:00
Validators framework and unit test
This commit is contained in:
@@ -778,25 +778,25 @@
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\modules\ripple_core\ripple_core.cpp" />
|
||||
<ClCompile Include="..\..\modules\ripple_core\validator\ripple_StringsValidatorSource.cpp">
|
||||
<ClCompile Include="..\..\modules\ripple_core\validator\ValidatorSourceStrings.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="..\..\modules\ripple_core\validator\ripple_TrustedUriValidatorSource.cpp">
|
||||
<ClCompile Include="..\..\modules\ripple_core\validator\ValidatorSourceTrustedUri.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="..\..\modules\ripple_core\validator\ripple_Validator.cpp">
|
||||
<ClCompile Include="..\..\modules\ripple_core\validator\Validator.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="..\..\modules\ripple_core\validator\ripple_Validators.cpp">
|
||||
<ClCompile Include="..\..\modules\ripple_core\validator\Validators.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
@@ -1398,13 +1398,13 @@
|
||||
<ClInclude Include="..\..\modules\ripple_app\misc\ripple_IFeeVote.h" />
|
||||
<ClInclude Include="..\..\modules\ripple_app\misc\ripple_IHashRouter.h" />
|
||||
<ClInclude Include="..\..\modules\ripple_app\misc\ProofOfWorkFactory.h" />
|
||||
<ClInclude Include="..\..\modules\ripple_app\misc\ripple_IValidations.h" />
|
||||
<ClInclude Include="..\..\modules\ripple_app\misc\ripple_NicknameState.h" />
|
||||
<ClInclude Include="..\..\modules\ripple_app\misc\ripple_Offer.h" />
|
||||
<ClInclude Include="..\..\modules\ripple_app\misc\ripple_OrderBook.h" />
|
||||
<ClInclude Include="..\..\modules\ripple_app\misc\ProofOfWork.h" />
|
||||
<ClInclude Include="..\..\modules\ripple_app\misc\ripple_SerializedLedger.h" />
|
||||
<ClInclude Include="..\..\modules\ripple_app\misc\ripple_SerializedTransaction.h" />
|
||||
<ClInclude Include="..\..\modules\ripple_app\misc\ripple_Validations.h" />
|
||||
<ClInclude Include="..\..\modules\ripple_app\node\ripple_SqliteBackendFactory.h" />
|
||||
<ClInclude Include="..\..\modules\ripple_app\paths\ripple_Pathfinder.h" />
|
||||
<ClInclude Include="..\..\modules\ripple_app\paths\ripple_PathRequest.h" />
|
||||
@@ -1501,12 +1501,11 @@
|
||||
<ClInclude Include="..\..\modules\ripple_core\node\NodeStore.h" />
|
||||
<ClInclude Include="..\..\modules\ripple_core\node\NullBackendFactory.h" />
|
||||
<ClInclude Include="..\..\modules\ripple_core\ripple_core.h" />
|
||||
<ClInclude Include="..\..\modules\ripple_core\validator\ripple_StringsValidatorSource.h" />
|
||||
<ClInclude Include="..\..\modules\ripple_core\validator\ripple_TrustedUriValidatorSource.h" />
|
||||
<ClInclude Include="..\..\modules\ripple_core\validator\ripple_Validator.h" />
|
||||
<ClInclude Include="..\..\modules\ripple_core\validator\ripple_ValidatorList.h" />
|
||||
<ClInclude Include="..\..\modules\ripple_core\validator\ripple_ValidatorImp.h" />
|
||||
<ClInclude Include="..\..\modules\ripple_core\validator\ripple_Validators.h" />
|
||||
<ClInclude Include="..\..\modules\ripple_core\validator\ValidatorSourceStrings.h" />
|
||||
<ClInclude Include="..\..\modules\ripple_core\validator\ValidatorSourceTrustedUri.h" />
|
||||
<ClInclude Include="..\..\modules\ripple_core\validator\Validator.h" />
|
||||
<ClInclude Include="..\..\modules\ripple_core\validator\ValidatorsImp.h" />
|
||||
<ClInclude Include="..\..\modules\ripple_core\validator\Validators.h" />
|
||||
<ClInclude Include="..\..\modules\ripple_data\crypto\ripple_Base58.h" />
|
||||
<ClInclude Include="..\..\modules\ripple_data\crypto\ripple_Base58Data.h" />
|
||||
<ClInclude Include="..\..\modules\ripple_data\crypto\ripple_CBigNum.h" />
|
||||
|
||||
@@ -159,18 +159,6 @@
|
||||
<ClCompile Include="..\..\src\cpp\protobuf_core.cpp">
|
||||
<Filter>[0] Subtrees\protobuf</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\modules\ripple_app\ripple_app_pt1.cpp">
|
||||
<Filter>[1] Ripple\ripple_app</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\modules\ripple_app\ripple_app_pt2.cpp">
|
||||
<Filter>[1] Ripple\ripple_app</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\modules\ripple_app\ripple_app_pt3.cpp">
|
||||
<Filter>[1] Ripple\ripple_app</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\modules\ripple_app\ripple_app_pt4.cpp">
|
||||
<Filter>[1] Ripple\ripple_app</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\modules\ripple_basics\containers\ripple_RangeSet.cpp">
|
||||
<Filter>[1] Ripple\ripple_basics\containers</Filter>
|
||||
</ClCompile>
|
||||
@@ -477,6 +465,18 @@
|
||||
<ClCompile Include="..\..\Subtrees\leveldb\port\port_win.cc">
|
||||
<Filter>[0] Subtrees\leveldb\port</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\modules\ripple_app\ripple_app_pt1.cpp">
|
||||
<Filter>[1] Ripple\ripple_app</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\modules\ripple_app\ripple_app_pt2.cpp">
|
||||
<Filter>[1] Ripple\ripple_app</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\modules\ripple_app\ripple_app_pt3.cpp">
|
||||
<Filter>[1] Ripple\ripple_app</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\modules\ripple_app\ripple_app_pt4.cpp">
|
||||
<Filter>[1] Ripple\ripple_app</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\modules\ripple_app\ripple_app_pt5.cpp">
|
||||
<Filter>[1] Ripple\ripple_app</Filter>
|
||||
</ClCompile>
|
||||
@@ -528,12 +528,6 @@
|
||||
<ClCompile Include="..\..\modules\ripple_app\data\ripple_SqliteDatabase.cpp">
|
||||
<Filter>[1] Ripple\ripple_app\data</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\modules\ripple_core\validator\ripple_Validator.cpp">
|
||||
<Filter>[1] Ripple\ripple_core\validator</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\modules\ripple_core\validator\ripple_Validators.cpp">
|
||||
<Filter>[1] Ripple\ripple_core\validator</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\modules\ripple_app\ledger\Ledger.cpp">
|
||||
<Filter>[1] Ripple\ripple_app\ledger</Filter>
|
||||
</ClCompile>
|
||||
@@ -570,12 +564,6 @@
|
||||
<ClCompile Include="..\..\modules\ripple_app\ledger\SerializedValidation.cpp">
|
||||
<Filter>[1] Ripple\ripple_app\ledger</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\modules\ripple_core\validator\ripple_TrustedUriValidatorSource.cpp">
|
||||
<Filter>[1] Ripple\ripple_core\validator</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\modules\ripple_core\validator\ripple_StringsValidatorSource.cpp">
|
||||
<Filter>[1] Ripple\ripple_core\validator</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\Subtrees\beast\modules\beast_crypto\beast_crypto.cpp">
|
||||
<Filter>[0] Subtrees\beast</Filter>
|
||||
</ClCompile>
|
||||
@@ -864,6 +852,18 @@
|
||||
<ClCompile Include="..\..\modules\ripple_core\node\NullBackendFactory.cpp">
|
||||
<Filter>[1] Ripple\ripple_core\node</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\modules\ripple_core\validator\ValidatorSourceStrings.cpp">
|
||||
<Filter>[1] Ripple\ripple_core\validator</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\modules\ripple_core\validator\ValidatorSourceTrustedUri.cpp">
|
||||
<Filter>[1] Ripple\ripple_core\validator</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\modules\ripple_core\validator\Validator.cpp">
|
||||
<Filter>[1] Ripple\ripple_core\validator</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\modules\ripple_core\validator\Validators.cpp">
|
||||
<Filter>[1] Ripple\ripple_core\validator</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\modules\ripple_app\ripple_app.h">
|
||||
@@ -1286,12 +1286,6 @@
|
||||
<ClInclude Include="..\..\modules\ripple_app\data\ripple_SqliteDatabase.h">
|
||||
<Filter>[1] Ripple\ripple_app\data</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\ripple_core\validator\ripple_Validator.h">
|
||||
<Filter>[1] Ripple\ripple_core\validator</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\ripple_core\validator\ripple_Validators.h">
|
||||
<Filter>[1] Ripple\ripple_core\validator</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\ripple_app\ledger\Ledger.h">
|
||||
<Filter>[1] Ripple\ripple_app\ledger</Filter>
|
||||
</ClInclude>
|
||||
@@ -1328,15 +1322,6 @@
|
||||
<ClInclude Include="..\..\modules\ripple_app\ledger\SerializedValidation.h">
|
||||
<Filter>[1] Ripple\ripple_app\ledger</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\ripple_core\validator\ripple_ValidatorList.h">
|
||||
<Filter>[1] Ripple\ripple_core\validator</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\ripple_core\validator\ripple_TrustedUriValidatorSource.h">
|
||||
<Filter>[1] Ripple\ripple_core\validator</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\ripple_core\validator\ripple_StringsValidatorSource.h">
|
||||
<Filter>[1] Ripple\ripple_core\validator</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\ripple_core\functional\ripple_ConfigSections.h">
|
||||
<Filter>[1] Ripple\ripple_core\functional</Filter>
|
||||
</ClInclude>
|
||||
@@ -1373,9 +1358,6 @@
|
||||
<ClInclude Include="..\..\modules\ripple_app\misc\ripple_IHashRouter.h">
|
||||
<Filter>[1] Ripple\ripple_app\misc</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\ripple_app\misc\ripple_IValidations.h">
|
||||
<Filter>[1] Ripple\ripple_app\misc</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\ripple_app\misc\ripple_NicknameState.h">
|
||||
<Filter>[1] Ripple\ripple_app\misc</Filter>
|
||||
</ClInclude>
|
||||
@@ -1499,9 +1481,6 @@
|
||||
<ClInclude Include="..\..\modules\ripple_app\tx\WalletAddTransactor.h">
|
||||
<Filter>[1] Ripple\ripple_app\tx</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\ripple_core\validator\ripple_ValidatorImp.h">
|
||||
<Filter>[1] Ripple\ripple_core\validator</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\ripple_app\main\ripple_FatalErrorReporter.h">
|
||||
<Filter>[1] Ripple\ripple_app\main</Filter>
|
||||
</ClInclude>
|
||||
@@ -1688,6 +1667,24 @@
|
||||
<ClInclude Include="..\..\modules\ripple_core\node\NullBackendFactory.h">
|
||||
<Filter>[1] Ripple\ripple_core\node</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\ripple_app\misc\ripple_Validations.h">
|
||||
<Filter>[1] Ripple\ripple_app\misc</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\ripple_core\validator\ValidatorSourceStrings.h">
|
||||
<Filter>[1] Ripple\ripple_core\validator</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\ripple_core\validator\ValidatorSourceTrustedUri.h">
|
||||
<Filter>[1] Ripple\ripple_core\validator</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\ripple_core\validator\Validator.h">
|
||||
<Filter>[1] Ripple\ripple_core\validator</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\ripple_core\validator\Validators.h">
|
||||
<Filter>[1] Ripple\ripple_core\validator</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\ripple_core\validator\ValidatorsImp.h">
|
||||
<Filter>[1] Ripple\ripple_core\validator</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<CustomBuild Include="..\..\modules\ripple_data\protocol\ripple.proto">
|
||||
|
||||
@@ -33,7 +33,7 @@ SerializedValidation::SerializedValidation (
|
||||
assert (mNodeID.isNonZero ());
|
||||
|
||||
if (!isFull)
|
||||
setFlag (sFullFlag);
|
||||
setFlag (kFullFlag);
|
||||
}
|
||||
|
||||
void SerializedValidation::sign (const RippleAddress& raPriv)
|
||||
@@ -98,7 +98,7 @@ RippleAddress SerializedValidation::getSignerPublic () const
|
||||
|
||||
bool SerializedValidation::isFull () const
|
||||
{
|
||||
return (getFlags () & sFullFlag) != 0;
|
||||
return (getFlags () & kFullFlag) != 0;
|
||||
}
|
||||
|
||||
Blob SerializedValidation::getSignature () const
|
||||
|
||||
@@ -17,7 +17,10 @@ public:
|
||||
typedef boost::shared_ptr<SerializedValidation> pointer;
|
||||
typedef const boost::shared_ptr<SerializedValidation>& ref;
|
||||
|
||||
static const uint32 sFullFlag = 0x1;
|
||||
enum
|
||||
{
|
||||
kFullFlag = 0x1
|
||||
};
|
||||
|
||||
// These throw if the object is not valid
|
||||
SerializedValidation (SerializerIterator & sit, bool checkSignature = true);
|
||||
|
||||
@@ -15,7 +15,6 @@ SETUP_LOG (Application)
|
||||
class ApplicationImp
|
||||
: public Application
|
||||
, public SharedSingleton <ApplicationImp>
|
||||
, public Validators::Listener
|
||||
, public NodeStore::Scheduler
|
||||
, LeakChecked <ApplicationImp>
|
||||
{
|
||||
@@ -168,12 +167,12 @@ public:
|
||||
getConfig ().nodeDatabase,
|
||||
getConfig ().ephemeralNodeDatabase,
|
||||
*this))
|
||||
, m_validators (Validators::New (this))
|
||||
, m_validators (Validators::New ())
|
||||
, mFeatures (IFeatures::New (2 * 7 * 24 * 60 * 60, 200)) // two weeks, 200/256
|
||||
, mFeeVote (IFeeVote::New (10, 50 * SYSTEM_CURRENCY_PARTS, 12.5 * SYSTEM_CURRENCY_PARTS))
|
||||
, mFeeTrack (ILoadFeeTrack::New ())
|
||||
, mHashRouter (IHashRouter::New (IHashRouter::getDefaultHoldTime ()))
|
||||
, mValidations (IValidations::New ())
|
||||
, mValidations (Validations::New ())
|
||||
, mUNL (UniqueNodeList::New ())
|
||||
, mProofOfWorkFactory (ProofOfWorkFactory::New ())
|
||||
, m_loadManager (LoadManager::New ())
|
||||
@@ -313,7 +312,7 @@ public:
|
||||
return *mHashRouter;
|
||||
}
|
||||
|
||||
IValidations& getValidations ()
|
||||
Validations& getValidations ()
|
||||
{
|
||||
return *mValidations;
|
||||
}
|
||||
@@ -697,7 +696,7 @@ private:
|
||||
ScopedPointer <IFeeVote> mFeeVote;
|
||||
ScopedPointer <ILoadFeeTrack> mFeeTrack;
|
||||
ScopedPointer <IHashRouter> mHashRouter;
|
||||
ScopedPointer <IValidations> mValidations;
|
||||
ScopedPointer <Validations> mValidations;
|
||||
ScopedPointer <UniqueNodeList> mUNL;
|
||||
ScopedPointer <ProofOfWorkFactory> mProofOfWorkFactory;
|
||||
ScopedPointer <Peers> m_peers;
|
||||
@@ -819,43 +818,33 @@ void ApplicationImp::doSweep(Job& j)
|
||||
|
||||
logTimedCall <Application> ("TransactionMaster::sweep", __FILE__, __LINE__, boost::bind (
|
||||
&TransactionMaster::sweep, &mMasterTransaction));
|
||||
//mMasterTransaction.sweep ();
|
||||
|
||||
logTimedCall <Application> ("NodeStore::sweep", __FILE__, __LINE__, boost::bind (
|
||||
&NodeStore::sweep, m_nodeStore.get ()));
|
||||
//m_nodeStore->sweep ();
|
||||
|
||||
logTimedCall <Application> ("LedgerMaster::sweep", __FILE__, __LINE__, boost::bind (
|
||||
&LedgerMaster::sweep, &m_ledgerMaster));
|
||||
//m_ledgerMaster.sweep ();
|
||||
|
||||
logTimedCall <Application> ("TempNodeCache::sweep", __FILE__, __LINE__, boost::bind (
|
||||
&NodeCache::sweep, &mTempNodeCache));
|
||||
//mTempNodeCache.sweep ();
|
||||
|
||||
logTimedCall <Application> ("Validations::sweep", __FILE__, __LINE__, boost::bind (
|
||||
&IValidations::sweep, mValidations.get ()));
|
||||
//mValidations->sweep ();
|
||||
&Validations::sweep, mValidations.get ()));
|
||||
|
||||
logTimedCall <Application> ("InboundLedgers::sweep", __FILE__, __LINE__, boost::bind (
|
||||
&InboundLedgers::sweep, &getInboundLedgers ()));
|
||||
//getInboundLedgers ().sweep ();
|
||||
|
||||
logTimedCall <Application> ("SLECache::sweep", __FILE__, __LINE__, boost::bind (
|
||||
&SLECache::sweep, &mSLECache));
|
||||
//mSLECache.sweep ();
|
||||
|
||||
logTimedCall <Application> ("AcceptedLedger::sweep", __FILE__, __LINE__,
|
||||
&AcceptedLedger::sweep);
|
||||
//AcceptedLedger::sweep (); // VFALCO NOTE AcceptedLedger is/has a singleton?
|
||||
|
||||
logTimedCall <Application> ("SHAMap::sweep", __FILE__, __LINE__,
|
||||
&SHAMap::sweep);
|
||||
//SHAMap::sweep (); // VFALCO NOTE SHAMap is/has a singleton?
|
||||
|
||||
logTimedCall <Application> ("NetworkOPs::sweepFetchPack", __FILE__, __LINE__, boost::bind (
|
||||
&NetworkOPs::sweepFetchPack, m_networkOPs.get ()));
|
||||
//m_networkOPs->sweepFetchPack ();
|
||||
|
||||
// VFALCO NOTE does the call to sweep() happen on another thread?
|
||||
mSweepTimer.expires_from_now (boost::posix_time::seconds (getConfig ().getSize (siSweepInterval)));
|
||||
|
||||
@@ -14,7 +14,6 @@ class IHashRouter;
|
||||
class ILoadFeeTrack;
|
||||
class Peers;
|
||||
class UniqueNodeList;
|
||||
class IValidations;
|
||||
class Validators;
|
||||
|
||||
class NodeStore;
|
||||
@@ -86,8 +85,7 @@ public:
|
||||
virtual Peers& getPeers () = 0;
|
||||
virtual ProofOfWorkFactory& getProofOfWorkFactory () = 0;
|
||||
virtual UniqueNodeList& getUNL () = 0;
|
||||
virtual IValidations& getValidations () = 0;
|
||||
|
||||
virtual Validations& getValidations () = 0;
|
||||
virtual NodeStore& getNodeStore () = 0;
|
||||
virtual JobQueue& getJobQueue () = 0;
|
||||
virtual InboundLedgers& getInboundLedgers () = 0;
|
||||
|
||||
@@ -4,14 +4,14 @@
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
class Validations;
|
||||
class ValidationsImp;
|
||||
|
||||
SETUP_LOG (Validations)
|
||||
|
||||
typedef std::map<uint160, SerializedValidation::pointer>::value_type u160_val_pair;
|
||||
typedef boost::shared_ptr<ValidationSet> VSpointer;
|
||||
|
||||
class Validations : public IValidations
|
||||
class ValidationsImp : public Validations
|
||||
{
|
||||
private:
|
||||
typedef RippleMutex LockType;
|
||||
@@ -45,7 +45,7 @@ private:
|
||||
}
|
||||
|
||||
public:
|
||||
Validations ()
|
||||
ValidationsImp ()
|
||||
: mLock (this, "Validations", __FILE__, __LINE__)
|
||||
, mValidations ("Validations", 128, 600), mWriting (false)
|
||||
{
|
||||
@@ -394,7 +394,7 @@ private:
|
||||
|
||||
mWriting = true;
|
||||
getApp().getJobQueue ().addJob (jtWRITE, "Validations::doWrite",
|
||||
BIND_TYPE (&Validations::doWrite, this, P_1));
|
||||
BIND_TYPE (&ValidationsImp::doWrite, this, P_1));
|
||||
}
|
||||
|
||||
void doWrite (Job&)
|
||||
@@ -443,9 +443,9 @@ private:
|
||||
}
|
||||
};
|
||||
|
||||
IValidations* IValidations::New ()
|
||||
Validations* Validations::New ()
|
||||
{
|
||||
return new Validations;
|
||||
return new ValidationsImp;
|
||||
}
|
||||
|
||||
// vim:ts=4
|
||||
|
||||
@@ -4,19 +4,19 @@
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_IVALIDATIONS_H
|
||||
#define RIPPLE_IVALIDATIONS_H
|
||||
#ifndef RIPPLE_VALIDATIONS_H_INCLUDED
|
||||
#define RIPPLE_VALIDATIONS_H_INCLUDED
|
||||
|
||||
// VFALCO TODO rename and move these typedefs into the IValidations interface
|
||||
// VFALCO TODO rename and move these typedefs into the Validations interface
|
||||
typedef boost::unordered_map<uint160, SerializedValidation::pointer> ValidationSet;
|
||||
typedef std::pair<int, uint160> currentValidationCount; // nodes validating and highest node ID validating
|
||||
|
||||
class IValidations : LeakChecked <IValidations>
|
||||
class Validations : LeakChecked <Validations>
|
||||
{
|
||||
public:
|
||||
static IValidations* New ();
|
||||
static Validations* New ();
|
||||
|
||||
virtual ~IValidations () { }
|
||||
virtual ~Validations () { }
|
||||
|
||||
virtual bool addValidation (SerializedValidation::ref, const std::string& source) = 0;
|
||||
|
||||
@@ -1468,6 +1468,19 @@ static void checkValidation (Job&, SerializedValidation::pointer val, bool isTru
|
||||
|
||||
std::set<uint64> peers;
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
//
|
||||
{
|
||||
SerializedValidation const& sv (*val);
|
||||
Validators::ReceivedValidation rv;
|
||||
rv.ledgerHash = sv.getLedgerHash ();
|
||||
uint160 const publicKeyHash (sv.getSignerPublic ().getNodeID ());
|
||||
rv.signerPublicKeyHash = RipplePublicKeyHash (publicKeyHash.begin ());
|
||||
getApp ().getValidators ().receiveValidation (rv);
|
||||
}
|
||||
//
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
if (getApp().getOPs ().recvValidation (val, source) &&
|
||||
getApp().getHashRouter ().swapSet (signingHash, peers, SF_RELAYED))
|
||||
{
|
||||
|
||||
@@ -78,7 +78,7 @@ namespace ripple
|
||||
#include "peers/ripple_Peers.h"
|
||||
#include "peers/ripple_ClusterNodeStatus.h"
|
||||
#include "peers/ripple_UniqueNodeList.h"
|
||||
#include "misc/ripple_IValidations.h"
|
||||
#include "misc/ripple_Validations.h"
|
||||
#include "peers/ripple_PeerSet.h"
|
||||
#include "ledger/ripple_InboundLedger.h"
|
||||
#include "ledger/ripple_InboundLedgers.h"
|
||||
|
||||
@@ -27,4 +27,12 @@ typedef UntrackedMutexType <boost::recursive_mutex> RippleRecursiveMutex;
|
||||
typedef boost::recursive_mutex DeprecatedRecursiveMutex;
|
||||
typedef DeprecatedRecursiveMutex::scoped_lock DeprecatedScopedLock;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** A container used to hold a public key in binary format. */
|
||||
typedef UnsignedInteger <33> RipplePublicKey;
|
||||
|
||||
/** A container holding the hash of a public key in binary format. */
|
||||
typedef UnsignedInteger <20> RipplePublicKeyHash;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -46,10 +46,13 @@ namespace ripple
|
||||
#include "node/NodeStore.cpp"
|
||||
#include "node/NodeObject.cpp"
|
||||
|
||||
#include "validator/ripple_Validator.cpp"
|
||||
#include "validator/ripple_ValidatorImp.h" // private
|
||||
#include "validator/ripple_Validators.cpp"
|
||||
#include "validator/ripple_StringsValidatorSource.cpp"
|
||||
#include "validator/ripple_TrustedUriValidatorSource.cpp"
|
||||
# include "validator/Validator.h"
|
||||
#include "validator/Validator.cpp"
|
||||
# include "validator/ValidatorSourceStrings.h"
|
||||
# include "validator/ValidatorSourceTrustedUri.h"
|
||||
# include "validator/ValidatorsImp.h" // private
|
||||
#include "validator/ValidatorSourceStrings.cpp"
|
||||
#include "validator/ValidatorSourceTrustedUri.cpp"
|
||||
#include "validator/Validators.cpp"
|
||||
|
||||
}
|
||||
|
||||
@@ -28,11 +28,7 @@ namespace ripple
|
||||
#include "node/NodeObject.h"
|
||||
#include "node/NodeStore.h"
|
||||
|
||||
#include "validator/ripple_Validator.h"
|
||||
#include "validator/ripple_ValidatorList.h"
|
||||
#include "validator/ripple_Validators.h"
|
||||
#include "validator/ripple_StringsValidatorSource.h"
|
||||
#include "validator/ripple_TrustedUriValidatorSource.h"
|
||||
#include "validator/Validators.h"
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
Validator::Validator (PublicKey const& publicKey)
|
||||
Validator::Validator (RipplePublicKey const& publicKey)
|
||||
: m_publicKey (publicKey)
|
||||
{
|
||||
}
|
||||
@@ -4,8 +4,8 @@
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_VALIDATOR_H_INCLUDED
|
||||
#define RIPPLE_VALIDATOR_H_INCLUDED
|
||||
#ifndef RIPPLE_CORE_VALIDATOR_VALIDATOR_H_INCLUDED
|
||||
#define RIPPLE_CORE_VALIDATOR_VALIDATOR_H_INCLUDED
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
class Validator : public SharedObject
|
||||
{
|
||||
public:
|
||||
typedef SharedObjectPtr <Validator> Ptr;
|
||||
|
||||
/** Fixed information on a validator.
|
||||
|
||||
This describes a validator.
|
||||
@@ -41,12 +43,7 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
// VFALCO TODO magic number argh!!!
|
||||
// This type should be located elsewhere.
|
||||
//
|
||||
typedef UnsignedInteger <33> PublicKey;
|
||||
|
||||
PublicKey publicKey;
|
||||
RipplePublicKey publicKey;
|
||||
//String friendlyName;
|
||||
//String organizationType;
|
||||
//String jurisdicton;
|
||||
@@ -74,10 +71,6 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
typedef SharedObjectPtr <Validator> Ptr;
|
||||
|
||||
typedef Info::PublicKey PublicKey;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
// Comparison function for Validator objects
|
||||
@@ -135,12 +128,12 @@ public:
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
explicit Validator (PublicKey const& publicKey);
|
||||
explicit Validator (RipplePublicKey const& publicKey);
|
||||
|
||||
PublicKey const& getPublicKey () const { return m_publicKey; }
|
||||
RipplePublicKey const& getPublicKey () const { return m_publicKey; }
|
||||
|
||||
private:
|
||||
PublicKey const m_publicKey;
|
||||
RipplePublicKey const m_publicKey;
|
||||
|
||||
};
|
||||
|
||||
34
modules/ripple_core/validator/ValidatorSourceStrings.cpp
Normal file
34
modules/ripple_core/validator/ValidatorSourceStrings.cpp
Normal file
@@ -0,0 +1,34 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
Copyright (c) 2011-2013, OpenCoin, Inc.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
class ValidatorSourceStringsImp : public ValidatorSourceStrings
|
||||
{
|
||||
public:
|
||||
ValidatorSourceStringsImp (StringArray const& strings)
|
||||
{
|
||||
}
|
||||
|
||||
~ValidatorSourceStringsImp ()
|
||||
{
|
||||
}
|
||||
|
||||
Array <Info> fetch (CancelCallback&)
|
||||
{
|
||||
return Array <Info> ();
|
||||
}
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
ValidatorSourceStrings* ValidatorSourceStrings::New (StringArray const& strings)
|
||||
{
|
||||
ScopedPointer <ValidatorSourceStrings> object (
|
||||
new ValidatorSourceStringsImp (strings));
|
||||
|
||||
return object.release ();
|
||||
}
|
||||
@@ -4,17 +4,17 @@
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_STRINGSVALIDATORSOURCE_H_INCLUDED
|
||||
#define RIPPLE_STRINGSVALIDATORSOURCE_H_INCLUDED
|
||||
#ifndef RIPPLE_CORE_VALIDATOR_VALIDATORSOURCESTRINGS_H_INCLUDED
|
||||
#define RIPPLE_CORE_VALIDATOR_VALIDATORSOURCESTRINGS_H_INCLUDED
|
||||
|
||||
/** Provides validators from a set of Validator strings.
|
||||
|
||||
Typically this will come from a local configuration file.
|
||||
*/
|
||||
class StringsValidatorSource : public Validators::Source
|
||||
class ValidatorSourceStrings : public Validators::Source
|
||||
{
|
||||
public:
|
||||
static StringsValidatorSource* New (StringArray const& strings);
|
||||
static ValidatorSourceStrings* New (StringArray const& strings);
|
||||
};
|
||||
|
||||
#endif
|
||||
36
modules/ripple_core/validator/ValidatorSourceTrustedUri.cpp
Normal file
36
modules/ripple_core/validator/ValidatorSourceTrustedUri.cpp
Normal file
@@ -0,0 +1,36 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
Copyright (c) 2011-2013, OpenCoin, Inc.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
class ValidatorSourceTrustedUriImp : public ValidatorSourceTrustedUri
|
||||
{
|
||||
public:
|
||||
explicit ValidatorSourceTrustedUriImp (String const& uri)
|
||||
: m_uri (uri)
|
||||
{
|
||||
}
|
||||
|
||||
~ValidatorSourceTrustedUriImp ()
|
||||
{
|
||||
}
|
||||
|
||||
Array <Info> fetch (CancelCallback&)
|
||||
{
|
||||
return Array <Info> ();
|
||||
}
|
||||
|
||||
private:
|
||||
String const m_uri;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
ValidatorSourceTrustedUri* ValidatorSourceTrustedUri::New (String const& uri)
|
||||
{
|
||||
ScopedPointer <ValidatorSourceTrustedUri> object (
|
||||
new ValidatorSourceTrustedUriImp (uri));
|
||||
|
||||
return object.release ();
|
||||
}
|
||||
@@ -4,15 +4,15 @@
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_TRUSTEDURIVALIDATORSOURCE_H_INCLUDED
|
||||
#define RIPPLE_TRUSTEDURIVALIDATORSOURCE_H_INCLUDED
|
||||
#ifndef RIPPLE_CORE_VALIDATOR_VALIDATORSOURCETRUSTEDURI_H_INCLUDED
|
||||
#define RIPPLE_CORE_VALIDATOR_VALIDATORSOURCETRUSTEDURI_H_INCLUDED
|
||||
|
||||
/** Provides validators from a trusted URI (e.g. HTTPS)
|
||||
*/
|
||||
class TrustedUriValidatorSource : public Validators::Source
|
||||
class ValidatorSourceTrustedUri : public Validators::Source
|
||||
{
|
||||
public:
|
||||
static TrustedUriValidatorSource* New (String url);
|
||||
static ValidatorSourceTrustedUri* New (String const& uri);
|
||||
};
|
||||
|
||||
#endif
|
||||
209
modules/ripple_core/validator/Validators.cpp
Normal file
209
modules/ripple_core/validator/Validators.cpp
Normal file
@@ -0,0 +1,209 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
Copyright (c) 2011-2013, OpenCoin, Inc.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
/*
|
||||
|
||||
Goal:
|
||||
|
||||
Provide the listener with a ValidatorList.
|
||||
- This forms the UNL
|
||||
|
||||
Task:
|
||||
|
||||
fetch ValidatorInfo array from a source
|
||||
|
||||
- We have the old one and the new one, compute the following:
|
||||
|
||||
* unchanged validators list
|
||||
* new validators list
|
||||
* removed validators list
|
||||
|
||||
- From the unchanged / new / removed, figure out what to do.
|
||||
|
||||
Two important questions:
|
||||
|
||||
- Are there any validators in my ChosenValidators that I dont want
|
||||
* For example, they have dropped off all the trusted lists
|
||||
|
||||
- Do I have enough?
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
ChosenValidators
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
David:
|
||||
I've cut 2 of the 6 active client-facing servers to hyper. Since then, we've
|
||||
had 5 spinouts on 3 servers, none of them on the 2 I've cut over. But they
|
||||
are also the most recently restarted servers, so it's not a 100% fair test.
|
||||
|
||||
Maybe OC should have a URL that you can query to get the latest list of URI's
|
||||
for OC-approved organzations that publish lists of validators. The server and
|
||||
client can ship with that master trust URL and also the list of URI's at the
|
||||
time it's released, in case for some reason it can't pull from OC. That would
|
||||
make the default installation safe even against major changes in the
|
||||
organizations that publish validator lists.
|
||||
|
||||
The difference is that if an organization that provides lists of validators
|
||||
goes rogue, administrators don't have to act.
|
||||
|
||||
TODO:
|
||||
Write up from end-user perspective on the deployment and administration
|
||||
of this feature, on the wiki. "DRAFT" or "PROPOSE" to mark it as provisional.
|
||||
Template: https://ripple.com/wiki/Federation_protocol
|
||||
- What to do if you're a publisher of ValidatorList
|
||||
- What to do if you're a rippled administrator
|
||||
- Overview of how ChosenValidators works
|
||||
|
||||
|
||||
Goals:
|
||||
Make default configuration of rippled secure.
|
||||
* Ship with TrustedUriList
|
||||
* Also have a preset RankedValidators
|
||||
Eliminate administrative burden of maintaining
|
||||
Produce the ChosenValidators list.
|
||||
Allow quantitative analysis of network health.
|
||||
|
||||
What determines that a validator is good?
|
||||
- Are they present (i.e. sending validations)
|
||||
- Are they on the consensus ledger
|
||||
- What percentage of consensus rounds do they participate in
|
||||
- Are they stalling consensus
|
||||
* Measurements of constructive/destructive behavior is
|
||||
calculated in units of percentage of ledgers for which
|
||||
the behavior is measured.
|
||||
|
||||
Nouns
|
||||
|
||||
Validator
|
||||
- Signs ledgers and participate in consensus
|
||||
- Fields
|
||||
* Public key
|
||||
* Friendly name
|
||||
* Jurisdiction
|
||||
* Org type: profit, nonprofit, "profit/gateway"
|
||||
- Metadata
|
||||
* Visible on the network?
|
||||
* On the consensus ledger?
|
||||
* Percentage of recent participation in consensus
|
||||
* Frequency of stalling the consensus process
|
||||
|
||||
ValidatorSource
|
||||
- Abstract
|
||||
- Provides a list of Validator
|
||||
|
||||
ValidatorList
|
||||
- Essentially an array of Validator
|
||||
|
||||
ValidatorSourceTrustedUri
|
||||
- ValidatorSource which uses HTTPS and a predefined URI
|
||||
- Domain owner is responsible for removing bad validators
|
||||
|
||||
ValidatorSourceTrustedUri::List
|
||||
- Essentially an array of ValidatorSourceTrustedUri
|
||||
- Can be read from a file
|
||||
|
||||
LocalFileValidatorSource
|
||||
- ValidatorSource which reads information from a local file.
|
||||
|
||||
TrustedUriList // A copy of this ships with the app
|
||||
* has a KnownValidators
|
||||
|
||||
KnownValidators
|
||||
* A series of KnownValidator that comes from a TrustedUri
|
||||
* Persistent storage has a timestamp
|
||||
|
||||
RankedValidators
|
||||
* Created as the union of all KnownValidators with "weight" being the
|
||||
number of appearances.
|
||||
|
||||
ChosenValidators
|
||||
* Result of the algorithm that chooses a random subset of RankedKnownValidators
|
||||
* "local health" percentage is the percent of validations from this list that
|
||||
you've seen recently. And have they been behaving.
|
||||
*/
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
Validators* Validators::New ()
|
||||
{
|
||||
return new ValidatorsImp (nullptr);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
class ValidatorsTests : public UnitTest
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
numberOfTestValidators = 1000
|
||||
};
|
||||
|
||||
struct TestSource : Validators::Source
|
||||
{
|
||||
TestSource (String const& name, uint32 start, uint32 end)
|
||||
: m_name (name)
|
||||
, m_start (start)
|
||||
, m_end (end)
|
||||
{
|
||||
}
|
||||
|
||||
Array <Info> fetch (CancelCallback& cancel)
|
||||
{
|
||||
Array <Info> list;
|
||||
list.ensureStorageAllocated (numberOfTestValidators);
|
||||
for (uint32 i = m_start ; i < m_end; ++i)
|
||||
{
|
||||
Info info;
|
||||
info.key = Validators::KeyType::createFromInteger (i);
|
||||
list.add (info);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
String m_name;
|
||||
std::size_t m_start;
|
||||
std::size_t m_end;
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void addSources (ValidatorsImp::Logic& logic)
|
||||
{
|
||||
logic.addSource (new TestSource ("source 1", 0, 1000));
|
||||
logic.addSource (new TestSource ("source 2", 200, 1500));
|
||||
logic.addSource (new TestSource ("source 3", 500, 2000));
|
||||
logic.addSource (new TestSource ("source 4", 750, 2200));
|
||||
logic.addSource (new TestSource ("source 5", 1500, 3200));
|
||||
}
|
||||
|
||||
void testLogic ()
|
||||
{
|
||||
beginTestCase ("logic");
|
||||
|
||||
ValidatorsImp::Logic logic;
|
||||
addSources (logic);
|
||||
|
||||
ValidatorsImp::NoOpCancelCallback cancelCallback;
|
||||
logic.checkSources (cancelCallback);
|
||||
|
||||
ValidatorsImp::ChosenList::Ptr list (logic.getChosenList ());
|
||||
|
||||
pass ();
|
||||
}
|
||||
|
||||
void runTest ()
|
||||
{
|
||||
testLogic ();
|
||||
}
|
||||
|
||||
ValidatorsTests () : UnitTest ("Validators", "ripple", runManual)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
static ValidatorsTests validatorsTests;
|
||||
|
||||
107
modules/ripple_core/validator/Validators.h
Normal file
107
modules/ripple_core/validator/Validators.h
Normal file
@@ -0,0 +1,107 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
Copyright (c) 2011-2013, OpenCoin, Inc.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_CORE_VALIDATOR_VALIDATORS_H_INCLUDED
|
||||
#define RIPPLE_CORE_VALIDATOR_VALIDATORS_H_INCLUDED
|
||||
|
||||
/** Maintains the list of chosen validators.
|
||||
|
||||
The algorithm for acquiring, building, and calculating metadata on
|
||||
the list of chosen validators is critical to the health of the network.
|
||||
|
||||
All operations are performed asynchronously on an internal thread.
|
||||
*/
|
||||
class Validators : public Uncopyable
|
||||
{
|
||||
public:
|
||||
typedef RipplePublicKeyHash KeyType;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/** A source of validator descriptors. */
|
||||
class Source
|
||||
{
|
||||
public:
|
||||
/** A Source's descriptor for a Validator. */
|
||||
struct Info
|
||||
{
|
||||
/** The unique key for this validator. */
|
||||
KeyType key;
|
||||
};
|
||||
|
||||
/** Destroy the Source.
|
||||
This can be called from any thread. If the Source is busy
|
||||
fetching, the destructor must block until the operation is either
|
||||
canceled or complete.
|
||||
*/
|
||||
virtual ~Source () { }
|
||||
|
||||
struct CancelCallback
|
||||
{
|
||||
virtual bool shouldCancel () = 0;
|
||||
};
|
||||
|
||||
/** Fetch the most recent list from the Source.
|
||||
If possible, the Source should periodically poll the
|
||||
CancelCallback, and abort the operation if shouldCancel
|
||||
returns `true`.
|
||||
This call will block.
|
||||
*/
|
||||
virtual Array <Info> fetch (CancelCallback& callback) = 0;
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/** Create a new Validators object.
|
||||
*/
|
||||
static Validators* New ();
|
||||
|
||||
/** Destroy the object.
|
||||
|
||||
Any pending source fetch operations are aborted.
|
||||
|
||||
There may be some listener calls made before the
|
||||
destructor returns.
|
||||
*/
|
||||
virtual ~Validators () { }
|
||||
|
||||
/** Add a live source of validators.
|
||||
The caller loses ownership of the object.
|
||||
Thread safety:
|
||||
Can be called from any thread.
|
||||
*/
|
||||
virtual void addSource (Source* source) = 0;
|
||||
|
||||
/** Add a static source of validators.
|
||||
The Source is called to fetch once and the results are kept
|
||||
permanently. The fetch is performed asynchronously, this call
|
||||
returns immediately. If the fetch fails, it is not reattempted.
|
||||
The caller loses ownership of the object.
|
||||
Thread safety:
|
||||
Can be called from any thread.
|
||||
*/
|
||||
virtual void addStaticSource (Source* source) = 0;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
// Trusted Validators
|
||||
|
||||
//virtual bool isPublicKeyTrusted (Validator::PublicKey const&) = 0;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
struct ReceivedValidation
|
||||
{
|
||||
uint256 ledgerHash;
|
||||
RipplePublicKeyHash signerPublicKeyHash;
|
||||
};
|
||||
|
||||
/** Called when a validation with a proper signature is received.
|
||||
*/
|
||||
virtual void receiveValidation (ReceivedValidation const& rv) = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
438
modules/ripple_core/validator/ValidatorsImp.h
Normal file
438
modules/ripple_core/validator/ValidatorsImp.h
Normal file
@@ -0,0 +1,438 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
Copyright (c) 2011-2013, OpenCoin, Inc.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_CORE_VALIDATOR_VALIDATORSIMP_H_INCLUDED
|
||||
#define RIPPLE_CORE_VALIDATOR_VALIDATORSIMP_H_INCLUDED
|
||||
|
||||
// private implementation
|
||||
|
||||
class ValidatorsImp
|
||||
: public Validators
|
||||
, private ThreadWithCallQueue::EntryPoints
|
||||
, private DeadlineTimer::Listener
|
||||
, LeakChecked <ValidatorsImp>
|
||||
{
|
||||
public:
|
||||
// Tunable constants
|
||||
enum
|
||||
{
|
||||
// We will fetch a source at this interval
|
||||
hoursBetweenFetches = 24
|
||||
|
||||
,secondsBetweenFetches = hoursBetweenFetches * 60 * 60
|
||||
|
||||
// Wake up every hour to check source times
|
||||
,secondsPerUpdate = 60 * 60
|
||||
|
||||
// This tunes the preallocated arrays
|
||||
,expectedNumberOfResults = 1000
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
// Dummy CancelCallback that does nothing
|
||||
//
|
||||
struct NoOpCancelCallback : Source::CancelCallback
|
||||
{
|
||||
bool shouldCancel ()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/** Receive event notifications on Validators operations.
|
||||
*/
|
||||
class Listener
|
||||
{
|
||||
public:
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
class ChosenList : public SharedObject
|
||||
{
|
||||
public:
|
||||
typedef SharedObjectPtr <ChosenList> Ptr;
|
||||
|
||||
struct Info
|
||||
{
|
||||
Info ()
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
typedef HashMap <KeyType, Info, KeyType::HashFunction> MapType;
|
||||
|
||||
ChosenList ()
|
||||
{
|
||||
}
|
||||
|
||||
std::size_t size () const noexcept
|
||||
{
|
||||
return m_map.size ();
|
||||
}
|
||||
|
||||
void insert (KeyType const& key, Info const& info) noexcept
|
||||
{
|
||||
m_map [key] = info;
|
||||
}
|
||||
|
||||
bool contains (KeyType const& key) const noexcept
|
||||
{
|
||||
return m_map.find (key) != m_map.cend ();
|
||||
}
|
||||
|
||||
private:
|
||||
MapType m_map;
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
// Encapsulates the logic for creating the chosen validators.
|
||||
// This is a separate class to facilitate the unit tests.
|
||||
//
|
||||
class Logic
|
||||
{
|
||||
public:
|
||||
// Information associated with each Source
|
||||
//
|
||||
struct SourceInfo
|
||||
{
|
||||
enum
|
||||
{
|
||||
keysPreallocationSize = 1000
|
||||
};
|
||||
|
||||
enum Status
|
||||
{
|
||||
statusNone,
|
||||
statusFetched,
|
||||
statusFailed
|
||||
};
|
||||
|
||||
ScopedPointer <Source> source;
|
||||
Status status;
|
||||
Time whenToFetch;
|
||||
int numberOfFailures;
|
||||
|
||||
// The result of hte last fetch
|
||||
Array <Source::Info> list;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
|
||||
SourceInfo () noexcept
|
||||
: status (statusNone)
|
||||
, whenToFetch (Time::getCurrentTime ())
|
||||
, numberOfFailures (0)
|
||||
{
|
||||
list.ensureStorageAllocated (keysPreallocationSize);
|
||||
}
|
||||
|
||||
~SourceInfo ()
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
typedef DynamicList <SourceInfo> SourcesType;
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
// Information associated with each distinguishable validator
|
||||
//
|
||||
struct ValidatorInfo
|
||||
{
|
||||
ValidatorInfo ()
|
||||
: refCount (0)
|
||||
{
|
||||
}
|
||||
|
||||
KeyType key;
|
||||
int refCount;
|
||||
};
|
||||
|
||||
typedef HashMap <KeyType, ValidatorInfo, KeyType::HashFunction> MapType;
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
Logic ()
|
||||
: m_chosenListNeedsUpdate (false)
|
||||
{
|
||||
}
|
||||
|
||||
// Add a live source to the list of sources.
|
||||
//
|
||||
void addSource (Source* source)
|
||||
{
|
||||
SourceInfo& info (*m_sources.emplace_back ());
|
||||
info.source = source;
|
||||
}
|
||||
|
||||
// Add a one-time static source.
|
||||
// Fetch is called right away, this call blocks.
|
||||
//
|
||||
void addStaticSource (Source* source)
|
||||
{
|
||||
ScopedPointer <Source> object (source);
|
||||
|
||||
NoOpCancelCallback cancelCallback;
|
||||
|
||||
Array <Source::Info> list (object->fetch (cancelCallback));
|
||||
|
||||
addSourceInfo (list);
|
||||
}
|
||||
|
||||
// Called when we receive a validation from a peer.
|
||||
//
|
||||
void receiveValidation (Validators::ReceivedValidation const& rv)
|
||||
{
|
||||
MapType::iterator iter (m_map.find (rv.signerPublicKeyHash));
|
||||
if (iter != m_map.end ())
|
||||
{
|
||||
// Exists
|
||||
//ValidatorInfo& validatorInfo (iter->value ());
|
||||
}
|
||||
else
|
||||
{
|
||||
// New
|
||||
//ValidatorInfo& validatorInfo (m_map.insert (rv.signerPublicKeyHash));
|
||||
}
|
||||
}
|
||||
|
||||
// Add each entry in the list to the map, incrementing the
|
||||
// reference count if it already exists, and updating fields.
|
||||
//
|
||||
void addSourceInfo (Array <Source::Info> const& list)
|
||||
{
|
||||
for (std::size_t i = 0; i < list.size (); ++i)
|
||||
{
|
||||
Source::Info const& info (list.getReference (i));
|
||||
MapType::Result result (m_map.insert (info.key));
|
||||
ValidatorInfo& validatorInfo (result.iter->value ());
|
||||
++validatorInfo.refCount;
|
||||
if (result.inserted)
|
||||
{
|
||||
// This is a new one
|
||||
markDirtyChosenList ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Decrement the reference count of each item in the list
|
||||
// in the map
|
||||
//
|
||||
void removeSourceInfo (Array <Source::Info> const& list)
|
||||
{
|
||||
for (std::size_t i = 0; i < list.size (); ++i)
|
||||
{
|
||||
Source::Info const& info (list.getReference (i));
|
||||
MapType::iterator iter (m_map.find (info.key));
|
||||
bassert (iter != m_map.end ());
|
||||
ValidatorInfo& validatorInfo (iter->value ());
|
||||
if (--validatorInfo.refCount == 0)
|
||||
{
|
||||
// Last reference removed
|
||||
m_map.erase (info.key);
|
||||
markDirtyChosenList ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Fetch one source
|
||||
//
|
||||
void fetchSource (SourceInfo& info, Source::CancelCallback& callback)
|
||||
{
|
||||
Array <Source::Info> list (info.source->fetch (callback));
|
||||
if (! callback.shouldCancel ())
|
||||
{
|
||||
// Reset fetch timer for the source.
|
||||
info.whenToFetch = Time::getCurrentTime () +
|
||||
RelativeTime (secondsBetweenFetches);
|
||||
|
||||
// Add the new source info to the map
|
||||
addSourceInfo (list);
|
||||
|
||||
// Swap lists
|
||||
info.list.swapWith (list);
|
||||
|
||||
// Remove the old source info from the map
|
||||
removeSourceInfo (list);
|
||||
|
||||
// See if we need to rebuild
|
||||
checkDirtyChosenList ();
|
||||
}
|
||||
}
|
||||
|
||||
// Check each source to see if it needs fetching.
|
||||
//
|
||||
void checkSources (Source::CancelCallback& callback)
|
||||
{
|
||||
Time const currentTime (Time::getCurrentTime ());
|
||||
for (SourcesType::iterator iter = m_sources.begin ();
|
||||
! callback.shouldCancel () && iter != m_sources.end (); ++iter)
|
||||
{
|
||||
SourceInfo& info (*iter);
|
||||
if (info.whenToFetch <= currentTime)
|
||||
fetchSource (info, callback);
|
||||
}
|
||||
}
|
||||
|
||||
// Signal that the Chosen List needs to be rebuilt.
|
||||
//
|
||||
void markDirtyChosenList ()
|
||||
{
|
||||
m_chosenListNeedsUpdate = true;
|
||||
}
|
||||
|
||||
// Check the dirty state of the Chosen List, and rebuild it
|
||||
// if necessary.
|
||||
//
|
||||
void checkDirtyChosenList ()
|
||||
{
|
||||
if (m_chosenListNeedsUpdate)
|
||||
{
|
||||
buildChosenList ();
|
||||
m_chosenListNeedsUpdate = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Rebuilds the Chosen List
|
||||
//
|
||||
void buildChosenList ()
|
||||
{
|
||||
ChosenList::Ptr list (new ChosenList);
|
||||
|
||||
for (MapType::iterator iter = m_map.begin ();
|
||||
iter != m_map.end (); ++iter)
|
||||
{
|
||||
//ValidatorInfo const& validatorInfo (iter->value ());
|
||||
ChosenList::Info info;
|
||||
list->insert (iter->key (), info);
|
||||
}
|
||||
|
||||
// This is thread safe
|
||||
m_chosenList = list;
|
||||
}
|
||||
|
||||
// Get a reference to the chosen list.
|
||||
// This is safe to call from any thread at any time.
|
||||
//
|
||||
ChosenList::Ptr getChosenList ()
|
||||
{
|
||||
return m_chosenList;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
//
|
||||
// Ripple interface
|
||||
//
|
||||
// These routines are modeled after UniqueNodeList
|
||||
|
||||
bool isTrustedPublicKeyHash (RipplePublicKeyHash const& key)
|
||||
{
|
||||
return m_chosenList->contains (key);
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
private:
|
||||
SourcesType m_sources;
|
||||
MapType m_map;
|
||||
bool m_chosenListNeedsUpdate;
|
||||
ChosenList::Ptr m_chosenList;
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
public:
|
||||
explicit ValidatorsImp (Listener* listener)
|
||||
: m_listener (listener)
|
||||
, m_thread ("Validators")
|
||||
, m_timer (this)
|
||||
{
|
||||
//m_thread.start (this);
|
||||
}
|
||||
|
||||
~ValidatorsImp ()
|
||||
{
|
||||
}
|
||||
|
||||
void addSource (Source* source)
|
||||
{
|
||||
m_thread.call (&Logic::addSource, &m_logic, source);
|
||||
}
|
||||
|
||||
void addStaticSource (Source* source)
|
||||
{
|
||||
m_thread.call (&Logic::addStaticSource, &m_logic, source);
|
||||
}
|
||||
|
||||
void receiveValidation (ReceivedValidation const& rv)
|
||||
{
|
||||
m_thread.call (&Logic::receiveValidation, &m_logic, rv);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void onDeadlineTimer (DeadlineTimer&)
|
||||
{
|
||||
// This will make us fall into the idle proc as needed
|
||||
//
|
||||
m_thread.interrupt ();
|
||||
}
|
||||
|
||||
void threadInit ()
|
||||
{
|
||||
m_timer.setRecurringExpiration (secondsPerUpdate);
|
||||
}
|
||||
|
||||
void threadExit ()
|
||||
{
|
||||
}
|
||||
|
||||
bool threadIdle ()
|
||||
{
|
||||
bool interrupted = false;
|
||||
|
||||
struct ThreadCancelCallback : Source::CancelCallback, Uncopyable
|
||||
{
|
||||
explicit ThreadCancelCallback (ThreadWithCallQueue& thread)
|
||||
: m_thread (thread)
|
||||
, m_interrupted (false)
|
||||
{
|
||||
}
|
||||
|
||||
bool shouldCancel ()
|
||||
{
|
||||
if (m_interrupted)
|
||||
return true;
|
||||
return m_interrupted = m_thread.interruptionPoint ();
|
||||
}
|
||||
|
||||
private:
|
||||
ThreadWithCallQueue& m_thread;
|
||||
bool m_interrupted;
|
||||
};
|
||||
|
||||
ThreadCancelCallback cancelCallback (m_thread);
|
||||
|
||||
m_logic.checkSources (cancelCallback);
|
||||
|
||||
return interrupted;
|
||||
}
|
||||
|
||||
private:
|
||||
Logic m_logic;
|
||||
Listener* const m_listener;
|
||||
ThreadWithCallQueue m_thread;
|
||||
DeadlineTimer m_timer;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,29 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
Copyright (c) 2011-2013, OpenCoin, Inc.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
class StringsValidatorSourceImp : public StringsValidatorSource
|
||||
{
|
||||
public:
|
||||
StringsValidatorSourceImp (StringArray const& strings)
|
||||
{
|
||||
}
|
||||
|
||||
~StringsValidatorSourceImp ()
|
||||
{
|
||||
}
|
||||
|
||||
Array <Validator::Info> fetch ()
|
||||
{
|
||||
return Array <Validator::Info> ();
|
||||
}
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
StringsValidatorSource* StringsValidatorSource::New (StringArray const& strings)
|
||||
{
|
||||
return new StringsValidatorSourceImp (strings);
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
Copyright (c) 2011-2013, OpenCoin, Inc.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
class TrustedUriValidatorSourceImp : public TrustedUriValidatorSource
|
||||
{
|
||||
public:
|
||||
explicit TrustedUriValidatorSourceImp (String const url)
|
||||
: m_url (url)
|
||||
{
|
||||
}
|
||||
|
||||
~TrustedUriValidatorSourceImp ()
|
||||
{
|
||||
}
|
||||
|
||||
Array <Validator::Info> fetch ()
|
||||
{
|
||||
return Array <Validator::Info> ();
|
||||
}
|
||||
|
||||
private:
|
||||
String const m_url;
|
||||
};
|
||||
|
||||
TrustedUriValidatorSource* TrustedUriValidatorSource::New (String url)
|
||||
{
|
||||
return new TrustedUriValidatorSourceImp (url);
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
Copyright (c) 2011-2013, OpenCoin, Inc.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_VALIDATORLISTIMP_H_INCLUDED
|
||||
#define RIPPLE_VALIDATORLISTIMP_H_INCLUDED
|
||||
|
||||
// This is a private header
|
||||
|
||||
#endif
|
||||
@@ -1,10 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
Copyright (c) 2011-2013, OpenCoin, Inc.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_VALIDATORLIST_H_INCLUDED
|
||||
#define RIPPLE_VALIDATORLIST_H_INCLUDED
|
||||
|
||||
#endif
|
||||
@@ -1,451 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
Copyright (c) 2011-2013, OpenCoin, Inc.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
/*
|
||||
|
||||
Goal:
|
||||
|
||||
Provide the listener with a ValidatorList.
|
||||
- This forms the UNL
|
||||
|
||||
Task:
|
||||
|
||||
fetch ValidatorInfo array from a source
|
||||
|
||||
- We have the old one and the new one, compute the following:
|
||||
|
||||
* unchanged validators list
|
||||
* new validators list
|
||||
* removed validators list
|
||||
|
||||
- From the unchanged / new / removed, figure out what to do.
|
||||
|
||||
Two important questions:
|
||||
|
||||
- Are there any validators in my ChosenValidators that I dont want
|
||||
* For example, they have dropped off all the trusted lists
|
||||
|
||||
- Do I have enough?
|
||||
|
||||
*/
|
||||
|
||||
class ValidatorsImp
|
||||
: public Validators
|
||||
, private ThreadWithCallQueue::EntryPoints
|
||||
, private DeadlineTimer::Listener
|
||||
, LeakChecked <ValidatorsImp>
|
||||
{
|
||||
public:
|
||||
// Tunable constants
|
||||
enum
|
||||
{
|
||||
// We will fetch a source at this interval
|
||||
hoursBetweenFetches = 24
|
||||
|
||||
,secondsBetweenFetches = hoursBetweenFetches * 60 * 60
|
||||
|
||||
// Wake up every hour to check source times
|
||||
,secondsPerUpdate = 60 * 60
|
||||
|
||||
// This tunes the preallocated arrays
|
||||
,expectedNumberOfResults = 1000
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
struct SourceInfo : LeakChecked <SourceInfo>
|
||||
{
|
||||
enum Status
|
||||
{
|
||||
statusNone,
|
||||
statusFetched,
|
||||
statusFailed,
|
||||
};
|
||||
|
||||
explicit SourceInfo (Source* source_)
|
||||
: source (source_)
|
||||
, status (statusNone)
|
||||
, numberOfFailures (0)
|
||||
{
|
||||
}
|
||||
|
||||
ScopedPointer <Source> const source;
|
||||
Status status;
|
||||
Time whenToFetch;
|
||||
int numberOfFailures;
|
||||
Validator::List::Ptr list;
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
// Called during the list comparison
|
||||
//
|
||||
struct CompareCallback
|
||||
{
|
||||
virtual void onValidatorAdded (Validator const& validator) { }
|
||||
virtual void onValidatorRemoved (Validator const& validator) { }
|
||||
virtual void onValidatorUnchanged (Validator const& validator) { }
|
||||
};
|
||||
|
||||
// Given the old list and the new list for a source, this
|
||||
// computes which validators were added or removed, and
|
||||
// updates some statistics.
|
||||
//
|
||||
static void compareLists (Validator::List const& oldList,
|
||||
Validator::List const& newList,
|
||||
CompareCallback& callback)
|
||||
{
|
||||
// Validator::List is always sorted so walk both arrays and
|
||||
// do an element-wise comparison to perform set calculations.
|
||||
//
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
while (i < oldList.size () || j < newList.size ())
|
||||
{
|
||||
if (i < oldList.size () && j < newList.size ())
|
||||
{
|
||||
int const compare = Validator::Compare::compareElements (
|
||||
oldList [i], newList [j]);
|
||||
|
||||
if (compare < 0)
|
||||
{
|
||||
callback.onValidatorRemoved (*oldList [i]);
|
||||
++i;
|
||||
}
|
||||
else if (compare > 0)
|
||||
{
|
||||
callback.onValidatorAdded (*newList [j]);
|
||||
++j;
|
||||
}
|
||||
else
|
||||
{
|
||||
bassert (oldList [i] == newList [j]);
|
||||
|
||||
callback.onValidatorUnchanged (*newList [j]);
|
||||
++i;
|
||||
++j;
|
||||
}
|
||||
}
|
||||
else if (i < oldList.size ())
|
||||
{
|
||||
callback.onValidatorRemoved (*oldList [i]);
|
||||
++i;
|
||||
}
|
||||
else
|
||||
{
|
||||
bassert (j < newList.size ());
|
||||
|
||||
callback.onValidatorAdded (*newList [j]);
|
||||
++j;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Encapsulates the logic for creating the chosen validators.
|
||||
// This is a separate class to facilitate the unit tests.
|
||||
//
|
||||
class Logic : public CompareCallback
|
||||
{
|
||||
private:
|
||||
HashMap <Validator::PublicKey,
|
||||
Validator::Ptr,
|
||||
Validator::PublicKey::HashFunction> m_map;
|
||||
|
||||
OwnedArray <SourceInfo> m_sources;
|
||||
|
||||
public:
|
||||
Logic ()
|
||||
{
|
||||
}
|
||||
|
||||
void addSource (Source* source)
|
||||
{
|
||||
m_sources.add (new SourceInfo (source));
|
||||
}
|
||||
|
||||
OwnedArray <SourceInfo>& getSources ()
|
||||
{
|
||||
return m_sources;
|
||||
}
|
||||
|
||||
void onValidatorAdded (Validator const& validator)
|
||||
{
|
||||
}
|
||||
|
||||
void onValidatorRemoved (Validator const& validator)
|
||||
{
|
||||
}
|
||||
|
||||
void onValidatorUnchanged (Validator const& validator)
|
||||
{
|
||||
}
|
||||
|
||||
// Produces an array of references to validators given the validator info.
|
||||
//
|
||||
Validator::List::Ptr createListFromInfo (Array <Validator::Info>& info)
|
||||
{
|
||||
Validator::Info::sortAndRemoveDuplicates (info);
|
||||
|
||||
SharedObjectArray <Validator> items;
|
||||
|
||||
items.ensureStorageAllocated (info.size ());
|
||||
|
||||
for (int i = 0; i < info.size (); ++i)
|
||||
{
|
||||
Validator::PublicKey const& key (info [i].publicKey);
|
||||
|
||||
Validator::Ptr validator = m_map [key];
|
||||
|
||||
if (validator == nullptr)
|
||||
{
|
||||
validator = new Validator (key);
|
||||
|
||||
//m_map.set (key, validator);
|
||||
}
|
||||
|
||||
items.add (validator);
|
||||
}
|
||||
|
||||
return new Validator::List (items);
|
||||
}
|
||||
|
||||
// Fetch the validators from a source and process the result
|
||||
//
|
||||
void fetchAndProcessSource (SourceInfo& sourceInfo)
|
||||
{
|
||||
Array <Validator::Info> newInfo = sourceInfo.source->fetch ();
|
||||
|
||||
if (newInfo.size () != 0)
|
||||
{
|
||||
sourceInfo.status = SourceInfo::statusFetched;
|
||||
|
||||
sourceInfo.whenToFetch = Time::getCurrentTime () +
|
||||
RelativeTime (hoursBetweenFetches * 60.0 * 60.0);
|
||||
|
||||
Validator::List::Ptr newList (createListFromInfo (newInfo));
|
||||
|
||||
compareLists (*sourceInfo.list, *newList, *this);
|
||||
|
||||
sourceInfo.list = newList;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Failed to fetch, don't update fetch time
|
||||
sourceInfo.status = SourceInfo::statusFailed;
|
||||
sourceInfo.numberOfFailures++;
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
public:
|
||||
explicit ValidatorsImp (Validators::Listener* listener)
|
||||
: m_listener (listener)
|
||||
, m_thread ("Validators")
|
||||
, m_timer (this)
|
||||
{
|
||||
m_thread.start (this);
|
||||
}
|
||||
|
||||
~ValidatorsImp ()
|
||||
{
|
||||
}
|
||||
|
||||
void addSource (Source* source)
|
||||
{
|
||||
m_thread.call (&ValidatorsImp::doAddSource, this, source);
|
||||
}
|
||||
|
||||
void doAddSource (Source* source)
|
||||
{
|
||||
m_logic.addSource (source);
|
||||
}
|
||||
|
||||
void onDeadlineTimer (DeadlineTimer&)
|
||||
{
|
||||
// This will make us fall into the idle proc as needed
|
||||
//
|
||||
m_thread.interrupt ();
|
||||
}
|
||||
|
||||
// Fetch sources whose deadline timers have arrived.
|
||||
//
|
||||
bool scanSources ()
|
||||
{
|
||||
bool interrupted = false;
|
||||
|
||||
for (int i = 0; i < m_logic.getSources ().size (); ++i)
|
||||
{
|
||||
SourceInfo& sourceInfo (*m_logic.getSources ()[i]);
|
||||
|
||||
Time const currentTime = Time::getCurrentTime ();
|
||||
|
||||
if (currentTime <= sourceInfo.whenToFetch)
|
||||
{
|
||||
m_logic.fetchAndProcessSource (sourceInfo);
|
||||
}
|
||||
|
||||
interrupted = m_thread.interruptionPoint ();
|
||||
|
||||
if (interrupted)
|
||||
break;
|
||||
}
|
||||
|
||||
return interrupted;
|
||||
}
|
||||
|
||||
void threadInit ()
|
||||
{
|
||||
m_timer.setRecurringExpiration (secondsPerUpdate);
|
||||
}
|
||||
|
||||
void threadExit ()
|
||||
{
|
||||
}
|
||||
|
||||
bool threadIdle ()
|
||||
{
|
||||
bool interrupted = false;
|
||||
|
||||
interrupted = scanSources ();
|
||||
|
||||
return interrupted;
|
||||
}
|
||||
|
||||
private:
|
||||
Logic m_logic;
|
||||
Validators::Listener* const m_listener;
|
||||
ThreadWithCallQueue m_thread;
|
||||
DeadlineTimer m_timer;
|
||||
};
|
||||
|
||||
Validators* Validators::New (Listener* listener)
|
||||
{
|
||||
return new ValidatorsImp (listener);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
class ValidatorsTests : public UnitTest
|
||||
{
|
||||
public:
|
||||
// Produces validators for unit tests.
|
||||
class TestSource : public Validators::Source
|
||||
{
|
||||
public:
|
||||
TestSource (unsigned int startIndex, unsigned int endIndex)
|
||||
: m_startIndex (startIndex)
|
||||
, m_endIndex (endIndex)
|
||||
{
|
||||
}
|
||||
|
||||
Array <Validator::Info> fetch ()
|
||||
{
|
||||
Array <Validator::Info> results;
|
||||
|
||||
for (unsigned int publicKeyIndex = m_startIndex; publicKeyIndex <= m_endIndex; ++publicKeyIndex)
|
||||
{
|
||||
Validator::Info info;
|
||||
|
||||
info.publicKey = Validator::PublicKey::createFromInteger (publicKeyIndex);
|
||||
|
||||
results.add (info);
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
private:
|
||||
unsigned int const m_startIndex;
|
||||
unsigned int const m_endIndex;
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
struct TestCompareCallback : public ValidatorsImp::CompareCallback
|
||||
{
|
||||
int numTotal;
|
||||
int numAdded;
|
||||
int numRemoved;
|
||||
int numUnchanged;
|
||||
|
||||
TestCompareCallback ()
|
||||
: numTotal (0)
|
||||
, numAdded (0)
|
||||
, numRemoved (0)
|
||||
, numUnchanged (0)
|
||||
{
|
||||
}
|
||||
|
||||
void onValidatorAdded (Validator const& validator)
|
||||
{
|
||||
++numTotal;
|
||||
++numAdded;
|
||||
}
|
||||
|
||||
void onValidatorRemoved (Validator const& validator)
|
||||
{
|
||||
++numTotal;
|
||||
++numRemoved;
|
||||
}
|
||||
|
||||
void onValidatorUnchanged (Validator const& validator)
|
||||
{
|
||||
++numTotal;
|
||||
++numUnchanged;
|
||||
}
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
ValidatorsTests () : UnitTest ("Validators", "ripple", runManual)
|
||||
{
|
||||
}
|
||||
|
||||
// Check logic for comparing a source's fetch results
|
||||
void testCompare ()
|
||||
{
|
||||
beginTestCase ("compare");
|
||||
|
||||
{
|
||||
Array <Validator::Info> results = TestSource (1, 32).fetch ();
|
||||
expect (results.size () == 32);
|
||||
}
|
||||
|
||||
{
|
||||
Array <Validator::Info> oldInfo = TestSource (1, 4).fetch ();
|
||||
expect (oldInfo.size () == 4);
|
||||
|
||||
Array <Validator::Info> newInfo = TestSource (3, 6).fetch ();
|
||||
expect (newInfo.size () == 4);
|
||||
|
||||
ValidatorsImp::Logic logic;
|
||||
|
||||
Validator::List::Ptr oldList = logic.createListFromInfo (oldInfo);
|
||||
expect (oldList->size () == 4);
|
||||
|
||||
Validator::List::Ptr newList = logic.createListFromInfo (newInfo);
|
||||
expect (newList->size () == 4);
|
||||
|
||||
TestCompareCallback cb;
|
||||
ValidatorsImp::compareLists (*oldList, *newList, cb);
|
||||
|
||||
expect (cb.numAdded == 2);
|
||||
expect (cb.numRemoved == 2);
|
||||
expect (cb.numUnchanged == 2);
|
||||
}
|
||||
}
|
||||
|
||||
void runTest ()
|
||||
{
|
||||
testCompare ();
|
||||
}
|
||||
};
|
||||
|
||||
static ValidatorsTests validatorsTests;
|
||||
|
||||
@@ -1,69 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
Copyright (c) 2011-2013, OpenCoin, Inc.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_VALIDATORS_H_INCLUDED
|
||||
#define RIPPLE_VALIDATORS_H_INCLUDED
|
||||
|
||||
/** Maintains the list of chosen validators.
|
||||
|
||||
The algorithm for acquiring, building, and calculating metadata on
|
||||
the list of chosen validators is critical to the health of the network.
|
||||
|
||||
All operations are performed asynchronously on an internal thread.
|
||||
*/
|
||||
class Validators : public Uncopyable
|
||||
{
|
||||
public:
|
||||
/** Provides a ValidatorList.
|
||||
*/
|
||||
class Source
|
||||
{
|
||||
public:
|
||||
/** Destroy the source.
|
||||
|
||||
If a fetch is active, it will be aborted before the
|
||||
destructor returns.
|
||||
*/
|
||||
virtual ~Source () { }
|
||||
|
||||
/** Fetch the validator list from this source.
|
||||
|
||||
This call blocks.
|
||||
*/
|
||||
virtual Array <Validator::Info> fetch () =0;
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/** Receive event notifications on Validators operations.
|
||||
*/
|
||||
class Listener
|
||||
{
|
||||
public:
|
||||
virtual void onValidatorsChosen (Validator::List::Ptr list) { }
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/** Create a new Validators object.
|
||||
*/
|
||||
static Validators* New (Listener* listener);
|
||||
|
||||
/** Destroy the object.
|
||||
|
||||
Any pending source fetch operations are aborted.
|
||||
|
||||
There may be some listener calls made before the
|
||||
destructor returns.
|
||||
*/
|
||||
virtual ~Validators () { }
|
||||
|
||||
/** Add a source of validators.
|
||||
*/
|
||||
virtual void addSource (Source* source) = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user