Compare commits

..

2 Commits

Author SHA1 Message Date
Nicholas Dudfield
65c6ad4ba3 Merge remote-tracking branch 'origin/dev' into request-id-correlation 2026-06-17 14:35:14 +07:00
Nicholas Dudfield
7ef50e4114 feat(protocol): add request correlation ids 2026-04-30 11:29:28 +07:00
10 changed files with 52 additions and 60 deletions

View File

@@ -95,16 +95,8 @@ if [[ "$4" == "" ]]; then
echo "Non GH, local building, no Action runner magic" echo "Non GH, local building, no Action runner magic"
else else
# GH Action, runner # GH Action, runner
if [[ "$(git rev-parse --abbrev-ref HEAD)" == "release" ]]; then cp /io/release-build/xahaud /data/builds/$(date +%Y).$(date +%-m).$(date +%-d)-$(git rev-parse --abbrev-ref HEAD)+$4
echo "building on the release branch... placing it in builds/candidate" cp /io/release-build/release.info /data/builds/$(date +%Y).$(date +%-m).$(date +%-d)-$(git rev-parse --abbrev-ref HEAD)+$4.releaseinfo
mkdir /data/builds/candidate
cp /io/release-build/xahaud /data/builds/candidate/$(date +%Y).$(date +%-m).$(date +%-d)-$(git rev-parse --abbrev-ref HEAD)+$4
cp /io/release-build/release.info /data/builds/candidate/$(date +%Y).$(date +%-m).$(date +%-d)-$(git rev-parse --abbrev-ref HEAD)+$4.releaseinfo
else
echo "building non-release branch, placing it in builds root"
cp /io/release-build/xahaud /data/builds/$(date +%Y).$(date +%-m).$(date +%-d)-$(git rev-parse --abbrev-ref HEAD)+$4
cp /io/release-build/release.info /data/builds/$(date +%Y).$(date +%-m).$(date +%-d)-$(git rev-parse --abbrev-ref HEAD)+$4.releaseinfo
fi
echo "Published build to: http://build.xahau.tech/" echo "Published build to: http://build.xahau.tech/"
echo $(date +%Y).$(date +%-m).$(date +%-d)-$(git rev-parse --abbrev-ref HEAD)+$4 echo $(date +%Y).$(date +%-m).$(date +%-d)-$(git rev-parse --abbrev-ref HEAD)+$4
fi fi

View File

