Merge master (0.70.2) into develop (0.80.0-rc2)

This commit is contained in:
Nik Bougalis
2017-09-22 17:16:17 -07:00
736 changed files with 73760 additions and 30382 deletions

View File

@@ -51,6 +51,7 @@ enum error_code_i
rpcHIGH_FEE,
rpcNOT_ENABLED,
rpcNOT_READY,
rpcAMENDMENT_BLOCKED,
// Networking
rpcNO_CLOSED,

View File

@@ -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

View File

@@ -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;

View File

@@ -87,6 +87,12 @@ public:
return size_;
}
bool
empty() const noexcept
{
return size_ == 0;
}
Slice
slice() const noexcept
{

View File

@@ -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;

View File

@@ -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 = {};

View File

@@ -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)
{

View File

@@ -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)
"+"

View File

@@ -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.");

View File

@@ -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

View File

@@ -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");

View File

@@ -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);

View File

@@ -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;
}

View File

@@ -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." } },