diff --git a/include/xrpl/protocol/detail/sfields.macro b/include/xrpl/protocol/detail/sfields.macro index 73b0b9574..ae0975285 100644 --- a/include/xrpl/protocol/detail/sfields.macro +++ b/include/xrpl/protocol/detail/sfields.macro @@ -222,7 +222,6 @@ TYPED_SFIELD(sfHookCanEmit, UINT256, 96) TYPED_SFIELD(sfEmittedTxnID, UINT256, 97) TYPED_SFIELD(sfGovernanceMarks, UINT256, 98) TYPED_SFIELD(sfGovernanceFlags, UINT256, 99) -TYPED_SFIELD(sfEntropyDigest, UINT256, 100) // number (common) TYPED_SFIELD(sfNumber, NUMBER, 1) diff --git a/include/xrpl/protocol/detail/transactions.macro b/include/xrpl/protocol/detail/transactions.macro index 8c60ffd5a..60172effe 100644 --- a/include/xrpl/protocol/detail/transactions.macro +++ b/include/xrpl/protocol/detail/transactions.macro @@ -623,5 +623,4 @@ TRANSACTION(ttCONSENSUS_ENTROPY, 105, ConsensusEntropy, ({ {sfDigest, soeREQUIRED}, {sfEntropyCount, soeREQUIRED}, {sfEntropyTier, soeREQUIRED}, - {sfBlob, soeOPTIONAL}, })) diff --git a/src/test/app/HookAPI_test.cpp b/src/test/app/HookAPI_test.cpp index 131520dbe..2c901c510 100644 --- a/src/test/app/HookAPI_test.cpp +++ b/src/test/app/HookAPI_test.cpp @@ -948,6 +948,83 @@ public: } } + void + test_xport_reserve(FeatureBitset features) + { + testcase("Test xport_reserve"); + + using namespace jtx; + using namespace hook_api; + + auto const alice = Account{"alice"}; + Env env{*this, features}; + STTx invokeTx = STTx(ttINVOKE, [&](STObject& obj) {}); + OpenView ov{*env.current()}; + ApplyContext applyCtx = createApplyContext(env, ov, invokeTx); + + { + // ALREADY_SET + StubHookContext stubCtx{.expected_export_count = 1}; + auto hookCtx = + makeStubHookContext(applyCtx, alice.id(), alice.id(), stubCtx); + auto& api = hookCtx.api(); + auto const result = api.xport_reserve(2); + BEAST_EXPECT(result.error() == ALREADY_SET); + } + + { + // TOO_SMALL + auto hookCtx = + makeStubHookContext(applyCtx, alice.id(), alice.id(), {}); + auto& api = hookCtx.api(); + auto const result = api.xport_reserve(0); + BEAST_EXPECT(result.error() == TOO_SMALL); + } + + { + // TOO_BIG + auto hookCtx = + makeStubHookContext(applyCtx, alice.id(), alice.id(), {}); + auto& api = hookCtx.api(); + auto const result = api.xport_reserve(hook_api::max_export + 1); + BEAST_EXPECT(result.error() == TOO_BIG); + } + + { + // SUCCESS + auto hookCtx = + makeStubHookContext(applyCtx, alice.id(), alice.id(), {}); + auto& api = hookCtx.api(); + auto const result = api.xport_reserve(2); + BEAST_EXPECT(result.has_value()); + BEAST_EXPECT(hookCtx.expected_export_count == 2); + BEAST_EXPECT(hookCtx.expected_etxn_count == 2); + } + + { + // xport_reserve composes with an earlier emit reservation. + auto hookCtx = + makeStubHookContext(applyCtx, alice.id(), alice.id(), {}); + auto& api = hookCtx.api(); + BEAST_EXPECT(api.etxn_reserve(1).has_value()); + BEAST_EXPECT(api.xport_reserve(2).has_value()); + BEAST_EXPECT(hookCtx.expected_export_count == 2); + BEAST_EXPECT(hookCtx.expected_etxn_count == 3); + } + + { + // xport_reserve consumes the shared emitted-txn reservation slot, + // so a later etxn_reserve cannot reset it. + auto hookCtx = + makeStubHookContext(applyCtx, alice.id(), alice.id(), {}); + auto& api = hookCtx.api(); + BEAST_EXPECT(api.xport_reserve(1).has_value()); + BEAST_EXPECT(api.etxn_reserve(1).error() == ALREADY_SET); + BEAST_EXPECT(hookCtx.expected_export_count == 1); + BEAST_EXPECT(hookCtx.expected_etxn_count == 1); + } + } + void test_fee_base(FeatureBitset features) { @@ -4855,6 +4932,7 @@ public: test_etxn_fee_base(features); test_etxn_nonce(features); test_etxn_reserve(features); + test_xport_reserve(features); test_fee_base(features); test_otxn_field(features); diff --git a/src/test/jtx/hook.h b/src/test/jtx/hook.h index 0812a6de3..47cb48abe 100644 --- a/src/test/jtx/hook.h +++ b/src/test/jtx/hook.h @@ -91,6 +91,7 @@ struct StubHookContext uint16_t emit_nonce_counter{0}; uint16_t ledger_nonce_counter{0}; int64_t expected_etxn_count{-1}; + int64_t expected_export_count{-1}; std::map nonce_used{}; uint32_t generation = 0; uint64_t burden = 0; diff --git a/src/test/jtx/impl/hook.cpp b/src/test/jtx/impl/hook.cpp index 07b72ad00..678aa8c4d 100644 --- a/src/test/jtx/impl/hook.cpp +++ b/src/test/jtx/impl/hook.cpp @@ -111,6 +111,7 @@ makeStubHookContext( .emit_nonce_counter = stubHookContext.emit_nonce_counter, .ledger_nonce_counter = stubHookContext.ledger_nonce_counter, .expected_etxn_count = stubHookContext.expected_etxn_count, + .expected_export_count = stubHookContext.expected_export_count, .nonce_used = stubHookContext.nonce_used, .generation = stubHookContext.generation, .burden = stubHookContext.burden,