From 4f5a3241deff55f0047f6fc980e45461581e1835 Mon Sep 17 00:00:00 2001 From: Denis Angell Date: Fri, 20 Feb 2026 22:14:28 +0100 Subject: [PATCH] move `checkBatchSign` --- include/xrpl/tx/Transactor.h | 21 ++++++------ include/xrpl/tx/transactors/Batch.h | 3 ++ src/libxrpl/tx/Transactor.cpp | 46 -------------------------- src/libxrpl/tx/transactors/Batch.cpp | 49 ++++++++++++++++++++++++++-- 4 files changed, 60 insertions(+), 59 deletions(-) diff --git a/include/xrpl/tx/Transactor.h b/include/xrpl/tx/Transactor.h index 0e88cf92e1..f1c335bc80 100644 --- a/include/xrpl/tx/Transactor.h +++ b/include/xrpl/tx/Transactor.h @@ -162,9 +162,6 @@ public: static NotTEC checkSign(PreclaimContext const& ctx); - static NotTEC - checkBatchSign(PreclaimContext const& ctx); - // Returns the fee in fee units, not scaled for load. static XRPAmount calculateBaseFee(ReadView const& view, STTx const& tx); @@ -293,14 +290,7 @@ protected: std::optional value, unit::ValueUnit min = unit::ValueUnit{}); -private: - std::pair - reset(XRPAmount fee); - - TER - consumeSeqProxy(SLE::pointer const& sleAccount); - TER - payFee(); +protected: static NotTEC checkSingleSign( ReadView const& view, @@ -316,6 +306,15 @@ private: STObject const& sigObject, beast::Journal const j); +private: + std::pair + reset(XRPAmount fee); + + TER + consumeSeqProxy(SLE::pointer const& sleAccount); + TER + payFee(); + void trapTransaction(uint256) const; /** Performs early sanity checks on the account and fee fields. diff --git a/include/xrpl/tx/transactors/Batch.h b/include/xrpl/tx/transactors/Batch.h index 0861deb094..901677ea2e 100644 --- a/include/xrpl/tx/transactors/Batch.h +++ b/include/xrpl/tx/transactors/Batch.h @@ -27,6 +27,9 @@ public: static NotTEC preflightSigValidated(PreflightContext const& ctx); + static NotTEC + checkBatchSign(PreclaimContext const& ctx); + static NotTEC checkSign(PreclaimContext const& ctx); diff --git a/src/libxrpl/tx/Transactor.cpp b/src/libxrpl/tx/Transactor.cpp index 4e27a171d1..669acb330e 100644 --- a/src/libxrpl/tx/Transactor.cpp +++ b/src/libxrpl/tx/Transactor.cpp @@ -698,52 +698,6 @@ Transactor::checkSign(PreclaimContext const& ctx) return checkSign(ctx.view, ctx.flags, ctx.parentBatchId, idAccount, ctx.tx, ctx.j); } -NotTEC -Transactor::checkBatchSign(PreclaimContext const& ctx) -{ - NotTEC ret = tesSUCCESS; - STArray const& signers{ctx.tx.getFieldArray(sfBatchSigners)}; - for (auto const& signer : signers) - { - auto const idAccount = signer.getAccountID(sfAccount); - - Blob const& pkSigner = signer.getFieldVL(sfSigningPubKey); - if (pkSigner.empty()) - { - if (ret = checkMultiSign(ctx.view, ctx.flags, idAccount, signer, ctx.j); - !isTesSuccess(ret)) - return ret; - } - else - { - // LCOV_EXCL_START - if (!publicKeyType(makeSlice(pkSigner))) - return tefBAD_AUTH; - // LCOV_EXCL_STOP - - auto const idSigner = calcAccountID(PublicKey(makeSlice(pkSigner))); - auto const sleAccount = ctx.view.read(keylet::account(idAccount)); - - // A batch can include transactions from an un-created account ONLY - // when the account master key is the signer - if (!sleAccount) - { - if (idAccount != idSigner) - return tefBAD_AUTH; - } - else - { - if (isPseudoAccount(sleAccount)) - return tefBAD_AUTH; - - if (ret = checkSingleSign(ctx.view, idSigner, idAccount, sleAccount, ctx.j); !isTesSuccess(ret)) - return ret; - } - } - } - return ret; -} - NotTEC Transactor::checkSingleSign( ReadView const& view, diff --git a/src/libxrpl/tx/transactors/Batch.cpp b/src/libxrpl/tx/transactors/Batch.cpp index 4bff670d8c..b911f2257a 100644 --- a/src/libxrpl/tx/transactors/Batch.cpp +++ b/src/libxrpl/tx/transactors/Batch.cpp @@ -461,6 +461,51 @@ Batch::preflightSigValidated(PreflightContext const& ctx) return tesSUCCESS; } +NotTEC +Batch::checkBatchSign(PreclaimContext const& ctx) +{ + NotTEC ret = tesSUCCESS; + STArray const& signers{ctx.tx.getFieldArray(sfBatchSigners)}; + for (auto const& signer : signers) + { + auto const idAccount = signer.getAccountID(sfAccount); + + Blob const& pkSigner = signer.getFieldVL(sfSigningPubKey); + if (pkSigner.empty()) + { + if (ret = checkMultiSign(ctx.view, ctx.flags, idAccount, signer, ctx.j); !isTesSuccess(ret)) + return ret; + } + else + { + // LCOV_EXCL_START + if (!publicKeyType(makeSlice(pkSigner))) + return tefBAD_AUTH; + // LCOV_EXCL_STOP + + auto const idSigner = calcAccountID(PublicKey(makeSlice(pkSigner))); + auto const sleAccount = ctx.view.read(keylet::account(idAccount)); + + // A batch can include transactions from an un-created account ONLY + // when the account master key is the signer + if (!sleAccount) + { + if (idAccount != idSigner) + return tefBAD_AUTH; + } + else + { + if (isPseudoAccount(sleAccount)) + return tefBAD_AUTH; + + if (ret = checkSingleSign(ctx.view, idSigner, idAccount, sleAccount, ctx.j); !isTesSuccess(ret)) + return ret; + } + } + } + return ret; +} + /** * @brief Checks the validity of signatures for a batch transaction. * @@ -469,7 +514,7 @@ Batch::preflightSigValidated(PreflightContext const& ctx) * corresponding error code. * * Next, it verifies the batch-specific signature requirements by calling - * Transactor::checkBatchSign. If this check fails, it also returns the + * Batch::checkBatchSign. If this check fails, it also returns the * corresponding error code. * * If both checks succeed, the function returns tesSUCCESS. @@ -484,7 +529,7 @@ Batch::checkSign(PreclaimContext const& ctx) if (auto ret = Transactor::checkSign(ctx); !isTesSuccess(ret)) return ret; - if (auto ret = Transactor::checkBatchSign(ctx); !isTesSuccess(ret)) + if (auto ret = checkBatchSign(ctx); !isTesSuccess(ret)) return ret; return tesSUCCESS;