mirror of
https://github.com/XRPLF/rippled.git
synced 2025-12-06 17:27:55 +00:00
Merge master (0.70.2) into develop (0.80.0-rc2)
This commit is contained in:
@@ -51,6 +51,7 @@ enum error_code_i
|
||||
rpcHIGH_FEE,
|
||||
rpcNOT_ENABLED,
|
||||
rpcNOT_READY,
|
||||
rpcAMENDMENT_BLOCKED,
|
||||
|
||||
// Networking
|
||||
rpcNO_CLOSED,
|
||||
|
||||
@@ -21,18 +21,127 @@
|
||||
#define RIPPLE_PROTOCOL_FEATURE_H_INCLUDED
|
||||
|
||||
#include <ripple/basics/base_uint.h>
|
||||
#include <boost/container/flat_map.hpp>
|
||||
#include <boost/optional.hpp>
|
||||
#include <array>
|
||||
#include <bitset>
|
||||
#include <string>
|
||||
|
||||
/**
|
||||
* @page Feature How to add new features
|
||||
*
|
||||
* Steps required to add new features to the code:
|
||||
*
|
||||
* 1) add the new feature name to the featureNames array below
|
||||
* 2) add a uint256 declaration for the feature to the bottom of this file
|
||||
* 3) add a uint256 definition for the feature to the corresponding source
|
||||
* file (Feature.cpp)
|
||||
* 4) if the feature is going to be supported in the near future, add its
|
||||
* sha512half value and name (matching exactly the featureName here) to the
|
||||
* supportedAmendments in Amendments.cpp.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace ripple {
|
||||
|
||||
/** Convert feature description to feature id. */
|
||||
/** @{ */
|
||||
uint256
|
||||
feature (std::string const& name);
|
||||
namespace detail {
|
||||
|
||||
class FeatureCollections
|
||||
{
|
||||
static constexpr char const* const featureNames[] =
|
||||
{"MultiSign",
|
||||
"Tickets",
|
||||
"TrustSetAuth",
|
||||
"FeeEscalation",
|
||||
"OwnerPaysFee",
|
||||
"CompareFlowV1V2",
|
||||
"SHAMapV2",
|
||||
"PayChan",
|
||||
"Flow",
|
||||
"CompareTakerFlowCross",
|
||||
"FlowCross",
|
||||
"CryptoConditions",
|
||||
"TickSize",
|
||||
"fix1368",
|
||||
"Escrow",
|
||||
"CryptoConditionsSuite",
|
||||
"fix1373",
|
||||
"EnforceInvariants",
|
||||
"SortedDirectories",
|
||||
"fix1201",
|
||||
"fix1512"};
|
||||
|
||||
std::vector<uint256> features;
|
||||
boost::container::flat_map<uint256, std::size_t> featureToIndex;
|
||||
boost::container::flat_map<std::string, uint256> nameToFeature;
|
||||
|
||||
public:
|
||||
FeatureCollections();
|
||||
|
||||
static constexpr std::size_t numFeatures()
|
||||
{
|
||||
return sizeof (featureNames) / sizeof (featureNames[0]);
|
||||
}
|
||||
|
||||
boost::optional<uint256>
|
||||
getRegisteredFeature(std::string const& name) const;
|
||||
|
||||
std::size_t
|
||||
featureToBitsetIndex(uint256 const& f) const;
|
||||
|
||||
uint256 const&
|
||||
bitsetIndexToFeature(size_t i) const;
|
||||
};
|
||||
|
||||
} // detail
|
||||
|
||||
boost::optional<uint256>
|
||||
getRegisteredFeature (std::string const& name);
|
||||
|
||||
using FeatureBitset = std::bitset<detail::FeatureCollections::numFeatures()>;
|
||||
|
||||
size_t
|
||||
featureToBitsetIndex(uint256 const& f);
|
||||
|
||||
uint256
|
||||
feature (const char* name);
|
||||
/** @} */
|
||||
bitsetIndexToFeature(size_t i);
|
||||
|
||||
template <class F>
|
||||
void
|
||||
foreachFeature(FeatureBitset bs, F&& f)
|
||||
{
|
||||
for (size_t i = 0; i < bs.size(); ++i)
|
||||
if (bs[i])
|
||||
f(bitsetIndexToFeature(i));
|
||||
}
|
||||
|
||||
template <class Col>
|
||||
FeatureBitset
|
||||
makeFeatureBitset(Col&& fs)
|
||||
{
|
||||
FeatureBitset result;
|
||||
for (auto const& f : fs)
|
||||
result.set(featureToBitsetIndex(f));
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class Col>
|
||||
FeatureBitset
|
||||
addFeatures(FeatureBitset bs, Col&& fs)
|
||||
{
|
||||
for (auto const& f : fs)
|
||||
bs.set(featureToBitsetIndex(f));
|
||||
return bs;
|
||||
}
|
||||
|
||||
template <class Col>
|
||||
FeatureBitset
|
||||
removeFeatures(FeatureBitset bs, Col&& fs)
|
||||
{
|
||||
for (auto const& f : fs)
|
||||
bs.reset(featureToBitsetIndex(f));
|
||||
return bs;
|
||||
}
|
||||
|
||||
extern uint256 const featureMultiSign;
|
||||
extern uint256 const featureTickets;
|
||||
@@ -52,6 +161,9 @@ extern uint256 const featureEscrow;
|
||||
extern uint256 const featureCryptoConditionsSuite;
|
||||
extern uint256 const fix1373;
|
||||
extern uint256 const featureEnforceInvariants;
|
||||
extern uint256 const featureSortedDirectories;
|
||||
extern uint256 const fix1201;
|
||||
extern uint256 const fix1512;
|
||||
|
||||
} // ripple
|
||||
|
||||
|
||||
@@ -27,24 +27,30 @@ namespace ripple {
|
||||
|
||||
/** Protocol specific constants, types, and data.
|
||||
|
||||
This information is part of the Ripple protocol. Specifically,
|
||||
it is required for peers to be able to communicate with each other.
|
||||
This information is, implicitly, part of the Ripple
|
||||
protocol.
|
||||
|
||||
@note Changing these will create a hard fork.
|
||||
|
||||
@ingroup protocol
|
||||
@defgroup protocol
|
||||
@note Changing these values without adding code to the
|
||||
server to detect "pre-change" and "post-change"
|
||||
will result in a hard fork.
|
||||
*/
|
||||
struct Protocol
|
||||
{
|
||||
/** Smallest legal byte size of a transaction.
|
||||
*/
|
||||
static int const txMinSizeBytes = 32;
|
||||
/** Smallest legal byte size of a transaction. */
|
||||
std::size_t constexpr txMinSizeBytes = 32;
|
||||
|
||||
/** Largest legal byte size of a transaction.
|
||||
*/
|
||||
static int const txMaxSizeBytes = 1024 * 1024; // 1048576
|
||||
};
|
||||
/** Largest legal byte size of a transaction. */
|
||||
std::size_t constexpr txMaxSizeBytes = 1024 * 1024;
|
||||
|
||||
/** The maximum number of unfunded offers to delete at once */
|
||||
std::size_t constexpr unfundedOfferRemoveLimit = 1000;
|
||||
|
||||
/** The maximum number of metadata entries allowed in one transaction */
|
||||
std::size_t constexpr oversizeMetaDataCap = 5200;
|
||||
|
||||
/** The maximum number of entries per directory page */
|
||||
std::size_t constexpr dirNodeMaxEntries = 32;
|
||||
|
||||
/** The maximum number of pages allowed in a directory */
|
||||
std::uint64_t constexpr dirNodeMaxPages = 262144;
|
||||
|
||||
/** A ledger index. */
|
||||
using LedgerIndex = std::uint32_t;
|
||||
|
||||
@@ -87,6 +87,12 @@ public:
|
||||
return size_;
|
||||
}
|
||||
|
||||
bool
|
||||
empty() const noexcept
|
||||
{
|
||||
return size_ == 0;
|
||||
}
|
||||
|
||||
Slice
|
||||
slice() const noexcept
|
||||
{
|
||||
|
||||
@@ -416,6 +416,7 @@ extern SF_U256 const sfAmendment;
|
||||
extern SF_U256 const sfTicketID;
|
||||
extern SF_U256 const sfDigest;
|
||||
extern SF_U256 const sfPayChannel;
|
||||
extern SF_U256 const sfConsensusHash;
|
||||
|
||||
// currency amount (common)
|
||||
extern SF_Amount const sfAmount;
|
||||
|
||||
@@ -100,26 +100,11 @@ public:
|
||||
// Signs the validation and returns the signing hash
|
||||
uint256 sign (SecretKey const& secretKey);
|
||||
|
||||
// The validation this replaced
|
||||
uint256 const& getPreviousHash ()
|
||||
{
|
||||
return mPreviousHash;
|
||||
}
|
||||
bool isPreviousHash (uint256 const& h) const
|
||||
{
|
||||
return mPreviousHash == h;
|
||||
}
|
||||
void setPreviousHash (uint256 const& h)
|
||||
{
|
||||
mPreviousHash = h;
|
||||
}
|
||||
|
||||
private:
|
||||
static SOTemplate const& getFormat ();
|
||||
|
||||
void setNode ();
|
||||
|
||||
uint256 mPreviousHash;
|
||||
NodeID mNodeID;
|
||||
bool mTrusted = false;
|
||||
NetClock::time_point mSeen = {};
|
||||
|
||||
@@ -144,6 +144,18 @@ public:
|
||||
return mValue;
|
||||
}
|
||||
|
||||
std::vector<uint256>::iterator
|
||||
insert(std::vector<uint256>::const_iterator pos, uint256 const& value)
|
||||
{
|
||||
return mValue.insert(pos, value);
|
||||
}
|
||||
|
||||
std::vector<uint256>::iterator
|
||||
insert(std::vector<uint256>::const_iterator pos, uint256&& value)
|
||||
{
|
||||
return mValue.insert(pos, std::move(value));
|
||||
}
|
||||
|
||||
void
|
||||
push_back (uint256 const& v)
|
||||
{
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
#include <BeastConfig.h>
|
||||
#include <ripple/basics/contract.h>
|
||||
#include <ripple/beast/core/PlatformConfig.h>
|
||||
#include <ripple/beast/core/SemanticVersion.h>
|
||||
#include <ripple/protocol/BuildInfo.h>
|
||||
|
||||
@@ -33,7 +34,7 @@ char const* const versionString =
|
||||
// The build version number. You must edit this for each release
|
||||
// and follow the format described at http://semver.org/
|
||||
//
|
||||
"0.70.2"
|
||||
"0.80.0-rc2"
|
||||
|
||||
#if defined(DEBUG) || defined(SANITIZER)
|
||||
"+"
|
||||
|
||||
@@ -53,6 +53,7 @@ public:
|
||||
add (rpcACT_EXISTS, "actExists", "Account already exists.");
|
||||
add (rpcACT_MALFORMED, "actMalformed", "Account malformed.");
|
||||
add (rpcACT_NOT_FOUND, "actNotFound", "Account not found.");
|
||||
add (rpcAMENDMENT_BLOCKED, "amendmentBlocked", "Amendment blocked, need upgrade.");
|
||||
add (rpcATX_DEPRECATED, "deprecated", "Use the new API or specify a ledger range.");
|
||||
add (rpcBAD_BLOB, "badBlob", "Blob must be a non-empty hex string.");
|
||||
add (rpcBAD_FEATURE, "badFeature", "Feature unknown or invalid.");
|
||||
|
||||
@@ -18,50 +18,103 @@
|
||||
//==============================================================================
|
||||
|
||||
#include <BeastConfig.h>
|
||||
#include <ripple/protocol/digest.h>
|
||||
#include <ripple/protocol/Feature.h>
|
||||
#include <ripple/basics/contract.h>
|
||||
#include <ripple/protocol/digest.h>
|
||||
|
||||
#include <cstring>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
static
|
||||
uint256
|
||||
feature (char const* s, std::size_t n)
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
constexpr char const* const detail::FeatureCollections::featureNames[];
|
||||
|
||||
detail::FeatureCollections::FeatureCollections()
|
||||
{
|
||||
sha512_half_hasher h;
|
||||
h(s, n);
|
||||
return static_cast<uint256>(h);
|
||||
features.reserve(numFeatures());
|
||||
featureToIndex.reserve(numFeatures());
|
||||
nameToFeature.reserve(numFeatures());
|
||||
|
||||
for (std::size_t i = 0; i < numFeatures(); ++i)
|
||||
{
|
||||
auto const name = featureNames[i];
|
||||
sha512_half_hasher h;
|
||||
h (name, std::strlen (name));
|
||||
auto const f = static_cast<uint256>(h);
|
||||
|
||||
features.push_back(f);
|
||||
featureToIndex[f] = i;
|
||||
nameToFeature[name] = f;
|
||||
}
|
||||
}
|
||||
|
||||
uint256
|
||||
feature (std::string const& name)
|
||||
boost::optional<uint256>
|
||||
detail::FeatureCollections::getRegisteredFeature(std::string const& name) const
|
||||
{
|
||||
return feature(name.c_str(), name.size());
|
||||
auto const i = nameToFeature.find(name);
|
||||
if (i == nameToFeature.end())
|
||||
return boost::none;
|
||||
return i->second;
|
||||
}
|
||||
|
||||
uint256
|
||||
feature (const char* name)
|
||||
size_t
|
||||
detail::FeatureCollections::featureToBitsetIndex(uint256 const& f) const
|
||||
{
|
||||
return feature(name, std::strlen(name));
|
||||
auto const i = featureToIndex.find(f);
|
||||
if (i == featureToIndex.end())
|
||||
LogicError("Invalid Feature ID");
|
||||
return i->second;
|
||||
}
|
||||
|
||||
uint256 const featureMultiSign = feature("MultiSign");
|
||||
uint256 const featureTickets = feature("Tickets");
|
||||
uint256 const featureTrustSetAuth = feature("TrustSetAuth");
|
||||
uint256 const featureFeeEscalation = feature("FeeEscalation");
|
||||
uint256 const featureOwnerPaysFee = feature("OwnerPaysFee");
|
||||
uint256 const featureCompareFlowV1V2 = feature("CompareFlowV1V2");
|
||||
uint256 const featureSHAMapV2 = feature("SHAMapV2");
|
||||
uint256 const featurePayChan = feature("PayChan");
|
||||
uint256 const featureFlow = feature("Flow");
|
||||
uint256 const featureCompareTakerFlowCross = feature("CompareTakerFlowCross");
|
||||
uint256 const featureFlowCross = feature("FlowCross");
|
||||
uint256 const featureCryptoConditions = feature("CryptoConditions");
|
||||
uint256 const featureTickSize = feature("TickSize");
|
||||
uint256 const fix1368 = feature("fix1368");
|
||||
uint256 const featureEscrow = feature("Escrow");
|
||||
uint256 const featureCryptoConditionsSuite = feature("CryptoConditionsSuite");
|
||||
uint256 const fix1373 = feature("fix1373");
|
||||
uint256 const featureEnforceInvariants = feature("EnforceInvariants");
|
||||
uint256 const&
|
||||
detail::FeatureCollections::bitsetIndexToFeature(size_t i) const
|
||||
{
|
||||
if (i >= features.size())
|
||||
LogicError("Invalid FeatureBitset index");
|
||||
return features[i];
|
||||
}
|
||||
|
||||
static detail::FeatureCollections const featureCollections;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
boost::optional<uint256>
|
||||
getRegisteredFeature (std::string const& name)
|
||||
{
|
||||
return featureCollections.getRegisteredFeature(name);
|
||||
}
|
||||
|
||||
size_t featureToBitsetIndex(uint256 const& f)
|
||||
{
|
||||
return featureCollections.featureToBitsetIndex(f);
|
||||
}
|
||||
|
||||
uint256 bitsetIndexToFeature(size_t i)
|
||||
{
|
||||
return featureCollections.bitsetIndexToFeature(i);
|
||||
}
|
||||
|
||||
uint256 const featureMultiSign = *getRegisteredFeature("MultiSign");
|
||||
uint256 const featureTickets = *getRegisteredFeature("Tickets");
|
||||
uint256 const featureTrustSetAuth = *getRegisteredFeature("TrustSetAuth");
|
||||
uint256 const featureFeeEscalation = *getRegisteredFeature("FeeEscalation");
|
||||
uint256 const featureOwnerPaysFee = *getRegisteredFeature("OwnerPaysFee");
|
||||
uint256 const featureCompareFlowV1V2 = *getRegisteredFeature("CompareFlowV1V2");
|
||||
uint256 const featureSHAMapV2 = *getRegisteredFeature("SHAMapV2");
|
||||
uint256 const featurePayChan = *getRegisteredFeature("PayChan");
|
||||
uint256 const featureFlow = *getRegisteredFeature("Flow");
|
||||
uint256 const featureCompareTakerFlowCross = *getRegisteredFeature("CompareTakerFlowCross");
|
||||
uint256 const featureFlowCross = *getRegisteredFeature("FlowCross");
|
||||
uint256 const featureCryptoConditions = *getRegisteredFeature("CryptoConditions");
|
||||
uint256 const featureTickSize = *getRegisteredFeature("TickSize");
|
||||
uint256 const fix1368 = *getRegisteredFeature("fix1368");
|
||||
uint256 const featureEscrow = *getRegisteredFeature("Escrow");
|
||||
uint256 const featureCryptoConditionsSuite = *getRegisteredFeature("CryptoConditionsSuite");
|
||||
uint256 const fix1373 = *getRegisteredFeature("fix1373");
|
||||
uint256 const featureEnforceInvariants = *getRegisteredFeature("EnforceInvariants");
|
||||
uint256 const featureSortedDirectories = *getRegisteredFeature("SortedDirectories");
|
||||
uint256 const fix1201 = *getRegisteredFeature("fix1201");
|
||||
uint256 const fix1512 = *getRegisteredFeature("fix1512");
|
||||
|
||||
} // ripple
|
||||
|
||||
@@ -169,6 +169,7 @@ SF_U256 const sfAmendment = make::one<SF_U256::type>(&sfAmendment, STI_H
|
||||
SF_U256 const sfTicketID = make::one<SF_U256::type>(&sfTicketID, STI_HASH256, 20, "TicketID");
|
||||
SF_U256 const sfDigest = make::one<SF_U256::type>(&sfDigest, STI_HASH256, 21, "Digest");
|
||||
SF_U256 const sfPayChannel = make::one<SF_U256::type>(&sfPayChannel, STI_HASH256, 22, "Channel");
|
||||
SF_U256 const sfConsensusHash = make::one<SF_U256::type>(&sfConsensusHash, STI_HASH256, 23, "ConsensusHash");
|
||||
|
||||
// currency amount (common)
|
||||
SF_Amount const sfAmount = make::one<SF_Amount::type>(&sfAmount, STI_AMOUNT, 1, "Amount");
|
||||
|
||||
@@ -72,7 +72,7 @@ STTx::STTx (SerialIter& sit)
|
||||
{
|
||||
int length = sit.getBytesLeft ();
|
||||
|
||||
if ((length < Protocol::txMinSizeBytes) || (length > Protocol::txMaxSizeBytes))
|
||||
if ((length < txMinSizeBytes) || (length > txMaxSizeBytes))
|
||||
Throw<std::runtime_error> ("Transaction length invalid");
|
||||
|
||||
set (sit);
|
||||
|
||||
@@ -161,10 +161,11 @@ SOTemplate const& STValidation::getFormat ()
|
||||
format.push_back (SOElement (sfSigningTime, SOE_REQUIRED));
|
||||
format.push_back (SOElement (sfSigningPubKey, SOE_REQUIRED));
|
||||
format.push_back (SOElement (sfSignature, SOE_OPTIONAL));
|
||||
format.push_back (SOElement (sfConsensusHash, SOE_OPTIONAL));
|
||||
}
|
||||
};
|
||||
|
||||
static FormatHolder holder;
|
||||
static const FormatHolder holder;
|
||||
|
||||
return holder.format;
|
||||
}
|
||||
|
||||
@@ -126,7 +126,7 @@ transResults()
|
||||
{ temBAD_SIGNATURE, { "temBAD_SIGNATURE", "Malformed: Bad signature." } },
|
||||
{ temBAD_SIGNER, { "temBAD_SIGNER", "Malformed: No signer may duplicate account or other signers." } },
|
||||
{ temBAD_SRC_ACCOUNT, { "temBAD_SRC_ACCOUNT", "Malformed: Bad source account." } },
|
||||
{ temBAD_TRANSFER_RATE, { "temBAD_TRANSFER_RATE", "Malformed: Transfer rate must be >= 1.0" } },
|
||||
{ temBAD_TRANSFER_RATE, { "temBAD_TRANSFER_RATE", "Malformed: Transfer rate must be >= 1.0 and <= 2.0" } },
|
||||
{ temBAD_WEIGHT, { "temBAD_WEIGHT", "Malformed: Weight must be a positive value." } },
|
||||
{ temDST_IS_SRC, { "temDST_IS_SRC", "Destination may not be source." } },
|
||||
{ temDST_NEEDED, { "temDST_NEEDED", "Destination not specified." } },
|
||||
|
||||
Reference in New Issue
Block a user