mirror of
https://github.com/Xahau/xahaud.git
synced 2026-08-23 00:10:54 +00:00
fix(import): allow ticket xpop network id
This commit is contained in:
@@ -1248,9 +1248,11 @@ struct Export_test : public beast::unit_test::suite
|
||||
|
||||
Account const alice{"alice"};
|
||||
Account const carol{"carol"};
|
||||
std::uint32_t const xahauNetworkID = 21337;
|
||||
std::uint32_t const targetNetworkID = 31337;
|
||||
|
||||
// ── Xahau env: export the inner tx ─────────────────────────────
|
||||
Env xahau{*this, xpopCtx.makeEnvConfig(21337), features};
|
||||
Env xahau{*this, xpopCtx.makeEnvConfig(xahauNetworkID), features};
|
||||
|
||||
xahau.fund(XRP(10000), alice, carol);
|
||||
xahau.close();
|
||||
@@ -1264,9 +1266,9 @@ struct Export_test : public beast::unit_test::suite
|
||||
// TicketSequence (required for exports — avoids sequence jams
|
||||
// if the tx bounces on XRPL).
|
||||
//
|
||||
// OperationLimit tells Import::preflight which network this
|
||||
// tx targets (must match Xahau's NETWORK_ID).
|
||||
//
|
||||
// sfNetworkID targets the destination network. Ticket-path imports
|
||||
// must accept it back because the shadow ticket hash binds this exact
|
||||
// inner transaction; OperationLimit is only for B2M imports.
|
||||
// We'll create the matching ticket on the XRPL side later.
|
||||
std::uint32_t const ticketSeq = 2; // alice's first ticket on XRPL
|
||||
|
||||
@@ -1279,6 +1281,7 @@ struct Export_test : public beast::unit_test::suite
|
||||
innerObj.setFieldU32(sfFlags, tfFullyCanonicalSig);
|
||||
innerObj.setFieldU32(sfSequence, 0);
|
||||
innerObj.setFieldU32(sfTicketSequence, ticketSeq);
|
||||
innerObj.setFieldU32(sfNetworkID, targetNetworkID);
|
||||
innerObj.setFieldU32(sfLastLedgerSequence, 100);
|
||||
innerObj.setFieldAmount(sfAmount, XRPAmount{1000000});
|
||||
innerObj.setFieldAmount(sfFee, XRPAmount{20});
|
||||
@@ -1336,7 +1339,7 @@ struct Export_test : public beast::unit_test::suite
|
||||
BEAST_EXPECT(xahau.current()->exists(stKey));
|
||||
|
||||
// ── XRPL env: submit the multisigned blob ──────────────────────
|
||||
Env xrpl{*this};
|
||||
Env xrpl{*this, xpopCtx.makeEnvConfig(targetNetworkID)};
|
||||
|
||||
xrpl.fund(XRP(10000), alice, carol);
|
||||
xrpl.close();
|
||||
@@ -1397,6 +1400,7 @@ struct Export_test : public beast::unit_test::suite
|
||||
noop.setFieldU16(sfTransactionType, ttACCOUNT_SET);
|
||||
noop.setFieldU32(sfFlags, tfFullyCanonicalSig);
|
||||
noop.setFieldU32(sfSequence, xrpl.seq(alice));
|
||||
noop.setFieldU32(sfNetworkID, targetNetworkID);
|
||||
noop.setFieldAmount(sfFee, XRPAmount{20}); // (1+1)*base
|
||||
noop.setFieldVL(sfSigningPubKey, Blob{});
|
||||
noop.setAccountID(sfAccount, alice.id());
|
||||
|
||||
@@ -215,8 +215,9 @@ Import::preflight(PreflightContext const& ctx)
|
||||
<< " hasResult="
|
||||
<< meta->isFieldPresent(sfTransactionResult);
|
||||
|
||||
if (stpTrans->isFieldPresent(sfTicketSequence) &&
|
||||
!ctx.rules.enabled(featureExport))
|
||||
bool const hasTicket = stpTrans->isFieldPresent(sfTicketSequence);
|
||||
|
||||
if (hasTicket && !ctx.rules.enabled(featureExport))
|
||||
{
|
||||
JLOG(ctx.j.warn()) << "Import: cannot use TicketSequence XPOP.";
|
||||
return temMALFORMED;
|
||||
@@ -269,9 +270,10 @@ Import::preflight(PreflightContext const& ctx)
|
||||
return temMALFORMED;
|
||||
}
|
||||
|
||||
// ensure inner txn is for networkid = 0 (network id must therefore be
|
||||
// missing)
|
||||
if (stpTrans->isFieldPresent(sfNetworkID))
|
||||
// B2M imports use OperationLimit to target this network and therefore
|
||||
// reject inner NetworkID. Export callbacks may carry a target NetworkID;
|
||||
// the shadow ticket binds that exact inner transaction hash.
|
||||
if (!hasTicket && stpTrans->isFieldPresent(sfNetworkID))
|
||||
{
|
||||
JLOG(ctx.j.warn()) << "Import: attempted to import xpop containing a "
|
||||
"txn with a sfNetworkID field. "
|
||||
@@ -283,7 +285,7 @@ Import::preflight(PreflightContext const& ctx)
|
||||
// tx was destined for this network. For the export callback path
|
||||
// (sfTicketSequence present), the shadow ticket already establishes
|
||||
// the relationship, so OperationLimit is not required.
|
||||
if (!stpTrans->isFieldPresent(sfTicketSequence))
|
||||
if (!hasTicket)
|
||||
{
|
||||
if (!stpTrans->isFieldPresent(sfOperationLimit))
|
||||
{
|
||||
@@ -311,7 +313,7 @@ Import::preflight(PreflightContext const& ctx)
|
||||
// export callback path and is validator-multisigned (not alice-signed).
|
||||
// The shadow ticket already proves the relationship, so skip the
|
||||
// signing key match check.
|
||||
if (!stpTrans->isFieldPresent(sfTicketSequence))
|
||||
if (!hasTicket)
|
||||
{
|
||||
auto outer = tx.getSigningPubKey();
|
||||
auto inner = stpTrans->getSigningPubKey();
|
||||
|
||||
Reference in New Issue
Block a user