mirror of
https://github.com/Xahau/xahaud.git
synced 2026-10-09 13:28:02 +00:00
etxn_fee_base: compute the fee against the applied view (fix20261001) (#842)
This commit is contained in:
@@ -732,6 +732,56 @@ public:
|
||||
else
|
||||
BEAST_EXPECT(result.value() == baseFee + memoSize);
|
||||
}
|
||||
{
|
||||
// fix20261001: the minimum fee is computed against the view
|
||||
// being applied, not the node-local open ledger. Simulate that
|
||||
// by inserting a hook definition (with a callback fee) into
|
||||
// applyCtx.view() only -- it is never inserted into the open
|
||||
// ledger the node otherwise reads.
|
||||
uint256 const hookHash{1};
|
||||
|
||||
STTx const emittedTx = STTx(ttINVOKE, [&](STObject& obj) {
|
||||
obj[sfAccount] = alice.id();
|
||||
obj[sfSequence] = 0;
|
||||
obj[sfSigningPubKey] = Slice{};
|
||||
obj[sfFirstLedgerSequence] = ov.seq() + 1;
|
||||
obj[sfLastLedgerSequence] = ov.seq() + 5;
|
||||
obj[sfFee] = env.closed()->fees().base;
|
||||
|
||||
auto& emitDetails = obj.peekFieldObject(sfEmitDetails);
|
||||
emitDetails[sfEmitGeneration] = 1;
|
||||
emitDetails[sfEmitBurden] = 1;
|
||||
emitDetails[sfEmitParentTxnID] = invokeTx.getTransactionID();
|
||||
emitDetails[sfEmitNonce] = uint256();
|
||||
emitDetails[sfEmitHookHash] = hookHash;
|
||||
});
|
||||
Serializer const emittedTxSerializer = emittedTx.getSerializer();
|
||||
|
||||
auto const baseline =
|
||||
api.etxn_fee_base(emittedTxSerializer.slice());
|
||||
BEAST_EXPECT(baseline.has_value());
|
||||
|
||||
auto hookDef =
|
||||
std::make_shared<SLE>(keylet::hookDefinition(hookHash));
|
||||
hookDef->setFieldH256(sfHookHash, hookHash);
|
||||
hookDef->setFieldH256(sfHookNamespace, uint256());
|
||||
hookDef->setFieldArray(sfHookParameters, STArray{});
|
||||
hookDef->setFieldU16(sfHookApiVersion, 0);
|
||||
hookDef->setFieldVL(sfCreateCode, std::vector<uint8_t>{});
|
||||
hookDef->setFieldH256(sfHookSetTxnID, invokeTx.getTransactionID());
|
||||
hookDef->setFieldU64(sfReferenceCount, 1);
|
||||
hookDef->setFieldAmount(sfFee, XRPAmount{0});
|
||||
hookDef->setFieldAmount(sfHookCallbackFee, XRPAmount{12345});
|
||||
applyCtx.view().insert(hookDef);
|
||||
|
||||
auto const result = api.etxn_fee_base(emittedTxSerializer.slice());
|
||||
BEAST_EXPECT(result.has_value());
|
||||
|
||||
if (env.closed()->rules().enabled(fix20261001))
|
||||
BEAST_EXPECT(result.value() == baseline.value() + 12345);
|
||||
else
|
||||
BEAST_EXPECT(result.value() == baseline.value());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@@ -4718,6 +4768,7 @@ public:
|
||||
test_otxn_generation(features);
|
||||
test_etxn_details(features);
|
||||
test_etxn_fee_base(features - fixHookAPI20251128);
|
||||
test_etxn_fee_base(features - fix20261001);
|
||||
test_etxn_fee_base(features);
|
||||
test_etxn_nonce(features);
|
||||
test_etxn_reserve(features);
|
||||
|
||||
@@ -868,14 +868,22 @@ HookAPI::etxn_fee_base(ripple::Slice const& txBlob) const
|
||||
std::unique_ptr<STTx const> stpTrans =
|
||||
std::make_unique<STTx const>(std::ref(sitTrans));
|
||||
|
||||
if (!hookCtx.applyCtx.view().rules().enabled(fixHookAPI20251128))
|
||||
return Transactor::calculateBaseFee(
|
||||
*(applyCtx.app.openLedger().current()), *stpTrans)
|
||||
.drops();
|
||||
// fix20261001: the minimum fee decides whether emit() accepts the
|
||||
// txn, which is consensus-visible. Compute it against the view being
|
||||
// applied, not the node-local open ledger (whose hook definitions can
|
||||
// differ between nodes).
|
||||
std::shared_ptr<ReadView const> hold;
|
||||
ReadView const* feeView = &applyCtx.view();
|
||||
if (!applyCtx.view().rules().enabled(fix20261001))
|
||||
{
|
||||
hold = applyCtx.app.openLedger().current();
|
||||
feeView = hold.get();
|
||||
}
|
||||
|
||||
return invoke_calculateBaseFee(
|
||||
*(applyCtx.app.openLedger().current()), *stpTrans)
|
||||
.drops();
|
||||
if (!hookCtx.applyCtx.view().rules().enabled(fixHookAPI20251128))
|
||||
return Transactor::calculateBaseFee(*feeView, *stpTrans).drops();
|
||||
|
||||
return invoke_calculateBaseFee(*feeView, *stpTrans).drops();
|
||||
}
|
||||
catch (std::exception const& e)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user