Compare commits

...

3 Commits

Author SHA1 Message Date
Denis Angell
6cb1485d5c Update View.h 2023-11-30 17:48:33 +01:00
Denis Angell
bd79b7f339 Update PayChan_test.cpp 2023-11-30 16:33:05 +01:00
Denis Angell
ae573894c9 add paychan rippling test 2023-11-30 16:32:13 +01:00
2 changed files with 105 additions and 5 deletions

View File

@@ -534,8 +534,18 @@ trustAdjustLockedBalance(
STAmount balance = high ? -(*sleLine)[sfBalance] : (*sleLine)[sfBalance];
// this would mean somehow the issuer is trying to lock balance
if (balance < beast::zero)
if (view.rules().enabled(fixXahauV1) && balance < beast::zero)
{
JLOG(j.warn()) << "trustAdjustLockedBalance: negative balance"
<< "\n";
return tecUNFUNDED_PAYMENT;
}
else if (balance < beast::zero)
{
JLOG(j.warn()) << "trustAdjustLockedBalance: negative balance"
<< "\n";
return tecINTERNAL;
}
if (deltaAmt == beast::zero)
return tesSUCCESS;
@@ -543,7 +553,7 @@ trustAdjustLockedBalance(
// can't lock or unlock a zero balance
if (balance == beast::zero)
{
JLOG(j.trace()) << "trustAdjustLockedBalance failed, zero balance";
JLOG(j.trace()) << "trustAdjustLockedBalance: zero balance";
return tecUNFUNDED_PAYMENT;
}
@@ -568,7 +578,12 @@ trustAdjustLockedBalance(
}
if (finalLockedBalance < beast::zero)
{
JLOG(j.warn())
<< "trustAdjustLockedBalance: finalLockedBalance < beast::zero"
<< "\n";
return tecINTERNAL;
}
// check if there is significant precision loss
if (!isAddable(balance, deltaAmt) ||
@@ -657,7 +672,11 @@ trustTransferAllowed(
for (AccountID const& p : parties)
{
if (p == issue.account)
{
JLOG(j.warn()) << "trustAdjustLockedBalance: p == issue.account"
<< "\n";
continue;
}
auto const line =
view.read(keylet::line(p, issue.account, issue.currency));
@@ -679,7 +698,7 @@ trustTransferAllowed(
// the point of transfer.
continue;
}
// sanity check the line, insane lines are a bar to xfer
if (lockedBalanceAllowed)
{
@@ -687,7 +706,12 @@ trustTransferAllowed(
// always a bar to xfer
if (line->getFieldAmount(sfLowLimit).getIssuer() ==
line->getFieldAmount(sfHighLimit).getIssuer())
{
JLOG(j.warn())
<< "trustAdjustLockedBalance: sfLowLimit == sfHighLimit"
<< "\n";
return tecINTERNAL;
}
if (line->isFieldPresent(sfLockedBalance))
{

View File

@@ -5315,8 +5315,6 @@ struct PayChan_test : public beast::unit_test::suite
auto const gw = Account{"gateway"};
auto const USD = gw["USD"];
auto const aliceUSD = alice["USD"];
auto const bobUSD = bob["USD"];
{
// test pay more than locked amount
// ie. has 10000, lock 1000 then try to pay 10000
@@ -5513,6 +5511,83 @@ struct PayChan_test : public beast::unit_test::suite
}
}
void
testIOURippling(FeatureBitset features)
{
testcase("IOU Rippling");
using namespace test::jtx;
using namespace std::literals;
Env env{*this, features};
auto const alice = Account("alice");
auto const bob = Account("bob");
auto const carol = Account("carol");
auto const USDA = alice["USD"];
auto const USDB = bob["USD"];
auto const USDC = carol["USD"];
env.fund(XRP(10000), alice, bob, carol);
env.close();
// alice trusts USD bob & carol
env(trust(alice, USDB(100)));
env(trust(alice, USDC(100)));
// bob trusts USD alice & carol
env(trust(bob, USDA(100)));
env(trust(bob, USDC(100)));
// carol trusts USD alice & bob
env(trust(carol, USDA(100)));
env(trust(carol, USDB(100)));
env.close();
// alice pays bob USDA
env(pay(alice, bob, USDA(10)));
// carol pays alice USDC
env(pay(carol, alice, USDC(10)));
env.close();
/*
aliceUSDABal: 0/USD(alice)
aliceUSDBBal: -10/USD(bob)
aliceUSDCBal: 10/USD(carol)
bobUSDABal: 10/USD(alice)
bobUSDBBal: 0/USD(bob)
bobUSDCBal: 0/USD(carol)
carolUSDABal: -10/USD(alice)
carolUSDBBal: 0/USD(bob)
carolUSDCBal: 0/USD(carol)
*/
// negative direction source
{
// alice cannot create to carol with USDB
auto const pk = bob.pk();
auto const settleDelay = 100s;
env(create(alice, carol, USDB(10), settleDelay, pk), ter(tecUNFUNDED_PAYMENT));
env.close();
}
// negative direction destination
{
// bob can create to carol with USDA
auto const pk = bob.pk();
auto const settleDelay = 1s;
auto const chan = channel(bob, carol, env.seq(bob));
env(create(bob, carol, USDA(10), settleDelay, pk), ter(tesSUCCESS));
env.close();
auto const preBobUSDALocked = -lockedAmount(env, bob, alice, USDA);
BEAST_EXPECT(preBobUSDALocked == USDA(10));
// carol can claim
auto sig = signClaimIOUAuth(pk, bob.sk(), chan, USDA(10));
env(claim(carol, chan, USDA(10), USDA(10), Slice(sig), pk), txflags(tfClose), ter(tesSUCCESS));
env.close();
auto const postBobUSDALocked = -lockedAmount(env, bob, alice, USDA);
BEAST_EXPECT(postBobUSDALocked == USDA(0));
}
}
void
testWithFeats(FeatureBitset features)
{
@@ -5569,6 +5644,7 @@ struct PayChan_test : public beast::unit_test::suite
testIOUTLINSF(features);
testIOUMismatchFunding(features);
testIOUPrecisionLoss(features);
testIOURippling(features);
}
public: