feat: XLS-68: Sponsor, #5887 continuation (#7350)

Co-authored-by: tequ <git@tequ.dev>
Co-authored-by: yinyiqian1 <yqian@ripple.com>
Co-authored-by: Mayukha Vadari <mvadari@ripple.com>
Co-authored-by: Mayukha Vadari <mvadari@gmail.com>
Co-authored-by: xrplf-ai-reviewer[bot] <266832837+xrplf-ai-reviewer[bot]@users.noreply.github.com>
Co-authored-by: Peter Chen <34582813+PeterChen13579@users.noreply.github.com>
Co-authored-by: Zhiyuan Wang <96991820+Kassaking7@users.noreply.github.com>
Co-authored-by: Ayaz Salikhov <asalikhov@ripple.com>
Co-authored-by: Ayaz Salikhov <mathbunnyru@users.noreply.github.com>
Co-authored-by: Zhiyuan Wang <1830604455@qq.com>
This commit is contained in:
Olek
2026-07-10 17:58:19 -04:00
committed by GitHub
parent c7adb215ed
commit fd2cc6dcb3
170 changed files with 13151 additions and 660 deletions

View File

@@ -28,6 +28,7 @@
#include <xrpl/protocol/SeqProxy.h>
#include <xrpl/protocol/Serializer.h>
#include <xrpl/protocol/Sign.h>
#include <xrpl/protocol/TxFlags.h>
#include <xrpl/protocol/TxFormats.h>
#include <xrpl/protocol/jss.h>
@@ -271,6 +272,13 @@ STTx::checkSign(Rules const& rules) const
return std::unexpected("Counterparty: " + ret.error());
}
if (isFieldPresent(sfSponsorSignature))
{
auto const sponsorSignatureObj = getFieldObject(sfSponsorSignature);
if (auto const ret = checkSign(rules, sponsorSignatureObj); !ret)
return std::unexpected("Sponsor: " + ret.error());
}
// Verify the batch signer signatures here too, so they are cached with the
// rest of signature checking (checkValidity / SF_SIGGOOD) and stay out of
// the transaction engine. Gated on a batch (batchTxnIds_ seated) that
@@ -551,7 +559,7 @@ STTx::checkMultiSign(Rules const& rules, STObject const& sigObject) const
// For delegated transactions sfDelegate is the account whose signer list is checked,
// the delegate account itself can not be among the signers.
auto const txnAccountID =
&sigObject != this ? std::nullopt : std::optional<AccountID>(getFeePayer());
&sigObject != this ? std::nullopt : std::optional<AccountID>(getInitiator());
// We can ease the computational load inside the loop a bit by
// pre-constructing part of the data that we hash. Fill a Serializer
@@ -603,6 +611,15 @@ STTx::getBatchTransactionIDs() const
return *batchTxnIds_;
}
AccountID
STTx::getFeePayerID() const
{
if (isFieldPresent(sfSponsor) && ((getFieldU32(sfSponsorFlags) & spfSponsorFee) != 0u))
return at(sfSponsor);
return getInitiator();
}
//------------------------------------------------------------------------------
static bool