Skip to content

Commit 510314d

Browse files
authored
fix(amendment): Add missing fields for keylets to ledger objects (#5646)
This change adds a fix amendment (`fixIncludeKeyletFields`) that adds: * `sfSequence` to `Escrow` and `PayChannel` * `sfOwner` to `SignerList` * `sfOracleDocumentID` to `Oracle` This ensures that all ledger entries hold all the information needed to determine their keylet.
1 parent 37b9518 commit 510314d

File tree

12 files changed

+144
-51
lines changed

12 files changed

+144
-51
lines changed

include/xrpl/protocol/Indexes.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,9 +287,11 @@ delegate(AccountID const& account, AccountID const& authorizedAccount) noexcept;
287287
Keylet
288288
bridge(STXChainBridge const& bridge, STXChainBridge::ChainType chainType);
289289

290+
// `seq` is stored as `sfXChainClaimID` in the object
290291
Keylet
291292
xChainClaimID(STXChainBridge const& bridge, std::uint64_t seq);
292293

294+
// `seq` is stored as `sfXChainAccountCreateCount` in the object
293295
Keylet
294296
xChainCreateAccountClaimID(STXChainBridge const& bridge, std::uint64_t seq);
295297

include/xrpl/protocol/detail/features.macro

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
// If you add an amendment here, then do not forget to increment `numFeatures`
3333
// in include/xrpl/protocol/Feature.h.
3434

35+
XRPL_FIX (IncludeKeyletFields, Supported::no, VoteBehavior::DefaultNo)
3536
XRPL_FEATURE(DynamicMPT, Supported::no, VoteBehavior::DefaultNo)
3637
XRPL_FIX (TokenEscrowV1, Supported::yes, VoteBehavior::DefaultNo)
3738
XRPL_FIX (DelegateV1_1, Supported::no, VoteBehavior::DefaultNo)

include/xrpl/protocol/detail/ledger_entries.macro

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ LEDGER_ENTRY(ltNFTOKEN_PAGE, 0x0050, NFTokenPage, nft_page, ({
120120
// All fields are soeREQUIRED because there is always a SignerEntries.
121121
// If there are no SignerEntries the node is deleted.
122122
LEDGER_ENTRY(ltSIGNER_LIST, 0x0053, SignerList, signer_list, ({
123+
{sfOwner, soeOPTIONAL},
123124
{sfOwnerNode, soeREQUIRED},
124125
{sfSignerQuorum, soeREQUIRED},
125126
{sfSignerEntries, soeREQUIRED},
@@ -188,7 +189,7 @@ LEDGER_ENTRY(ltDIR_NODE, 0x0064, DirectoryNode, directory, ({
188189
{sfNFTokenID, soeOPTIONAL},
189190
{sfPreviousTxnID, soeOPTIONAL},
190191
{sfPreviousTxnLgrSeq, soeOPTIONAL},
191-
{sfDomainID, soeOPTIONAL}
192+
{sfDomainID, soeOPTIONAL} // order book directories
192193
}))
193194

194195
/** The ledger object which lists details about amendments on the network.
@@ -343,6 +344,7 @@ LEDGER_ENTRY(ltXCHAIN_OWNED_CREATE_ACCOUNT_CLAIM_ID, 0x0074, XChainOwnedCreateAc
343344
*/
344345
LEDGER_ENTRY(ltESCROW, 0x0075, Escrow, escrow, ({
345346
{sfAccount, soeREQUIRED},
347+
{sfSequence, soeOPTIONAL},
346348
{sfDestination, soeREQUIRED},
347349
{sfAmount, soeREQUIRED},
348350
{sfCondition, soeOPTIONAL},
@@ -365,6 +367,7 @@ LEDGER_ENTRY(ltESCROW, 0x0075, Escrow, escrow, ({
365367
LEDGER_ENTRY(ltPAYCHAN, 0x0078, PayChannel, payment_channel, ({
366368
{sfAccount, soeREQUIRED},
367369
{sfDestination, soeREQUIRED},
370+
{sfSequence, soeOPTIONAL},
368371
{sfAmount, soeREQUIRED},
369372
{sfBalance, soeREQUIRED},
370373
{sfPublicKey, soeREQUIRED},
@@ -433,6 +436,7 @@ LEDGER_ENTRY(ltMPTOKEN, 0x007f, MPToken, mptoken, ({
433436
*/
434437
LEDGER_ENTRY(ltORACLE, 0x0080, Oracle, oracle, ({
435438
{sfOwner, soeREQUIRED},
439+
{sfOracleDocumentID, soeOPTIONAL},
436440
{sfProvider, soeREQUIRED},
437441
{sfPriceDataSeries, soeREQUIRED},
438442
{sfAssetClass, soeREQUIRED},

src/test/app/Escrow_test.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,14 @@ struct Escrow_test : public beast::unit_test::suite
253253
BEAST_EXPECT(sle);
254254
BEAST_EXPECT((*sle)[sfSourceTag] == 1);
255255
BEAST_EXPECT((*sle)[sfDestinationTag] == 2);
256+
if (features[fixIncludeKeyletFields])
257+
{
258+
BEAST_EXPECT((*sle)[sfSequence] == seq);
259+
}
260+
else
261+
{
262+
BEAST_EXPECT(!sle->isFieldPresent(sfSequence));
263+
}
256264
}
257265

258266
void
@@ -1718,6 +1726,7 @@ struct Escrow_test : public beast::unit_test::suite
17181726
FeatureBitset const all{testable_amendments()};
17191727
testWithFeats(all);
17201728
testWithFeats(all - featureTokenEscrow);
1729+
testTags(all - fixIncludeKeyletFields);
17211730
}
17221731
};
17231732

src/test/app/MultiSign_test.cpp

Lines changed: 74 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ class MultiSign_test : public beast::unit_test::suite
6363

6464
public:
6565
void
66-
test_noReserve(FeatureBitset features)
66+
testNoReserve(FeatureBitset features)
6767
{
6868
testcase("No Reserve");
6969

@@ -133,7 +133,7 @@ class MultiSign_test : public beast::unit_test::suite
133133
}
134134

135135
void
136-
test_signerListSet(FeatureBitset features)
136+
testSignerListSet(FeatureBitset features)
137137
{
138138
testcase("SignerListSet");
139139

@@ -215,7 +215,7 @@ class MultiSign_test : public beast::unit_test::suite
215215
}
216216

217217
void
218-
test_phantomSigners(FeatureBitset features)
218+
testPhantomSigners(FeatureBitset features)
219219
{
220220
testcase("Phantom Signers");
221221

@@ -282,7 +282,7 @@ class MultiSign_test : public beast::unit_test::suite
282282
}
283283

284284
void
285-
test_fee(FeatureBitset features)
285+
testFee(FeatureBitset features)
286286
{
287287
testcase("Fee");
288288

@@ -346,7 +346,7 @@ class MultiSign_test : public beast::unit_test::suite
346346
}
347347

348348
void
349-
test_misorderedSigners(FeatureBitset features)
349+
testMisorderedSigners(FeatureBitset features)
350350
{
351351
testcase("Misordered Signers");
352352

@@ -374,7 +374,7 @@ class MultiSign_test : public beast::unit_test::suite
374374
}
375375

376376
void
377-
test_masterSigners(FeatureBitset features)
377+
testMasterSigners(FeatureBitset features)
378378
{
379379
testcase("Master Signers");
380380

@@ -429,7 +429,7 @@ class MultiSign_test : public beast::unit_test::suite
429429
}
430430

431431
void
432-
test_regularSigners(FeatureBitset features)
432+
testRegularSigners(FeatureBitset features)
433433
{
434434
testcase("Regular Signers");
435435

@@ -494,7 +494,7 @@ class MultiSign_test : public beast::unit_test::suite
494494
}
495495

496496
void
497-
test_regularSignersUsingSubmitMulti(FeatureBitset features)
497+
testRegularSignersUsingSubmitMulti(FeatureBitset features)
498498
{
499499
testcase("Regular Signers Using submit_multisigned");
500500

@@ -734,7 +734,7 @@ class MultiSign_test : public beast::unit_test::suite
734734
}
735735

736736
void
737-
test_heterogeneousSigners(FeatureBitset features)
737+
testHeterogeneousSigners(FeatureBitset features)
738738
{
739739
testcase("Heterogenious Signers");
740740

@@ -881,7 +881,7 @@ class MultiSign_test : public beast::unit_test::suite
881881
// We want to always leave an account signable. Make sure the that we
882882
// disallow removing the last way a transaction may be signed.
883883
void
884-
test_keyDisable(FeatureBitset features)
884+
testKeyDisable(FeatureBitset features)
885885
{
886886
testcase("Key Disable");
887887

@@ -963,7 +963,7 @@ class MultiSign_test : public beast::unit_test::suite
963963
// Verify that the first regular key can be made for free using the
964964
// master key, but not when multisigning.
965965
void
966-
test_regKey(FeatureBitset features)
966+
testRegKey(FeatureBitset features)
967967
{
968968
testcase("Regular Key");
969969

@@ -1000,7 +1000,7 @@ class MultiSign_test : public beast::unit_test::suite
10001000

10011001
// See if every kind of transaction can be successfully multi-signed.
10021002
void
1003-
test_txTypes(FeatureBitset features)
1003+
testTxTypes(FeatureBitset features)
10041004
{
10051005
testcase("Transaction Types");
10061006

@@ -1089,7 +1089,7 @@ class MultiSign_test : public beast::unit_test::suite
10891089
}
10901090

10911091
void
1092-
test_badSignatureText(FeatureBitset features)
1092+
testBadSignatureText(FeatureBitset features)
10931093
{
10941094
testcase("Bad Signature Text");
10951095

@@ -1285,7 +1285,7 @@ class MultiSign_test : public beast::unit_test::suite
12851285
}
12861286

12871287
void
1288-
test_noMultiSigners(FeatureBitset features)
1288+
testNoMultiSigners(FeatureBitset features)
12891289
{
12901290
testcase("No Multisigners");
12911291

@@ -1304,7 +1304,7 @@ class MultiSign_test : public beast::unit_test::suite
13041304
}
13051305

13061306
void
1307-
test_multisigningMultisigner(FeatureBitset features)
1307+
testMultisigningMultisigner(FeatureBitset features)
13081308
{
13091309
testcase("Multisigning multisigner");
13101310

@@ -1381,7 +1381,7 @@ class MultiSign_test : public beast::unit_test::suite
13811381
}
13821382

13831383
void
1384-
test_signForHash(FeatureBitset features)
1384+
testSignForHash(FeatureBitset features)
13851385
{
13861386
testcase("sign_for Hash");
13871387

@@ -1464,7 +1464,7 @@ class MultiSign_test : public beast::unit_test::suite
14641464
}
14651465

14661466
void
1467-
test_amendmentTransition()
1467+
testAmendmentTransition()
14681468
{
14691469
testcase("Amendment Transition");
14701470

@@ -1559,7 +1559,7 @@ class MultiSign_test : public beast::unit_test::suite
15591559
}
15601560

15611561
void
1562-
test_signersWithTickets(FeatureBitset features)
1562+
testSignersWithTickets(FeatureBitset features)
15631563
{
15641564
testcase("Signers With Tickets");
15651565

@@ -1600,7 +1600,7 @@ class MultiSign_test : public beast::unit_test::suite
16001600
}
16011601

16021602
void
1603-
test_signersWithTags(FeatureBitset features)
1603+
testSignersWithTags(FeatureBitset features)
16041604
{
16051605
if (!features[featureExpandedSignerList])
16061606
return;
@@ -1680,7 +1680,7 @@ class MultiSign_test : public beast::unit_test::suite
16801680
}
16811681

16821682
void
1683-
test_signerListSetFlags(FeatureBitset features)
1683+
testSignerListSetFlags(FeatureBitset features)
16841684
{
16851685
using namespace test::jtx;
16861686

@@ -1702,27 +1702,57 @@ class MultiSign_test : public beast::unit_test::suite
17021702
env.close();
17031703
}
17041704

1705+
void
1706+
testSignerListObject(FeatureBitset features)
1707+
{
1708+
testcase("SignerList Object");
1709+
1710+
// Verify that the SignerList object is created correctly.
1711+
using namespace jtx;
1712+
Env env{*this, features};
1713+
Account const alice{"alice", KeyType::ed25519};
1714+
env.fund(XRP(1000), alice);
1715+
env.close();
1716+
1717+
// Attach phantom signers to alice.
1718+
env(signers(alice, 1, {{bogie, 1}, {demon, 1}}));
1719+
env.close();
1720+
1721+
// Verify that the SignerList object was created correctly.
1722+
auto const& sle = env.le(keylet::signers(alice.id()));
1723+
BEAST_EXPECT(sle);
1724+
BEAST_EXPECT(sle->getFieldArray(sfSignerEntries).size() == 2);
1725+
if (features[fixIncludeKeyletFields])
1726+
{
1727+
BEAST_EXPECT((*sle)[sfOwner] == alice.id());
1728+
}
1729+
else
1730+
{
1731+
BEAST_EXPECT(!sle->isFieldPresent(sfOwner));
1732+
}
1733+
}
1734+
17051735
void
17061736
testAll(FeatureBitset features)
17071737
{
1708-
test_noReserve(features);
1709-
test_signerListSet(features);
1710-
test_phantomSigners(features);
1711-
test_fee(features);
1712-
test_misorderedSigners(features);
1713-
test_masterSigners(features);
1714-
test_regularSigners(features);
1715-
test_regularSignersUsingSubmitMulti(features);
1716-
test_heterogeneousSigners(features);
1717-
test_keyDisable(features);
1718-
test_regKey(features);
1719-
test_txTypes(features);
1720-
test_badSignatureText(features);
1721-
test_noMultiSigners(features);
1722-
test_multisigningMultisigner(features);
1723-
test_signForHash(features);
1724-
test_signersWithTickets(features);
1725-
test_signersWithTags(features);
1738+
testNoReserve(features);
1739+
testSignerListSet(features);
1740+
testPhantomSigners(features);
1741+
testFee(features);
1742+
testMisorderedSigners(features);
1743+
testMasterSigners(features);
1744+
testRegularSigners(features);
1745+
testRegularSignersUsingSubmitMulti(features);
1746+
testHeterogeneousSigners(features);
1747+
testKeyDisable(features);
1748+
testRegKey(features);
1749+
testTxTypes(features);
1750+
testBadSignatureText(features);
1751+
testNoMultiSigners(features);
1752+
testMultisigningMultisigner(features);
1753+
testSignForHash(features);
1754+
testSignersWithTickets(features);
1755+
testSignersWithTags(features);
17261756
}
17271757

17281758
void
@@ -1739,10 +1769,13 @@ class MultiSign_test : public beast::unit_test::suite
17391769
testAll(all - featureExpandedSignerList);
17401770
testAll(all);
17411771

1742-
test_signerListSetFlags(all - fixInvalidTxFlags);
1743-
test_signerListSetFlags(all);
1772+
testSignerListSetFlags(all - fixInvalidTxFlags);
1773+
testSignerListSetFlags(all);
1774+
1775+
testSignerListObject(all - fixIncludeKeyletFields);
1776+
testSignerListObject(all);
17441777

1745-
test_amendmentTransition();
1778+
testAmendmentTransition();
17461779
}
17471780
};
17481781

0 commit comments

Comments
 (0)