Compare commits

..

8 Commits

Author SHA1 Message Date
Mayukha Vadari
7ec35ce1a1 Merge remote-tracking branch 'upstream/develop' into copilot/convert-boost-to-std-string-view 2026-02-26 14:50:36 -05:00
Mayukha Vadari
daa032d064 Merge commit '2c1fad1023' into copilot/convert-boost-to-std-string-view
# Conflicts:
#	include/xrpl/server/detail/BaseWSPeer.h
2026-02-26 14:50:01 -05:00
Mayukha Vadari
a2cee3b6ab Merge branch 'develop' into copilot/convert-boost-to-std-string-view 2026-02-06 11:43:57 -05:00
copilot-swe-agent[bot]
ae624ab894 Remove unnecessary boost/beast/core/string.hpp includes
Co-authored-by: mvadari <8029314+mvadari@users.noreply.github.com>
2026-01-30 17:27:50 +00:00
copilot-swe-agent[bot]
21ac390a37 Fix lambda return type inconsistency in ServerHandler
Co-authored-by: mvadari <8029314+mvadari@users.noreply.github.com>
2026-01-30 17:02:18 +00:00
copilot-swe-agent[bot]
86aca89bc4 Fix std::string_view constructor usage in BaseWSPeer
Co-authored-by: mvadari <8029314+mvadari@users.noreply.github.com>
2026-01-30 16:28:46 +00:00
copilot-swe-agent[bot]
b26dd49fb6 Replace all boost::beast::string_view with std::string_view
Co-authored-by: mvadari <8029314+mvadari@users.noreply.github.com>
2026-01-30 16:26:37 +00:00
copilot-swe-agent[bot]
0969281538 Initial plan 2026-01-30 16:23:54 +00:00
21 changed files with 145 additions and 191 deletions

View File

