mirror of
https://github.com/XRPLF/rippled.git
synced 2025-12-06 17:27:55 +00:00
Rename Feature to Amendment:
* Added a README.md describing an Amendment
This commit is contained in:
committed by
Vinnie Falco
parent
98612a7cd6
commit
3025d8611b
@@ -1072,7 +1072,7 @@
|
|||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="..\..\src\ripple_app\misc\FeaturesImpl.cpp">
|
<ClCompile Include="..\..\src\ripple_app\misc\AmendmentTableImpl.cpp">
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||||
@@ -2952,7 +2952,7 @@
|
|||||||
<ClInclude Include="..\..\src\ripple_app\misc\AccountItems.h" />
|
<ClInclude Include="..\..\src\ripple_app\misc\AccountItems.h" />
|
||||||
<ClInclude Include="..\..\src\ripple_app\misc\AccountState.h" />
|
<ClInclude Include="..\..\src\ripple_app\misc\AccountState.h" />
|
||||||
<ClInclude Include="..\..\src\ripple_app\misc\CanonicalTXSet.h" />
|
<ClInclude Include="..\..\src\ripple_app\misc\CanonicalTXSet.h" />
|
||||||
<ClInclude Include="..\..\src\ripple_app\misc\FeatureTable.h" />
|
<ClInclude Include="..\..\src\ripple_app\misc\AmendmentTable.h" />
|
||||||
<ClInclude Include="..\..\src\ripple_app\misc\FeeVote.h" />
|
<ClInclude Include="..\..\src\ripple_app\misc\FeeVote.h" />
|
||||||
<ClInclude Include="..\..\src\ripple_app\misc\IHashRouter.h" />
|
<ClInclude Include="..\..\src\ripple_app\misc\IHashRouter.h" />
|
||||||
<ClInclude Include="..\..\src\ripple_app\misc\ProofOfWorkFactory.h" />
|
<ClInclude Include="..\..\src\ripple_app\misc\ProofOfWorkFactory.h" />
|
||||||
@@ -3247,6 +3247,7 @@
|
|||||||
<None Include="..\..\src\ripple\validators\TODO.md" />
|
<None Include="..\..\src\ripple\validators\TODO.md" />
|
||||||
<None Include="..\..\src\ripple\validators\README.md" />
|
<None Include="..\..\src\ripple\validators\README.md" />
|
||||||
<None Include="..\..\src\ripple_app\ledger\TODO.md" />
|
<None Include="..\..\src\ripple_app\ledger\TODO.md" />
|
||||||
|
<None Include="..\..\src\ripple_app\misc\README.md" />
|
||||||
<None Include="..\..\src\ripple_app\TODO.md" />
|
<None Include="..\..\src\ripple_app\TODO.md" />
|
||||||
<None Include="..\..\src\ripple_core\nodestore\README.md" />
|
<None Include="..\..\src\ripple_core\nodestore\README.md" />
|
||||||
<None Include="..\..\src\ripple_overlay\README.md" />
|
<None Include="..\..\src\ripple_overlay\README.md" />
|
||||||
|
|||||||
@@ -1716,10 +1716,10 @@
|
|||||||
<ClCompile Include="..\..\src\ripple_rpc\impl\LookupLedger.cpp">
|
<ClCompile Include="..\..\src\ripple_rpc\impl\LookupLedger.cpp">
|
||||||
<Filter>[2] Old Ripple\ripple_rpc\impl</Filter>
|
<Filter>[2] Old Ripple\ripple_rpc\impl</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="..\..\src\ripple_app\misc\FeaturesImpl.cpp">
|
<ClCompile Include="..\..\src\ripple_app\misc\FeeVoteImpl.cpp">
|
||||||
<Filter>[2] Old Ripple\ripple_app\misc</Filter>
|
<Filter>[2] Old Ripple\ripple_app\misc</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="..\..\src\ripple_app\misc\FeeVoteImpl.cpp">
|
<ClCompile Include="..\..\src\ripple_app\misc\AmendmentTableImpl.cpp">
|
||||||
<Filter>[2] Old Ripple\ripple_app\misc</Filter>
|
<Filter>[2] Old Ripple\ripple_app\misc</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="..\..\src\ripple\proto\ripple.pb.cc">
|
<ClCompile Include="..\..\src\ripple\proto\ripple.pb.cc">
|
||||||
@@ -3342,7 +3342,7 @@
|
|||||||
<ClInclude Include="..\..\src\ripple_app\misc\FeeVote.h">
|
<ClInclude Include="..\..\src\ripple_app\misc\FeeVote.h">
|
||||||
<Filter>[2] Old Ripple\ripple_app\misc</Filter>
|
<Filter>[2] Old Ripple\ripple_app\misc</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="..\..\src\ripple_app\misc\FeatureTable.h">
|
<ClInclude Include="..\..\src\ripple_app\misc\AmendmentTable.h">
|
||||||
<Filter>[2] Old Ripple\ripple_app\misc</Filter>
|
<Filter>[2] Old Ripple\ripple_app\misc</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="..\..\src\ripple\proto\ripple.pb.h">
|
<ClInclude Include="..\..\src\ripple\proto\ripple.pb.h">
|
||||||
@@ -3473,8 +3473,9 @@
|
|||||||
<None Include="..\..\src\ripple_core\nodestore\README.md">
|
<None Include="..\..\src\ripple_core\nodestore\README.md">
|
||||||
<Filter>[2] Old Ripple\ripple_core\nodestore</Filter>
|
<Filter>[2] Old Ripple\ripple_core\nodestore</Filter>
|
||||||
</None>
|
</None>
|
||||||
</ItemGroup>
|
<None Include="..\..\src\ripple_app\misc\README.md">
|
||||||
<ItemGroup>
|
<Filter>[2] Old Ripple\ripple_app\misc</Filter>
|
||||||
|
</None>
|
||||||
<CustomBuild Include="..\..\src\ripple\proto\ripple.proto">
|
<CustomBuild Include="..\..\src\ripple\proto\ripple.proto">
|
||||||
<Filter>[1] Ripple\proto</Filter>
|
<Filter>[1] Ripple\proto</Filter>
|
||||||
</CustomBuild>
|
</CustomBuild>
|
||||||
|
|||||||
@@ -211,8 +211,8 @@ correctly to find the boost headers.
|
|||||||
/** Config: RIPPLE_PROPOSE_FEATURES
|
/** Config: RIPPLE_PROPOSE_FEATURES
|
||||||
This determines whether to add any features to the proposed transaction set.
|
This determines whether to add any features to the proposed transaction set.
|
||||||
*/
|
*/
|
||||||
#ifndef RIPPLE_PROPOSE_FEATURES
|
#ifndef RIPPLE_PROPOSE_AMENDMENTS
|
||||||
#define RIPPLE_PROPOSE_FEATURES 0
|
#define RIPPLE_PROPOSE_AMENDMENTS 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -961,7 +961,7 @@ private:
|
|||||||
// next ledger is flag ledger
|
// next ledger is flag ledger
|
||||||
{
|
{
|
||||||
m_feeVote.doValidation (newLCL, *v);
|
m_feeVote.doValidation (newLCL, *v);
|
||||||
getApp().getFeatureTable ().doValidation (newLCL, *v);
|
getApp().getAmendmentTable ().doValidation (newLCL, *v);
|
||||||
}
|
}
|
||||||
|
|
||||||
v->sign (signingHash, mValPrivate);
|
v->sign (signingHash, mValPrivate);
|
||||||
@@ -1491,7 +1491,7 @@ private:
|
|||||||
SHAMap::pointer preSet
|
SHAMap::pointer preSet
|
||||||
= initialLedger.peekTransactionMap ()->snapShot (true);
|
= initialLedger.peekTransactionMap ()->snapShot (true);
|
||||||
m_feeVote.doVoting (mPreviousLedger, preSet);
|
m_feeVote.doVoting (mPreviousLedger, preSet);
|
||||||
getApp().getFeatureTable ().doVoting (mPreviousLedger, preSet);
|
getApp().getAmendmentTable ().doVoting (mPreviousLedger, preSet);
|
||||||
initialSet = preSet->snapShot (false);
|
initialSet = preSet->snapShot (false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -1504,11 +1504,11 @@ uint256 Ledger::getLedgerFeeIndex ()
|
|||||||
return s.getSHA512Half ();
|
return s.getSHA512Half ();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint256 Ledger::getLedgerFeatureIndex ()
|
uint256 Ledger::getLedgerAmendmentIndex ()
|
||||||
{
|
{
|
||||||
// get the index of the node that holds the enabled features
|
// get the index of the node that holds the enabled amendments
|
||||||
Serializer s (2);
|
Serializer s (2);
|
||||||
s.add16 (spaceFeature);
|
s.add16 (spaceAmendment);
|
||||||
return s.getSHA512Half ();
|
return s.getSHA512Half ();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1616,15 +1616,15 @@ std::vector< std::pair<std::uint32_t, uint256> > Ledger::getLedgerHashes ()
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<uint256> Ledger::getLedgerFeatures ()
|
std::vector<uint256> Ledger::getLedgerAmendments ()
|
||||||
{
|
{
|
||||||
std::vector<uint256> usFeatures;
|
std::vector<uint256> usAmendments;
|
||||||
SLE::pointer sleFeatures = getSLEi (getLedgerFeatureIndex ());
|
SLE::pointer sleAmendments = getSLEi (getLedgerAmendmentIndex ());
|
||||||
|
|
||||||
if (sleFeatures)
|
if (sleAmendments)
|
||||||
usFeatures = sleFeatures->getFieldV256 (sfFeatures).peekValue ();
|
usAmendments = sleAmendments->getFieldV256 (sfAmendments).peekValue ();
|
||||||
|
|
||||||
return usFeatures;
|
return usAmendments;
|
||||||
}
|
}
|
||||||
|
|
||||||
// XRP to XRP not allowed.
|
// XRP to XRP not allowed.
|
||||||
|
|||||||
@@ -300,9 +300,9 @@ public:
|
|||||||
uint256 getLedgerHash (std::uint32_t ledgerIndex);
|
uint256 getLedgerHash (std::uint32_t ledgerIndex);
|
||||||
std::vector< std::pair<std::uint32_t, uint256> > getLedgerHashes ();
|
std::vector< std::pair<std::uint32_t, uint256> > getLedgerHashes ();
|
||||||
|
|
||||||
static uint256 getLedgerFeatureIndex ();
|
static uint256 getLedgerAmendmentIndex ();
|
||||||
static uint256 getLedgerFeeIndex ();
|
static uint256 getLedgerFeeIndex ();
|
||||||
std::vector<uint256> getLedgerFeatures ();
|
std::vector<uint256> getLedgerAmendments ();
|
||||||
|
|
||||||
std::vector<uint256> getNeededTransactionHashes (int max, SHAMapSyncFilter * filter);
|
std::vector<uint256> getNeededTransactionHashes (int max, SHAMapSyncFilter * filter);
|
||||||
std::vector<uint256> getNeededAccountStateHashes (int max, SHAMapSyncFilter * filter);
|
std::vector<uint256> getNeededAccountStateHashes (int max, SHAMapSyncFilter * filter);
|
||||||
|
|||||||
@@ -146,7 +146,7 @@ SOTemplate const& SerializedValidation::getFormat ()
|
|||||||
format.push_back (SOElement (sfLedgerSequence, SOE_OPTIONAL));
|
format.push_back (SOElement (sfLedgerSequence, SOE_OPTIONAL));
|
||||||
format.push_back (SOElement (sfCloseTime, SOE_OPTIONAL));
|
format.push_back (SOElement (sfCloseTime, SOE_OPTIONAL));
|
||||||
format.push_back (SOElement (sfLoadFee, SOE_OPTIONAL));
|
format.push_back (SOElement (sfLoadFee, SOE_OPTIONAL));
|
||||||
format.push_back (SOElement (sfFeatures, SOE_OPTIONAL));
|
format.push_back (SOElement (sfAmendments, SOE_OPTIONAL));
|
||||||
format.push_back (SOElement (sfBaseFee, SOE_OPTIONAL));
|
format.push_back (SOElement (sfBaseFee, SOE_OPTIONAL));
|
||||||
format.push_back (SOElement (sfReserveBase, SOE_OPTIONAL));
|
format.push_back (SOElement (sfReserveBase, SOE_OPTIONAL));
|
||||||
format.push_back (SOElement (sfReserveIncrement, SOE_OPTIONAL));
|
format.push_back (SOElement (sfReserveIncrement, SOE_OPTIONAL));
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ namespace ripple {
|
|||||||
// VFALCO TODO Clean this global up
|
// VFALCO TODO Clean this global up
|
||||||
static bool volatile doShutdown = false;
|
static bool volatile doShutdown = false;
|
||||||
|
|
||||||
static int const MAJORITY_FRACTION (200);
|
static int const MAJORITY_FRACTION (204);
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
@@ -59,8 +59,8 @@ class PathRequestLog;
|
|||||||
template <> char const* LogPartition::getPartitionName <PathRequestLog> () { return "PathRequest"; }
|
template <> char const* LogPartition::getPartitionName <PathRequestLog> () { return "PathRequest"; }
|
||||||
class RPCManagerLog;
|
class RPCManagerLog;
|
||||||
template <> char const* LogPartition::getPartitionName <RPCManagerLog> () { return "RPCManager"; }
|
template <> char const* LogPartition::getPartitionName <RPCManagerLog> () { return "RPCManager"; }
|
||||||
class FeaturesLog;
|
class AmendmentTableLog;
|
||||||
template <> char const* LogPartition::getPartitionName <FeaturesLog>() { return "FeatureTable"; }
|
template <> char const* LogPartition::getPartitionName <AmendmentTableLog>() { return "AmendmentTable"; }
|
||||||
|
|
||||||
template <> char const* LogPartition::getPartitionName <CollectorManager> () { return "Collector"; }
|
template <> char const* LogPartition::getPartitionName <CollectorManager> () { return "Collector"; }
|
||||||
|
|
||||||
@@ -141,7 +141,7 @@ public:
|
|||||||
std::unique_ptr <SNTPClient> m_sntpClient;
|
std::unique_ptr <SNTPClient> m_sntpClient;
|
||||||
std::unique_ptr <TxQueue> m_txQueue;
|
std::unique_ptr <TxQueue> m_txQueue;
|
||||||
std::unique_ptr <Validators::Manager> m_validators;
|
std::unique_ptr <Validators::Manager> m_validators;
|
||||||
std::unique_ptr <FeatureTable> m_featureTable;
|
std::unique_ptr <AmendmentTable> m_amendmentTable;
|
||||||
std::unique_ptr <LoadFeeTrack> mFeeTrack;
|
std::unique_ptr <LoadFeeTrack> mFeeTrack;
|
||||||
std::unique_ptr <IHashRouter> mHashRouter;
|
std::unique_ptr <IHashRouter> mHashRouter;
|
||||||
std::unique_ptr <Validations> mValidations;
|
std::unique_ptr <Validations> mValidations;
|
||||||
@@ -296,8 +296,8 @@ public:
|
|||||||
getConfig ().getModuleDatabasePath (),
|
getConfig ().getModuleDatabasePath (),
|
||||||
LogPartition::getJournal <ValidatorsLog> ())))
|
LogPartition::getJournal <ValidatorsLog> ())))
|
||||||
|
|
||||||
, m_featureTable (make_FeatureTable (weeks(2), MAJORITY_FRACTION, // 200/256
|
, m_amendmentTable (make_AmendmentTable (weeks(2), MAJORITY_FRACTION, // 204/256 about 80%
|
||||||
LogPartition::getJournal <FeaturesLog> ()))
|
LogPartition::getJournal <AmendmentTableLog> ()))
|
||||||
|
|
||||||
, mFeeTrack (LoadFeeTrack::New (LogPartition::getJournal <LoadManagerLog> ()))
|
, mFeeTrack (LoadFeeTrack::New (LogPartition::getJournal <LoadManagerLog> ()))
|
||||||
|
|
||||||
@@ -450,9 +450,9 @@ public:
|
|||||||
return *m_validators;
|
return *m_validators;
|
||||||
}
|
}
|
||||||
|
|
||||||
FeatureTable& getFeatureTable ()
|
AmendmentTable& getAmendmentTable()
|
||||||
{
|
{
|
||||||
return *m_featureTable;
|
return *m_amendmentTable;
|
||||||
}
|
}
|
||||||
|
|
||||||
LoadFeeTrack& getFeeTrack ()
|
LoadFeeTrack& getFeeTrack ()
|
||||||
@@ -609,7 +609,7 @@ public:
|
|||||||
if (!getConfig ().RUN_STANDALONE)
|
if (!getConfig ().RUN_STANDALONE)
|
||||||
updateTables ();
|
updateTables ();
|
||||||
|
|
||||||
m_featureTable->addInitial ();
|
m_amendmentTable->addInitial();
|
||||||
Pathfinder::initPathTable ();
|
Pathfinder::initPathTable ();
|
||||||
|
|
||||||
m_ledgerMaster->setMinValidations (getConfig ().VALIDATION_QUORUM);
|
m_ledgerMaster->setMinValidations (getConfig ().VALIDATION_QUORUM);
|
||||||
@@ -1069,7 +1069,7 @@ void ApplicationImp::startNewLedger ()
|
|||||||
{
|
{
|
||||||
Ledger::pointer firstLedger = boost::make_shared<Ledger> (rootAddress, SYSTEM_CURRENCY_START);
|
Ledger::pointer firstLedger = boost::make_shared<Ledger> (rootAddress, SYSTEM_CURRENCY_START);
|
||||||
assert (!!firstLedger->getAccountState (rootAddress));
|
assert (!!firstLedger->getAccountState (rootAddress));
|
||||||
// WRITEME: Add any default features
|
// WRITEME: Add any default amendments
|
||||||
// WRITEME: Set default fee/reserve
|
// WRITEME: Set default fee/reserve
|
||||||
firstLedger->updateHash ();
|
firstLedger->updateHash ();
|
||||||
firstLedger->setClosed ();
|
firstLedger->setClosed ();
|
||||||
@@ -1215,7 +1215,7 @@ bool serverOkay (std::string& reason)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getApp().getOPs ().isFeatureBlocked ())
|
if (getApp().getOPs ().isAmendmentBlocked ())
|
||||||
{
|
{
|
||||||
reason = "Server version too old";
|
reason = "Server version too old";
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ namespace RPC { class Manager; }
|
|||||||
|
|
||||||
// VFALCO TODO Fix forward declares required for header dependency loops
|
// VFALCO TODO Fix forward declares required for header dependency loops
|
||||||
class CollectorManager;
|
class CollectorManager;
|
||||||
class FeatureTable;
|
class AmendmentTable;
|
||||||
class IHashRouter;
|
class IHashRouter;
|
||||||
class LoadFeeTrack;
|
class LoadFeeTrack;
|
||||||
class Overlay;
|
class Overlay;
|
||||||
@@ -88,7 +88,7 @@ public:
|
|||||||
virtual NodeCache& getTempNodeCache () = 0;
|
virtual NodeCache& getTempNodeCache () = 0;
|
||||||
virtual SLECache& getSLECache () = 0;
|
virtual SLECache& getSLECache () = 0;
|
||||||
virtual Validators::Manager& getValidators () = 0;
|
virtual Validators::Manager& getValidators () = 0;
|
||||||
virtual FeatureTable& getFeatureTable () = 0;
|
virtual AmendmentTable& getAmendmentTable() = 0;
|
||||||
virtual IHashRouter& getHashRouter () = 0;
|
virtual IHashRouter& getHashRouter () = 0;
|
||||||
virtual LoadFeeTrack& getFeeTrack () = 0;
|
virtual LoadFeeTrack& getFeeTrack () = 0;
|
||||||
virtual LoadManager& getLoadManager () = 0;
|
virtual LoadManager& getLoadManager () = 0;
|
||||||
|
|||||||
@@ -17,22 +17,22 @@
|
|||||||
*/
|
*/
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
|
|
||||||
#ifndef RIPPLE_FEATURES_H
|
#ifndef RIPPLE_AMENDMENT_TABLE_H
|
||||||
#define RIPPLE_FEATURES_H
|
#define RIPPLE_AMENDMENT_TABLE_H
|
||||||
|
|
||||||
#include "../book/Types.h"
|
#include "../book/Types.h"
|
||||||
|
|
||||||
namespace ripple {
|
namespace ripple {
|
||||||
|
|
||||||
class FeatureSet
|
/** The status of all amendments requested in a given window. */
|
||||||
|
class AmendmentSet
|
||||||
{
|
{
|
||||||
// the status of all features requested in a given window
|
|
||||||
public:
|
public:
|
||||||
std::uint32_t mCloseTime;
|
std::uint32_t mCloseTime;
|
||||||
int mTrustedValidations; // number of trusted validations
|
int mTrustedValidations; // number of trusted validations
|
||||||
ripple::unordered_map<uint256, int> mVotes; // yes votes by feature
|
ripple::unordered_map<uint256, int> mVotes; // yes votes by amendment
|
||||||
|
|
||||||
FeatureSet (std::uint32_t ct) : mCloseTime (ct), mTrustedValidations (0)
|
AmendmentSet (std::uint32_t ct) : mCloseTime (ct), mTrustedValidations (0)
|
||||||
{
|
{
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
@@ -40,16 +40,20 @@ public:
|
|||||||
{
|
{
|
||||||
++mTrustedValidations;
|
++mTrustedValidations;
|
||||||
}
|
}
|
||||||
void addVote (uint256 const& feature)
|
void addVote (uint256 const& amendment)
|
||||||
{
|
{
|
||||||
++mVotes[feature];
|
++mVotes[amendment];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class FeatureState
|
/** Current state of an amendment.
|
||||||
|
Tells if a amendment is supported, enabled or vetoed. A vetoed amendment
|
||||||
|
means the node will never announce its support.
|
||||||
|
*/
|
||||||
|
class AmendmentState
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
bool mVetoed; // We don't want this feature enabled
|
bool mVetoed; // We don't want this amendment enabled
|
||||||
bool mEnabled;
|
bool mEnabled;
|
||||||
bool mSupported;
|
bool mSupported;
|
||||||
bool mDefault; // Include in genesis ledger
|
bool mDefault; // Include in genesis ledger
|
||||||
@@ -59,7 +63,7 @@ public:
|
|||||||
|
|
||||||
std::string mFriendlyName;
|
std::string mFriendlyName;
|
||||||
|
|
||||||
FeatureState ()
|
AmendmentState ()
|
||||||
: mVetoed (false), mEnabled (false), mSupported (false), mDefault (false),
|
: mVetoed (false), mEnabled (false), mSupported (false), mDefault (false),
|
||||||
m_firstMajority (0), m_lastMajority (0)
|
m_firstMajority (0), m_lastMajority (0)
|
||||||
{
|
{
|
||||||
@@ -100,46 +104,44 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Feature table interface.
|
/** The amendment table stores the list of enabled and potential amendments.
|
||||||
|
Individuals amendments are voted on by validators during the consensus
|
||||||
The feature table stores the list of enabled and potential features.
|
|
||||||
Individuals features are voted on by validators during the consensus
|
|
||||||
process.
|
process.
|
||||||
*/
|
*/
|
||||||
class FeatureTable
|
class AmendmentTable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/** Create a new FeatureTable.
|
/** Create a new AmendmentTable.
|
||||||
|
|
||||||
@param majorityTime the number of seconds a feature must hold a majority
|
@param majorityTime the number of seconds an amendment must hold a majority
|
||||||
before we're willing to vote yes on it.
|
before we're willing to vote yes on it.
|
||||||
@param majorityFraction ratio, out of 256, of servers that must say
|
@param majorityFraction ratio, out of 256, of servers that must say
|
||||||
they want a feature before we consider it to
|
they want an amendment before we consider it to
|
||||||
have a majority.
|
have a majority.
|
||||||
@param journal
|
@param journal
|
||||||
*/
|
*/
|
||||||
|
|
||||||
virtual ~FeatureTable() { }
|
virtual ~AmendmentTable() { }
|
||||||
|
|
||||||
virtual void addInitial () = 0;
|
virtual void addInitial () = 0;
|
||||||
|
|
||||||
virtual FeatureState* addKnown (const char* featureID,
|
virtual AmendmentState* addKnown (const char* amendmentID,
|
||||||
const char* friendlyName, bool veto) = 0;
|
const char* friendlyName, bool veto) = 0;
|
||||||
virtual uint256 get (const std::string& name) = 0;
|
virtual uint256 get (const std::string& name) = 0;
|
||||||
|
|
||||||
virtual bool veto (uint256 const& feature) = 0;
|
virtual bool veto (uint256 const& amendment) = 0;
|
||||||
virtual bool unVeto (uint256 const& feature) = 0;
|
virtual bool unVeto (uint256 const& amendment) = 0;
|
||||||
|
|
||||||
virtual bool enable (uint256 const& feature) = 0;
|
virtual bool enable (uint256 const& amendment) = 0;
|
||||||
virtual bool disable (uint256 const& feature) = 0;
|
virtual bool disable (uint256 const& amendment) = 0;
|
||||||
|
|
||||||
virtual bool isEnabled (uint256 const& feature) = 0;
|
virtual bool isEnabled (uint256 const& amendment) = 0;
|
||||||
virtual bool isSupported (uint256 const& feature) = 0;
|
virtual bool isSupported (uint256 const& amendment) = 0;
|
||||||
|
|
||||||
virtual void setEnabled (const std::vector<uint256>& features) = 0;
|
virtual void setEnabled (const std::vector<uint256>& amendments) = 0;
|
||||||
virtual void setSupported (const std::vector<uint256>& features) = 0;
|
virtual void setSupported (const std::vector<uint256>& amendments) = 0;
|
||||||
|
|
||||||
virtual void reportValidations (const FeatureSet&) = 0;
|
virtual void reportValidations (const AmendmentSet&) = 0;
|
||||||
|
|
||||||
virtual Json::Value getJson (int) = 0;
|
virtual Json::Value getJson (int) = 0;
|
||||||
virtual Json::Value getJson (uint256 const& ) = 0;
|
virtual Json::Value getJson (uint256 const& ) = 0;
|
||||||
@@ -150,8 +152,8 @@ public:
|
|||||||
doVoting (Ledger::ref lastClosedLedger, SHAMap::ref initialPosition) = 0;
|
doVoting (Ledger::ref lastClosedLedger, SHAMap::ref initialPosition) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::unique_ptr<FeatureTable>
|
std::unique_ptr<AmendmentTable>
|
||||||
make_FeatureTable (std::chrono::seconds majorityTime, int majorityFraction,
|
make_AmendmentTable (std::chrono::seconds majorityTime, int majorityFraction,
|
||||||
beast::Journal journal);
|
beast::Journal journal);
|
||||||
|
|
||||||
} // ripple
|
} // ripple
|
||||||
@@ -19,38 +19,38 @@
|
|||||||
|
|
||||||
namespace ripple {
|
namespace ripple {
|
||||||
|
|
||||||
/** Track the list of "features"
|
/** Track the list of "amendments"
|
||||||
|
|
||||||
A "feature" is an option that can affect transaction processing
|
An "amendment" is an option that can affect transaction processing
|
||||||
rules that is identified by a 256-bit feature identifier
|
rules that is identified by a 256-bit amendment identifier
|
||||||
and adopted, or rejected, by the network.
|
and adopted, or rejected, by the network.
|
||||||
*/
|
*/
|
||||||
class FeaturesImpl : public FeatureTable
|
class AmendmentTableImpl : public AmendmentTable
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
typedef ripple::unordered_map<uint256, FeatureState> featureMap_t;
|
typedef ripple::unordered_map<uint256, AmendmentState> amendmentMap_t;
|
||||||
typedef std::pair<const uint256, FeatureState> featureIt_t;
|
typedef std::pair<const uint256, AmendmentState> amendmentIt_t;
|
||||||
typedef boost::unordered_set<uint256> featureList_t;
|
typedef boost::unordered_set<uint256> amendmentList_t;
|
||||||
|
|
||||||
typedef RippleMutex LockType;
|
typedef RippleMutex LockType;
|
||||||
typedef std::lock_guard <LockType> ScopedLockType;
|
typedef std::lock_guard <LockType> ScopedLockType;
|
||||||
LockType mLock;
|
LockType mLock;
|
||||||
|
|
||||||
featureMap_t mFeatureMap;
|
amendmentMap_t m_amendmentMap;
|
||||||
std::chrono::seconds m_majorityTime; // Seconds a feature must hold a majority
|
std::chrono::seconds m_majorityTime; // Seconds an amendment must hold a majority
|
||||||
int mMajorityFraction; // 256 = 100%
|
int mMajorityFraction; // 256 = 100%
|
||||||
core::Clock::time_point m_firstReport; // close time of first majority report
|
core::Clock::time_point m_firstReport; // close time of first majority report
|
||||||
core::Clock::time_point m_lastReport; // close time of most recent majority report
|
core::Clock::time_point m_lastReport; // close time of most recent majority report
|
||||||
beast::Journal m_journal;
|
beast::Journal m_journal;
|
||||||
|
|
||||||
FeatureState* getCreate (uint256 const& feature, bool create);
|
AmendmentState* getCreate (uint256 const& amendment, bool create);
|
||||||
bool shouldEnable (std::uint32_t closeTime, const FeatureState& fs);
|
bool shouldEnable (std::uint32_t closeTime, const AmendmentState& fs);
|
||||||
void setJson (Json::Value& v, const FeatureState&);
|
void setJson (Json::Value& v, const AmendmentState&);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
FeaturesImpl (std::chrono::seconds majorityTime, int majorityFraction,
|
AmendmentTableImpl (std::chrono::seconds majorityTime, int majorityFraction,
|
||||||
beast::Journal journal)
|
beast::Journal journal)
|
||||||
: m_majorityTime (majorityTime)
|
: m_majorityTime (majorityTime)
|
||||||
, mMajorityFraction (majorityFraction)
|
, mMajorityFraction (majorityFraction)
|
||||||
@@ -62,23 +62,23 @@ public:
|
|||||||
|
|
||||||
void addInitial () override;
|
void addInitial () override;
|
||||||
|
|
||||||
FeatureState* addKnown (const char* featureID, const char* friendlyName,
|
AmendmentState* addKnown (const char* amendmentID, const char* friendlyName,
|
||||||
bool veto) override;
|
bool veto) override;
|
||||||
uint256 get (const std::string& name) override;
|
uint256 get (const std::string& name) override;
|
||||||
|
|
||||||
bool veto (uint256 const& feature) override;
|
bool veto (uint256 const& amendment) override;
|
||||||
bool unVeto (uint256 const& feature) override;
|
bool unVeto (uint256 const& amendment) override;
|
||||||
|
|
||||||
bool enable (uint256 const& feature) override;
|
bool enable (uint256 const& amendment) override;
|
||||||
bool disable (uint256 const& feature) override;
|
bool disable (uint256 const& amendment) override;
|
||||||
|
|
||||||
bool isEnabled (uint256 const& feature) override;
|
bool isEnabled (uint256 const& amendment) override;
|
||||||
bool isSupported (uint256 const& feature) override;
|
bool isSupported (uint256 const& amendment) override;
|
||||||
|
|
||||||
void setEnabled (const std::vector<uint256>& features) override;
|
void setEnabled (const std::vector<uint256>& amendments) override;
|
||||||
void setSupported (const std::vector<uint256>& features) override;
|
void setSupported (const std::vector<uint256>& amendments) override;
|
||||||
|
|
||||||
void reportValidations (const FeatureSet&) override;
|
void reportValidations (const AmendmentSet&) override;
|
||||||
|
|
||||||
Json::Value getJson (int) override;
|
Json::Value getJson (int) override;
|
||||||
Json::Value getJson (uint256 const&) override;
|
Json::Value getJson (uint256 const&) override;
|
||||||
@@ -86,35 +86,35 @@ public:
|
|||||||
void doValidation (Ledger::ref lastClosedLedger, STObject& baseValidation) override;
|
void doValidation (Ledger::ref lastClosedLedger, STObject& baseValidation) override;
|
||||||
void doVoting (Ledger::ref lastClosedLedger, SHAMap::ref initialPosition) override;
|
void doVoting (Ledger::ref lastClosedLedger, SHAMap::ref initialPosition) override;
|
||||||
|
|
||||||
featureList_t getVetoed ();
|
amendmentList_t getVetoed();
|
||||||
featureList_t getEnabled ();
|
amendmentList_t getEnabled();
|
||||||
featureList_t getToEnable (core::Clock::time_point closeTime); // gets features we would vote to enable
|
amendmentList_t getToEnable(core::Clock::time_point closeTime); // gets amendments we would vote to enable
|
||||||
featureList_t getDesired (); // features we support, do not veto, are not enabled
|
amendmentList_t getDesired(); // amendments we support, do not veto, are not enabled
|
||||||
};
|
};
|
||||||
|
|
||||||
void
|
void
|
||||||
FeaturesImpl::addInitial ()
|
AmendmentTableImpl::addInitial ()
|
||||||
{
|
{
|
||||||
// For each feature this version supports, construct the FeatureState object by calling
|
// For each amendment this version supports, construct the AmendmentState object by calling
|
||||||
// addKnown. Set any vetoes or defaults. A pointer to the FeatureState can be stashed
|
// addKnown. Set any vetoes or defaults. A pointer to the AmendmentState can be stashed
|
||||||
}
|
}
|
||||||
|
|
||||||
FeatureState*
|
AmendmentState*
|
||||||
FeaturesImpl::getCreate (uint256 const& featureHash, bool create)
|
AmendmentTableImpl::getCreate (uint256 const& amendmentHash, bool create)
|
||||||
{
|
{
|
||||||
// call with the mutex held
|
// call with the mutex held
|
||||||
auto iter (mFeatureMap.find (featureHash));
|
auto iter (m_amendmentMap.find (amendmentHash));
|
||||||
|
|
||||||
if (iter == mFeatureMap.end ())
|
if (iter == m_amendmentMap.end())
|
||||||
{
|
{
|
||||||
if (!create)
|
if (!create)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
FeatureState* feature = & (mFeatureMap[featureHash]);
|
AmendmentState* amendment = & (m_amendmentMap[amendmentHash]);
|
||||||
|
|
||||||
{
|
{
|
||||||
std::string query = "SELECT FirstMajority,LastMajority FROM Features WHERE hash='";
|
std::string query = "SELECT FirstMajority,LastMajority FROM Features WHERE hash='";
|
||||||
query.append (featureHash.GetHex ());
|
query.append (amendmentHash.GetHex ());
|
||||||
query.append ("';");
|
query.append ("';");
|
||||||
|
|
||||||
DeprecatedScopedLock sl (getApp().getWalletDB ()->getDBLock ());
|
DeprecatedScopedLock sl (getApp().getWalletDB ()->getDBLock ());
|
||||||
@@ -122,22 +122,22 @@ FeaturesImpl::getCreate (uint256 const& featureHash, bool create)
|
|||||||
|
|
||||||
if (db->executeSQL (query) && db->startIterRows ())
|
if (db->executeSQL (query) && db->startIterRows ())
|
||||||
{
|
{
|
||||||
feature->m_firstMajority = db->getBigInt("FirstMajority");
|
amendment->m_firstMajority = db->getBigInt("FirstMajority");
|
||||||
feature->m_lastMajority = db->getBigInt("LastMajority");
|
amendment->m_lastMajority = db->getBigInt("LastMajority");
|
||||||
db->endIterRows ();
|
db->endIterRows ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return feature;
|
return amendment;
|
||||||
}
|
}
|
||||||
|
|
||||||
return & (iter->second);
|
return & (iter->second);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint256
|
uint256
|
||||||
FeaturesImpl::get (const std::string& name)
|
AmendmentTableImpl::get (const std::string& name)
|
||||||
{
|
{
|
||||||
for (auto const& e : mFeatureMap)
|
for (auto const& e : m_amendmentMap)
|
||||||
{
|
{
|
||||||
if (name == e.second.mFriendlyName)
|
if (name == e.second.mFriendlyName)
|
||||||
return e.first;
|
return e.first;
|
||||||
@@ -146,12 +146,12 @@ FeaturesImpl::get (const std::string& name)
|
|||||||
return uint256 ();
|
return uint256 ();
|
||||||
}
|
}
|
||||||
|
|
||||||
FeatureState*
|
AmendmentState*
|
||||||
FeaturesImpl::addKnown (const char* featureID, const char* friendlyName,
|
AmendmentTableImpl::addKnown (const char* amendmentID, const char* friendlyName,
|
||||||
bool veto)
|
bool veto)
|
||||||
{
|
{
|
||||||
uint256 hash;
|
uint256 hash;
|
||||||
hash.SetHex (featureID);
|
hash.SetHex (amendmentID);
|
||||||
|
|
||||||
if (hash.isZero ())
|
if (hash.isZero ())
|
||||||
{
|
{
|
||||||
@@ -159,7 +159,7 @@ FeaturesImpl::addKnown (const char* featureID, const char* friendlyName,
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
FeatureState* f = getCreate (hash, true);
|
AmendmentState* f = getCreate (hash, true);
|
||||||
|
|
||||||
if (friendlyName != nullptr)
|
if (friendlyName != nullptr)
|
||||||
f->setFriendlyName (friendlyName);
|
f->setFriendlyName (friendlyName);
|
||||||
@@ -171,10 +171,10 @@ FeaturesImpl::addKnown (const char* featureID, const char* friendlyName,
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
FeaturesImpl::veto (uint256 const& feature)
|
AmendmentTableImpl::veto (uint256 const& amendment)
|
||||||
{
|
{
|
||||||
ScopedLockType sl (mLock);
|
ScopedLockType sl (mLock);
|
||||||
FeatureState* s = getCreate (feature, true);
|
AmendmentState* s = getCreate (amendment, true);
|
||||||
|
|
||||||
if (s->mVetoed)
|
if (s->mVetoed)
|
||||||
return false;
|
return false;
|
||||||
@@ -184,10 +184,10 @@ FeaturesImpl::veto (uint256 const& feature)
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
FeaturesImpl::unVeto (uint256 const& feature)
|
AmendmentTableImpl::unVeto (uint256 const& amendment)
|
||||||
{
|
{
|
||||||
ScopedLockType sl (mLock);
|
ScopedLockType sl (mLock);
|
||||||
FeatureState* s = getCreate (feature, false);
|
AmendmentState* s = getCreate (amendment, false);
|
||||||
|
|
||||||
if (!s || !s->mVetoed)
|
if (!s || !s->mVetoed)
|
||||||
return false;
|
return false;
|
||||||
@@ -197,10 +197,10 @@ FeaturesImpl::unVeto (uint256 const& feature)
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
FeaturesImpl::enable (uint256 const& feature)
|
AmendmentTableImpl::enable (uint256 const& amendment)
|
||||||
{
|
{
|
||||||
ScopedLockType sl (mLock);
|
ScopedLockType sl (mLock);
|
||||||
FeatureState* s = getCreate (feature, true);
|
AmendmentState* s = getCreate (amendment, true);
|
||||||
|
|
||||||
if (s->mEnabled)
|
if (s->mEnabled)
|
||||||
return false;
|
return false;
|
||||||
@@ -210,10 +210,10 @@ FeaturesImpl::enable (uint256 const& feature)
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
FeaturesImpl::disable (uint256 const& feature)
|
AmendmentTableImpl::disable (uint256 const& amendment)
|
||||||
{
|
{
|
||||||
ScopedLockType sl (mLock);
|
ScopedLockType sl (mLock);
|
||||||
FeatureState* s = getCreate (feature, false);
|
AmendmentState* s = getCreate (amendment, false);
|
||||||
|
|
||||||
if (!s || !s->mEnabled)
|
if (!s || !s->mEnabled)
|
||||||
return false;
|
return false;
|
||||||
@@ -223,27 +223,27 @@ FeaturesImpl::disable (uint256 const& feature)
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
FeaturesImpl::isEnabled (uint256 const& feature)
|
AmendmentTableImpl::isEnabled (uint256 const& amendment)
|
||||||
{
|
{
|
||||||
ScopedLockType sl (mLock);
|
ScopedLockType sl (mLock);
|
||||||
FeatureState* s = getCreate (feature, false);
|
AmendmentState* s = getCreate (amendment, false);
|
||||||
return s && s->mEnabled;
|
return s && s->mEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
FeaturesImpl::isSupported (uint256 const& feature)
|
AmendmentTableImpl::isSupported (uint256 const& amendment)
|
||||||
{
|
{
|
||||||
ScopedLockType sl (mLock);
|
ScopedLockType sl (mLock);
|
||||||
FeatureState* s = getCreate (feature, false);
|
AmendmentState* s = getCreate (amendment, false);
|
||||||
return s && s->mSupported;
|
return s && s->mSupported;
|
||||||
}
|
}
|
||||||
|
|
||||||
FeaturesImpl::featureList_t
|
AmendmentTableImpl::amendmentList_t
|
||||||
FeaturesImpl::getVetoed ()
|
AmendmentTableImpl::getVetoed ()
|
||||||
{
|
{
|
||||||
featureList_t ret;
|
amendmentList_t ret;
|
||||||
ScopedLockType sl (mLock);
|
ScopedLockType sl (mLock);
|
||||||
for (auto const& e : mFeatureMap)
|
for (auto const& e : m_amendmentMap)
|
||||||
{
|
{
|
||||||
if (e.second.mVetoed)
|
if (e.second.mVetoed)
|
||||||
ret.insert (e.first);
|
ret.insert (e.first);
|
||||||
@@ -251,12 +251,12 @@ FeaturesImpl::getVetoed ()
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
FeaturesImpl::featureList_t
|
AmendmentTableImpl::amendmentList_t
|
||||||
FeaturesImpl::getEnabled ()
|
AmendmentTableImpl::getEnabled ()
|
||||||
{
|
{
|
||||||
featureList_t ret;
|
amendmentList_t ret;
|
||||||
ScopedLockType sl (mLock);
|
ScopedLockType sl (mLock);
|
||||||
for (auto const& e : mFeatureMap)
|
for (auto const& e : m_amendmentMap)
|
||||||
{
|
{
|
||||||
if (e.second.mEnabled)
|
if (e.second.mEnabled)
|
||||||
ret.insert (e.first);
|
ret.insert (e.first);
|
||||||
@@ -265,7 +265,8 @@ FeaturesImpl::getEnabled ()
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
FeaturesImpl::shouldEnable (std::uint32_t closeTime, const FeatureState& fs)
|
AmendmentTableImpl::shouldEnable (std::uint32_t closeTime,
|
||||||
|
const AmendmentState& fs)
|
||||||
{
|
{
|
||||||
if (fs.mVetoed || fs.mEnabled || !fs.mSupported || (fs.m_lastMajority != m_lastReport))
|
if (fs.mVetoed || fs.mEnabled || !fs.mSupported || (fs.m_lastMajority != m_lastReport))
|
||||||
return false;
|
return false;
|
||||||
@@ -280,15 +281,15 @@ FeaturesImpl::shouldEnable (std::uint32_t closeTime, const FeatureState& fs)
|
|||||||
return (fs.m_lastMajority - fs.m_firstMajority) > m_majorityTime.count();
|
return (fs.m_lastMajority - fs.m_firstMajority) > m_majorityTime.count();
|
||||||
}
|
}
|
||||||
|
|
||||||
FeaturesImpl::featureList_t
|
AmendmentTableImpl::amendmentList_t
|
||||||
FeaturesImpl::getToEnable (core::Clock::time_point closeTime)
|
AmendmentTableImpl::getToEnable (core::Clock::time_point closeTime)
|
||||||
{
|
{
|
||||||
featureList_t ret;
|
amendmentList_t ret;
|
||||||
ScopedLockType sl (mLock);
|
ScopedLockType sl (mLock);
|
||||||
|
|
||||||
if (m_lastReport != 0)
|
if (m_lastReport != 0)
|
||||||
{
|
{
|
||||||
for (auto const& e : mFeatureMap)
|
for (auto const& e : m_amendmentMap)
|
||||||
{
|
{
|
||||||
if (shouldEnable (closeTime, e.second))
|
if (shouldEnable (closeTime, e.second))
|
||||||
ret.insert (e.first);
|
ret.insert (e.first);
|
||||||
@@ -298,13 +299,13 @@ FeaturesImpl::getToEnable (core::Clock::time_point closeTime)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
FeaturesImpl::featureList_t
|
AmendmentTableImpl::amendmentList_t
|
||||||
FeaturesImpl::getDesired ()
|
AmendmentTableImpl::getDesired ()
|
||||||
{
|
{
|
||||||
featureList_t ret;
|
amendmentList_t ret;
|
||||||
ScopedLockType sl (mLock);
|
ScopedLockType sl (mLock);
|
||||||
|
|
||||||
for (auto const& e : mFeatureMap)
|
for (auto const& e : m_amendmentMap)
|
||||||
{
|
{
|
||||||
if (e.second.mSupported && !e.second.mEnabled && !e.second.mVetoed)
|
if (e.second.mSupported && !e.second.mEnabled && !e.second.mVetoed)
|
||||||
ret.insert (e.first);
|
ret.insert (e.first);
|
||||||
@@ -314,7 +315,7 @@ FeaturesImpl::getDesired ()
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
FeaturesImpl::reportValidations (const FeatureSet& set)
|
AmendmentTableImpl::reportValidations (const AmendmentSet& set)
|
||||||
{
|
{
|
||||||
if (set.mTrustedValidations == 0)
|
if (set.mTrustedValidations == 0)
|
||||||
return;
|
return;
|
||||||
@@ -328,14 +329,14 @@ FeaturesImpl::reportValidations (const FeatureSet& set)
|
|||||||
if (m_firstReport == 0)
|
if (m_firstReport == 0)
|
||||||
m_firstReport = set.mCloseTime;
|
m_firstReport = set.mCloseTime;
|
||||||
|
|
||||||
std::vector<uint256> changedFeatures;
|
std::vector<uint256> changedAmendments;
|
||||||
changedFeatures.resize (set.mVotes.size ());
|
changedAmendments.resize(set.mVotes.size());
|
||||||
|
|
||||||
for (auto const& e : set.mVotes)
|
for (auto const& e : set.mVotes)
|
||||||
{
|
{
|
||||||
FeatureState& state = mFeatureMap[e.first];
|
AmendmentState& state = m_amendmentMap[e.first];
|
||||||
if (m_journal.debug) m_journal.debug <<
|
if (m_journal.debug) m_journal.debug <<
|
||||||
"Feature " << e.first.GetHex () <<
|
"Amendment " << e.first.GetHex () <<
|
||||||
" has " << e.second <<
|
" has " << e.second <<
|
||||||
" votes, needs " << threshold;
|
" votes, needs " << threshold;
|
||||||
|
|
||||||
@@ -347,11 +348,11 @@ FeaturesImpl::reportValidations (const FeatureSet& set)
|
|||||||
if (state.m_firstMajority == 0)
|
if (state.m_firstMajority == 0)
|
||||||
{
|
{
|
||||||
if (m_journal.warning) m_journal.warning <<
|
if (m_journal.warning) m_journal.warning <<
|
||||||
"Feature " << e.first <<
|
"Amendment " << e.first <<
|
||||||
" attains a majority vote";
|
" attains a majority vote";
|
||||||
|
|
||||||
state.m_firstMajority = set.mCloseTime;
|
state.m_firstMajority = set.mCloseTime;
|
||||||
changedFeatures.push_back (e.first);
|
changedAmendments.push_back(e.first);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else // we have no majority
|
else // we have no majority
|
||||||
@@ -359,26 +360,26 @@ FeaturesImpl::reportValidations (const FeatureSet& set)
|
|||||||
if (state.m_firstMajority != 0)
|
if (state.m_firstMajority != 0)
|
||||||
{
|
{
|
||||||
if (m_journal.warning) m_journal.warning <<
|
if (m_journal.warning) m_journal.warning <<
|
||||||
"Feature " << e.first <<
|
"Amendment " << e.first <<
|
||||||
" loses majority vote";
|
" loses majority vote";
|
||||||
|
|
||||||
state.m_firstMajority = 0;
|
state.m_firstMajority = 0;
|
||||||
state.m_lastMajority = 0;
|
state.m_lastMajority = 0;
|
||||||
changedFeatures.push_back (e.first);
|
changedAmendments.push_back(e.first);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_lastReport = set.mCloseTime;
|
m_lastReport = set.mCloseTime;
|
||||||
|
|
||||||
if (!changedFeatures.empty ())
|
if (!changedAmendments.empty())
|
||||||
{
|
{
|
||||||
DeprecatedScopedLock sl (getApp().getWalletDB ()->getDBLock ());
|
DeprecatedScopedLock sl (getApp().getWalletDB ()->getDBLock ());
|
||||||
Database* db = getApp().getWalletDB ()->getDB ();
|
Database* db = getApp().getWalletDB ()->getDB ();
|
||||||
|
|
||||||
db->executeSQL ("BEGIN TRANSACTION;");
|
db->executeSQL ("BEGIN TRANSACTION;");
|
||||||
for (auto const& hash : changedFeatures)
|
for (auto const& hash : changedAmendments)
|
||||||
{
|
{
|
||||||
FeatureState& fState = mFeatureMap[hash];
|
AmendmentState& fState = m_amendmentMap[hash];
|
||||||
db->executeSQL (boost::str (boost::format (
|
db->executeSQL (boost::str (boost::format (
|
||||||
"UPDATE Features SET FirstMajority = %d WHERE Hash = '%s';"
|
"UPDATE Features SET FirstMajority = %d WHERE Hash = '%s';"
|
||||||
) % fState.m_firstMajority % hash.GetHex ()));
|
) % fState.m_firstMajority % hash.GetHex ()));
|
||||||
@@ -387,63 +388,65 @@ FeaturesImpl::reportValidations (const FeatureSet& set)
|
|||||||
) % fState.m_lastMajority % hash.GetHex()));
|
) % fState.m_lastMajority % hash.GetHex()));
|
||||||
}
|
}
|
||||||
db->executeSQL ("END TRANSACTION;");
|
db->executeSQL ("END TRANSACTION;");
|
||||||
changedFeatures.clear ();
|
changedAmendments.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
FeaturesImpl::setEnabled (const std::vector<uint256>& features)
|
AmendmentTableImpl::setEnabled (const std::vector<uint256>& amendments)
|
||||||
{
|
{
|
||||||
ScopedLockType sl (mLock);
|
ScopedLockType sl (mLock);
|
||||||
for (auto& e : mFeatureMap)
|
for (auto& e : m_amendmentMap)
|
||||||
{
|
{
|
||||||
e.second.mEnabled = false;
|
e.second.mEnabled = false;
|
||||||
}
|
}
|
||||||
for (auto const& e : features)
|
for (auto const& e : amendments)
|
||||||
{
|
{
|
||||||
mFeatureMap[e].mEnabled = true;
|
m_amendmentMap[e].mEnabled = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
FeaturesImpl::setSupported (const std::vector<uint256>& features)
|
AmendmentTableImpl::setSupported (const std::vector<uint256>& amendments)
|
||||||
{
|
{
|
||||||
ScopedLockType sl (mLock);
|
ScopedLockType sl (mLock);
|
||||||
for (auto &e : mFeatureMap)
|
for (auto &e : m_amendmentMap)
|
||||||
{
|
{
|
||||||
e.second.mSupported = false;
|
e.second.mSupported = false;
|
||||||
}
|
}
|
||||||
for (auto const& e : features)
|
for (auto const& e : amendments)
|
||||||
{
|
{
|
||||||
mFeatureMap[e].mSupported = true;
|
m_amendmentMap[e].mSupported = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
FeaturesImpl::doValidation (Ledger::ref lastClosedLedger, STObject& baseValidation)
|
AmendmentTableImpl::doValidation (Ledger::ref lastClosedLedger,
|
||||||
|
STObject& baseValidation)
|
||||||
{
|
{
|
||||||
featureList_t lFeatures = getDesired ();
|
amendmentList_t lAmendments = getDesired();
|
||||||
|
|
||||||
if (lFeatures.empty ())
|
if (lAmendments.empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
STVector256 vFeatures (sfFeatures);
|
STVector256 vAmendments (sfAmendments);
|
||||||
for (auto const& uFeature : lFeatures)
|
for (auto const& uAmendment : lAmendments)
|
||||||
{
|
{
|
||||||
vFeatures.addValue (uFeature);
|
vAmendments.addValue (uAmendment);
|
||||||
}
|
}
|
||||||
vFeatures.sort ();
|
vAmendments.sort ();
|
||||||
baseValidation.setFieldV256 (sfFeatures, vFeatures);
|
baseValidation.setFieldV256 (sfAmendments, vAmendments);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
FeaturesImpl::doVoting (Ledger::ref lastClosedLedger, SHAMap::ref initialPosition)
|
AmendmentTableImpl::doVoting (Ledger::ref lastClosedLedger,
|
||||||
|
SHAMap::ref initialPosition)
|
||||||
{
|
{
|
||||||
|
|
||||||
// LCL must be flag ledger
|
// LCL must be flag ledger
|
||||||
assert((lastClosedLedger->getLedgerSeq () % 256) == 0);
|
assert((lastClosedLedger->getLedgerSeq () % 256) == 0);
|
||||||
|
|
||||||
FeatureSet featureSet (lastClosedLedger->getParentCloseTimeNC ());
|
AmendmentSet amendmentSet (lastClosedLedger->getParentCloseTimeNC ());
|
||||||
|
|
||||||
// get validations for ledger before flag ledger
|
// get validations for ledger before flag ledger
|
||||||
ValidationSet valSet = getApp().getValidations ().getValidations (lastClosedLedger->getParentHash ());
|
ValidationSet valSet = getApp().getValidations ().getValidations (lastClosedLedger->getParentHash ());
|
||||||
@@ -453,29 +456,28 @@ FeaturesImpl::doVoting (Ledger::ref lastClosedLedger, SHAMap::ref initialPositio
|
|||||||
|
|
||||||
if (val.isTrusted ())
|
if (val.isTrusted ())
|
||||||
{
|
{
|
||||||
featureSet.addVoter ();
|
amendmentSet.addVoter ();
|
||||||
if (val.isFieldPresent (sfFeatures))
|
if (val.isFieldPresent (sfAmendments))
|
||||||
{
|
{
|
||||||
for (auto const& feature : val.getFieldV256 (sfFeatures))
|
for (auto const& amendment : val.getFieldV256 (sfAmendments))
|
||||||
{
|
{
|
||||||
featureSet.addVote (feature);
|
amendmentSet.addVote (amendment);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
reportValidations (featureSet);
|
reportValidations (amendmentSet);
|
||||||
|
|
||||||
featureList_t lFeatures = getToEnable (lastClosedLedger->getCloseTimeNC ());
|
amendmentList_t lAmendments = getToEnable (lastClosedLedger->getCloseTimeNC ());
|
||||||
for (auto const& uFeature : lFeatures)
|
for (auto const& uAmendment : lAmendments)
|
||||||
{
|
{
|
||||||
if (m_journal.warning) m_journal.warning <<
|
if (m_journal.warning) m_journal.warning <<
|
||||||
"Voting for feature: " << uFeature;
|
"Voting for amendment: " << uAmendment;
|
||||||
|
|
||||||
// Create the transaction to enable the feature
|
// Create the transaction to enable the amendment
|
||||||
SerializedTransaction trans (ttFEATURE);
|
SerializedTransaction trans (ttAMENDMENT);
|
||||||
trans.setFieldAccount (sfAccount, uint160 ());
|
trans.setFieldAccount (sfAccount, uint160 ());
|
||||||
trans.setFieldH256 (sfFeature, uFeature);
|
trans.setFieldH256 (sfAmendment, uAmendment);
|
||||||
uint256 txID = trans.getTransactionID ();
|
uint256 txID = trans.getTransactionID ();
|
||||||
|
|
||||||
if (m_journal.warning) m_journal.warning <<
|
if (m_journal.warning) m_journal.warning <<
|
||||||
@@ -484,24 +486,24 @@ FeaturesImpl::doVoting (Ledger::ref lastClosedLedger, SHAMap::ref initialPositio
|
|||||||
// Inject the transaction into our initial proposal
|
// Inject the transaction into our initial proposal
|
||||||
Serializer s;
|
Serializer s;
|
||||||
trans.add (s, true);
|
trans.add (s, true);
|
||||||
#if RIPPLE_PROPOSE_FEATURES
|
#if RIPPLE_PROPOSE_AMENDMENTS
|
||||||
SHAMapItem::pointer tItem = boost::make_shared<SHAMapItem> (txID, s.peekData ());
|
SHAMapItem::pointer tItem = boost::make_shared<SHAMapItem> (txID, s.peekData ());
|
||||||
if (!initialPosition->addGiveItem (tItem, true, false))
|
if (!initialPosition->addGiveItem (tItem, true, false))
|
||||||
{
|
{
|
||||||
if (m_journal.warning) m_journal.warning <<
|
if (m_journal.warning) m_journal.warning <<
|
||||||
"Ledger already had feature transaction";
|
"Ledger already had amendment transaction";
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Json::Value
|
Json::Value
|
||||||
FeaturesImpl::getJson (int)
|
AmendmentTableImpl::getJson (int)
|
||||||
{
|
{
|
||||||
Json::Value ret(Json::objectValue);
|
Json::Value ret(Json::objectValue);
|
||||||
{
|
{
|
||||||
ScopedLockType sl(mLock);
|
ScopedLockType sl(mLock);
|
||||||
for (auto const& e : mFeatureMap)
|
for (auto const& e : m_amendmentMap)
|
||||||
{
|
{
|
||||||
setJson (ret[e.first.GetHex ()] = Json::objectValue, e.second);
|
setJson (ret[e.first.GetHex ()] = Json::objectValue, e.second);
|
||||||
}
|
}
|
||||||
@@ -510,7 +512,7 @@ FeaturesImpl::getJson (int)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
FeaturesImpl::setJson (Json::Value& v, const FeatureState& fs)
|
AmendmentTableImpl::setJson (Json::Value& v, const AmendmentState& fs)
|
||||||
{
|
{
|
||||||
if (!fs.mFriendlyName.empty())
|
if (!fs.mFriendlyName.empty())
|
||||||
v["name"] = fs.mFriendlyName;
|
v["name"] = fs.mFriendlyName;
|
||||||
@@ -556,26 +558,26 @@ FeaturesImpl::setJson (Json::Value& v, const FeatureState& fs)
|
|||||||
}
|
}
|
||||||
|
|
||||||
Json::Value
|
Json::Value
|
||||||
FeaturesImpl::getJson (uint256 const& featureID)
|
AmendmentTableImpl::getJson (uint256 const& amendmentID)
|
||||||
{
|
{
|
||||||
Json::Value ret = Json::objectValue;
|
Json::Value ret = Json::objectValue;
|
||||||
Json::Value& jFeature = (ret[featureID.GetHex()] = Json::objectValue);
|
Json::Value& jAmendment = (ret[amendmentID.GetHex ()] = Json::objectValue);
|
||||||
|
|
||||||
{
|
{
|
||||||
ScopedLockType sl(mLock);
|
ScopedLockType sl(mLock);
|
||||||
|
|
||||||
FeatureState *featureState = getCreate (featureID, true);
|
AmendmentState *amendmentState = getCreate (amendmentID, true);
|
||||||
setJson (jFeature, *featureState);
|
setJson (jAmendment, *amendmentState);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<FeatureTable>
|
std::unique_ptr<AmendmentTable>
|
||||||
make_FeatureTable (std::chrono::seconds majorityTime, int majorityFraction,
|
make_AmendmentTable (std::chrono::seconds majorityTime, int majorityFraction,
|
||||||
beast::Journal journal)
|
beast::Journal journal)
|
||||||
{
|
{
|
||||||
return std::make_unique<FeaturesImpl> (majorityTime, majorityFraction,
|
return std::make_unique<AmendmentTableImpl> (majorityTime, majorityFraction,
|
||||||
journal);
|
journal);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,7 +58,7 @@ public:
|
|||||||
, mNeedNetworkLedger (false)
|
, mNeedNetworkLedger (false)
|
||||||
, mProposing (false)
|
, mProposing (false)
|
||||||
, mValidating (false)
|
, mValidating (false)
|
||||||
, mFeatureBlocked (false)
|
, m_amendmentBlocked (false)
|
||||||
, m_heartbeatTimer (this)
|
, m_heartbeatTimer (this)
|
||||||
, m_clusterTimer (this)
|
, m_clusterTimer (this)
|
||||||
, m_ledgerMaster (ledgerMaster)
|
, m_ledgerMaster (ledgerMaster)
|
||||||
@@ -299,11 +299,11 @@ public:
|
|||||||
{
|
{
|
||||||
return mValidating;
|
return mValidating;
|
||||||
}
|
}
|
||||||
bool isFeatureBlocked ()
|
bool isAmendmentBlocked ()
|
||||||
{
|
{
|
||||||
return mFeatureBlocked;
|
return m_amendmentBlocked;
|
||||||
}
|
}
|
||||||
void setFeatureBlocked ();
|
void setAmendmentBlocked ();
|
||||||
void consensusViewChange ();
|
void consensusViewChange ();
|
||||||
int getPreviousProposers ()
|
int getPreviousProposers ()
|
||||||
{
|
{
|
||||||
@@ -469,7 +469,7 @@ private:
|
|||||||
OperatingMode mMode;
|
OperatingMode mMode;
|
||||||
bool mNeedNetworkLedger;
|
bool mNeedNetworkLedger;
|
||||||
bool mProposing, mValidating;
|
bool mProposing, mValidating;
|
||||||
bool mFeatureBlocked;
|
bool m_amendmentBlocked;
|
||||||
boost::posix_time::ptime mConnectTime;
|
boost::posix_time::ptime mConnectTime;
|
||||||
beast::DeadlineTimer m_heartbeatTimer;
|
beast::DeadlineTimer m_heartbeatTimer;
|
||||||
beast::DeadlineTimer m_clusterTimer;
|
beast::DeadlineTimer m_clusterTimer;
|
||||||
@@ -1191,9 +1191,9 @@ Json::Value NetworkOPsImp::getOwnerInfo (Ledger::pointer lpLedger, const RippleA
|
|||||||
// Other
|
// Other
|
||||||
//
|
//
|
||||||
|
|
||||||
void NetworkOPsImp::setFeatureBlocked ()
|
void NetworkOPsImp::setAmendmentBlocked ()
|
||||||
{
|
{
|
||||||
mFeatureBlocked = true;
|
m_amendmentBlocked = true;
|
||||||
setMode (omTRACKING);
|
setMode (omTRACKING);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1728,7 +1728,7 @@ void NetworkOPsImp::setMode (OperatingMode om)
|
|||||||
om = omCONNECTED;
|
om = omCONNECTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((om > omTRACKING) && mFeatureBlocked)
|
if ((om > omTRACKING) && m_amendmentBlocked)
|
||||||
om = omTRACKING;
|
om = omTRACKING;
|
||||||
|
|
||||||
if (mMode == om)
|
if (mMode == om)
|
||||||
@@ -2207,8 +2207,8 @@ Json::Value NetworkOPsImp::getServerInfo (bool human, bool admin)
|
|||||||
|
|
||||||
info["complete_ledgers"] = getApp().getLedgerMaster ().getCompleteLedgers ();
|
info["complete_ledgers"] = getApp().getLedgerMaster ().getCompleteLedgers ();
|
||||||
|
|
||||||
if (mFeatureBlocked)
|
if (m_amendmentBlocked)
|
||||||
info["feature_blocked"] = true;
|
info["amendment_blocked"] = true;
|
||||||
|
|
||||||
size_t fp = mFetchPack.getCacheSize ();
|
size_t fp = mFetchPack.getCacheSize ();
|
||||||
|
|
||||||
|
|||||||
@@ -251,8 +251,8 @@ public:
|
|||||||
virtual void setProposing (bool isProposing, bool isValidating) = 0;
|
virtual void setProposing (bool isProposing, bool isValidating) = 0;
|
||||||
virtual bool isProposing () = 0;
|
virtual bool isProposing () = 0;
|
||||||
virtual bool isValidating () = 0;
|
virtual bool isValidating () = 0;
|
||||||
virtual bool isFeatureBlocked () = 0;
|
virtual bool isAmendmentBlocked () = 0;
|
||||||
virtual void setFeatureBlocked () = 0;
|
virtual void setAmendmentBlocked () = 0;
|
||||||
virtual void consensusViewChange () = 0;
|
virtual void consensusViewChange () = 0;
|
||||||
virtual int getPreviousProposers () = 0;
|
virtual int getPreviousProposers () = 0;
|
||||||
virtual int getPreviousConvergeTime () = 0;
|
virtual int getPreviousConvergeTime () = 0;
|
||||||
|
|||||||
30
src/ripple_app/misc/README.md
Normal file
30
src/ripple_app/misc/README.md
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
|
||||||
|
# Amendment
|
||||||
|
|
||||||
|
An Amendment is a new or proposed change to a ledger rule. Ledger rules affect
|
||||||
|
transaction processing and consensus; peers must use the same set of rules for
|
||||||
|
consensus to succeed, otherwise different instances of rippled will get
|
||||||
|
different results. Amendments can be almost anything but they must be accepted
|
||||||
|
by a network majority through a consensus process before they are utilized. An
|
||||||
|
Amendment must receive at least an 80% approval rate from validating nodes for
|
||||||
|
a period of two weeks before being accepted. The following example outlines the
|
||||||
|
process of an Amendment from its conception to approval and usage.
|
||||||
|
|
||||||
|
* A community member makes proposes to change transaction processing in some
|
||||||
|
way. The proposal is discussed amongst the community and receives its support
|
||||||
|
creating a community or human consensus.
|
||||||
|
|
||||||
|
* Some members contribute their time and work to develop the Amendment.
|
||||||
|
|
||||||
|
* A pull request is created and the new code is folded into a rippled build
|
||||||
|
and made available for use.
|
||||||
|
|
||||||
|
* The consensus process begins with the validating nodes.
|
||||||
|
|
||||||
|
* If the Amendment holds an 80% majority for a two week period, nodes will begin
|
||||||
|
including the transaction to enable it in their initial sets.
|
||||||
|
|
||||||
|
Nodes may veto Amendments they consider undesirable by never announcing their
|
||||||
|
support for those Amendments. Just a few nodes vetoing an Amendment will normally
|
||||||
|
keep it from being accepted. Nodes could also vote yes on an Amendments even
|
||||||
|
before it obtains a super-majority. This might make sense for a critical bug fix.
|
||||||
@@ -83,7 +83,7 @@
|
|||||||
#include "main/LoadManager.h"
|
#include "main/LoadManager.h"
|
||||||
#include "misc/OrderBook.h"
|
#include "misc/OrderBook.h"
|
||||||
#include "shamap/SHAMapSyncFilters.h"
|
#include "shamap/SHAMapSyncFilters.h"
|
||||||
#include "misc/FeatureTable.h"
|
#include "misc/AmendmentTable.h"
|
||||||
#include "misc/FeeVote.h"
|
#include "misc/FeeVote.h"
|
||||||
#include "misc/IHashRouter.h"
|
#include "misc/IHashRouter.h"
|
||||||
#include "peers/ClusterNodeStatus.h"
|
#include "peers/ClusterNodeStatus.h"
|
||||||
|
|||||||
@@ -31,4 +31,4 @@
|
|||||||
#include "misc/HashRouter.cpp"
|
#include "misc/HashRouter.cpp"
|
||||||
#include "misc/Offer.cpp"
|
#include "misc/Offer.cpp"
|
||||||
#include "paths/Pathfinder.cpp"
|
#include "paths/Pathfinder.cpp"
|
||||||
#include "misc/FeaturesImpl.cpp"
|
#include "misc/AmendmentTableImpl.cpp"
|
||||||
|
|||||||
@@ -21,8 +21,8 @@ namespace ripple {
|
|||||||
|
|
||||||
TER ChangeTransactor::doApply ()
|
TER ChangeTransactor::doApply ()
|
||||||
{
|
{
|
||||||
if (mTxn.getTxnType () == ttFEATURE)
|
if (mTxn.getTxnType () == ttAMENDMENT)
|
||||||
return applyFeature ();
|
return applyAmendment ();
|
||||||
|
|
||||||
if (mTxn.getTxnType () == ttFEE)
|
if (mTxn.getTxnType () == ttFEE)
|
||||||
return applyFee ();
|
return applyFee ();
|
||||||
@@ -89,30 +89,32 @@ TER ChangeTransactor::preCheck ()
|
|||||||
return tesSUCCESS;
|
return tesSUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
TER ChangeTransactor::applyFeature ()
|
TER ChangeTransactor::applyAmendment ()
|
||||||
{
|
{
|
||||||
uint256 feature (mTxn.getFieldH256 (sfFeature));
|
uint256 amendment (mTxn.getFieldH256 (sfAmendment));
|
||||||
|
|
||||||
SLE::pointer featureObject (mEngine->entryCache (
|
SLE::pointer amendmentObject (mEngine->entryCache (
|
||||||
ltFEATURES, Ledger::getLedgerFeatureIndex ()));
|
ltAMENDMENTS, Ledger::getLedgerAmendmentIndex ()));
|
||||||
|
|
||||||
if (!featureObject)
|
if (!amendmentObject)
|
||||||
featureObject = mEngine->entryCreate (
|
{
|
||||||
ltFEATURES, Ledger::getLedgerFeatureIndex ());
|
amendmentObject = mEngine->entryCreate(
|
||||||
|
ltAMENDMENTS, Ledger::getLedgerAmendmentIndex());
|
||||||
|
}
|
||||||
|
|
||||||
STVector256 features (featureObject->getFieldV256 (sfFeatures));
|
STVector256 amendments (amendmentObject->getFieldV256 (sfAmendments));
|
||||||
|
|
||||||
if (features.hasValue (feature))
|
if (amendments.hasValue (amendment))
|
||||||
return tefALREADY;
|
return tefALREADY;
|
||||||
|
|
||||||
features.addValue (feature);
|
amendments.addValue (amendment);
|
||||||
featureObject->setFieldV256 (sfFeatures, features);
|
amendmentObject->setFieldV256 (sfAmendments, amendments);
|
||||||
mEngine->entryModify (featureObject);
|
mEngine->entryModify (amendmentObject);
|
||||||
|
|
||||||
getApp().getFeatureTable ().enable (feature);
|
getApp().getAmendmentTable ().enable (amendment);
|
||||||
|
|
||||||
if (!getApp().getFeatureTable ().isSupported (feature))
|
if (!getApp().getAmendmentTable ().isSupported (amendment))
|
||||||
getApp().getOPs ().setFeatureBlocked ();
|
getApp().getOPs ().setAmendmentBlocked ();
|
||||||
|
|
||||||
return tesSUCCESS;
|
return tesSUCCESS;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ public:
|
|||||||
TER preCheck () override;
|
TER preCheck () override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TER applyFeature ();
|
TER applyAmendment ();
|
||||||
TER applyFee ();
|
TER applyFee ();
|
||||||
|
|
||||||
// VFALCO TODO Can this be removed?
|
// VFALCO TODO Can this be removed?
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ std::unique_ptr<Transactor> Transactor::makeTransactor (
|
|||||||
return std::unique_ptr<Transactor> (
|
return std::unique_ptr<Transactor> (
|
||||||
new WalletAddTransactor (txn, params, engine));
|
new WalletAddTransactor (txn, params, engine));
|
||||||
|
|
||||||
case ttFEATURE:
|
case ttAMENDMENT:
|
||||||
case ttFEE:
|
case ttFEE:
|
||||||
return std::unique_ptr<Transactor> (
|
return std::unique_ptr<Transactor> (
|
||||||
new ChangeTransactor (txn, params, engine));
|
new ChangeTransactor (txn, params, engine));
|
||||||
|
|||||||
@@ -108,8 +108,8 @@ LedgerFormats::LedgerFormats ()
|
|||||||
<< SOElement (sfHashes, SOE_REQUIRED)
|
<< SOElement (sfHashes, SOE_REQUIRED)
|
||||||
;
|
;
|
||||||
|
|
||||||
add ("EnabledFeatures", ltFEATURES)
|
add ("EnabledAmendments", ltAMENDMENTS)
|
||||||
<< SOElement (sfFeatures, SOE_REQUIRED)
|
<< SOElement (sfAmendments, SOE_REQUIRED)
|
||||||
;
|
;
|
||||||
|
|
||||||
add ("FeeSettings", ltFEE_SETTINGS)
|
add ("FeeSettings", ltFEE_SETTINGS)
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ enum LedgerEntryType
|
|||||||
|
|
||||||
ltLEDGER_HASHES = 'h',
|
ltLEDGER_HASHES = 'h',
|
||||||
|
|
||||||
ltFEATURES = 'f',
|
ltAMENDMENTS = 'f',
|
||||||
|
|
||||||
ltFEE_SETTINGS = 's',
|
ltFEE_SETTINGS = 's',
|
||||||
};
|
};
|
||||||
@@ -87,7 +87,7 @@ enum LedgerNameSpace
|
|||||||
spaceBookDir = 'B', // Directory of order books.
|
spaceBookDir = 'B', // Directory of order books.
|
||||||
spaceContract = 'c',
|
spaceContract = 'c',
|
||||||
spaceSkipList = 's',
|
spaceSkipList = 's',
|
||||||
spaceFeature = 'f',
|
spaceAmendment = 'f',
|
||||||
spaceFee = 'e',
|
spaceFee = 'e',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -124,7 +124,7 @@ FIELD (AccountTxnID, HASH256, 9)
|
|||||||
FIELD (BookDirectory, HASH256, 16)
|
FIELD (BookDirectory, HASH256, 16)
|
||||||
FIELD (InvoiceID, HASH256, 17)
|
FIELD (InvoiceID, HASH256, 17)
|
||||||
FIELD (Nickname, HASH256, 18)
|
FIELD (Nickname, HASH256, 18)
|
||||||
FIELD (Feature, HASH256, 19)
|
FIELD (Amendment, HASH256, 19)
|
||||||
|
|
||||||
// 160-bit (common)
|
// 160-bit (common)
|
||||||
FIELD (TakerPaysCurrency, HASH160, 1)
|
FIELD (TakerPaysCurrency, HASH160, 1)
|
||||||
@@ -177,7 +177,7 @@ FIELD (Paths, PATHSET, 1)
|
|||||||
// vector of 256-bit
|
// vector of 256-bit
|
||||||
FIELD (Indexes, VECTOR256, 1)
|
FIELD (Indexes, VECTOR256, 1)
|
||||||
FIELD (Hashes, VECTOR256, 2)
|
FIELD (Hashes, VECTOR256, 2)
|
||||||
FIELD (Features, VECTOR256, 3)
|
FIELD (Amendments, VECTOR256, 3)
|
||||||
|
|
||||||
// inner object
|
// inner object
|
||||||
// OBJECT/1 is reserved for end of object
|
// OBJECT/1 is reserved for end of object
|
||||||
|
|||||||
@@ -77,8 +77,8 @@ TxFormats::TxFormats ()
|
|||||||
<< SOElement (sfTarget, SOE_REQUIRED)
|
<< SOElement (sfTarget, SOE_REQUIRED)
|
||||||
;
|
;
|
||||||
|
|
||||||
add ("EnableFeature", ttFEATURE)
|
add ("EnableAmendment", ttAMENDMENT)
|
||||||
<< SOElement (sfFeature, SOE_REQUIRED)
|
<< SOElement (sfAmendment, SOE_REQUIRED)
|
||||||
;
|
;
|
||||||
|
|
||||||
add ("SetFee", ttFEE)
|
add ("SetFee", ttFEE)
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ enum TxType
|
|||||||
|
|
||||||
ttTRUST_SET = 20,
|
ttTRUST_SET = 20,
|
||||||
|
|
||||||
ttFEATURE = 100,
|
ttAMENDMENT = 100,
|
||||||
ttFEE = 101,
|
ttFEE = 101,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -45,11 +45,11 @@ Json::Value RPCHandler::doFeature (Json::Value params, Resource::Charge& loadTyp
|
|||||||
if (!params.isMember ("feature"))
|
if (!params.isMember ("feature"))
|
||||||
{
|
{
|
||||||
Json::Value jvReply = Json::objectValue;
|
Json::Value jvReply = Json::objectValue;
|
||||||
jvReply["features"] = getApp().getFeatureTable ().getJson (0);
|
jvReply["features"] = getApp().getAmendmentTable ().getJson(0);
|
||||||
return jvReply;
|
return jvReply;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint256 uFeature = getApp().getFeatureTable ().get (params["feature"].asString ());
|
uint256 uFeature = getApp().getAmendmentTable ().get(params["feature"].asString());
|
||||||
|
|
||||||
if (uFeature.isZero ())
|
if (uFeature.isZero ())
|
||||||
{
|
{
|
||||||
@@ -60,7 +60,7 @@ Json::Value RPCHandler::doFeature (Json::Value params, Resource::Charge& loadTyp
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!params.isMember ("vote"))
|
if (!params.isMember ("vote"))
|
||||||
return getApp().getFeatureTable ().getJson (uFeature);
|
return getApp().getAmendmentTable ().getJson(uFeature);
|
||||||
|
|
||||||
// WRITEME
|
// WRITEME
|
||||||
return rpcError (rpcNOT_SUPPORTED);
|
return rpcError (rpcNOT_SUPPORTED);
|
||||||
|
|||||||
Reference in New Issue
Block a user