mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-21 11:35:53 +00:00
fixInnerObjTemplate2 amendment (#5047)
* fixInnerObjTemplate2 amendment: Apply inner object templates to all remaining (non-AMM) inner objects. Adds a unit test for applying the template to sfMajorities. Other remaining inner objects showed no problems having templates applied. * Move CMake directory * Rearrange sources * Rewrite includes * Recompute loops --------- Co-authored-by: Pretty Printer <cpp@ripple.com>
This commit is contained in:
@@ -80,7 +80,7 @@ namespace detail {
|
|||||||
// Feature.cpp. Because it's only used to reserve storage, and determine how
|
// Feature.cpp. Because it's only used to reserve storage, and determine how
|
||||||
// large to make the FeatureBitset, it MAY be larger. It MUST NOT be less than
|
// large to make the FeatureBitset, it MAY be larger. It MUST NOT be less than
|
||||||
// the actual number of amendments. A LogicError on startup will verify this.
|
// the actual number of amendments. A LogicError on startup will verify this.
|
||||||
static constexpr std::size_t numFeatures = 76;
|
static constexpr std::size_t numFeatures = 77;
|
||||||
|
|
||||||
/** Amendments that this server supports and the default voting behavior.
|
/** Amendments that this server supports and the default voting behavior.
|
||||||
Whether they are enabled depends on the Rules defined in the validated
|
Whether they are enabled depends on the Rules defined in the validated
|
||||||
@@ -369,6 +369,7 @@ extern uint256 const fixAMMv1_1;
|
|||||||
extern uint256 const featureNFTokenMintOffer;
|
extern uint256 const featureNFTokenMintOffer;
|
||||||
extern uint256 const fixReducedOffersV2;
|
extern uint256 const fixReducedOffersV2;
|
||||||
extern uint256 const fixEnforceNFTokenTrustline;
|
extern uint256 const fixEnforceNFTokenTrustline;
|
||||||
|
extern uint256 const fixInnerObjTemplate2;
|
||||||
|
|
||||||
} // namespace ripple
|
} // namespace ripple
|
||||||
|
|
||||||
|
|||||||
@@ -44,7 +44,6 @@
|
|||||||
namespace ripple {
|
namespace ripple {
|
||||||
|
|
||||||
class STArray;
|
class STArray;
|
||||||
class Rules;
|
|
||||||
|
|
||||||
inline void
|
inline void
|
||||||
throwFieldNotFound(SField const& field)
|
throwFieldNotFound(SField const& field)
|
||||||
@@ -105,7 +104,7 @@ public:
|
|||||||
explicit STObject(SField const& name);
|
explicit STObject(SField const& name);
|
||||||
|
|
||||||
static STObject
|
static STObject
|
||||||
makeInnerObject(SField const& name, Rules const& rules);
|
makeInnerObject(SField const& name);
|
||||||
|
|
||||||
iterator
|
iterator
|
||||||
begin() const;
|
begin() const;
|
||||||
|
|||||||
@@ -496,6 +496,7 @@ REGISTER_FIX (fixAMMv1_1, Supported::yes, VoteBehavior::De
|
|||||||
REGISTER_FEATURE(NFTokenMintOffer, Supported::yes, VoteBehavior::DefaultNo);
|
REGISTER_FEATURE(NFTokenMintOffer, Supported::yes, VoteBehavior::DefaultNo);
|
||||||
REGISTER_FIX (fixReducedOffersV2, Supported::yes, VoteBehavior::DefaultNo);
|
REGISTER_FIX (fixReducedOffersV2, Supported::yes, VoteBehavior::DefaultNo);
|
||||||
REGISTER_FIX (fixEnforceNFTokenTrustline, Supported::yes, VoteBehavior::DefaultNo);
|
REGISTER_FIX (fixEnforceNFTokenTrustline, Supported::yes, VoteBehavior::DefaultNo);
|
||||||
|
REGISTER_FIX (fixInnerObjTemplate2, Supported::yes, VoteBehavior::DefaultNo);
|
||||||
|
|
||||||
// The following amendments are obsolete, but must remain supported
|
// The following amendments are obsolete, but must remain supported
|
||||||
// because they could potentially get enabled.
|
// because they could potentially get enabled.
|
||||||
|
|||||||
@@ -61,10 +61,19 @@ STObject::STObject(SerialIter& sit, SField const& name, int depth) noexcept(
|
|||||||
}
|
}
|
||||||
|
|
||||||
STObject
|
STObject
|
||||||
STObject::makeInnerObject(SField const& name, Rules const& rules)
|
STObject::makeInnerObject(SField const& name)
|
||||||
{
|
{
|
||||||
STObject obj{name};
|
STObject obj{name};
|
||||||
if (rules.enabled(fixInnerObjTemplate))
|
|
||||||
|
// The if is complicated because inner object templates were added in
|
||||||
|
// two phases:
|
||||||
|
// 1. If there are no available Rules, then always apply the template.
|
||||||
|
// 2. fixInnerObjTemplate added templates to two AMM inner objects.
|
||||||
|
// 3. fixInnerObjTemplate2 added templates to all remaining inner objects.
|
||||||
|
std::optional<Rules> const& rules = getCurrentTransactionRules();
|
||||||
|
bool const isAMMObj = name == sfAuctionSlot || name == sfVoteEntry;
|
||||||
|
if (!rules || (rules->enabled(fixInnerObjTemplate) && isAMMObj) ||
|
||||||
|
(rules->enabled(fixInnerObjTemplate2) && !isAMMObj))
|
||||||
{
|
{
|
||||||
if (SOTemplate const* elements =
|
if (SOTemplate const* elements =
|
||||||
InnerObjectFormats::getInstance().findSOTemplateBySField(name))
|
InnerObjectFormats::getInstance().findSOTemplateBySField(name))
|
||||||
|
|||||||
@@ -203,7 +203,8 @@ AttestationClaim::AttestationClaim(Json::Value const& v)
|
|||||||
STObject
|
STObject
|
||||||
AttestationClaim::toSTObject() const
|
AttestationClaim::toSTObject() const
|
||||||
{
|
{
|
||||||
STObject o{sfXChainClaimAttestationCollectionElement};
|
STObject o =
|
||||||
|
STObject::makeInnerObject(sfXChainClaimAttestationCollectionElement);
|
||||||
addHelper(o);
|
addHelper(o);
|
||||||
o[sfXChainClaimID] = claimID;
|
o[sfXChainClaimID] = claimID;
|
||||||
if (dst)
|
if (dst)
|
||||||
@@ -345,7 +346,8 @@ AttestationCreateAccount::AttestationCreateAccount(
|
|||||||
STObject
|
STObject
|
||||||
AttestationCreateAccount::toSTObject() const
|
AttestationCreateAccount::toSTObject() const
|
||||||
{
|
{
|
||||||
STObject o{sfXChainCreateAccountAttestationCollectionElement};
|
STObject o = STObject::makeInnerObject(
|
||||||
|
sfXChainCreateAccountAttestationCollectionElement);
|
||||||
addHelper(o);
|
addHelper(o);
|
||||||
|
|
||||||
o[sfXChainAccountCreateCount] = createCount;
|
o[sfXChainAccountCreateCount] = createCount;
|
||||||
@@ -497,7 +499,7 @@ XChainClaimAttestation::XChainClaimAttestation(
|
|||||||
STObject
|
STObject
|
||||||
XChainClaimAttestation::toSTObject() const
|
XChainClaimAttestation::toSTObject() const
|
||||||
{
|
{
|
||||||
STObject o{sfXChainClaimProofSig};
|
STObject o = STObject::makeInnerObject(sfXChainClaimProofSig);
|
||||||
o[sfAttestationSignerAccount] =
|
o[sfAttestationSignerAccount] =
|
||||||
STAccount{sfAttestationSignerAccount, keyAccount};
|
STAccount{sfAttestationSignerAccount, keyAccount};
|
||||||
o[sfPublicKey] = publicKey;
|
o[sfPublicKey] = publicKey;
|
||||||
@@ -609,7 +611,7 @@ XChainCreateAccountAttestation::XChainCreateAccountAttestation(
|
|||||||
STObject
|
STObject
|
||||||
XChainCreateAccountAttestation::toSTObject() const
|
XChainCreateAccountAttestation::toSTObject() const
|
||||||
{
|
{
|
||||||
STObject o{sfXChainCreateAccountProofSig};
|
STObject o = STObject::makeInnerObject(sfXChainCreateAccountProofSig);
|
||||||
|
|
||||||
o[sfAttestationSignerAccount] =
|
o[sfAttestationSignerAccount] =
|
||||||
STAccount{sfAttestationSignerAccount, keyAccount};
|
STAccount{sfAttestationSignerAccount, keyAccount};
|
||||||
|
|||||||
@@ -300,8 +300,14 @@ public:
|
|||||||
{
|
{
|
||||||
// Put a bunch of different LedgerEntryTypes into a ledger
|
// Put a bunch of different LedgerEntryTypes into a ledger
|
||||||
using namespace test::jtx;
|
using namespace test::jtx;
|
||||||
|
|
||||||
|
// Make sure fixInnerObjTemplate2 doesn't break amendments.
|
||||||
|
for (FeatureBitset const& features :
|
||||||
|
{supported_amendments() - fixInnerObjTemplate2,
|
||||||
|
supported_amendments() | fixInnerObjTemplate2})
|
||||||
|
{
|
||||||
using namespace std::chrono;
|
using namespace std::chrono;
|
||||||
Env env{*this, envconfig(validator, "")};
|
Env env{*this, envconfig(validator, ""), features};
|
||||||
|
|
||||||
Account const gw{"gateway"};
|
Account const gw{"gateway"};
|
||||||
auto const USD = gw["USD"];
|
auto const USD = gw["USD"];
|
||||||
@@ -352,8 +358,11 @@ public:
|
|||||||
if (!majorities.empty())
|
if (!majorities.empty())
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
env(signers(
|
env(signers(
|
||||||
Account{"bob0"}, 1, {{Account{"bob1"}, 1}, {Account{"bob2"}, 1}}));
|
Account{"bob0"},
|
||||||
|
1,
|
||||||
|
{{Account{"bob1"}, 1}, {Account{"bob2"}, 1}}));
|
||||||
env(ticket::create(env.master, 1));
|
env(ticket::create(env.master, 1));
|
||||||
|
|
||||||
{
|
{
|
||||||
@@ -363,7 +372,8 @@ public:
|
|||||||
jv[jss::Account] = Account{"bob5"}.human();
|
jv[jss::Account] = Account{"bob5"}.human();
|
||||||
jv[jss::Destination] = Account{"bob6"}.human();
|
jv[jss::Destination] = Account{"bob6"}.human();
|
||||||
jv[jss::Amount] = XRP(50).value().getJson(JsonOptions::none);
|
jv[jss::Amount] = XRP(50).value().getJson(JsonOptions::none);
|
||||||
jv[sfFinishAfter.fieldName] = NetClock::time_point{env.now() + 10s}
|
jv[sfFinishAfter.fieldName] =
|
||||||
|
NetClock::time_point{env.now() + 10s}
|
||||||
.time_since_epoch()
|
.time_since_epoch()
|
||||||
.count();
|
.count();
|
||||||
env(jv);
|
env(jv);
|
||||||
@@ -377,8 +387,10 @@ public:
|
|||||||
jv[jss::Destination] = Account{"bob7"}.human();
|
jv[jss::Destination] = Account{"bob7"}.human();
|
||||||
jv[jss::Amount] = XRP(100).value().getJson(JsonOptions::none);
|
jv[jss::Amount] = XRP(100).value().getJson(JsonOptions::none);
|
||||||
jv[jss::SettleDelay] = NetClock::duration{10s}.count();
|
jv[jss::SettleDelay] = NetClock::duration{10s}.count();
|
||||||
jv[sfPublicKey.fieldName] = strHex(Account{"bob6"}.pk().slice());
|
jv[sfPublicKey.fieldName] =
|
||||||
jv[sfCancelAfter.fieldName] = NetClock::time_point{env.now() + 300s}
|
strHex(Account{"bob6"}.pk().slice());
|
||||||
|
jv[sfCancelAfter.fieldName] =
|
||||||
|
NetClock::time_point{env.now() + 300s}
|
||||||
.time_since_epoch()
|
.time_since_epoch()
|
||||||
.count();
|
.count();
|
||||||
env(jv);
|
env(jv);
|
||||||
@@ -497,6 +509,7 @@ public:
|
|||||||
BEAST_EXPECT(jrr["error_message"] == "Invalid field 'type'.");
|
BEAST_EXPECT(jrr["error_message"] == "Invalid field 'type'.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
run() override
|
run() override
|
||||||
|
|||||||
@@ -793,7 +793,7 @@ Ledger::updateNegativeUNL()
|
|||||||
|
|
||||||
if (hasToDisable)
|
if (hasToDisable)
|
||||||
{
|
{
|
||||||
newNUnl.emplace_back(sfDisabledValidator);
|
newNUnl.push_back(STObject::makeInnerObject(sfDisabledValidator));
|
||||||
newNUnl.back().setFieldVL(
|
newNUnl.back().setFieldVL(
|
||||||
sfPublicKey, sle->getFieldVL(sfValidatorToDisable));
|
sfPublicKey, sle->getFieldVL(sfValidatorToDisable));
|
||||||
newNUnl.back().setFieldU32(sfFirstLedgerSequence, seq());
|
newNUnl.back().setFieldU32(sfFirstLedgerSequence, seq());
|
||||||
|
|||||||
@@ -312,7 +312,7 @@ initializeFeeAuctionVote(
|
|||||||
auto const& rules = view.rules();
|
auto const& rules = view.rules();
|
||||||
// AMM creator gets the voting slot.
|
// AMM creator gets the voting slot.
|
||||||
STArray voteSlots;
|
STArray voteSlots;
|
||||||
STObject voteEntry = STObject::makeInnerObject(sfVoteEntry, rules);
|
STObject voteEntry = STObject::makeInnerObject(sfVoteEntry);
|
||||||
if (tfee != 0)
|
if (tfee != 0)
|
||||||
voteEntry.setFieldU16(sfTradingFee, tfee);
|
voteEntry.setFieldU16(sfTradingFee, tfee);
|
||||||
voteEntry.setFieldU32(sfVoteWeight, VOTE_WEIGHT_SCALE_FACTOR);
|
voteEntry.setFieldU32(sfVoteWeight, VOTE_WEIGHT_SCALE_FACTOR);
|
||||||
@@ -325,7 +325,7 @@ initializeFeeAuctionVote(
|
|||||||
if (rules.enabled(fixInnerObjTemplate) &&
|
if (rules.enabled(fixInnerObjTemplate) &&
|
||||||
!ammSle->isFieldPresent(sfAuctionSlot))
|
!ammSle->isFieldPresent(sfAuctionSlot))
|
||||||
{
|
{
|
||||||
STObject auctionSlot = STObject::makeInnerObject(sfAuctionSlot, rules);
|
STObject auctionSlot = STObject::makeInnerObject(sfAuctionSlot);
|
||||||
ammSle->set(std::move(auctionSlot));
|
ammSle->set(std::move(auctionSlot));
|
||||||
}
|
}
|
||||||
STObject& auctionSlot = ammSle->peekFieldObject(sfAuctionSlot);
|
STObject& auctionSlot = ammSle->peekFieldObject(sfAuctionSlot);
|
||||||
|
|||||||
@@ -104,7 +104,7 @@ applyVote(
|
|||||||
Number den{0};
|
Number den{0};
|
||||||
// Account already has vote entry
|
// Account already has vote entry
|
||||||
bool foundAccount = false;
|
bool foundAccount = false;
|
||||||
auto const& rules = ctx_.view().rules();
|
|
||||||
// Iterate over the current vote entries and update each entry
|
// Iterate over the current vote entries and update each entry
|
||||||
// per current total tokens balance and each LP tokens balance.
|
// per current total tokens balance and each LP tokens balance.
|
||||||
// Find the entry with the least tokens and whether the account
|
// Find the entry with the least tokens and whether the account
|
||||||
@@ -120,7 +120,7 @@ applyVote(
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
auto feeVal = entry[sfTradingFee];
|
auto feeVal = entry[sfTradingFee];
|
||||||
STObject newEntry = STObject::makeInnerObject(sfVoteEntry, rules);
|
STObject newEntry = STObject::makeInnerObject(sfVoteEntry);
|
||||||
// The account already has the vote entry.
|
// The account already has the vote entry.
|
||||||
if (account == account_)
|
if (account == account_)
|
||||||
{
|
{
|
||||||
@@ -159,7 +159,7 @@ applyVote(
|
|||||||
{
|
{
|
||||||
auto update = [&](std::optional<std::uint8_t> const& minPos =
|
auto update = [&](std::optional<std::uint8_t> const& minPos =
|
||||||
std::nullopt) {
|
std::nullopt) {
|
||||||
STObject newEntry = STObject::makeInnerObject(sfVoteEntry, rules);
|
STObject newEntry = STObject::makeInnerObject(sfVoteEntry);
|
||||||
if (feeNew != 0)
|
if (feeNew != 0)
|
||||||
newEntry.setFieldU16(sfTradingFee, feeNew);
|
newEntry.setFieldU16(sfTradingFee, feeNew);
|
||||||
newEntry.setFieldU32(
|
newEntry.setFieldU32(
|
||||||
|
|||||||
@@ -300,11 +300,11 @@ Change::applyAmendment()
|
|||||||
if (gotMajority)
|
if (gotMajority)
|
||||||
{
|
{
|
||||||
// This amendment now has a majority
|
// This amendment now has a majority
|
||||||
newMajorities.push_back(STObject(sfMajority));
|
newMajorities.push_back(STObject::makeInnerObject(sfMajority));
|
||||||
auto& entry = newMajorities.back();
|
auto& entry = newMajorities.back();
|
||||||
entry.emplace_back(STUInt256(sfAmendment, amendment));
|
entry[sfAmendment] = amendment;
|
||||||
entry.emplace_back(STUInt32(
|
entry[sfCloseTime] =
|
||||||
sfCloseTime, view().parentCloseTime().time_since_epoch().count()));
|
view().parentCloseTime().time_since_epoch().count();
|
||||||
|
|
||||||
if (!ctx_.app.getAmendmentTable().isSupported(amendment))
|
if (!ctx_.app.getAmendmentTable().isSupported(amendment))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -416,11 +416,11 @@ SetSignerList::writeSignersToSLE(
|
|||||||
STArray toLedger(signers_.size());
|
STArray toLedger(signers_.size());
|
||||||
for (auto const& entry : signers_)
|
for (auto const& entry : signers_)
|
||||||
{
|
{
|
||||||
toLedger.emplace_back(sfSignerEntry);
|
toLedger.push_back(STObject::makeInnerObject(sfSignerEntry));
|
||||||
STObject& obj = toLedger.back();
|
STObject& obj = toLedger.back();
|
||||||
obj.reserve(2);
|
obj.reserve(2);
|
||||||
obj.setAccountID(sfAccount, entry.account);
|
obj[sfAccount] = entry.account;
|
||||||
obj.setFieldU16(sfSignerWeight, entry.weight);
|
obj[sfSignerWeight] = entry.weight;
|
||||||
|
|
||||||
// This is a defensive check to make absolutely sure we will never write
|
// This is a defensive check to make absolutely sure we will never write
|
||||||
// a tag into the ledger while featureExpandedSignerList is not enabled
|
// a tag into the ledger while featureExpandedSignerList is not enabled
|
||||||
|
|||||||
@@ -1051,7 +1051,7 @@ transactionSignFor(
|
|||||||
auto& sttx = preprocResult.second;
|
auto& sttx = preprocResult.second;
|
||||||
{
|
{
|
||||||
// Make the signer object that we'll inject.
|
// Make the signer object that we'll inject.
|
||||||
STObject signer(sfSigner);
|
STObject signer = STObject::makeInnerObject(sfSigner);
|
||||||
signer[sfAccount] = *signerAccountID;
|
signer[sfAccount] = *signerAccountID;
|
||||||
signer.setFieldVL(sfTxnSignature, signForParams.getSignature());
|
signer.setFieldVL(sfTxnSignature, signForParams.getSignature());
|
||||||
signer.setFieldVL(
|
signer.setFieldVL(
|
||||||
|
|||||||
Reference in New Issue
Block a user