@@ -116,6 +116,11 @@ message TMTransaction
message TMTransactions message TMTransactions
{ {
repeated TMTransaction transactions = 1; repeated TMTransaction transactions = 1;
// Optional opaque request/response correlation ID. If present on the
// TMGetObjectByHash(otTRANSACTIONS) request, the responder copies it
// unchanged. This field is not routing state and does not affect message
// processing, resource charging, duplicate suppression, or consensus.
optional uint64 requestId = 2;
} }
@@ -267,6 +272,10 @@ message TMGetObjectByHash
optional bytes ledgerHash = 4; // the hash of the ledger these queries are for optional bytes ledgerHash = 4; // the hash of the ledger these queries are for
optional bool fat = 5; // return related nodes optional bool fat = 5; // return related nodes
repeated TMIndexedObject objects = 6; // the specific objects requested repeated TMIndexedObject objects = 6; // the specific objects requested
// Optional opaque request/response correlation ID. Responders copy this
// value unchanged when forming a reply. This is distinct from the existing
// uint32 seq field and has no protocol meaning beyond correlation.
optional uint64 requestId = 7;
} }
@@ -306,6 +315,10 @@ message TMGetLedger
optional uint64 requestCookie = 6; optional uint64 requestCookie = 6;
optional TMQueryType queryType = 7; optional TMQueryType queryType = 7;
optional uint32 queryDepth = 8; // How deep to go, number of extra levels optional uint32 queryDepth = 8; // How deep to go, number of extra levels
// Optional opaque request/response correlation ID. Responders copy this
// value unchanged into TMLedgerData. This is separate from requestCookie:
// requestCookie is relay routing state; requestId is only correlation.
optional uint64 requestId = 9;
} }
enum TMReplyError enum TMReplyError
@@ -323,6 +336,9 @@ message TMLedgerData
repeated TMLedgerNode nodes = 4; repeated TMLedgerNode nodes = 4;
optional uint32 requestCookie = 5; optional uint32 requestCookie = 5;
optional TMReplyError error = 6; optional TMReplyError error = 6;
// Optional opaque request/response correlation ID copied from TMGetLedger.
// Receivers must not use it for relay routing or data validation.
optional uint64 requestId = 7;
} }
message TMPing message TMPing
@@ -335,6 +351,9 @@ message TMPing
optional uint32 seq = 2; // detect stale replies, ensure other side is reading optional uint32 seq = 2; // detect stale replies, ensure other side is reading
optional uint64 pingTime = 3; // know when we think we sent the ping optional uint64 pingTime = 3; // know when we think we sent the ping
optional uint64 netTime = 4; optional uint64 netTime = 4;
// Optional opaque request/response correlation ID copied from ptPING to
// ptPONG. The existing seq field remains the ping liveness cookie.
optional uint64 requestId = 5;
} }
message TMSquelch message TMSquelch
@@ -355,6 +374,8 @@ message TMProofPathRequest
required bytes key = 1; required bytes key = 1;
required bytes ledgerHash = 2; required bytes ledgerHash = 2;
required TMLedgerMapType type = 3; required TMLedgerMapType type = 3;
// Optional opaque request/response correlation ID copied into the response.
optional uint64 requestId = 4;
} }
message TMProofPathResponse message TMProofPathResponse
@@ -365,11 +386,15 @@ message TMProofPathResponse
optional bytes ledgerHeader = 4; optional bytes ledgerHeader = 4;
repeated bytes path = 5; repeated bytes path = 5;
optional TMReplyError error = 6; optional TMReplyError error = 6;
// Optional opaque request/response correlation ID copied from the request.
optional uint64 requestId = 7;
} }
message TMReplayDeltaRequest message TMReplayDeltaRequest
{ {
required bytes ledgerHash = 1; required bytes ledgerHash = 1;
// Optional opaque request/response correlation ID copied into the response.
optional uint64 requestId = 2;
} }
message TMReplayDeltaResponse message TMReplayDeltaResponse
@@ -378,6 +403,8 @@ message TMReplayDeltaResponse
optional bytes ledgerHeader = 2; optional bytes ledgerHeader = 2;
repeated bytes transaction = 3; repeated bytes transaction = 3;
optional TMReplyError error = 4; optional TMReplyError error = 4;
// Optional opaque request/response correlation ID copied from the request.
optional uint64 requestId = 5;
} }
message TMHaveTransactions message TMHaveTransactions

View File

