mirror of
https://github.com/XRPLF/rippled.git
synced 2026-06-04 17:27:00 +00:00
Transfer Trustline Sponsorship
This commit is contained in:
@@ -2299,16 +2299,16 @@ public:
|
||||
BEAST_EXPECT(sponsoredOwnerCount(env, alice) == 1);
|
||||
BEAST_EXPECT(sponsoringOwnerCount(env, sponsor) == 1);
|
||||
|
||||
// // transfer sponsor
|
||||
// env(sponsor::transfer(alice, keylet::signers(alice).key),
|
||||
// sponsor::as(sponsor2, tfSponsorReserve),
|
||||
// sponsor::sig(sponsor2));
|
||||
// env.close();
|
||||
// transfer sponsor
|
||||
env(sponsor::transfer(alice, keylet::signers(alice).key),
|
||||
sponsor::as(sponsor2, tfSponsorReserve),
|
||||
sponsor::sig(sponsor2));
|
||||
env.close();
|
||||
|
||||
// BEAST_EXPECT(ownerCount(env, alice) == 1);
|
||||
// BEAST_EXPECT(sponsoredOwnerCount(env, alice) == 1);
|
||||
// BEAST_EXPECT(sponsoringOwnerCount(env, sponsor) == 0);
|
||||
// BEAST_EXPECT(sponsoringOwnerCount(env, sponsor2) == 1);
|
||||
BEAST_EXPECT(ownerCount(env, alice) == 1);
|
||||
BEAST_EXPECT(sponsoredOwnerCount(env, alice) == 1);
|
||||
BEAST_EXPECT(sponsoringOwnerCount(env, sponsor) == 0);
|
||||
BEAST_EXPECT(sponsoringOwnerCount(env, sponsor2) == 1);
|
||||
|
||||
// Delete
|
||||
env(signers(alice, none));
|
||||
@@ -2329,8 +2329,9 @@ public:
|
||||
Account const alice("alice");
|
||||
Account const bob("bob");
|
||||
Account const sponsor("sponsor");
|
||||
Account const sponsor2("sponsor2");
|
||||
|
||||
env.fund(XRP(1000000), alice, bob, sponsor);
|
||||
env.fund(XRP(1000000), alice, bob, sponsor, sponsor2);
|
||||
env.close();
|
||||
|
||||
auto const& highAcc = alice > bob ? alice : bob;
|
||||
@@ -2352,11 +2353,33 @@ public:
|
||||
BEAST_EXPECT(sponsoredOwnerCount(env, user) == 1);
|
||||
BEAST_EXPECT(sponsoringOwnerCount(env, sponsor) == 1);
|
||||
|
||||
auto const line = env.le(keylet::line(user, issuer, USD.currency));
|
||||
BEAST_EXPECT(
|
||||
env.le(keylet::line(user, issuer, USD.currency))
|
||||
->getAccountID(
|
||||
isIssuerHigh ? sfLowSponsorAccount
|
||||
: sfHighSponsorAccount) == sponsor.id());
|
||||
line->getAccountID(
|
||||
isIssuerHigh ? sfLowSponsorAccount
|
||||
: sfHighSponsorAccount) == sponsor.id());
|
||||
BEAST_EXPECT(!line->isFieldPresent(
|
||||
isIssuerHigh ? sfHighSponsorAccount : sfLowSponsorAccount));
|
||||
|
||||
// transfer sponsor
|
||||
env(sponsor::transfer(
|
||||
user, keylet::line(user, issuer, USD.currency).key),
|
||||
sponsor::as(sponsor2, tfSponsorReserve),
|
||||
sponsor::sig(sponsor2));
|
||||
env.close();
|
||||
|
||||
BEAST_EXPECT(ownerCount(env, user) == 1);
|
||||
BEAST_EXPECT(sponsoredOwnerCount(env, user) == 1);
|
||||
BEAST_EXPECT(sponsoringOwnerCount(env, sponsor) == 0);
|
||||
BEAST_EXPECT(sponsoringOwnerCount(env, sponsor2) == 1);
|
||||
|
||||
auto const line2 = env.le(keylet::line(user, issuer, USD.currency));
|
||||
BEAST_EXPECT(
|
||||
line2->getAccountID(
|
||||
isIssuerHigh ? sfLowSponsorAccount
|
||||
: sfHighSponsorAccount) == sponsor2.id());
|
||||
BEAST_EXPECT(!line2->isFieldPresent(
|
||||
isIssuerHigh ? sfHighSponsorAccount : sfLowSponsorAccount));
|
||||
|
||||
// delete TrustLine
|
||||
env(trust(user, USD(0)));
|
||||
@@ -2368,7 +2391,6 @@ public:
|
||||
|
||||
BEAST_EXPECT(!env.le(keylet::line(user, issuer, USD.currency)));
|
||||
}
|
||||
// TODO: transfer sponsor
|
||||
}
|
||||
|
||||
void
|
||||
@@ -2598,6 +2620,7 @@ public:
|
||||
void
|
||||
testSponsorReserve()
|
||||
{
|
||||
// TODO: add checks fo InsufficientReserve for Sponsoring ledger entry
|
||||
testRequireFlag();
|
||||
testCheck();
|
||||
testOffer();
|
||||
|
||||
@@ -95,7 +95,23 @@ getLedgerEntryOwner(
|
||||
uint256 const& key = sle->key();
|
||||
return AccountID::fromVoid(key.data());
|
||||
}
|
||||
// case ltRIPPLE_STATE:
|
||||
case ltRIPPLE_STATE: {
|
||||
if (sle->isFlag(lsfHighReserve))
|
||||
{
|
||||
auto const highAccount =
|
||||
sle->getFieldAmount(sfHighLimit).getIssuer();
|
||||
if (highAccount == account)
|
||||
return highAccount;
|
||||
}
|
||||
if (sle->isFlag(lsfLowReserve))
|
||||
{
|
||||
auto const lowAccount =
|
||||
sle->getFieldAmount(sfLowLimit).getIssuer();
|
||||
if (lowAccount == account)
|
||||
return lowAccount;
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
case ltACCOUNT_ROOT: {
|
||||
// AccountRoot is not supported for object sponsorship
|
||||
return std::nullopt;
|
||||
@@ -126,6 +142,37 @@ getLedgerEntryOwnerCount(T const& sle)
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
inline SF_ACCOUNT const&
|
||||
getLedgerEntrySponsorField(T const& sle, AccountID const& owner)
|
||||
{
|
||||
switch (sle->getType())
|
||||
{
|
||||
case ltRIPPLE_STATE: {
|
||||
if (sle->isFlag(lsfHighReserve))
|
||||
{
|
||||
auto const highAccount =
|
||||
sle->getFieldAmount(sfHighLimit).getIssuer();
|
||||
if (highAccount == owner)
|
||||
return sfHighSponsorAccount;
|
||||
}
|
||||
if (sle->isFlag(lsfLowReserve))
|
||||
{
|
||||
auto const lowAccount =
|
||||
sle->getFieldAmount(sfLowLimit).getIssuer();
|
||||
if (lowAccount == owner)
|
||||
return sfLowSponsorAccount;
|
||||
}
|
||||
XRPL_ASSERT(
|
||||
false,
|
||||
"Should not happen. Owner should be checked before calling "
|
||||
"this function.");
|
||||
}
|
||||
default:
|
||||
return sfSponsorAccount;
|
||||
}
|
||||
};
|
||||
|
||||
TER
|
||||
SponsorshipTransfer::preclaim(PreclaimContext const& ctx)
|
||||
{
|
||||
@@ -151,11 +198,14 @@ SponsorshipTransfer::preclaim(PreclaimContext const& ctx)
|
||||
if (!owner || owner != ctx.tx[sfAccount])
|
||||
return tecNO_PERMISSION;
|
||||
|
||||
auto const& sponsorField = getLedgerEntrySponsorField(sle, *owner);
|
||||
|
||||
if (newSponsor)
|
||||
{
|
||||
if (sle->isFieldPresent(sfSponsorAccount))
|
||||
if (sle->isFieldPresent(sponsorField))
|
||||
{
|
||||
// transfer sponsor
|
||||
// check if the object owner isn't the same as the new sponsor
|
||||
if ((*newSponsor)->getAccountID(sfAccount) == owner)
|
||||
return tecNO_PERMISSION;
|
||||
}
|
||||
@@ -164,7 +214,7 @@ SponsorshipTransfer::preclaim(PreclaimContext const& ctx)
|
||||
{
|
||||
// dissolve sponsor
|
||||
// check object is sponsored
|
||||
if (!sle->isFieldPresent(sfSponsorAccount))
|
||||
if (!sle->isFieldPresent(sponsorField))
|
||||
return tecNO_PERMISSION;
|
||||
}
|
||||
|
||||
@@ -242,10 +292,12 @@ SponsorshipTransfer::doApply()
|
||||
|
||||
auto const ownerCountDelta = getLedgerEntryOwnerCount(objSle);
|
||||
|
||||
auto const& sponsorField = getLedgerEntrySponsorField(objSle, *owner);
|
||||
|
||||
if (tx.isFieldPresent(sfSponsor))
|
||||
{
|
||||
auto const sponsorObj = tx.getFieldObject(sfSponsor);
|
||||
auto const oldSponsor = objSle->getAccountID(sfSponsorAccount);
|
||||
auto const oldSponsor = objSle->getAccountID(sponsorField);
|
||||
auto const newSponsor = sponsorObj[sfAccount];
|
||||
// decrement old sponsoring count if exists
|
||||
if (auto const oldSponsorSle =
|
||||
@@ -279,7 +331,7 @@ SponsorshipTransfer::doApply()
|
||||
ownerCountDelta);
|
||||
view().update(newSponsorSle);
|
||||
|
||||
objSle->setAccountID(sfSponsorAccount, newSponsor);
|
||||
objSle->setAccountID(sponsorField, newSponsor);
|
||||
view().update(objSle);
|
||||
}
|
||||
else
|
||||
|
||||
Reference in New Issue
Block a user