@@ -10,6 +10,7 @@
#include <cctype>
#include <iterator>
#include <string>
#include <string_view>
#include <vector>
namespace beast {
@@ -181,7 +182,7 @@ split_commas(FwdIt first, FwdIt last)
template <class Result = std::vector<std::string>>
Result
split_commas(boost::beast::string_view const& s)
split_commas(std::string_view const& s)
{
return split_commas(s.begin(), s.end());
}

View File

@@ -1,20 +1,19 @@
#pragma once
#include <boost/beast/core/string.hpp>
#include <functional>
#include <string>
#include <string_view>
namespace Json {
class Value;
using Output = std::function<void(boost::beast::string_view const&)>;
using Output = std::function<void(std::string_view const&)>;
inline Output
stringOutput(std::string& s)
{
return [&](boost::beast::string_view const& b) { s.append(b.data(), b.size()); };
return [&](std::string_view const& b) { s.append(b.data(), b.size()); };
}
/** Writes a minimal representation of a Json value to an Output in O(n) time.

View File

@@ -15,9 +15,10 @@
// Add new amendments to the top of this list.
// Keep it sorted in reverse chronological order.
XRPL_FEATURE(BatchV1_1, Supported::no, VoteBehavior::DefaultNo)
XRPL_FIX (PermissionedDomainInvariant, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FIX (ExpiredNFTokenOfferRemoval, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FIX (BatchInnerSigs, Supported::no, VoteBehavior::DefaultNo)
XRPL_FEATURE(LendingProtocol, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FEATURE(PermissionDelegationV1_1, Supported::no, VoteBehavior::DefaultNo)
XRPL_FIX (DirectoryLimit, Supported::yes, VoteBehavior::DefaultNo)
@@ -31,6 +32,7 @@ XRPL_FEATURE(TokenEscrow, Supported::yes, VoteBehavior::DefaultNo
XRPL_FIX (EnforceNFTokenTrustlineV2, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FIX (AMMv1_3, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FEATURE(PermissionedDEX, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FEATURE(Batch, Supported::no, VoteBehavior::DefaultNo)
XRPL_FEATURE(SingleAssetVault, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FIX (PayChanCancelAfter, Supported::yes, VoteBehavior::DefaultNo)
// Check flags in Credential transactions

View File

@@ -918,7 +918,7 @@ TRANSACTION(ttVAULT_CLAWBACK, 70, VaultClawback,
#endif
TRANSACTION(ttBATCH, 71, Batch,
Delegation::notDelegable,
featureBatchV1_1,
featureBatch,
noPriv,
({
{sfRawTransactions, soeREQUIRED},

View File

@@ -17,6 +17,7 @@
#include <functional>
#include <list>
#include <string_view>
namespace xrpl {
@@ -48,8 +49,7 @@ private:
bool ping_active_ = false;
boost::beast::websocket::ping_data payload_;
error_code ec_;
std::function<void(boost::beast::websocket::frame_type, boost::beast::string_view)>
control_callback_;
std::function<void(boost::beast::websocket::frame_type, std::string_view)> control_callback_;
public:
template <class Body, class Headers>
@@ -137,7 +137,7 @@ protected:
on_ping(error_code const& ec);
void
on_ping_pong(boost::beast::websocket::frame_type kind, boost::beast::string_view payload);
on_ping_pong(boost::beast::websocket::frame_type kind, std::string_view payload);
void
on_timer(error_code ec);
@@ -414,11 +414,11 @@ template <class Handler, class Impl>
void
BaseWSPeer<Handler, Impl>::on_ping_pong(
boost::beast::websocket::frame_type kind,
boost::beast::string_view payload)
std::string_view payload)
{
if (kind == boost::beast::websocket::frame_type::pong)
{
boost::beast::string_view p(payload_.begin());
std::string_view p(payload_.begin(), payload_.size());
if (payload == p)
{
close_on_timer_ = false;

View File

@@ -162,6 +162,9 @@ 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);
@@ -290,7 +293,14 @@ protected:
std::optional<T> value,
unit::ValueUnit<Unit, T> min = unit::ValueUnit<Unit, T>{});
protected:
private:
std::pair<TER, XRPAmount>
reset(XRPAmount fee);
TER
consumeSeqProxy(SLE::pointer const& sleAccount);
TER
payFee();
static NotTEC
checkSingleSign(
ReadView const& view,
@@ -306,15 +316,6 @@ protected:
STObject const& sigObject,
beast::Journal const j);
private:
std::pair<TER, XRPAmount>
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.

View File

@@ -27,9 +27,6 @@ public:
static NotTEC
preflightSigValidated(PreflightContext const& ctx);
static NotTEC
checkBatchSign(PreclaimContext const& ctx);
static NotTEC
checkSign(PreclaimContext const& ctx);

View File

@@ -8,6 +8,7 @@
#include <set>
#include <stack>
#include <string>
#include <string_view>
#include <utility>
#include <vector>
@@ -87,14 +88,14 @@ public:
}
void
output(boost::beast::string_view const& bytes)
output(std::string_view const& bytes)
{
markStarted();
output_(bytes);
}
void
stringOutput(boost::beast::string_view const& bytes)
stringOutput(std::string_view const& bytes)
{
markStarted();
std::size_t position = 0, writtenUntil = 0;

View File

@@ -278,8 +278,6 @@ STTx::checkBatchSign(Rules const& rules) const
JLOG(debugLog().fatal()) << "not a batch transaction";
return Unexpected("Not a batch transaction.");
}
if (!isFieldPresent(sfBatchSigners))
return Unexpected("Missing BatchSigners field.");
STArray const& signers{getFieldArray(sfBatchSigners)};
for (auto const& signer : signers)
{
@@ -294,8 +292,9 @@ STTx::checkBatchSign(Rules const& rules) const
}
catch (std::exception const& e)
{
return Unexpected(std::string("Internal batch signature check failure: ") + e.what());
JLOG(debugLog().error()) << "Batch signature check failed: " << e.what();
}
return Unexpected("Internal batch signature check failure.");
}
Json::Value
@@ -417,7 +416,6 @@ STTx::checkBatchSingleSign(STObject const& batchSigner) const
{
Serializer msg;
serializeBatch(msg, getFlags(), getBatchTransactionIDs());
finishMultiSigningData(batchSigner.getAccountID(sfAccount), msg);
return singleSignHelper(batchSigner, msg.slice());
}
@@ -490,7 +488,7 @@ multiSignHelper(
if (!validSig)
return Unexpected(
std::string("Invalid signature on account ") + toBase58(accountID) +
(errorWhat ? ": " + *errorWhat : "") + ".");
errorWhat.value_or("") + ".");
}
// All signatures verified.
return {};

View File

@@ -175,12 +175,12 @@ Transactor::preflight1(PreflightContext const& ctx, std::uint32_t flagMask)
if (ctx.tx.getSeqProxy().isTicket() && ctx.tx.isFieldPresent(sfAccountTxnID))
return temINVALID;
if (ctx.tx.isFlag(tfInnerBatchTxn) && !ctx.rules.enabled(featureBatchV1_1))
if (ctx.tx.isFlag(tfInnerBatchTxn) && !ctx.rules.enabled(featureBatch))
return temINVALID_FLAG;
XRPL_ASSERT(
ctx.tx.isFlag(tfInnerBatchTxn) == ctx.parentBatchId.has_value() ||
!ctx.rules.enabled(featureBatchV1_1),
!ctx.rules.enabled(featureBatch),
"Inner batch transaction must have a parent batch ID.");
return tesSUCCESS;
@@ -196,13 +196,13 @@ Transactor::preflight2(PreflightContext const& ctx)
return *ret;
// It should be impossible for the InnerBatchTxn flag to be set without
// featureBatchV1_1 being enabled
// featureBatch being enabled
XRPL_ASSERT_PARTS(
!ctx.tx.isFlag(tfInnerBatchTxn) || ctx.rules.enabled(featureBatchV1_1),
!ctx.tx.isFlag(tfInnerBatchTxn) || ctx.rules.enabled(featureBatch),
"xrpl::Transactor::preflight2",
"InnerBatch flag only set if feature enabled");
// Skip signature check on batch inner transactions
if (ctx.tx.isFlag(tfInnerBatchTxn) && ctx.rules.enabled(featureBatchV1_1))
if (ctx.tx.isFlag(tfInnerBatchTxn) && ctx.rules.enabled(featureBatch))
return tesSUCCESS;
// Do not add any checks after this point that are relevant for
// batch inner transactions. They will be skipped.
@@ -647,7 +647,7 @@ Transactor::checkSign(
auto const pkSigner = sigObject.getFieldVL(sfSigningPubKey);
// Ignore signature check on batch inner transactions
if (parentBatchId && view.rules().enabled(featureBatchV1_1))
if (parentBatchId && view.rules().enabled(featureBatch))
{
// Defensive Check: These values are also checked in Batch::preflight
if (sigObject.isFieldPresent(sfTxnSignature) || !pkSigner.empty() ||
@@ -699,6 +699,50 @@ 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;
return tesSUCCESS;
}
if (ret = checkSingleSign(ctx.view, idSigner, idAccount, sleAccount, ctx.j);
!isTesSuccess(ret))
return ret;
}
}
return ret;
}
NotTEC
Transactor::checkSingleSign(
ReadView const& view,

View File

@@ -24,12 +24,29 @@ checkValidity(HashRouter& router, STTx const& tx, Rules const& rules)
auto const flags = router.getFlags(id);
// Ignore signature check on batch inner transactions
if (tx.isFlag(tfInnerBatchTxn) && rules.enabled(featureBatchV1_1))
if (tx.isFlag(tfInnerBatchTxn) && rules.enabled(featureBatch))
{
// Defensive Check: These values are also checked in Batch::preflight
if (tx.isFieldPresent(sfTxnSignature) || !tx.getSigningPubKey().empty() ||
tx.isFieldPresent(sfSigners))
return {Validity::SigBad, "Malformed: Invalid inner batch transaction."};
// This block should probably have never been included in the
// original `Batch` implementation. An inner transaction never
// has a valid signature.
bool const neverValid = rules.enabled(fixBatchInnerSigs);
if (!neverValid)
{
std::string reason;
if (!passesLocalChecks(tx, reason))
{
router.setFlags(id, SF_LOCALBAD);
return {Validity::SigGoodOnly, reason};
}
router.setFlags(id, SF_SIGGOOD);
return {Validity::Valid, ""};
}
}
if (any(flags & SF_SIGBAD))

View File

@@ -107,18 +107,7 @@ Batch::calculateBaseFee(ReadView const& view, STTx const& tx)
if (signer.isFieldPresent(sfTxnSignature))
signerCount += 1;
else if (signer.isFieldPresent(sfSigners))
{
auto const& nestedSigners = signer.getFieldArray(sfSigners);
// LCOV_EXCL_START
if (nestedSigners.size() > STTx::maxMultiSigners)
{
JLOG(debugLog().error())
<< "BatchTrace: Nested Signers array exceeds max entries.";
return XRPAmount{INITIAL_XRP};
}
// LCOV_EXCL_STOP
signerCount += nestedSigners.size();
}
signerCount += signer.getFieldArray(sfSigners).size();
}
}
@@ -216,14 +205,6 @@ Batch::preflight(PreflightContext const& ctx)
return temARRAY_TOO_LARGE;
}
if (ctx.tx.isFieldPresent(sfBatchSigners) &&
ctx.tx.getFieldArray(sfBatchSigners).size() > maxBatchTxCount)
{
JLOG(ctx.j.debug()) << "BatchTrace[" << parentBatchId << "]:"
<< "signers array exceeds 8 entries.";
return temARRAY_TOO_LARGE;
}
// Validation Inner Batch Txns
std::unordered_set<uint256> uniqueHashes;
std::unordered_map<AccountID, std::unordered_set<std::uint32_t>> accountSeqTicket;
@@ -445,7 +426,7 @@ Batch::preflightSigValidated(PreflightContext const& ctx)
if (requiredSigners.erase(signerAccount) == 0)
{
JLOG(ctx.j.debug()) << "BatchTrace[" << parentBatchId << "]: "
<< "extra signer provided: " << signerAccount;
<< "no account signature for inner txn.";
return temBAD_SIGNER;
}
}
@@ -470,54 +451,6 @@ 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));
if (sleAccount)
{
if (isPseudoAccount(sleAccount))
return tefBAD_AUTH;
if (ret = checkSingleSign(ctx.view, idSigner, idAccount, sleAccount, ctx.j);
!isTesSuccess(ret))
return ret;
}
else
{
if (idAccount != idSigner)
return tefBAD_AUTH;
// A batch can include transactions from an un-created account ONLY
// when the account master key is the signer
}
}
}
return ret;
}
/**
* @brief Checks the validity of signatures for a batch transaction.
*
@@ -526,7 +459,7 @@ Batch::checkBatchSign(PreclaimContext const& ctx)
* corresponding error code.
*
* Next, it verifies the batch-specific signature requirements by calling
* Batch::checkBatchSign. If this check fails, it also returns the
* Transactor::checkBatchSign. If this check fails, it also returns the
* corresponding error code.
*
* If both checks succeed, the function returns tesSUCCESS.
@@ -541,11 +474,8 @@ Batch::checkSign(PreclaimContext const& ctx)
if (auto ret = Transactor::checkSign(ctx); !isTesSuccess(ret))
return ret;
if (ctx.tx.isFieldPresent(sfBatchSigners))
{
if (auto ret = checkBatchSign(ctx); !isTesSuccess(ret))
return ret;
}
if (auto ret = Transactor::checkBatchSign(ctx); !isTesSuccess(ret))
return ret;
return tesSUCCESS;
}

View File

@@ -26,7 +26,7 @@ LoanSet::preflight(PreflightContext const& ctx)
auto const& tx = ctx.tx;
// Special case for Batch inner transactions
if (tx.isFlag(tfInnerBatchTxn) && ctx.rules.enabled(featureBatchV1_1) &&
if (tx.isFlag(tfInnerBatchTxn) && ctx.rules.enabled(featureBatch) &&
!tx.isFieldPresent(sfCounterparty))
{
auto const parentBatchId = ctx.parentBatchId.value_or(uint256{0});

View File

@@ -141,11 +141,14 @@ class Batch_test : public beast::unit_test::suite
using namespace test::jtx;
using namespace std::literals;
bool const withInnerSigFix = features[fixBatchInnerSigs];
for (bool const withBatch : {true, false})
{
testcase << "enabled: Batch " << (withBatch ? "enabled" : "disabled");
testcase << "enabled: Batch " << (withBatch ? "enabled" : "disabled")
<< ", Inner Sig Fix: " << (withInnerSigFix ? "enabled" : "disabled");
auto const amend = withBatch ? features : features - featureBatchV1_1;
auto const amend = withBatch ? features : features - featureBatch;
test::jtx::Env env{*this, amend};
@@ -550,7 +553,6 @@ class Batch_test : public beast::unit_test::suite
Serializer msg;
serializeBatch(msg, tfAllOrNothing, jt.stx->getBatchTransactionIDs());
finishMultiSigningData(bob.id(), msg);
auto const sig = xrpl::sign(bob.pk(), bob.sk(), msg.slice());
jt.jv[sfBatchSigners.jsonName][0u][sfBatchSigner.jsonName][sfAccount.jsonName] =
bob.human();
@@ -1403,7 +1405,7 @@ class Batch_test : public beast::unit_test::suite
env.close();
}
// temARRAY_TOO_LARGE: Batch preflight: signers array exceeds 8 entries.
// temARRAY_TOO_LARGE: Batch: signers array exceeds 8 entries.
{
test::jtx::Env env{*this, features};
@@ -2189,16 +2191,22 @@ class Batch_test : public beast::unit_test::suite
void
doTestInnerSubmitRPC(FeatureBitset features, bool withBatch)
{
std::string const testName =
std::string("inner submit rpc: batch ") + (withBatch ? "enabled" : "disabled") + ": ";
bool const withInnerSigFix = features[fixBatchInnerSigs];
auto const amend = withBatch ? features : features - featureBatchV1_1;
std::string const testName = [&]() {
std::stringstream ss;
ss << "inner submit rpc: batch " << (withBatch ? "enabled" : "disabled")
<< ", inner sig fix: " << (withInnerSigFix ? "enabled" : "disabled") << ": ";
return ss.str();
}();
auto const amend = withBatch ? features : features - featureBatch;
using namespace test::jtx;
using namespace std::literals;
test::jtx::Env env{*this, amend};
if (!BEAST_EXPECT(amend[featureBatchV1_1] == withBatch))
if (!BEAST_EXPECT(amend[featureBatch] == withBatch))
return;
auto const alice = Account("alice");
@@ -2320,7 +2328,8 @@ class Batch_test : public beast::unit_test::suite
s.slice(),
__LINE__,
"fails local checks: Empty SigningPubKey.",
"fails local checks: Empty SigningPubKey.");
"fails local checks: Empty SigningPubKey.",
withBatch && !withInnerSigFix);
}
// Invalid RPC Submission: tfInnerBatchTxn pseudo-transaction
@@ -2331,7 +2340,7 @@ class Batch_test : public beast::unit_test::suite
{
STTx amendTx(ttAMENDMENT, [seq = env.closed()->header().seq + 1](auto& obj) {
obj.setAccountID(sfAccount, AccountID());
obj.setFieldH256(sfAmendment, featureBatchV1_1);
obj.setFieldH256(sfAmendment, fixBatchInnerSigs);
obj.setFieldU32(sfLedgerSequence, seq);
obj.setFieldU32(sfFlags, tfInnerBatchTxn);
});
@@ -2343,7 +2352,8 @@ class Batch_test : public beast::unit_test::suite
"Pseudo-transaction",
s.slice(),
__LINE__,
"fails local checks: Empty SigningPubKey.",
withInnerSigFix ? "fails local checks: Empty SigningPubKey."
: "fails local checks: Cannot submit pseudo transactions.",
"fails local checks: Empty SigningPubKey.");
}
}
@@ -2404,53 +2414,6 @@ class Batch_test : public beast::unit_test::suite
BEAST_EXPECT(env.balance(bob) == XRP(1000));
}
void
testCheckAllSignatures(FeatureBitset features)
{
testcase("check all signatures");
using namespace test::jtx;
using namespace std::literals;
// Verifies that checkBatchSign validates all signers even when an
// unfunded account (signed with its master key) appears first in the
// sorted signer list. A funded account with an invalid signature must
// still be rejected with tefBAD_AUTH.
test::jtx::Env env{*this, features};
auto const alice = Account("alice");
// "aaa" sorts before other accounts alphabetically, ensuring the
// unfunded account is checked first in the sorted signer list
auto const unfunded = Account("aaa");
auto const carol = Account("carol");
env.fund(XRP(10000), alice, carol);
env.close();
// Verify sort order: unfunded.id() < carol.id()
BEAST_EXPECT(unfunded.id() < carol.id());
auto const seq = env.seq(alice);
auto const ledSeq = env.current()->seq();
auto const batchFee = batch::calcBatchFee(env, 2, 3);
// The batch includes:
// 1. alice pays unfunded (to create unfunded's account)
// 2. unfunded does a noop (signed by unfunded's master key - valid)
// 3. carol pays alice (signed by alice's key - INVALID since alice is
// not carol's regular key)
//
// checkBatchSign must validate all signers regardless of order.
// This must fail with tefBAD_AUTH.
env(batch::outer(alice, seq, batchFee, tfAllOrNothing),
batch::inner(pay(alice, unfunded, XRP(100)), seq + 1),
batch::inner(noop(unfunded), ledSeq),
batch::inner(pay(carol, alice, XRP(1000)), env.seq(carol)),
batch::sig(unfunded, Reg{carol, alice}),
ter(tefBAD_AUTH));
env.close();
}
void
testAccountSet(FeatureBitset features)
{
@@ -4368,7 +4331,6 @@ class Batch_test : public beast::unit_test::suite
testIndependent(features);
testInnerSubmitRPC(features);
testAccountActivation(features);
testCheckAllSignatures(features);
testAccountSet(features);
testAccountDelete(features);
testLoan(features);
@@ -4394,6 +4356,7 @@ public:
{
using namespace test::jtx;
auto const sa = testable_amendments();
testWithFeats(sa - fixBatchInnerSigs);
testWithFeats(sa);
}
};

View File

@@ -74,7 +74,6 @@ sig::operator()(Env& env, JTx& jt) const
Serializer msg;
serializeBatch(msg, stx.getFlags(), stx.getBatchTransactionIDs());
finishMultiSigningData(e.acct.id(), msg);
auto const sig = xrpl::sign(*publicKeyType(e.sig.pk().slice()), e.sig.sk(), msg.slice());
jo[sfTxnSignature.getJsonName()] = strHex(Slice{sig.data(), sig.size()});
}

View File

@@ -116,7 +116,7 @@ class Feature_test : public beast::unit_test::suite
// or removed, swap out for any other feature.
BEAST_EXPECT(
featureToName(fixRemoveNFTokenAutoTrustLine) == "fixRemoveNFTokenAutoTrustLine");
BEAST_EXPECT(featureToName(featureBatchV1_1) == "BatchV1_1");
BEAST_EXPECT(featureToName(featureBatch) == "Batch");
BEAST_EXPECT(featureToName(featureDID) == "DID");
BEAST_EXPECT(featureToName(fixIncludeKeyletFields) == "fixIncludeKeyletFields");
BEAST_EXPECT(featureToName(featureTokenEscrow) == "TokenEscrow");

View File

@@ -1119,8 +1119,7 @@ NetworkOPsImp::submitTransaction(std::shared_ptr<STTx const> const& iTrans)
}
// Enforce Network bar for batch txn
if (iTrans->isFlag(tfInnerBatchTxn) &&
m_ledgerMaster.getValidatedRules().enabled(featureBatchV1_1))
if (iTrans->isFlag(tfInnerBatchTxn) && m_ledgerMaster.getValidatedRules().enabled(featureBatch))
{
JLOG(m_journal.error()) << "Submitted transaction invalid: tfInnerBatchTxn flag present.";
return;
@@ -1186,7 +1185,7 @@ NetworkOPsImp::preProcessTransaction(std::shared_ptr<Transaction>& transaction)
// under no circumstances will we ever accept an inner txn within a batch
// txn from the network.
auto const sttx = *transaction->getSTransaction();
if (sttx.isFlag(tfInnerBatchTxn) && view->rules().enabled(featureBatchV1_1))
if (sttx.isFlag(tfInnerBatchTxn) && view->rules().enabled(featureBatch))
{
transaction->setStatus(INVALID);
transaction->setResult(temINVALID_FLAG);

View File

@@ -1291,7 +1291,7 @@ PeerImp::handleTransaction(
// Charge strongly for attempting to relay a txn with tfInnerBatchTxn
// LCOV_EXCL_START
/*
There is no need to check whether the featureBatchV1_1 amendment is
There is no need to check whether the featureBatch amendment is
enabled.
* If the `tfInnerBatchTxn` flag is set, and the amendment is
@@ -2740,7 +2740,7 @@ PeerImp::checkTransaction(
// charge strongly for relaying batch txns
// LCOV_EXCL_START
/*
There is no need to check whether the featureBatchV1_1 amendment is
There is no need to check whether the featureBatch amendment is
enabled.
* If the `tfInnerBatchTxn` flag is set, and the amendment is

View File

@@ -59,7 +59,7 @@ to_string(ProtocolVersion const& p)
}
std::vector<ProtocolVersion>
parseProtocolVersions(boost::beast::string_view const& value)
parseProtocolVersions(std::string_view const& value)
{
static boost::regex re(
"^" // start of line
@@ -130,7 +130,7 @@ negotiateProtocolVersion(std::vector<ProtocolVersion> const& versions)
}
std::optional<ProtocolVersion>
negotiateProtocolVersion(boost::beast::string_view const& versions)
negotiateProtocolVersion(std::string_view const& versions)
{
auto const them = parseProtocolVersions(versions);

View File

@@ -1,10 +1,9 @@
#pragma once
#include <boost/beast/core/string.hpp>
#include <cstdint>
#include <optional>
#include <string>
#include <string_view>
#include <utility>
#include <vector>
@@ -39,7 +38,7 @@ to_string(ProtocolVersion const& p);
no duplicates and will be sorted in ascending protocol order.
*/
std::vector<ProtocolVersion>
parseProtocolVersions(boost::beast::string_view const& s);
parseProtocolVersions(std::string_view const& s);
/** Given a list of supported protocol versions, choose the one we prefer. */
std::optional<ProtocolVersion>
@@ -47,7 +46,7 @@ negotiateProtocolVersion(std::vector<ProtocolVersion> const& versions);
/** Given a list of supported protocol versions, choose the one we prefer. */
std::optional<ProtocolVersion>
negotiateProtocolVersion(boost::beast::string_view const& versions);
negotiateProtocolVersion(std::string_view const& versions);
/** The list of all the protocol versions we support. */
std::string const&

View File

@@ -34,6 +34,7 @@
#include <algorithm>
#include <memory>
#include <stdexcept>
#include <string_view>
namespace xrpl {
@@ -230,7 +231,7 @@ ServerHandler::onHandoff(
static inline Json::Output
makeOutput(Session& session)
{
return [&](boost::beast::string_view const& b) { session.write(b.data(), b.size()); };
return [&](std::string_view const& b) { session.write(b.data(), b.size()); };
}
static std::map<std::string, std::string>
@@ -527,11 +528,14 @@ ServerHandler::processSession(
makeOutput(*session),
coro,
forwardedFor(session->request()),
[&] {
[&]() -> std::string_view {
auto const iter = session->request().find("X-User");
if (iter != session->request().end())
return iter->value();
return boost::beast::string_view{};
{
auto const val = iter->value();
return std::string_view(val.data(), val.size());
}
return std::string_view{};
}());
if (beast::rfc2616::is_keep_alive(session->request()))