@@ -34,7 +34,6 @@
// If you add an amendment here, then do not forget to increment `numFeatures` // If you add an amendment here, then do not forget to increment `numFeatures`
// in include/xrpl/protocol/Feature.h. // in include/xrpl/protocol/Feature.h.
XRPL_FEATURE(SecureUI, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FIX (HookMap, Supported::yes, VoteBehavior::DefaultYes) XRPL_FIX (HookMap, Supported::yes, VoteBehavior::DefaultYes)
XRPL_FIX (GuardDepth32, Supported::yes, VoteBehavior::DefaultNo) XRPL_FIX (GuardDepth32, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FEATURE(NamedHooks, Supported::yes, VoteBehavior::DefaultNo) XRPL_FEATURE(NamedHooks, Supported::yes, VoteBehavior::DefaultNo)

View File

@@ -262,7 +262,6 @@ LEDGER_ENTRY(ltACCOUNT_ROOT, 0x0061, AccountRoot, account, ({
{sfHookStateScale, soeOPTIONAL}, {sfHookStateScale, soeOPTIONAL},
{sfCron, soeOPTIONAL}, {sfCron, soeOPTIONAL},
{sfAMMID, soeOPTIONAL}, {sfAMMID, soeOPTIONAL},
{sfSecureUI, soeOPTIONAL},
})) }))
/** A ledger object which contains a list of object identifiers. /** A ledger object which contains a list of object identifiers.

View File

@@ -293,7 +293,6 @@ TYPED_SFIELD(sfAssetClass, VL, 29)
TYPED_SFIELD(sfProvider, VL, 30) TYPED_SFIELD(sfProvider, VL, 30)
TYPED_SFIELD(sfMPTokenMetadata, VL, 31) TYPED_SFIELD(sfMPTokenMetadata, VL, 31)
TYPED_SFIELD(sfCredentialType, VL, 32) TYPED_SFIELD(sfCredentialType, VL, 32)
TYPED_SFIELD(sfSecureUI, VL, 96)
TYPED_SFIELD(sfHookName, VL, 97) TYPED_SFIELD(sfHookName, VL, 97)
TYPED_SFIELD(sfRemarkValue, VL, 98) TYPED_SFIELD(sfRemarkValue, VL, 98)
TYPED_SFIELD(sfRemarkName, VL, 99) TYPED_SFIELD(sfRemarkName, VL, 99)

View File

@@ -74,7 +74,6 @@ TRANSACTION(ttACCOUNT_SET, 3, AccountSet, ({
{sfTickSize, soeOPTIONAL}, {sfTickSize, soeOPTIONAL},
{sfNFTokenMinter, soeOPTIONAL}, {sfNFTokenMinter, soeOPTIONAL},
{sfHookStateScale, soeOPTIONAL}, {sfHookStateScale, soeOPTIONAL},
{sfSecureUI, soeOPTIONAL},
})) }))
/** This transaction type cancels an existing escrow. */ /** This transaction type cancels an existing escrow. */

View File

@@ -2405,6 +2405,9 @@ LedgerMaster::makeFetchPack(
if (request->has_seq()) if (request->has_seq())
reply.set_seq(request->seq()); reply.set_seq(request->seq());
if (request->has_requestid())
reply.set_requestid(request->requestid());
reply.set_ledgerhash(request->ledgerhash()); reply.set_ledgerhash(request->ledgerhash());
reply.set_type(protocol::TMGetObjectByHash::otFETCH_PACK); reply.set_type(protocol::TMGetObjectByHash::otFETCH_PACK);

View File

@@ -42,6 +42,9 @@ LedgerReplayMsgHandler::processProofPathRequest(
protocol::TMProofPathRequest& packet = *msg; protocol::TMProofPathRequest& packet = *msg;
protocol::TMProofPathResponse reply; protocol::TMProofPathResponse reply;
if (packet.has_requestid())
reply.set_requestid(packet.requestid());
if (!packet.has_key() || !packet.has_ledgerhash() || !packet.has_type() || if (!packet.has_key() || !packet.has_ledgerhash() || !packet.has_type() ||
packet.ledgerhash().size() != uint256::size() || packet.ledgerhash().size() != uint256::size() ||
packet.key().size() != uint256::size() || packet.key().size() != uint256::size() ||
@@ -182,6 +185,9 @@ LedgerReplayMsgHandler::processReplayDeltaRequest(
protocol::TMReplayDeltaRequest& packet = *msg; protocol::TMReplayDeltaRequest& packet = *msg;
protocol::TMReplayDeltaResponse reply; protocol::TMReplayDeltaResponse reply;
if (packet.has_requestid())
reply.set_requestid(packet.requestid());
if (!packet.has_ledgerhash() || if (!packet.has_ledgerhash() ||
packet.ledgerhash().size() != uint256::size()) packet.ledgerhash().size() != uint256::size())
{ {

View File

@@ -197,31 +197,6 @@ SetAccount::preflight(PreflightContext const& ctx)
return temMALFORMED; return temMALFORMED;
} }
if (tx.isFieldPresent(sfSecureUI))
{
if (!ctx.rules.enabled(featureSecureUI))
return temMALFORMED;
Blob ui = tx.getFieldVL(sfSecureUI);
if (ui.size() == 0)
{
// this is an unset operation, pass
}
else if (ui.size() > 4096)
{
JLOG(j.trace()) << "SecureUI: Too long > 4096 bytes";
return temMALFORMED;
}
else if (!URIToken::validateUTF8(ui))
{
JLOG(j.trace()) << "SecureUI: Not UTF-8";
return temMALFORMED;
}
// valid
}
return preflight2(ctx); return preflight2(ctx);
} }
@@ -724,23 +699,6 @@ SetAccount::doApply()
sle->setFieldU16(sfHookStateScale, newScale); sle->setFieldU16(sfHookStateScale, newScale);
} }
} }
if (tx.isFieldPresent(sfSecureUI))
{
Blob ui = tx.getFieldVL(sfSecureUI);
if (ui.size() == 0)
{
// unset operation
if (sle->isFieldPresent(sfSecureUI))
sle->makeFieldAbsent(sfSecureUI);
}
else
{
// set operation
sle->setFieldVL(sfSecureUI, std::move(ui));
}
}
ctx_.view().update(sle); ctx_.view().update(sle);
return tesSUCCESS; return tesSUCCESS;

