From f52aec5d170c98a961772c44a2bc0cbe3d58301a Mon Sep 17 00:00:00 2001 From: bthomee Date: Wed, 11 Jun 2025 05:25:47 +0000 Subject: [PATCH] deploy: ea17abb92a261da2cbf2bbcdbd6231a29f1fa9db --- Batch__test_8cpp_source.html | 340 +++-- Delegate__test_8cpp_source.html | 1300 +++++++++----------- classripple_1_1test_1_1Batch__test.html | 4 +- classripple_1_1test_1_1Delegate__test.html | 14 +- 4 files changed, 839 insertions(+), 819 deletions(-) diff --git a/Batch__test_8cpp_source.html b/Batch__test_8cpp_source.html index 26f74eedc8..61a9677a4e 100644 --- a/Batch__test_8cpp_source.html +++ b/Batch__test_8cpp_source.html @@ -3843,99 +3843,240 @@ $(function() {
3765 }
3766
3767 // delegated non atomic inner (AccountSet)
-
3768 {
-
3769 test::jtx::Env env{*this, envconfig()};
-
3770
-
3771 auto const alice = Account("alice");
-
3772 auto const bob = Account("bob");
-
3773 auto const gw = Account("gw");
-
3774 auto const USD = gw["USD"];
-
3775 env.fund(XRP(10000), alice, bob, gw);
-
3776 env.close();
-
3777
-
3778 env(delegate::set(alice, bob, {"AccountDomainSet"}));
-
3779 env.close();
-
3780
-
3781 auto const preAlice = env.balance(alice);
-
3782 auto const preBob = env.balance(bob);
-
3783
-
3784 auto const batchFee = batch::calcBatchFee(env, 0, 2);
-
3785 auto const seq = env.seq(alice);
-
3786
-
3787 auto tx = batch::inner(noop(alice), seq + 1);
-
3788 std::string const domain = "example.com";
-
3789 tx[sfDomain.jsonName] = strHex(domain);
-
3790 tx[jss::Delegate] = bob.human();
-
3791 auto const [txIDs, batchID] = submitBatch(
-
3792 env,
-
3793 tesSUCCESS,
-
3794 batch::outer(alice, seq, batchFee, tfAllOrNothing),
-
3795 tx,
-
3796 batch::inner(pay(alice, bob, XRP(2)), seq + 2));
-
3797 env.close();
-
3798
-
3799 std::vector<TestLedgerData> testCases = {
-
3800 {0, "Batch", "tesSUCCESS", batchID, std::nullopt},
-
3801 {1, "AccountSet", "tesSUCCESS", txIDs[0], batchID},
-
3802 {2, "Payment", "tesSUCCESS", txIDs[1], batchID},
-
3803 };
-
3804 validateClosedLedger(env, testCases);
-
3805
-
3806 // Alice consumes sequences (# of txns)
-
3807 BEAST_EXPECT(env.seq(alice) == seq + 3);
-
3808
-
3809 // Alice pays XRP & Fee; Bob receives XRP
-
3810 BEAST_EXPECT(env.balance(alice) == preAlice - XRP(2) - batchFee);
-
3811 BEAST_EXPECT(env.balance(bob) == preBob + XRP(2));
-
3812 }
-
3813 }
-
3814
-
3815 void
-
3816 testWithFeats(FeatureBitset features)
-
3817 {
-
3818 testEnable(features);
-
3819 testPreflight(features);
-
3820 testPreclaim(features);
-
3821 testBadRawTxn(features);
-
3822 testBadSequence(features);
-
3823 testBadOuterFee(features);
-
3824 testCalculateBaseFee(features);
-
3825 testAllOrNothing(features);
-
3826 testOnlyOne(features);
-
3827 testUntilFailure(features);
-
3828 testIndependent(features);
-
3829 testInnerSubmitRPC(features);
-
3830 testAccountActivation(features);
-
3831 testAccountSet(features);
-
3832 testAccountDelete(features);
-
3833 testObjectCreateSequence(features);
-
3834 testObjectCreateTicket(features);
-
3835 testObjectCreate3rdParty(features);
-
3836 testTickets(features);
-
3837 testSequenceOpenLedger(features);
-
3838 testTicketsOpenLedger(features);
-
3839 testObjectsOpenLedger(features);
-
3840 testPseudoTxn(features);
-
3841 testOpenLedger(features);
-
3842 testBatchTxQueue(features);
-
3843 testBatchNetworkOps(features);
-
3844 testBatchDelegate(features);
-
3845 }
-
3846
-
3847public:
-
3848 void
-
3849 run() override
-
3850 {
-
3851 using namespace test::jtx;
-
3852 auto const sa = supported_amendments();
-
3853 testWithFeats(sa);
-
3854 }
-
3855};
-
3856
-
3857BEAST_DEFINE_TESTSUITE(Batch, app, ripple);
-
3858
-
3859} // namespace test
-
3860} // namespace ripple
+
3768 // this also makes sure tfInnerBatchTxn won't block delegated AccountSet
+
3769 // with granular permission
+
3770 {
+
3771 test::jtx::Env env{*this, envconfig()};
+
3772
+
3773 auto const alice = Account("alice");
+
3774 auto const bob = Account("bob");
+
3775 auto const gw = Account("gw");
+
3776 auto const USD = gw["USD"];
+
3777 env.fund(XRP(10000), alice, bob, gw);
+
3778 env.close();
+
3779
+
3780 env(delegate::set(alice, bob, {"AccountDomainSet"}));
+
3781 env.close();
+
3782
+
3783 auto const preAlice = env.balance(alice);
+
3784 auto const preBob = env.balance(bob);
+
3785
+
3786 auto const batchFee = batch::calcBatchFee(env, 0, 2);
+
3787 auto const seq = env.seq(alice);
+
3788
+
3789 auto tx = batch::inner(noop(alice), seq + 1);
+
3790 std::string const domain = "example.com";
+
3791 tx[sfDomain.jsonName] = strHex(domain);
+
3792 tx[jss::Delegate] = bob.human();
+
3793 auto const [txIDs, batchID] = submitBatch(
+
3794 env,
+
3795 tesSUCCESS,
+
3796 batch::outer(alice, seq, batchFee, tfAllOrNothing),
+
3797 tx,
+
3798 batch::inner(pay(alice, bob, XRP(2)), seq + 2));
+
3799 env.close();
+
3800
+
3801 std::vector<TestLedgerData> testCases = {
+
3802 {0, "Batch", "tesSUCCESS", batchID, std::nullopt},
+
3803 {1, "AccountSet", "tesSUCCESS", txIDs[0], batchID},
+
3804 {2, "Payment", "tesSUCCESS", txIDs[1], batchID},
+
3805 };
+
3806 validateClosedLedger(env, testCases);
+
3807
+
3808 // Alice consumes sequences (# of txns)
+
3809 BEAST_EXPECT(env.seq(alice) == seq + 3);
+
3810
+
3811 // Alice pays XRP & Fee; Bob receives XRP
+
3812 BEAST_EXPECT(env.balance(alice) == preAlice - XRP(2) - batchFee);
+
3813 BEAST_EXPECT(env.balance(bob) == preBob + XRP(2));
+
3814 }
+
3815
+
3816 // delegated non atomic inner (MPTokenIssuanceSet)
+
3817 // this also makes sure tfInnerBatchTxn won't block delegated
+
3818 // MPTokenIssuanceSet with granular permission
+
3819 {
+
3820 test::jtx::Env env{*this, envconfig()};
+
3821 Account alice{"alice"};
+
3822 Account bob{"bob"};
+
3823 env.fund(XRP(100000), alice, bob);
+
3824 env.close();
+
3825
+
3826 auto const mptID = makeMptID(env.seq(alice), alice);
+
3827 MPTTester mpt(env, alice, {.fund = false});
+
3828 env.close();
+
3829 mpt.create({.flags = tfMPTCanLock});
+
3830 env.close();
+
3831
+
3832 // alice gives granular permission to bob of MPTokenIssuanceLock
+
3833 env(delegate::set(
+
3834 alice, bob, {"MPTokenIssuanceLock", "MPTokenIssuanceUnlock"}));
+
3835 env.close();
+
3836
+
3837 auto const seq = env.seq(alice);
+
3838 auto const batchFee = batch::calcBatchFee(env, 0, 2);
+
3839
+
3840 Json::Value jv1;
+
3841 jv1[sfTransactionType] = jss::MPTokenIssuanceSet;
+
3842 jv1[sfAccount] = alice.human();
+
3843 jv1[sfDelegate] = bob.human();
+
3844 jv1[sfSequence] = seq + 1;
+
3845 jv1[sfMPTokenIssuanceID] = to_string(mptID);
+
3846 jv1[sfFlags] = tfMPTLock;
+
3847
+
3848 Json::Value jv2;
+
3849 jv2[sfTransactionType] = jss::MPTokenIssuanceSet;
+
3850 jv2[sfAccount] = alice.human();
+
3851 jv2[sfDelegate] = bob.human();
+
3852 jv2[sfSequence] = seq + 2;
+
3853 jv2[sfMPTokenIssuanceID] = to_string(mptID);
+
3854 jv2[sfFlags] = tfMPTUnlock;
+
3855
+
3856 auto const [txIDs, batchID] = submitBatch(
+
3857 env,
+
3858 tesSUCCESS,
+
3859 batch::outer(alice, seq, batchFee, tfAllOrNothing),
+
3860 batch::inner(jv1, seq + 1),
+
3861 batch::inner(jv2, seq + 2));
+
3862 env.close();
+
3863
+
3864 std::vector<TestLedgerData> testCases = {
+
3865 {0, "Batch", "tesSUCCESS", batchID, std::nullopt},
+
3866 {1, "MPTokenIssuanceSet", "tesSUCCESS", txIDs[0], batchID},
+
3867 {2, "MPTokenIssuanceSet", "tesSUCCESS", txIDs[1], batchID},
+
3868 };
+
3869 validateClosedLedger(env, testCases);
+
3870 }
+
3871
+
3872 // delegated non atomic inner (TrustSet)
+
3873 // this also makes sure tfInnerBatchTxn won't block delegated TrustSet
+
3874 // with granular permission
+
3875 {
+
3876 test::jtx::Env env{*this, envconfig()};
+
3877 Account gw{"gw"};
+
3878 Account alice{"alice"};
+
3879 Account bob{"bob"};
+
3880 env.fund(XRP(10000), gw, alice, bob);
+
3881 env(fset(gw, asfRequireAuth));
+
3882 env.close();
+
3883 env(trust(alice, gw["USD"](50)));
+
3884 env.close();
+
3885
+
3886 env(delegate::set(
+
3887 gw, bob, {"TrustlineAuthorize", "TrustlineFreeze"}));
+
3888 env.close();
+
3889
+
3890 auto const seq = env.seq(gw);
+
3891 auto const batchFee = batch::calcBatchFee(env, 0, 2);
+
3892
+
3893 auto jv1 = trust(gw, gw["USD"](0), alice, tfSetfAuth);
+
3894 jv1[sfDelegate] = bob.human();
+
3895 auto jv2 = trust(gw, gw["USD"](0), alice, tfSetFreeze);
+
3896 jv2[sfDelegate] = bob.human();
+
3897
+
3898 auto const [txIDs, batchID] = submitBatch(
+
3899 env,
+
3900 tesSUCCESS,
+
3901 batch::outer(gw, seq, batchFee, tfAllOrNothing),
+
3902 batch::inner(jv1, seq + 1),
+
3903 batch::inner(jv2, seq + 2));
+
3904 env.close();
+
3905
+
3906 std::vector<TestLedgerData> testCases = {
+
3907 {0, "Batch", "tesSUCCESS", batchID, std::nullopt},
+
3908 {1, "TrustSet", "tesSUCCESS", txIDs[0], batchID},
+
3909 {2, "TrustSet", "tesSUCCESS", txIDs[1], batchID},
+
3910 };
+
3911 validateClosedLedger(env, testCases);
+
3912 }
+
3913
+
3914 // inner transaction not authorized by the delegating account.
+
3915 {
+
3916 test::jtx::Env env{*this, envconfig()};
+
3917 Account gw{"gw"};
+
3918 Account alice{"alice"};
+
3919 Account bob{"bob"};
+
3920 env.fund(XRP(10000), gw, alice, bob);
+
3921 env(fset(gw, asfRequireAuth));
+
3922 env.close();
+
3923 env(trust(alice, gw["USD"](50)));
+
3924 env.close();
+
3925
+
3926 env(delegate::set(
+
3927 gw, bob, {"TrustlineAuthorize", "TrustlineFreeze"}));
+
3928 env.close();
+
3929
+
3930 auto const seq = env.seq(gw);
+
3931 auto const batchFee = batch::calcBatchFee(env, 0, 2);
+
3932
+
3933 auto jv1 = trust(gw, gw["USD"](0), alice, tfSetFreeze);
+
3934 jv1[sfDelegate] = bob.human();
+
3935 auto jv2 = trust(gw, gw["USD"](0), alice, tfClearFreeze);
+
3936 jv2[sfDelegate] = bob.human();
+
3937
+
3938 auto const [txIDs, batchID] = submitBatch(
+
3939 env,
+
3940 tesSUCCESS,
+
3941 batch::outer(gw, seq, batchFee, tfIndependent),
+
3942 batch::inner(jv1, seq + 1),
+
3943 // tecNO_DELEGATE_PERMISSION: not authorized to clear freeze
+
3944 batch::inner(jv2, seq + 2));
+
3945 env.close();
+
3946
+
3947 std::vector<TestLedgerData> testCases = {
+
3948 {0, "Batch", "tesSUCCESS", batchID, std::nullopt},
+
3949 {1, "TrustSet", "tesSUCCESS", txIDs[0], batchID},
+
3950 {2, "TrustSet", "tecNO_DELEGATE_PERMISSION", txIDs[1], batchID},
+
3951 };
+
3952 validateClosedLedger(env, testCases);
+
3953 }
+
3954 }
+
3955
+
3956 void
+
3957 testWithFeats(FeatureBitset features)
+
3958 {
+
3959 testEnable(features);
+
3960 testPreflight(features);
+
3961 testPreclaim(features);
+
3962 testBadRawTxn(features);
+
3963 testBadSequence(features);
+
3964 testBadOuterFee(features);
+
3965 testCalculateBaseFee(features);
+
3966 testAllOrNothing(features);
+
3967 testOnlyOne(features);
+
3968 testUntilFailure(features);
+
3969 testIndependent(features);
+
3970 testInnerSubmitRPC(features);
+
3971 testAccountActivation(features);
+
3972 testAccountSet(features);
+
3973 testAccountDelete(features);
+
3974 testObjectCreateSequence(features);
+
3975 testObjectCreateTicket(features);
+
3976 testObjectCreate3rdParty(features);
+
3977 testTickets(features);
+
3978 testSequenceOpenLedger(features);
+
3979 testTicketsOpenLedger(features);
+
3980 testObjectsOpenLedger(features);
+
3981 testPseudoTxn(features);
+
3982 testOpenLedger(features);
+
3983 testBatchTxQueue(features);
+
3984 testBatchNetworkOps(features);
+
3985 testBatchDelegate(features);
+
3986 }
+
3987
+
3988public:
+
3989 void
+
3990 run() override
+
3991 {
+
3992 using namespace test::jtx;
+
3993 auto const sa = supported_amendments();
+
3994 testWithFeats(sa);
+
3995 }
+
3996};
+
3997
+
3998BEAST_DEFINE_TESTSUITE(Batch, app, ripple);
+
3999
+
4000} // namespace test
+
4001} // namespace ripple
Represents a JSON value.
Definition: json_value.h:150
A generic endpoint for log messages.
Definition: Journal.h:60
@@ -3968,7 +4109,7 @@ $(function() {
void validateInnerTxn(jtx::Env &env, std::string const &batchID, TestLedgerData const &ledgerResult)
Definition: Batch_test.cpp:77
void testAccountSet(FeatureBitset features)
void testTickets(FeatureBitset features)
-
void run() override
Runs the suite.
+
void run() override
Runs the suite.
void testAllOrNothing(FeatureBitset features)
void testObjectCreate3rdParty(FeatureBitset features)
void testAccountActivation(FeatureBitset features)
@@ -3988,7 +4129,7 @@ $(function() {
auto openLedgerFee(jtx::Env &env, XRPAmount const &batchFee)
Definition: Batch_test.cpp:156
void testPreflight(FeatureBitset features)
Definition: Batch_test.cpp:215
void testUntilFailure(FeatureBitset features)
-
void testWithFeats(FeatureBitset features)
+
void testWithFeats(FeatureBitset features)
void testSequenceOpenLedger(FeatureBitset features)
void testTicketsOpenLedger(FeatureBitset features)
void testIndependent(FeatureBitset features)
@@ -4010,6 +4151,8 @@ $(function() {
Application & app()
Definition: Env.h:261
Json::Value rpc(unsigned apiVersion, std::unordered_map< std::string, std::string > const &headers, std::string const &cmd, Args &&... args)
Execute an RPC command.
Definition: Env.h:788
void fund(bool setDefaultRipple, STAmount const &amount, Account const &account)
Definition: Env.cpp:275
+
Definition: mpt.h:145
+
void create(MPTCreate const &arg=MPTCreate{})
Definition: mpt.cpp:86
Adds a new Batch Txn on a JTx and autofills.
Definition: batch.h:61
Set a batch nested multi-signature on a JTx.
Definition: batch.h:135
Set a batch signature on a JTx.
Definition: batch.h:112
@@ -4053,6 +4196,7 @@ $(function() {
base_uint< 256 > uint256
Definition: base_uint.h:558
constexpr std::uint32_t tfIndependent
Definition: TxFlags.h:243
void serializeBatch(Serializer &msg, std::uint32_t const &flags, std::vector< uint256 > const &txids)
+
constexpr std::uint32_t const tfMPTUnlock
Definition: TxFlags.h:160
constexpr std::uint32_t tfImmediateOrCancel
Definition: TxFlags.h:99
constexpr std::uint32_t asfDisableMaster
Definition: TxFlags.h:80
Buffer sign(PublicKey const &pk, SecretKey const &sk, Slice const &message)
Generate a signature for a message.
Definition: SecretKey.cpp:256
@@ -4064,8 +4208,10 @@ $(function() {
constexpr std::uint32_t tfUntilFailure
Definition: TxFlags.h:242
std::string strHex(FwdIt begin, FwdIt end)
Definition: strHex.h:30
constexpr std::uint32_t tfSetfAuth
Definition: TxFlags.h:115
+
constexpr std::uint32_t tfClearFreeze
Definition: TxFlags.h:119
@ ed25519
@ tecNO_ENTRY
Definition: TER.h:306
+
constexpr std::uint32_t const tfMPTLock
Definition: TxFlags.h:159
@ tesSUCCESS
Definition: TER.h:244
constexpr std::uint32_t tfDisallowXRP
Definition: TxFlags.h:70
ApplyResult apply(Application &app, OpenView &view, STTx const &tx, ApplyFlags flags, beast::Journal journal)
Apply a transaction to an OpenView.
Definition: apply.cpp:143
@@ -4075,8 +4221,12 @@ $(function() {
constexpr std::uint32_t asfAllowTrustLineClawback
Definition: TxFlags.h:94
XRPAmount toDrops(FeeLevel< T > const &level, XRPAmount baseFee)
Definition: TxQ.h:863
@ tapNONE
Definition: ApplyView.h:32
+
constexpr std::uint32_t asfRequireAuth
Definition: TxFlags.h:78
+
MPTID makeMptID(std::uint32_t sequence, AccountID const &account)
Definition: Indexes.cpp:170
@ terPRE_SEQ
Definition: TER.h:221
@ terQUEUED
Definition: TER.h:225
+
constexpr std::uint32_t tfSetFreeze
Definition: TxFlags.h:118
+
constexpr std::uint32_t const tfMPTCanLock
Definition: TxFlags.h:145
constexpr std::uint32_t tfInnerBatchTxn
Definition: TxFlags.h:61
@ temREDUNDANT
Definition: TER.h:112
@ temBAD_FEE
Definition: TER.h:92
diff --git a/Delegate__test_8cpp_source.html b/Delegate__test_8cpp_source.html index ba5d021a60..dfe37a68e3 100644 --- a/Delegate__test_8cpp_source.html +++ b/Delegate__test_8cpp_source.html @@ -991,717 +991,593 @@ $(function() {
913 gw, gw["USD"](0), alice, tfSetfAuth | tfFullyCanonicalSig),
914 delegate::as(bob));
915 }
-
916
-
917 // tfInnerBatchTxn won't block delegated transaction
-
918 {
-
919 Env env(*this);
-
920 Account gw{"gw"};
-
921 Account alice{"alice"};
-
922 Account bob{"bob"};
-
923 env.fund(XRP(10000), gw, alice, bob);
-
924 env(fset(gw, asfRequireAuth));
-
925 env.close();
-
926 env(trust(alice, gw["USD"](50)));
-
927 env.close();
-
928
-
929 env(delegate::set(
-
930 gw, bob, {"TrustlineAuthorize", "TrustlineFreeze"}));
-
931 env.close();
-
932
-
933 auto const seq = env.seq(gw);
-
934 auto const batchFee = batch::calcBatchFee(env, 0, 2);
-
935 auto jv1 = trust(gw, gw["USD"](0), alice, tfSetfAuth);
-
936 jv1[sfDelegate] = bob.human();
-
937 auto jv2 = trust(gw, gw["USD"](0), alice, tfSetFreeze);
-
938 jv2[sfDelegate] = bob.human();
-
939
-
940 // batch::inner will set tfInnerBatchTxn, this should not
-
941 // block delegated transaction
-
942 env(batch::outer(gw, seq, batchFee, tfAllOrNothing),
-
943 batch::inner(jv1, seq + 1),
-
944 batch::inner(jv2, seq + 2));
-
945 env.close();
-
946 }
-
947 }
-
948
-
949 void
-
950 testAccountSetGranular()
-
951 {
-
952 testcase("test AccountSet granular permissions");
-
953 using namespace jtx;
-
954
-
955 // test AccountDomainSet, AccountEmailHashSet,
-
956 // AccountMessageKeySet,AccountTransferRateSet, and AccountTickSizeSet
-
957 // granular permissions
-
958 {
-
959 Env env(*this);
-
960 auto const alice = Account{"alice"};
-
961 auto const bob = Account{"bob"};
-
962 env.fund(XRP(10000), alice, bob);
-
963 env.close();
-
964
-
965 // alice gives bob some random permission, which is not related to
-
966 // the AccountSet transaction
-
967 env(delegate::set(alice, bob, {"TrustlineUnfreeze"}));
-
968 env.close();
-
969
-
970 // bob does not have permission to set domain
-
971 // on behalf of alice
-
972 std::string const domain = "example.com";
-
973 auto jt = noop(alice);
-
974 jt[sfDomain] = strHex(domain);
-
975 jt[sfDelegate] = bob.human();
-
976
-
977 // add granular permission related to AccountSet but is not the
-
978 // correct permission for domain set
-
979 env(delegate::set(
-
980 alice, bob, {"TrustlineUnfreeze", "AccountEmailHashSet"}));
-
981 env.close();
-
982 env(jt, ter(tecNO_DELEGATE_PERMISSION));
-
983
-
984 // alice give granular permission of AccountDomainSet to bob
-
985 env(delegate::set(alice, bob, {"AccountDomainSet"}));
-
986 env.close();
-
987
-
988 // bob set account domain on behalf of alice
-
989 env(jt);
-
990 BEAST_EXPECT((*env.le(alice))[sfDomain] == makeSlice(domain));
-
991
-
992 // bob can reset domain
-
993 jt[sfDomain] = "";
-
994 env(jt);
-
995 BEAST_EXPECT(!env.le(alice)->isFieldPresent(sfDomain));
-
996
-
997 // bob tries to set unauthorized flag, it will fail
-
998 std::string const failDomain = "fail_domain_update";
-
999 jt[sfFlags] = tfRequireAuth;
-
1000 jt[sfDomain] = strHex(failDomain);
-
1001 env(jt, ter(tecNO_DELEGATE_PERMISSION));
-
1002 // reset flag number
-
1003 jt[sfFlags] = 0;
-
1004
-
1005 // bob tries to update domain and set email hash,
-
1006 // but he does not have permission to set email hash
-
1007 jt[sfDomain] = strHex(domain);
-
1008 std::string const mh("5F31A79367DC3137FADA860C05742EE6");
-
1009 jt[sfEmailHash] = mh;
-
1010 env(jt, ter(tecNO_DELEGATE_PERMISSION));
+
916 }
+
917
+
918 void
+
919 testAccountSetGranular()
+
920 {
+
921 testcase("test AccountSet granular permissions");
+
922 using namespace jtx;
+
923
+
924 // test AccountDomainSet, AccountEmailHashSet,
+
925 // AccountMessageKeySet,AccountTransferRateSet, and AccountTickSizeSet
+
926 // granular permissions
+
927 {
+
928 Env env(*this);
+
929 auto const alice = Account{"alice"};
+
930 auto const bob = Account{"bob"};
+
931 env.fund(XRP(10000), alice, bob);
+
932 env.close();
+
933
+
934 // alice gives bob some random permission, which is not related to
+
935 // the AccountSet transaction
+
936 env(delegate::set(alice, bob, {"TrustlineUnfreeze"}));
+
937 env.close();
+
938
+
939 // bob does not have permission to set domain
+
940 // on behalf of alice
+
941 std::string const domain = "example.com";
+
942 auto jt = noop(alice);
+
943 jt[sfDomain] = strHex(domain);
+
944 jt[sfDelegate] = bob.human();
+
945
+
946 // add granular permission related to AccountSet but is not the
+
947 // correct permission for domain set
+
948 env(delegate::set(
+
949 alice, bob, {"TrustlineUnfreeze", "AccountEmailHashSet"}));
+
950 env.close();
+
951 env(jt, ter(tecNO_DELEGATE_PERMISSION));
+
952
+
953 // alice give granular permission of AccountDomainSet to bob
+
954 env(delegate::set(alice, bob, {"AccountDomainSet"}));
+
955 env.close();
+
956
+
957 // bob set account domain on behalf of alice
+
958 env(jt);
+
959 BEAST_EXPECT((*env.le(alice))[sfDomain] == makeSlice(domain));
+
960
+
961 // bob can reset domain
+
962 jt[sfDomain] = "";
+
963 env(jt);
+
964 BEAST_EXPECT(!env.le(alice)->isFieldPresent(sfDomain));
+
965
+
966 // bob tries to set unauthorized flag, it will fail
+
967 std::string const failDomain = "fail_domain_update";
+
968 jt[sfFlags] = tfRequireAuth;
+
969 jt[sfDomain] = strHex(failDomain);
+
970 env(jt, ter(tecNO_DELEGATE_PERMISSION));
+
971 // reset flag number
+
972 jt[sfFlags] = 0;
+
973
+
974 // bob tries to update domain and set email hash,
+
975 // but he does not have permission to set email hash
+
976 jt[sfDomain] = strHex(domain);
+
977 std::string const mh("5F31A79367DC3137FADA860C05742EE6");
+
978 jt[sfEmailHash] = mh;
+
979 env(jt, ter(tecNO_DELEGATE_PERMISSION));
+
980
+
981 // alice give granular permission of AccountEmailHashSet to bob
+
982 env(delegate::set(
+
983 alice, bob, {"AccountDomainSet", "AccountEmailHashSet"}));
+
984 env.close();
+
985 env(jt);
+
986 BEAST_EXPECT(to_string((*env.le(alice))[sfEmailHash]) == mh);
+
987 BEAST_EXPECT((*env.le(alice))[sfDomain] == makeSlice(domain));
+
988
+
989 // bob does not have permission to set message key for alice
+
990 auto const rkp = randomKeyPair(KeyType::ed25519);
+
991 jt[sfMessageKey] = strHex(rkp.first.slice());
+
992 env(jt, ter(tecNO_DELEGATE_PERMISSION));
+
993
+
994 // alice give granular permission of AccountMessageKeySet to bob
+
995 env(delegate::set(
+
996 alice,
+
997 bob,
+
998 {"AccountDomainSet",
+
999 "AccountEmailHashSet",
+
1000 "AccountMessageKeySet"}));
+
1001 env.close();
+
1002
+
1003 // bob can set message key for alice
+
1004 env(jt);
+
1005 BEAST_EXPECT(
+
1006 strHex((*env.le(alice))[sfMessageKey]) ==
+
1007 strHex(rkp.first.slice()));
+
1008 jt[sfMessageKey] = "";
+
1009 env(jt);
+
1010 BEAST_EXPECT(!env.le(alice)->isFieldPresent(sfMessageKey));
1011
-
1012 // alice give granular permission of AccountEmailHashSet to bob
-
1013 env(delegate::set(
-
1014 alice, bob, {"AccountDomainSet", "AccountEmailHashSet"}));
-
1015 env.close();
-
1016 env(jt);
-
1017 BEAST_EXPECT(to_string((*env.le(alice))[sfEmailHash]) == mh);
-
1018 BEAST_EXPECT((*env.le(alice))[sfDomain] == makeSlice(domain));
-
1019
-
1020 // bob does not have permission to set message key for alice
-
1021 auto const rkp = randomKeyPair(KeyType::ed25519);
-
1022 jt[sfMessageKey] = strHex(rkp.first.slice());
-
1023 env(jt, ter(tecNO_DELEGATE_PERMISSION));
-
1024
-
1025 // alice give granular permission of AccountMessageKeySet to bob
-
1026 env(delegate::set(
-
1027 alice,
-
1028 bob,
-
1029 {"AccountDomainSet",
-
1030 "AccountEmailHashSet",
-
1031 "AccountMessageKeySet"}));
-
1032 env.close();
-
1033
-
1034 // bob can set message key for alice
-
1035 env(jt);
-
1036 BEAST_EXPECT(
-
1037 strHex((*env.le(alice))[sfMessageKey]) ==
-
1038 strHex(rkp.first.slice()));
-
1039 jt[sfMessageKey] = "";
-
1040 env(jt);
-
1041 BEAST_EXPECT(!env.le(alice)->isFieldPresent(sfMessageKey));
-
1042
-
1043 // bob does not have permission to set transfer rate for alice
-
1044 env(rate(alice, 2.0),
-
1045 delegate::as(bob),
-
1046 ter(tecNO_DELEGATE_PERMISSION));
+
1012 // bob does not have permission to set transfer rate for alice
+
1013 env(rate(alice, 2.0),
+
1014 delegate::as(bob),
+
1015 ter(tecNO_DELEGATE_PERMISSION));
+
1016
+
1017 // alice give granular permission of AccountTransferRateSet to bob
+
1018 env(delegate::set(
+
1019 alice,
+
1020 bob,
+
1021 {"AccountDomainSet",
+
1022 "AccountEmailHashSet",
+
1023 "AccountMessageKeySet",
+
1024 "AccountTransferRateSet"}));
+
1025 env.close();
+
1026 auto jtRate = rate(alice, 2.0);
+
1027 jtRate[sfDelegate] = bob.human();
+
1028 env(jtRate, delegate::as(bob));
+
1029 BEAST_EXPECT((*env.le(alice))[sfTransferRate] == 2000000000);
+
1030
+
1031 // bob does not have permission to set ticksize for alice
+
1032 jt[sfTickSize] = 8;
+
1033 env(jt, ter(tecNO_DELEGATE_PERMISSION));
+
1034
+
1035 // alice give granular permission of AccountTickSizeSet to bob
+
1036 env(delegate::set(
+
1037 alice,
+
1038 bob,
+
1039 {"AccountDomainSet",
+
1040 "AccountEmailHashSet",
+
1041 "AccountMessageKeySet",
+
1042 "AccountTransferRateSet",
+
1043 "AccountTickSizeSet"}));
+
1044 env.close();
+
1045 env(jt);
+
1046 BEAST_EXPECT((*env.le(alice))[sfTickSize] == 8);
1047
-
1048 // alice give granular permission of AccountTransferRateSet to bob
-
1049 env(delegate::set(
-
1050 alice,
-
1051 bob,
-
1052 {"AccountDomainSet",
-
1053 "AccountEmailHashSet",
-
1054 "AccountMessageKeySet",
-
1055 "AccountTransferRateSet"}));
-
1056 env.close();
-
1057 auto jtRate = rate(alice, 2.0);
-
1058 jtRate[sfDelegate] = bob.human();
-
1059 env(jtRate, delegate::as(bob));
-
1060 BEAST_EXPECT((*env.le(alice))[sfTransferRate] == 2000000000);
-
1061
-
1062 // bob does not have permission to set ticksize for alice
-
1063 jt[sfTickSize] = 8;
-
1064 env(jt, ter(tecNO_DELEGATE_PERMISSION));
+
1048 // can not set asfRequireAuth flag for alice
+
1049 env(fset(alice, asfRequireAuth),
+
1050 delegate::as(bob),
+
1051 ter(tecNO_DELEGATE_PERMISSION));
+
1052
+
1053 // reset Delegate will delete the Delegate
+
1054 // object
+
1055 env(delegate::set(alice, bob, {}));
+
1056 // bib still does not have permission to set asfRequireAuth for
+
1057 // alice
+
1058 env(fset(alice, asfRequireAuth),
+
1059 delegate::as(bob),
+
1060 ter(tecNO_DELEGATE_PERMISSION));
+
1061 // alice can set for herself
+
1062 env(fset(alice, asfRequireAuth));
+
1063 env.require(flags(alice, asfRequireAuth));
+
1064 env.close();
1065
-
1066 // alice give granular permission of AccountTickSizeSet to bob
-
1067 env(delegate::set(
-
1068 alice,
-
1069 bob,
-
1070 {"AccountDomainSet",
-
1071 "AccountEmailHashSet",
-
1072 "AccountMessageKeySet",
-
1073 "AccountTransferRateSet",
-
1074 "AccountTickSizeSet"}));
-
1075 env.close();
-
1076 env(jt);
-
1077 BEAST_EXPECT((*env.le(alice))[sfTickSize] == 8);
-
1078
-
1079 // can not set asfRequireAuth flag for alice
-
1080 env(fset(alice, asfRequireAuth),
-
1081 delegate::as(bob),
-
1082 ter(tecNO_DELEGATE_PERMISSION));
-
1083
-
1084 // reset Delegate will delete the Delegate
-
1085 // object
-
1086 env(delegate::set(alice, bob, {}));
-
1087 // bib still does not have permission to set asfRequireAuth for
-
1088 // alice
-
1089 env(fset(alice, asfRequireAuth),
-
1090 delegate::as(bob),
-
1091 ter(tecNO_DELEGATE_PERMISSION));
-
1092 // alice can set for herself
-
1093 env(fset(alice, asfRequireAuth));
-
1094 env.require(flags(alice, asfRequireAuth));
+
1066 // can not update tick size because bob no longer has permission
+
1067 jt[sfTickSize] = 7;
+
1068 env(jt, ter(tecNO_DELEGATE_PERMISSION));
+
1069
+
1070 env(delegate::set(
+
1071 alice,
+
1072 bob,
+
1073 {"AccountDomainSet",
+
1074 "AccountEmailHashSet",
+
1075 "AccountMessageKeySet"}));
+
1076 env.close();
+
1077
+
1078 // bob does not have permission to set wallet locater for alice
+
1079 std::string const locator =
+
1080 "9633EC8AF54F16B5286DB1D7B519EF49EEFC050C0C8AC4384F1D88ACD1BFDF"
+
1081 "05";
+
1082 auto jv2 = noop(alice);
+
1083 jv2[sfDomain] = strHex(domain);
+
1084 jv2[sfDelegate] = bob.human();
+
1085 jv2[sfWalletLocator] = locator;
+
1086 env(jv2, ter(tecNO_DELEGATE_PERMISSION));
+
1087 }
+
1088
+
1089 // can not set AccountSet flags on behalf of other account
+
1090 {
+
1091 Env env(*this);
+
1092 auto const alice = Account{"alice"};
+
1093 auto const bob = Account{"bob"};
+
1094 env.fund(XRP(10000), alice, bob);
1095 env.close();
1096
-
1097 // can not update tick size because bob no longer has permission
-
1098 jt[sfTickSize] = 7;
-
1099 env(jt, ter(tecNO_DELEGATE_PERMISSION));
-
1100
-
1101 env(delegate::set(
-
1102 alice,
-
1103 bob,
-
1104 {"AccountDomainSet",
-
1105 "AccountEmailHashSet",
-
1106 "AccountMessageKeySet"}));
-
1107 env.close();
-
1108
-
1109 // bob does not have permission to set wallet locater for alice
-
1110 std::string const locator =
-
1111 "9633EC8AF54F16B5286DB1D7B519EF49EEFC050C0C8AC4384F1D88ACD1BFDF"
-
1112 "05";
-
1113 auto jv2 = noop(alice);
-
1114 jv2[sfDomain] = strHex(domain);
-
1115 jv2[sfDelegate] = bob.human();
-
1116 jv2[sfWalletLocator] = locator;
-
1117 env(jv2, ter(tecNO_DELEGATE_PERMISSION));
-
1118 }
-
1119
-
1120 // can not set AccountSet flags on behalf of other account
-
1121 {
-
1122 Env env(*this);
-
1123 auto const alice = Account{"alice"};
-
1124 auto const bob = Account{"bob"};
-
1125 env.fund(XRP(10000), alice, bob);
-
1126 env.close();
-
1127
-
1128 auto testSetClearFlag = [&](std::uint32_t flag) {
-
1129 // bob can not set flag on behalf of alice
-
1130 env(fset(alice, flag),
-
1131 delegate::as(bob),
-
1132 ter(tecNO_DELEGATE_PERMISSION));
-
1133 // alice set by herself
-
1134 env(fset(alice, flag));
-
1135 env.close();
-
1136 env.require(flags(alice, flag));
-
1137 // bob can not clear on behalf of alice
-
1138 env(fclear(alice, flag),
-
1139 delegate::as(bob),
-
1140 ter(tecNO_DELEGATE_PERMISSION));
-
1141 };
-
1142
-
1143 // testSetClearFlag(asfNoFreeze);
-
1144 testSetClearFlag(asfRequireAuth);
-
1145 testSetClearFlag(asfAllowTrustLineClawback);
-
1146
-
1147 // alice gives some granular permissions to bob
-
1148 env(delegate::set(
-
1149 alice,
-
1150 bob,
-
1151 {"AccountDomainSet",
-
1152 "AccountEmailHashSet",
-
1153 "AccountMessageKeySet"}));
-
1154 env.close();
-
1155
-
1156 testSetClearFlag(asfDefaultRipple);
-
1157 testSetClearFlag(asfDepositAuth);
-
1158 testSetClearFlag(asfDisallowIncomingCheck);
-
1159 testSetClearFlag(asfDisallowIncomingNFTokenOffer);
-
1160 testSetClearFlag(asfDisallowIncomingPayChan);
-
1161 testSetClearFlag(asfDisallowIncomingTrustline);
-
1162 testSetClearFlag(asfDisallowXRP);
-
1163 testSetClearFlag(asfRequireDest);
-
1164 testSetClearFlag(asfGlobalFreeze);
-
1165
-
1166 // bob can not set asfAccountTxnID on behalf of alice
-
1167 env(fset(alice, asfAccountTxnID),
-
1168 delegate::as(bob),
-
1169 ter(tecNO_DELEGATE_PERMISSION));
-
1170 env(fset(alice, asfAccountTxnID));
-
1171 env.close();
-
1172 BEAST_EXPECT(env.le(alice)->isFieldPresent(sfAccountTxnID));
-
1173 env(fclear(alice, asfAccountTxnID),
-
1174 delegate::as(bob),
-
1175 ter(tecNO_DELEGATE_PERMISSION));
-
1176
-
1177 // bob can not set asfAuthorizedNFTokenMinter on behalf of alice
-
1178 Json::Value jt = fset(alice, asfAuthorizedNFTokenMinter);
-
1179 jt[sfDelegate] = bob.human();
-
1180 jt[sfNFTokenMinter] = bob.human();
-
1181 env(jt, ter(tecNO_DELEGATE_PERMISSION));
-
1182
-
1183 // bob gives alice some permissions
-
1184 env(delegate::set(
-
1185 bob,
-
1186 alice,
-
1187 {"AccountDomainSet",
-
1188 "AccountEmailHashSet",
-
1189 "AccountMessageKeySet"}));
-
1190 env.close();
-
1191
-
1192 // since we can not set asfNoFreeze if asfAllowTrustLineClawback is
-
1193 // set, which can not be clear either. Test alice set asfNoFreeze on
-
1194 // behalf of bob.
-
1195 env(fset(alice, asfNoFreeze),
-
1196 delegate::as(bob),
-
1197 ter(tecNO_DELEGATE_PERMISSION));
-
1198 env(fset(bob, asfNoFreeze));
-
1199 env.close();
-
1200 env.require(flags(bob, asfNoFreeze));
-
1201 // alice can not clear on behalf of bob
-
1202 env(fclear(alice, asfNoFreeze),
-
1203 delegate::as(bob),
-
1204 ter(tecNO_DELEGATE_PERMISSION));
-
1205
-
1206 // bob can not set asfDisableMaster on behalf of alice
-
1207 Account const bobKey{"bobKey", KeyType::secp256k1};
-
1208 env(regkey(bob, bobKey));
-
1209 env.close();
-
1210 env(fset(alice, asfDisableMaster),
-
1211 delegate::as(bob),
-
1212 sig(bob),
-
1213 ter(tecNO_DELEGATE_PERMISSION));
-
1214 }
-
1215
-
1216 // tfFullyCanonicalSig won't block delegated transaction
-
1217 {
-
1218 Env env(*this);
-
1219 Account alice{"alice"};
-
1220 Account bob{"bob"};
-
1221 env.fund(XRP(10000), alice, bob);
-
1222 env.close();
-
1223
-
1224 env(delegate::set(
-
1225 alice, bob, {"AccountDomainSet", "AccountEmailHashSet"}));
-
1226 env.close();
-
1227
-
1228 std::string const domain = "example.com";
-
1229 auto jt = noop(alice);
-
1230 jt[sfDomain] = strHex(domain);
-
1231 jt[sfDelegate] = bob.human();
-
1232 jt[sfFlags] = tfFullyCanonicalSig;
+
1097 auto testSetClearFlag = [&](std::uint32_t flag) {
+
1098 // bob can not set flag on behalf of alice
+
1099 env(fset(alice, flag),
+
1100 delegate::as(bob),
+
1101 ter(tecNO_DELEGATE_PERMISSION));
+
1102 // alice set by herself
+
1103 env(fset(alice, flag));
+
1104 env.close();
+
1105 env.require(flags(alice, flag));
+
1106 // bob can not clear on behalf of alice
+
1107 env(fclear(alice, flag),
+
1108 delegate::as(bob),
+
1109 ter(tecNO_DELEGATE_PERMISSION));
+
1110 };
+
1111
+
1112 // testSetClearFlag(asfNoFreeze);
+
1113 testSetClearFlag(asfRequireAuth);
+
1114 testSetClearFlag(asfAllowTrustLineClawback);
+
1115
+
1116 // alice gives some granular permissions to bob
+
1117 env(delegate::set(
+
1118 alice,
+
1119 bob,
+
1120 {"AccountDomainSet",
+
1121 "AccountEmailHashSet",
+
1122 "AccountMessageKeySet"}));
+
1123 env.close();
+
1124
+
1125 testSetClearFlag(asfDefaultRipple);
+
1126 testSetClearFlag(asfDepositAuth);
+
1127 testSetClearFlag(asfDisallowIncomingCheck);
+
1128 testSetClearFlag(asfDisallowIncomingNFTokenOffer);
+
1129 testSetClearFlag(asfDisallowIncomingPayChan);
+
1130 testSetClearFlag(asfDisallowIncomingTrustline);
+
1131 testSetClearFlag(asfDisallowXRP);
+
1132 testSetClearFlag(asfRequireDest);
+
1133 testSetClearFlag(asfGlobalFreeze);
+
1134
+
1135 // bob can not set asfAccountTxnID on behalf of alice
+
1136 env(fset(alice, asfAccountTxnID),
+
1137 delegate::as(bob),
+
1138 ter(tecNO_DELEGATE_PERMISSION));
+
1139 env(fset(alice, asfAccountTxnID));
+
1140 env.close();
+
1141 BEAST_EXPECT(env.le(alice)->isFieldPresent(sfAccountTxnID));
+
1142 env(fclear(alice, asfAccountTxnID),
+
1143 delegate::as(bob),
+
1144 ter(tecNO_DELEGATE_PERMISSION));
+
1145
+
1146 // bob can not set asfAuthorizedNFTokenMinter on behalf of alice
+
1147 Json::Value jt = fset(alice, asfAuthorizedNFTokenMinter);
+
1148 jt[sfDelegate] = bob.human();
+
1149 jt[sfNFTokenMinter] = bob.human();
+
1150 env(jt, ter(tecNO_DELEGATE_PERMISSION));
+
1151
+
1152 // bob gives alice some permissions
+
1153 env(delegate::set(
+
1154 bob,
+
1155 alice,
+
1156 {"AccountDomainSet",
+
1157 "AccountEmailHashSet",
+
1158 "AccountMessageKeySet"}));
+
1159 env.close();
+
1160
+
1161 // since we can not set asfNoFreeze if asfAllowTrustLineClawback is
+
1162 // set, which can not be clear either. Test alice set asfNoFreeze on
+
1163 // behalf of bob.
+
1164 env(fset(alice, asfNoFreeze),
+
1165 delegate::as(bob),
+
1166 ter(tecNO_DELEGATE_PERMISSION));
+
1167 env(fset(bob, asfNoFreeze));
+
1168 env.close();
+
1169 env.require(flags(bob, asfNoFreeze));
+
1170 // alice can not clear on behalf of bob
+
1171 env(fclear(alice, asfNoFreeze),
+
1172 delegate::as(bob),
+
1173 ter(tecNO_DELEGATE_PERMISSION));
+
1174
+
1175 // bob can not set asfDisableMaster on behalf of alice
+
1176 Account const bobKey{"bobKey", KeyType::secp256k1};
+
1177 env(regkey(bob, bobKey));
+
1178 env.close();
+
1179 env(fset(alice, asfDisableMaster),
+
1180 delegate::as(bob),
+
1181 sig(bob),
+
1182 ter(tecNO_DELEGATE_PERMISSION));
+
1183 }
+
1184
+
1185 // tfFullyCanonicalSig won't block delegated transaction
+
1186 {
+
1187 Env env(*this);
+
1188 Account alice{"alice"};
+
1189 Account bob{"bob"};
+
1190 env.fund(XRP(10000), alice, bob);
+
1191 env.close();
+
1192
+
1193 env(delegate::set(
+
1194 alice, bob, {"AccountDomainSet", "AccountEmailHashSet"}));
+
1195 env.close();
+
1196
+
1197 std::string const domain = "example.com";
+
1198 auto jt = noop(alice);
+
1199 jt[sfDomain] = strHex(domain);
+
1200 jt[sfDelegate] = bob.human();
+
1201 jt[sfFlags] = tfFullyCanonicalSig;
+
1202
+
1203 env(jt);
+
1204 BEAST_EXPECT((*env.le(alice))[sfDomain] == makeSlice(domain));
+
1205 }
+
1206 }
+
1207
+
1208 void
+
1209 testMPTokenIssuanceSetGranular()
+
1210 {
+
1211 testcase("test MPTokenIssuanceSet granular");
+
1212 using namespace jtx;
+
1213
+
1214 // test MPTokenIssuanceUnlock and MPTokenIssuanceLock permissions
+
1215 {
+
1216 Env env(*this);
+
1217 Account alice{"alice"};
+
1218 Account bob{"bob"};
+
1219 env.fund(XRP(100000), alice, bob);
+
1220 env.close();
+
1221
+
1222 MPTTester mpt(env, alice, {.fund = false});
+
1223 env.close();
+
1224 mpt.create({.flags = tfMPTCanLock});
+
1225 env.close();
+
1226
+
1227 // delegate ledger object is not created yet
+
1228 mpt.set(
+
1229 {.account = alice,
+
1230 .flags = tfMPTLock,
+
1231 .delegate = bob,
+
1232 .err = tecNO_DELEGATE_PERMISSION});
1233
-
1234 env(jt);
-
1235 BEAST_EXPECT((*env.le(alice))[sfDomain] == makeSlice(domain));
-
1236 }
-
1237
-
1238 // tfInnerBatchTxn won't block delegated transaction
-
1239 {
-
1240 Env env(*this);
-
1241 Account alice{"alice"};
-
1242 Account bob{"bob"};
-
1243 env.fund(XRP(10000), alice, bob);
-
1244 env.close();
-
1245
-
1246 env(delegate::set(
-
1247 alice, bob, {"AccountDomainSet", "AccountEmailHashSet"}));
-
1248 env.close();
-
1249
-
1250 auto const seq = env.seq(alice);
-
1251 auto const batchFee = batch::calcBatchFee(env, 0, 3);
+
1234 // alice gives granular permission to bob of MPTokenIssuanceUnlock
+
1235 env(delegate::set(alice, bob, {"MPTokenIssuanceUnlock"}));
+
1236 env.close();
+
1237 // bob does not have lock permission
+
1238 mpt.set(
+
1239 {.account = alice,
+
1240 .flags = tfMPTLock,
+
1241 .delegate = bob,
+
1242 .err = tecNO_DELEGATE_PERMISSION});
+
1243 // bob now has lock permission, but does not have unlock permission
+
1244 env(delegate::set(alice, bob, {"MPTokenIssuanceLock"}));
+
1245 env.close();
+
1246 mpt.set({.account = alice, .flags = tfMPTLock, .delegate = bob});
+
1247 mpt.set(
+
1248 {.account = alice,
+
1249 .flags = tfMPTUnlock,
+
1250 .delegate = bob,
+
1251 .err = tecNO_DELEGATE_PERMISSION});
1252
-
1253 auto jv1 = noop(alice);
-
1254 std::string const domain1 = "example1.com";
-
1255 jv1[sfDomain] = strHex(domain1);
-
1256 jv1[sfDelegate] = bob.human();
-
1257 jv1[sfSequence] = seq + 1;
-
1258
-
1259 auto jv2 = noop(alice);
-
1260 std::string const domain2 = "example2.com";
-
1261 jv2[sfDomain] = strHex(domain2);
-
1262 jv2[sfDelegate] = bob.human();
-
1263 jv2[sfSequence] = seq + 2;
-
1264
-
1265 // bob set domain back and add email hash for alice
-
1266 auto jv3 = noop(alice);
-
1267 std::string const mh("5F31A79367DC3137FADA860C05742EE6");
-
1268 jv3[sfDomain] = strHex(domain1);
-
1269 jv3[sfEmailHash] = mh;
-
1270 jv3[sfDelegate] = bob.human();
-
1271 jv3[sfSequence] = seq + 3;
-
1272
-
1273 // batch::inner will set tfInnerBatchTxn, this should not
-
1274 // block delegated transaction
-
1275 env(batch::outer(alice, seq, batchFee, tfAllOrNothing),
-
1276 batch::inner(jv1, seq + 1),
-
1277 batch::inner(jv2, seq + 2),
-
1278 batch::inner(jv3, seq + 3));
-
1279 env.close();
-
1280
-
1281 BEAST_EXPECT((*env.le(alice))[sfDomain] == makeSlice(domain1));
-
1282 BEAST_EXPECT(to_string((*env.le(alice))[sfEmailHash]) == mh);
-
1283 }
-
1284 }
+
1253 // now bob can lock and unlock
+
1254 env(delegate::set(
+
1255 alice, bob, {"MPTokenIssuanceLock", "MPTokenIssuanceUnlock"}));
+
1256 env.close();
+
1257 mpt.set({.account = alice, .flags = tfMPTUnlock, .delegate = bob});
+
1258 mpt.set({.account = alice, .flags = tfMPTLock, .delegate = bob});
+
1259 env.close();
+
1260 }
+
1261
+
1262 // test mix of granular and transaction level permission
+
1263 {
+
1264 Env env(*this);
+
1265 Account alice{"alice"};
+
1266 Account bob{"bob"};
+
1267 env.fund(XRP(100000), alice, bob);
+
1268 env.close();
+
1269
+
1270 MPTTester mpt(env, alice, {.fund = false});
+
1271 env.close();
+
1272 mpt.create({.flags = tfMPTCanLock});
+
1273 env.close();
+
1274
+
1275 // alice gives granular permission to bob of MPTokenIssuanceLock
+
1276 env(delegate::set(alice, bob, {"MPTokenIssuanceLock"}));
+
1277 env.close();
+
1278 mpt.set({.account = alice, .flags = tfMPTLock, .delegate = bob});
+
1279 // bob does not have unlock permission
+
1280 mpt.set(
+
1281 {.account = alice,
+
1282 .flags = tfMPTUnlock,
+
1283 .delegate = bob,
+
1284 .err = tecNO_DELEGATE_PERMISSION});
1285
-
1286 void
-
1287 testMPTokenIssuanceSetGranular()
-
1288 {
-
1289 testcase("test MPTokenIssuanceSet granular");
-
1290 using namespace jtx;
-
1291
-
1292 // test MPTokenIssuanceUnlock and MPTokenIssuanceLock permissions
-
1293 {
-
1294 Env env(*this);
-
1295 Account alice{"alice"};
-
1296 Account bob{"bob"};
-
1297 env.fund(XRP(100000), alice, bob);
-
1298 env.close();
+
1286 // alice gives bob some unrelated permission with
+
1287 // MPTokenIssuanceLock
+
1288 env(delegate::set(
+
1289 alice,
+
1290 bob,
+
1291 {"NFTokenMint", "MPTokenIssuanceLock", "NFTokenBurn"}));
+
1292 env.close();
+
1293 // bob can not unlock
+
1294 mpt.set(
+
1295 {.account = alice,
+
1296 .flags = tfMPTUnlock,
+
1297 .delegate = bob,
+
1298 .err = tecNO_DELEGATE_PERMISSION});
1299
-
1300 MPTTester mpt(env, alice, {.fund = false});
-
1301 env.close();
-
1302 mpt.create({.flags = tfMPTCanLock});
-
1303 env.close();
-
1304
-
1305 // delegate ledger object is not created yet
-
1306 mpt.set(
-
1307 {.account = alice,
-
1308 .flags = tfMPTLock,
-
1309 .delegate = bob,
-
1310 .err = tecNO_DELEGATE_PERMISSION});
-
1311
-
1312 // alice gives granular permission to bob of MPTokenIssuanceUnlock
-
1313 env(delegate::set(alice, bob, {"MPTokenIssuanceUnlock"}));
-
1314 env.close();
-
1315 // bob does not have lock permission
-
1316 mpt.set(
-
1317 {.account = alice,
-
1318 .flags = tfMPTLock,
-
1319 .delegate = bob,
-
1320 .err = tecNO_DELEGATE_PERMISSION});
-
1321 // bob now has lock permission, but does not have unlock permission
-
1322 env(delegate::set(alice, bob, {"MPTokenIssuanceLock"}));
-
1323 env.close();
-
1324 mpt.set({.account = alice, .flags = tfMPTLock, .delegate = bob});
-
1325 mpt.set(
-
1326 {.account = alice,
-
1327 .flags = tfMPTUnlock,
-
1328 .delegate = bob,
-
1329 .err = tecNO_DELEGATE_PERMISSION});
-
1330
-
1331 // now bob can lock and unlock
-
1332 env(delegate::set(
-
1333 alice, bob, {"MPTokenIssuanceLock", "MPTokenIssuanceUnlock"}));
-
1334 env.close();
-
1335 mpt.set({.account = alice, .flags = tfMPTUnlock, .delegate = bob});
-
1336 mpt.set({.account = alice, .flags = tfMPTLock, .delegate = bob});
-
1337 env.close();
-
1338 }
-
1339
-
1340 // test mix of granular and transaction level permission
-
1341 {
-
1342 Env env(*this);
-
1343 Account alice{"alice"};
-
1344 Account bob{"bob"};
-
1345 env.fund(XRP(100000), alice, bob);
-
1346 env.close();
-
1347
-
1348 MPTTester mpt(env, alice, {.fund = false});
-
1349 env.close();
-
1350 mpt.create({.flags = tfMPTCanLock});
-
1351 env.close();
-
1352
-
1353 // alice gives granular permission to bob of MPTokenIssuanceLock
-
1354 env(delegate::set(alice, bob, {"MPTokenIssuanceLock"}));
-
1355 env.close();
-
1356 mpt.set({.account = alice, .flags = tfMPTLock, .delegate = bob});
-
1357 // bob does not have unlock permission
-
1358 mpt.set(
-
1359 {.account = alice,
-
1360 .flags = tfMPTUnlock,
-
1361 .delegate = bob,
-
1362 .err = tecNO_DELEGATE_PERMISSION});
-
1363
-
1364 // alice gives bob some unrelated permission with
-
1365 // MPTokenIssuanceLock
-
1366 env(delegate::set(
-
1367 alice,
-
1368 bob,
-
1369 {"NFTokenMint", "MPTokenIssuanceLock", "NFTokenBurn"}));
-
1370 env.close();
-
1371 // bob can not unlock
-
1372 mpt.set(
-
1373 {.account = alice,
-
1374 .flags = tfMPTUnlock,
-
1375 .delegate = bob,
-
1376 .err = tecNO_DELEGATE_PERMISSION});
-
1377
-
1378 // alice add MPTokenIssuanceSet to permissions
-
1379 env(delegate::set(
-
1380 alice,
-
1381 bob,
-
1382 {"NFTokenMint",
-
1383 "MPTokenIssuanceLock",
-
1384 "NFTokenBurn",
-
1385 "MPTokenIssuanceSet"}));
-
1386 mpt.set({.account = alice, .flags = tfMPTUnlock, .delegate = bob});
-
1387 // alice can lock by herself
-
1388 mpt.set({.account = alice, .flags = tfMPTLock});
-
1389 mpt.set({.account = alice, .flags = tfMPTUnlock, .delegate = bob});
-
1390 mpt.set({.account = alice, .flags = tfMPTLock, .delegate = bob});
-
1391 }
-
1392
-
1393 // tfFullyCanonicalSig won't block delegated transaction
-
1394 {
-
1395 Env env(*this);
-
1396 Account alice{"alice"};
-
1397 Account bob{"bob"};
-
1398 env.fund(XRP(100000), alice, bob);
-
1399 env.close();
-
1400
-
1401 MPTTester mpt(env, alice, {.fund = false});
-
1402 env.close();
-
1403 mpt.create({.flags = tfMPTCanLock});
-
1404 env.close();
-
1405
-
1406 // alice gives granular permission to bob of MPTokenIssuanceLock
-
1407 env(delegate::set(alice, bob, {"MPTokenIssuanceLock"}));
-
1408 env.close();
-
1409 mpt.set(
-
1410 {.account = alice,
-
1411 .flags = tfMPTLock | tfFullyCanonicalSig,
-
1412 .delegate = bob});
-
1413 }
-
1414
-
1415 // tfInnerBatchTxn won't block delegated transaction
-
1416 {
-
1417 Env env(*this);
-
1418 Account alice{"alice"};
-
1419 Account bob{"bob"};
-
1420 env.fund(XRP(100000), alice, bob);
-
1421 env.close();
-
1422
-
1423 auto const mptID = makeMptID(env.seq(alice), alice);
-
1424 MPTTester mpt(env, alice, {.fund = false});
-
1425 env.close();
-
1426 mpt.create({.flags = tfMPTCanLock});
-
1427 env.close();
-
1428
-
1429 // alice gives granular permission to bob of MPTokenIssuanceLock
-
1430 env(delegate::set(
-
1431 alice, bob, {"MPTokenIssuanceLock", "MPTokenIssuanceUnlock"}));
-
1432 env.close();
-
1433
-
1434 auto const seq = env.seq(alice);
-
1435 auto const batchFee = batch::calcBatchFee(env, 0, 2);
-
1436
-
1437 Json::Value jv1;
-
1438 jv1[sfTransactionType] = jss::MPTokenIssuanceSet;
-
1439 jv1[sfAccount] = alice.human();
-
1440 jv1[sfDelegate] = bob.human();
-
1441 jv1[sfSequence] = seq + 1;
-
1442 jv1[sfMPTokenIssuanceID] = to_string(mptID);
-
1443 jv1[sfFlags] = tfMPTLock;
-
1444
-
1445 Json::Value jv2;
-
1446 jv2[sfTransactionType] = jss::MPTokenIssuanceSet;
-
1447 jv2[sfAccount] = alice.human();
-
1448 jv2[sfDelegate] = bob.human();
-
1449 jv2[sfSequence] = seq + 2;
-
1450 jv2[sfMPTokenIssuanceID] = to_string(mptID);
-
1451 jv2[sfFlags] = tfMPTUnlock;
-
1452
-
1453 // batch::inner will set tfInnerBatchTxn, this should not
-
1454 // block delegated transaction
-
1455 env(batch::outer(alice, seq, batchFee, tfAllOrNothing),
-
1456 batch::inner(jv1, seq + 1),
-
1457 batch::inner(jv2, seq + 2));
-
1458 env.close();
-
1459 }
-
1460 }
-
1461
-
1462 void
-
1463 testSingleSign()
-
1464 {
-
1465 testcase("test single sign");
-
1466 using namespace jtx;
-
1467
-
1468 Env env(*this);
-
1469 Account alice{"alice"};
-
1470 Account bob{"bob"};
-
1471 Account carol{"carol"};
-
1472 env.fund(XRP(100000), alice, bob, carol);
-
1473 env.close();
-
1474
-
1475 env(delegate::set(alice, bob, {"Payment"}));
-
1476 env.close();
-
1477
-
1478 auto aliceBalance = env.balance(alice);
-
1479 auto bobBalance = env.balance(bob);
-
1480 auto carolBalance = env.balance(carol);
-
1481
-
1482 env(pay(alice, carol, XRP(100)),
-
1483 fee(XRP(10)),
-
1484 delegate::as(bob),
-
1485 sig(bob));
-
1486 env.close();
-
1487 BEAST_EXPECT(env.balance(alice) == aliceBalance - XRP(100));
-
1488 BEAST_EXPECT(env.balance(bob) == bobBalance - XRP(10));
-
1489 BEAST_EXPECT(env.balance(carol) == carolBalance + XRP(100));
-
1490 }
-
1491
-
1492 void
-
1493 testSingleSignBadSecret()
-
1494 {
-
1495 testcase("test single sign with bad secret");
-
1496 using namespace jtx;
-
1497
-
1498 Env env(*this);
-
1499 Account alice{"alice"};
-
1500 Account bob{"bob"};
-
1501 Account carol{"carol"};
-
1502 env.fund(XRP(100000), alice, bob, carol);
-
1503 env.close();
-
1504
-
1505 env(delegate::set(alice, bob, {"Payment"}));
-
1506 env.close();
-
1507
-
1508 auto aliceBalance = env.balance(alice);
-
1509 auto bobBalance = env.balance(bob);
-
1510 auto carolBalance = env.balance(carol);
-
1511
-
1512 env(pay(alice, carol, XRP(100)),
-
1513 fee(XRP(10)),
-
1514 delegate::as(bob),
-
1515 sig(alice),
-
1516 ter(tefBAD_AUTH));
-
1517 env.close();
-
1518 BEAST_EXPECT(env.balance(alice) == aliceBalance);
-
1519 BEAST_EXPECT(env.balance(bob) == bobBalance);
-
1520 BEAST_EXPECT(env.balance(carol) == carolBalance);
-
1521 }
-
1522
-
1523 void
-
1524 testMultiSign()
-
1525 {
-
1526 testcase("test multi sign");
-
1527 using namespace jtx;
-
1528
-
1529 Env env(*this);
-
1530 Account alice{"alice"};
-
1531 Account bob{"bob"};
-
1532 Account carol{"carol"};
-
1533 Account daria{"daria"};
-
1534 Account edward{"edward"};
-
1535 env.fund(XRP(100000), alice, bob, carol, daria, edward);
-
1536 env.close();
-
1537
-
1538 env(signers(bob, 2, {{daria, 1}, {edward, 1}}));
-
1539 env.close();
-
1540
-
1541 env(delegate::set(alice, bob, {"Payment"}));
-
1542 env.close();
-
1543
-
1544 auto aliceBalance = env.balance(alice);
-
1545 auto bobBalance = env.balance(bob);
-
1546 auto carolBalance = env.balance(carol);
-
1547 auto dariaBalance = env.balance(daria);
-
1548 auto edwardBalance = env.balance(edward);
-
1549
-
1550 env(pay(alice, carol, XRP(100)),
-
1551 fee(XRP(10)),
-
1552 delegate::as(bob),
-
1553 msig(daria, edward));
-
1554 env.close();
-
1555 BEAST_EXPECT(env.balance(alice) == aliceBalance - XRP(100));
-
1556 BEAST_EXPECT(env.balance(bob) == bobBalance - XRP(10));
-
1557 BEAST_EXPECT(env.balance(carol) == carolBalance + XRP(100));
-
1558 BEAST_EXPECT(env.balance(daria) == dariaBalance);
-
1559 BEAST_EXPECT(env.balance(edward) == edwardBalance);
-
1560 }
-
1561
-
1562 void
-
1563 testMultiSignQuorumNotMet()
-
1564 {
-
1565 testcase("test multi sign which does not meet quorum");
-
1566 using namespace jtx;
-
1567
-
1568 Env env(*this);
-
1569 Account alice{"alice"};
-
1570 Account bob{"bob"};
-
1571 Account carol{"carol"};
-
1572 Account daria = Account{"daria"};
-
1573 Account edward = Account{"edward"};
-
1574 Account fred = Account{"fred"};
-
1575 env.fund(XRP(100000), alice, bob, carol, daria, edward, fred);
-
1576 env.close();
-
1577
-
1578 env(signers(bob, 3, {{daria, 1}, {edward, 1}, {fred, 1}}));
-
1579 env.close();
-
1580
-
1581 env(delegate::set(alice, bob, {"Payment"}));
-
1582 env.close();
-
1583
-
1584 auto aliceBalance = env.balance(alice);
-
1585 auto bobBalance = env.balance(bob);
-
1586 auto carolBalance = env.balance(carol);
-
1587 auto dariaBalance = env.balance(daria);
-
1588 auto edwardBalance = env.balance(edward);
-
1589
-
1590 env(pay(alice, carol, XRP(100)),
-
1591 fee(XRP(10)),
-
1592 delegate::as(bob),
-
1593 msig(daria, edward),
-
1594 ter(tefBAD_QUORUM));
-
1595 env.close();
-
1596 BEAST_EXPECT(env.balance(alice) == aliceBalance);
-
1597 BEAST_EXPECT(env.balance(bob) == bobBalance);
-
1598 BEAST_EXPECT(env.balance(carol) == carolBalance);
-
1599 BEAST_EXPECT(env.balance(daria) == dariaBalance);
-
1600 BEAST_EXPECT(env.balance(edward) == edwardBalance);
-
1601 }
-
1602
-
1603 void
-
1604 run() override
-
1605 {
-
1606 testFeatureDisabled();
-
1607 testDelegateSet();
-
1608 testInvalidRequest();
-
1609 testReserve();
-
1610 testFee();
-
1611 testSequence();
-
1612 testAccountDelete();
-
1613 testDelegateTransaction();
-
1614 testPaymentGranular();
-
1615 testTrustSetGranular();
-
1616 testAccountSetGranular();
-
1617 testMPTokenIssuanceSetGranular();
-
1618 testSingleSign();
-
1619 testSingleSignBadSecret();
-
1620 testMultiSign();
-
1621 testMultiSignQuorumNotMet();
-
1622 }
-
1623};
-
1624BEAST_DEFINE_TESTSUITE(Delegate, app, ripple);
-
1625} // namespace test
-
1626} // namespace ripple
+
1300 // alice add MPTokenIssuanceSet to permissions
+
1301 env(delegate::set(
+
1302 alice,
+
1303 bob,
+
1304 {"NFTokenMint",
+
1305 "MPTokenIssuanceLock",
+
1306 "NFTokenBurn",
+
1307 "MPTokenIssuanceSet"}));
+
1308 mpt.set({.account = alice, .flags = tfMPTUnlock, .delegate = bob});
+
1309 // alice can lock by herself
+
1310 mpt.set({.account = alice, .flags = tfMPTLock});
+
1311 mpt.set({.account = alice, .flags = tfMPTUnlock, .delegate = bob});
+
1312 mpt.set({.account = alice, .flags = tfMPTLock, .delegate = bob});
+
1313 }
+
1314
+
1315 // tfFullyCanonicalSig won't block delegated transaction
+
1316 {
+
1317 Env env(*this);
+
1318 Account alice{"alice"};
+
1319 Account bob{"bob"};
+
1320 env.fund(XRP(100000), alice, bob);
+
1321 env.close();
+
1322
+
1323 MPTTester mpt(env, alice, {.fund = false});
+
1324 env.close();
+
1325 mpt.create({.flags = tfMPTCanLock});
+
1326 env.close();
+
1327
+
1328 // alice gives granular permission to bob of MPTokenIssuanceLock
+
1329 env(delegate::set(alice, bob, {"MPTokenIssuanceLock"}));
+
1330 env.close();
+
1331 mpt.set(
+
1332 {.account = alice,
+
1333 .flags = tfMPTLock | tfFullyCanonicalSig,
+
1334 .delegate = bob});
+
1335 }
+
1336 }
+
1337
+
1338 void
+
1339 testSingleSign()
+
1340 {
+
1341 testcase("test single sign");
+
1342 using namespace jtx;
+
1343
+
1344 Env env(*this);
+
1345 Account alice{"alice"};
+
1346 Account bob{"bob"};
+
1347 Account carol{"carol"};
+
1348 env.fund(XRP(100000), alice, bob, carol);
+
1349 env.close();
+
1350
+
1351 env(delegate::set(alice, bob, {"Payment"}));
+
1352 env.close();
+
1353
+
1354 auto aliceBalance = env.balance(alice);
+
1355 auto bobBalance = env.balance(bob);
+
1356 auto carolBalance = env.balance(carol);
+
1357
+
1358 env(pay(alice, carol, XRP(100)),
+
1359 fee(XRP(10)),
+
1360 delegate::as(bob),
+
1361 sig(bob));
+
1362 env.close();
+
1363 BEAST_EXPECT(env.balance(alice) == aliceBalance - XRP(100));
+
1364 BEAST_EXPECT(env.balance(bob) == bobBalance - XRP(10));
+
1365 BEAST_EXPECT(env.balance(carol) == carolBalance + XRP(100));
+
1366 }
+
1367
+
1368 void
+
1369 testSingleSignBadSecret()
+
1370 {
+
1371 testcase("test single sign with bad secret");
+
1372 using namespace jtx;
+
1373
+
1374 Env env(*this);
+
1375 Account alice{"alice"};
+
1376 Account bob{"bob"};
+
1377 Account carol{"carol"};
+
1378 env.fund(XRP(100000), alice, bob, carol);
+
1379 env.close();
+
1380
+
1381 env(delegate::set(alice, bob, {"Payment"}));
+
1382 env.close();
+
1383
+
1384 auto aliceBalance = env.balance(alice);
+
1385 auto bobBalance = env.balance(bob);
+
1386 auto carolBalance = env.balance(carol);
+
1387
+
1388 env(pay(alice, carol, XRP(100)),
+
1389 fee(XRP(10)),
+
1390 delegate::as(bob),
+
1391 sig(alice),
+
1392 ter(tefBAD_AUTH));
+
1393 env.close();
+
1394 BEAST_EXPECT(env.balance(alice) == aliceBalance);
+
1395 BEAST_EXPECT(env.balance(bob) == bobBalance);
+
1396 BEAST_EXPECT(env.balance(carol) == carolBalance);
+
1397 }
+
1398
+
1399 void
+
1400 testMultiSign()
+
1401 {
+
1402 testcase("test multi sign");
+
1403 using namespace jtx;
+
1404
+
1405 Env env(*this);
+
1406 Account alice{"alice"};
+
1407 Account bob{"bob"};
+
1408 Account carol{"carol"};
+
1409 Account daria{"daria"};
+
1410 Account edward{"edward"};
+
1411 env.fund(XRP(100000), alice, bob, carol, daria, edward);
+
1412 env.close();
+
1413
+
1414 env(signers(bob, 2, {{daria, 1}, {edward, 1}}));
+
1415 env.close();
+
1416
+
1417 env(delegate::set(alice, bob, {"Payment"}));
+
1418 env.close();
+
1419
+
1420 auto aliceBalance = env.balance(alice);
+
1421 auto bobBalance = env.balance(bob);
+
1422 auto carolBalance = env.balance(carol);
+
1423 auto dariaBalance = env.balance(daria);
+
1424 auto edwardBalance = env.balance(edward);
+
1425
+
1426 env(pay(alice, carol, XRP(100)),
+
1427 fee(XRP(10)),
+
1428 delegate::as(bob),
+
1429 msig(daria, edward));
+
1430 env.close();
+
1431 BEAST_EXPECT(env.balance(alice) == aliceBalance - XRP(100));
+
1432 BEAST_EXPECT(env.balance(bob) == bobBalance - XRP(10));
+
1433 BEAST_EXPECT(env.balance(carol) == carolBalance + XRP(100));
+
1434 BEAST_EXPECT(env.balance(daria) == dariaBalance);
+
1435 BEAST_EXPECT(env.balance(edward) == edwardBalance);
+
1436 }
+
1437
+
1438 void
+
1439 testMultiSignQuorumNotMet()
+
1440 {
+
1441 testcase("test multi sign which does not meet quorum");
+
1442 using namespace jtx;
+
1443
+
1444 Env env(*this);
+
1445 Account alice{"alice"};
+
1446 Account bob{"bob"};
+
1447 Account carol{"carol"};
+
1448 Account daria = Account{"daria"};
+
1449 Account edward = Account{"edward"};
+
1450 Account fred = Account{"fred"};
+
1451 env.fund(XRP(100000), alice, bob, carol, daria, edward, fred);
+
1452 env.close();
+
1453
+
1454 env(signers(bob, 3, {{daria, 1}, {edward, 1}, {fred, 1}}));
+
1455 env.close();
+
1456
+
1457 env(delegate::set(alice, bob, {"Payment"}));
+
1458 env.close();
+
1459
+
1460 auto aliceBalance = env.balance(alice);
+
1461 auto bobBalance = env.balance(bob);
+
1462 auto carolBalance = env.balance(carol);
+
1463 auto dariaBalance = env.balance(daria);
+
1464 auto edwardBalance = env.balance(edward);
+
1465
+
1466 env(pay(alice, carol, XRP(100)),
+
1467 fee(XRP(10)),
+
1468 delegate::as(bob),
+
1469 msig(daria, edward),
+
1470 ter(tefBAD_QUORUM));
+
1471 env.close();
+
1472 BEAST_EXPECT(env.balance(alice) == aliceBalance);
+
1473 BEAST_EXPECT(env.balance(bob) == bobBalance);
+
1474 BEAST_EXPECT(env.balance(carol) == carolBalance);
+
1475 BEAST_EXPECT(env.balance(daria) == dariaBalance);
+
1476 BEAST_EXPECT(env.balance(edward) == edwardBalance);
+
1477 }
+
1478
+
1479 void
+
1480 run() override
+
1481 {
+
1482 testFeatureDisabled();
+
1483 testDelegateSet();
+
1484 testInvalidRequest();
+
1485 testReserve();
+
1486 testFee();
+
1487 testSequence();
+
1488 testAccountDelete();
+
1489 testDelegateTransaction();
+
1490 testPaymentGranular();
+
1491 testTrustSetGranular();
+
1492 testAccountSetGranular();
+
1493 testMPTokenIssuanceSetGranular();
+
1494 testSingleSign();
+
1495 testSingleSignBadSecret();
+
1496 testMultiSign();
+
1497 testMultiSignQuorumNotMet();
+
1498 }
+
1499};
+
1500BEAST_DEFINE_TESTSUITE(Delegate, app, ripple);
+
1501} // namespace test
+
1502} // namespace ripple
Represents a JSON value.
Definition: json_value.h:150
Value & append(Value const &value)
Append value to array at the end.
Definition: json_value.cpp:910
@@ -1711,21 +1587,21 @@ $(function() {
void testFeatureDisabled()
void testTrustSetGranular()
-
void run() override
Runs the suite.
-
void testMPTokenIssuanceSetGranular()
+
void run() override
Runs the suite.
+
void testMPTokenIssuanceSetGranular()
void testDelegateSet()
void testFee()
-
void testMultiSign()
+
void testMultiSign()
void testInvalidRequest()
void testSequence()
void testPaymentGranular()
-
void testSingleSignBadSecret()
+
void testSingleSignBadSecret()
void testReserve()
void testDelegateTransaction()
-
void testSingleSign()
+
void testSingleSign()
void testAccountDelete()
-
void testMultiSignQuorumNotMet()
-
void testAccountSetGranular()
+
void testMultiSignQuorumNotMet()
+
void testAccountSetGranular()
Immutable cryptographic account descriptor.
Definition: Account.h:39
A transaction testing environment.
Definition: Env.h:121
std::shared_ptr< ReadView const > closed()
Returns the last closed ledger.
Definition: Env.cpp:111
@@ -1739,7 +1615,6 @@ $(function() {
std::shared_ptr< SLE const > le(Account const &account) const
Return an account root.
Definition: Env.cpp:263
Definition: mpt.h:145
A balance matches.
Definition: balance.h:39
-
Adds a new Batch Txn on a JTx and autofills.
Definition: batch.h:61
Sets the optional URI on a DIDSet.
Definition: did.h:60
Set the domain on a JTx.
Definition: domain.h:30
Set the fee on a JTx.
Definition: fee.h:37
@@ -1752,8 +1627,6 @@ $(function() {
Keylet delegate(AccountID const &account, AccountID const &authorizedAccount) noexcept
A keylet for Delegate object.
Definition: Indexes.cpp:465
Keylet account(AccountID const &id) noexcept
AccountID root.
Definition: Indexes.cpp:184
Keylet ownerDir(AccountID const &id) noexcept
The root page of an account's directory.
Definition: Indexes.cpp:374
-
Json::Value outer(jtx::Account const &account, uint32_t seq, STAmount const &fee, std::uint32_t flags)
Batch.
Definition: batch.cpp:49
-
XRPAmount calcBatchFee(jtx::Env const &env, uint32_t const &numSigners, uint32_t const &txns=0)
Calculate Batch Fee.
Definition: batch.cpp:38
Json::Value create(A const &account, A const &dest, STAmount const &sendMax)
Create a check.
Definition: TestHelpers.h:329
Json::Value entry(jtx::Env &env, jtx::Account const &account, jtx::Account const &authorize)
Definition: delegate.cpp:55
Json::Value set(jtx::Account const &account, jtx::Account const &authorize, std::vector< std::string > const &permissions)
Definition: delegate.cpp:31
@@ -1770,7 +1643,6 @@ $(function() {
XRP_t const XRP
Converts to XRP Issue or STAmount.
Definition: amount.cpp:105
FeatureBitset supported_amendments()
Definition: Env.h:74
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: algorithm.h:26
-
constexpr std::uint32_t tfAllOrNothing
Definition: TxFlags.h:240
constexpr std::uint32_t asfGlobalFreeze
Definition: TxFlags.h:83
constexpr std::uint32_t asfDepositAuth
Definition: TxFlags.h:85
constexpr std::uint32_t asfDisallowIncomingNFTokenOffer
Definition: TxFlags.h:90
@@ -1808,7 +1680,6 @@ $(function() {
constexpr std::uint32_t tfFullyCanonicalSig
Transaction flags.
Definition: TxFlags.h:60
constexpr std::uint32_t asfAllowTrustLineClawback
Definition: TxFlags.h:94
constexpr std::uint32_t asfRequireAuth
Definition: TxFlags.h:78
-
MPTID makeMptID(std::uint32_t sequence, AccountID const &account)
Definition: Indexes.cpp:170
@ terINSUF_FEE_B
Definition: TER.h:216
constexpr std::uint32_t tfSetFreeze
Definition: TxFlags.h:118
constexpr std::uint32_t tfSetNoRipple
Definition: TxFlags.h:116
@@ -1821,7 +1692,6 @@ $(function() {
@ temARRAY_TOO_LARGE
Definition: TER.h:141
@ temDISABLED
Definition: TER.h:114
Definition: delegate.h:43
-
Set the sequence number on a JTx.
Definition: seq.h:34
diff --git a/classripple_1_1test_1_1Batch__test.html b/classripple_1_1test_1_1Batch__test.html index d87977a7d5..8eff0d1b59 100644 --- a/classripple_1_1test_1_1Batch__test.html +++ b/classripple_1_1test_1_1Batch__test.html @@ -1389,7 +1389,7 @@ template<typename... Args>
-

Definition at line 3816 of file Batch_test.cpp.

+

Definition at line 3957 of file Batch_test.cpp.

@@ -1420,7 +1420,7 @@ template<typename... Args>

Implements beast::unit_test::suite.

-

Definition at line 3849 of file Batch_test.cpp.

+

Definition at line 3990 of file Batch_test.cpp.

diff --git a/classripple_1_1test_1_1Delegate__test.html b/classripple_1_1test_1_1Delegate__test.html index 3648dc9bc0..75157f7427 100644 --- a/classripple_1_1test_1_1Delegate__test.html +++ b/classripple_1_1test_1_1Delegate__test.html @@ -545,7 +545,7 @@ Private Attributes
-

Definition at line 950 of file Delegate_test.cpp.

+

Definition at line 919 of file Delegate_test.cpp.

@@ -572,7 +572,7 @@ Private Attributes
-

Definition at line 1287 of file Delegate_test.cpp.

+

Definition at line 1209 of file Delegate_test.cpp.

@@ -599,7 +599,7 @@ Private Attributes
-

Definition at line 1463 of file Delegate_test.cpp.

+

Definition at line 1339 of file Delegate_test.cpp.

@@ -626,7 +626,7 @@ Private Attributes
-

Definition at line 1493 of file Delegate_test.cpp.

+

Definition at line 1369 of file Delegate_test.cpp.

@@ -653,7 +653,7 @@ Private Attributes
-

Definition at line 1524 of file Delegate_test.cpp.

+

Definition at line 1400 of file Delegate_test.cpp.

@@ -680,7 +680,7 @@ Private Attributes
-

Definition at line 1563 of file Delegate_test.cpp.

+

Definition at line 1439 of file Delegate_test.cpp.

@@ -711,7 +711,7 @@ Private Attributes

Implements beast::unit_test::suite.

-

Definition at line 1604 of file Delegate_test.cpp.

+

Definition at line 1480 of file Delegate_test.cpp.