Merge remote-tracking branch 'upstream/develop' into vault

* upstream/develop:
  fix: `fixPayChanV1` (4717)
This commit is contained in:
Ed Hennis
2025-04-09 18:22:00 -04:00
6 changed files with 69 additions and 12 deletions

View File

@@ -33,6 +33,7 @@
// in include/xrpl/protocol/Feature.h.
XRPL_FEATURE(SingleAssetVault, Supported::no, VoteBehavior::DefaultNo)
XRPL_FIX (PayChanCancelAfter, Supported::yes, VoteBehavior::DefaultNo)
// Check flags in Credential transactions
XRPL_FIX (InvalidTxFlags, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FIX (FrozenLPTokenTransfer, Supported::yes, VoteBehavior::DefaultNo)

View File

@@ -402,6 +402,52 @@ struct PayChan_test : public beast::unit_test::suite
BEAST_EXPECT(!channelExists(*env.current(), chan));
BEAST_EXPECT(env.balance(alice) == preAlice + channelFunds);
}
// fixPayChanCancelAfter
// CancelAfter should be greater than close time
{
for (bool const withFixPayChan : {true, false})
{
auto const amend = withFixPayChan
? features
: features - fixPayChanCancelAfter;
Env env{*this, amend};
env.fund(XRP(10000), alice, bob);
env.close();
auto const pk = alice.pk();
auto const settleDelay = 100s;
auto const channelFunds = XRP(1000);
NetClock::time_point const cancelAfter =
env.current()->info().parentCloseTime - 1s;
auto const txResult =
withFixPayChan ? ter(tecEXPIRED) : ter(tesSUCCESS);
env(create(
alice, bob, channelFunds, settleDelay, pk, cancelAfter),
txResult);
}
}
// fixPayChanCancelAfter
// CancelAfter can be equal to the close time
{
for (bool const withFixPayChan : {true, false})
{
auto const amend = withFixPayChan
? features
: features - fixPayChanCancelAfter;
Env env{*this, amend};
env.fund(XRP(10000), alice, bob);
env.close();
auto const pk = alice.pk();
auto const settleDelay = 100s;
auto const channelFunds = XRP(1000);
NetClock::time_point const cancelAfter =
env.current()->info().parentCloseTime;
env(create(
alice, bob, channelFunds, settleDelay, pk, cancelAfter),
ter(tesSUCCESS));
}
}
}
void

View File

@@ -76,18 +76,6 @@ namespace ripple {
//------------------------------------------------------------------------------
/** Has the specified time passed?
@param now the current time
@param mark the cutoff point
@return true if \a now refers to a time strictly after \a mark, else false.
*/
static inline bool
after(NetClock::time_point now, std::uint32_t mark)
{
return now.time_since_epoch().count() > mark;
}
TxConsequences
EscrowCreate::makeTxConsequences(PreflightContext const& ctx)
{

View File

@@ -252,6 +252,13 @@ PayChanCreate::doApply()
if (!sle)
return tefINTERNAL;
if (ctx_.view().rules().enabled(fixPayChanCancelAfter))
{
auto const closeTime = ctx_.view().info().parentCloseTime;
if (ctx_.tx[~sfCancelAfter] && after(closeTime, ctx_.tx[sfCancelAfter]))
return tecEXPIRED;
}
auto const dst = ctx_.tx[sfDestination];
// Create PayChan in ledger.

View File

@@ -822,6 +822,15 @@ sharesToAssetsWithdraw(
std::shared_ptr<SLE const> const& issuance,
STAmount const& shares);
/** Has the specified time passed?
@param now the current time
@param mark the cutoff point
@return true if \a now refers to a time strictly after \a mark, else false.
*/
bool
after(NetClock::time_point now, std::uint32_t mark);
} // namespace ripple
#endif

View File

@@ -2639,4 +2639,10 @@ sharesToAssetsWithdraw(
return assets;
}
bool
after(NetClock::time_point now, std::uint32_t mark)
{
return now.time_since_epoch().count() > mark;
}
} // namespace ripple