View File

@@ -2436,6 +2436,9 @@ PeerImp::onMessage(std::shared_ptr<protocol::TMGetObjectByHash> const& m)
if (packet.has_seq()) if (packet.has_seq())
reply.set_seq(packet.seq()); reply.set_seq(packet.seq());
if (packet.has_requestid())
reply.set_requestid(packet.requestid());
reply.set_type(packet.type()); reply.set_type(packet.type());
if (packet.has_ledgerhash()) if (packet.has_ledgerhash())
@@ -2748,6 +2751,9 @@ PeerImp::doTransactions(
{ {
protocol::TMTransactions reply; protocol::TMTransactions reply;
if (packet->has_requestid())
reply.set_requestid(packet->requestid());
JLOG(p_journal_.trace()) << "received TMGetObjectByHash requesting tx " JLOG(p_journal_.trace()) << "received TMGetObjectByHash requesting tx "
<< packet->objects_size(); << packet->objects_size();
@@ -3249,6 +3255,12 @@ PeerImp::processLedgerRequest(std::shared_ptr<protocol::TMGetLedger> const& m)
protocol::TMLedgerData ledgerData; protocol::TMLedgerData ledgerData;
bool fatLeaves{true}; bool fatLeaves{true};
auto const itype{m->itype()}; auto const itype{m->itype()};
auto const copyRequestMetadata = [&] {
if (m->has_requestcookie())
ledgerData.set_requestcookie(m->requestcookie());
if (m->has_requestid())
ledgerData.set_requestid(m->requestid());
};
if (itype == protocol::liTS_CANDIDATE) if (itype == protocol::liTS_CANDIDATE)
{ {
@@ -3260,8 +3272,7 @@ PeerImp::processLedgerRequest(std::shared_ptr<protocol::TMGetLedger> const& m)
ledgerData.set_ledgerseq(0); ledgerData.set_ledgerseq(0);
ledgerData.set_ledgerhash(m->ledgerhash()); ledgerData.set_ledgerhash(m->ledgerhash());
ledgerData.set_type(protocol::liTS_CANDIDATE); ledgerData.set_type(protocol::liTS_CANDIDATE);
if (m->has_requestcookie()) copyRequestMetadata();
ledgerData.set_requestcookie(m->requestcookie());
// We'll already have most transactions // We'll already have most transactions
fatLeaves = false; fatLeaves = false;
@@ -3288,8 +3299,7 @@ PeerImp::processLedgerRequest(std::shared_ptr<protocol::TMGetLedger> const& m)
ledgerData.set_ledgerhash(ledgerHash.begin(), ledgerHash.size()); ledgerData.set_ledgerhash(ledgerHash.begin(), ledgerHash.size());
ledgerData.set_ledgerseq(ledger->info().seq); ledgerData.set_ledgerseq(ledger->info().seq);
ledgerData.set_type(itype); ledgerData.set_type(itype);
if (m->has_requestcookie()) copyRequestMetadata();
ledgerData.set_requestcookie(m->requestcookie());
switch (itype) switch (itype)
{ {