From 3c108d3a8743bcfefdee5c15bececdd153faa4d8 Mon Sep 17 00:00:00 2001 From: Nicholas Dudfield Date: Fri, 26 Jun 2026 17:40:46 +0700 Subject: [PATCH] fix(protocol): preserve local TER code values Keep telENV_RPC_FAILED in its original local-error slot and append telSHADOW_TICKET_REQUIRED after it, with a TER regression test pinning both values. --- include/xrpl/protocol/TER.h | 4 +++- src/libxrpl/protocol/TER.cpp | 2 +- src/test/protocol/TER_test.cpp | 12 ++++++++++++ 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/include/xrpl/protocol/TER.h b/include/xrpl/protocol/TER.h index 87001a033..a194afa60 100644 --- a/include/xrpl/protocol/TER.h +++ b/include/xrpl/protocol/TER.h @@ -68,8 +68,10 @@ enum TELcodes : TERUnderlyingType { telNON_LOCAL_EMITTED_TXN, telIMPORT_VL_KEY_NOT_RECOGNISED, telCAN_NOT_QUEUE_IMPORT, - telSHADOW_TICKET_REQUIRED, + // Keep test-only sentinels before appended branch-local TEL codes so their + // numeric values do not move. telENV_RPC_FAILED, + telSHADOW_TICKET_REQUIRED, }; //------------------------------------------------------------------------------ diff --git a/src/libxrpl/protocol/TER.cpp b/src/libxrpl/protocol/TER.cpp index 051b511da..25b177818 100644 --- a/src/libxrpl/protocol/TER.cpp +++ b/src/libxrpl/protocol/TER.cpp @@ -172,8 +172,8 @@ transResults() MAKE_ERROR(telNON_LOCAL_EMITTED_TXN, "Emitted transaction cannot be applied because it was not generated locally."), MAKE_ERROR(telIMPORT_VL_KEY_NOT_RECOGNISED, "Import vl key was not recognized."), MAKE_ERROR(telCAN_NOT_QUEUE_IMPORT, "Import transaction was not able to be directly applied and cannot be queued."), - MAKE_ERROR(telSHADOW_TICKET_REQUIRED, "The imported transaction uses a TicketSequence but no shadow ticket exists."), MAKE_ERROR(telENV_RPC_FAILED, "Unit test RPC failure."), + MAKE_ERROR(telSHADOW_TICKET_REQUIRED, "The imported transaction uses a TicketSequence but no shadow ticket exists."), MAKE_ERROR(temMALFORMED, "Malformed transaction."), MAKE_ERROR(temBAD_AMM_TOKENS, "Malformed: Invalid LPTokens."), diff --git a/src/test/protocol/TER_test.cpp b/src/test/protocol/TER_test.cpp index a43fd8758..dbda4bbe8 100644 --- a/src/test/protocol/TER_test.cpp +++ b/src/test/protocol/TER_test.cpp @@ -49,6 +49,17 @@ struct TER_test : public beast::unit_test::suite } } + void + testLocalCodeValues() + { + // Local TEL codes are still serialized and surfaced by tests/tools, so + // new branch-local codes should append without moving existing values. + static_assert(TERtoInt(telENV_RPC_FAILED) == -380); + static_assert(TERtoInt(telSHADOW_TICKET_REQUIRED) == -379); + BEAST_EXPECT(TER::fromInt(-380) == telENV_RPC_FAILED); + BEAST_EXPECT(TER::fromInt(-379) == telSHADOW_TICKET_REQUIRED); + } + // Helper template that makes sure two types are not convertible or // assignable if not the same. // o I1 one tuple index. @@ -288,6 +299,7 @@ struct TER_test : public beast::unit_test::suite run() override { testTransResultInfo(); + testLocalCodeValues(); testConversion(); testComparison(); }