get new fees and reserves working (#5714)

This commit is contained in:
Mayukha Vadari
2025-08-29 10:58:52 -04:00
committed by GitHub
parent c2ea68cca4
commit 8ac514363d
2 changed files with 108 additions and 69 deletions

View File

@@ -1756,7 +1756,8 @@ struct Escrow_test : public beast::unit_test::suite
return cfg; return cfg;
}), }),
features); features);
XRPAmount const txnFees = env.current()->fees().base * 10 + 1000; XRPAmount const txnFees =
env.current()->fees().base * 10 + wasmHex.size() / 2 * 5;
// create escrow // create escrow
env.fund(XRP(5000), alice, carol); env.fund(XRP(5000), alice, carol);
@@ -1767,7 +1768,7 @@ struct Escrow_test : public beast::unit_test::suite
// FinishFunction + CancelAfter // FinishFunction + CancelAfter
env(escrowCreate, env(escrowCreate,
escrow::finish_function(wasmHex), escrow::finish_function(wasmHex),
escrow::cancel_time(env.now() + 100s), escrow::cancel_time(env.now() + 20s),
fee(txnFees)); fee(txnFees));
env.close(); env.close();
} }
@@ -1775,7 +1776,7 @@ struct Escrow_test : public beast::unit_test::suite
// FinishFunction + Condition + CancelAfter // FinishFunction + Condition + CancelAfter
env(escrowCreate, env(escrowCreate,
escrow::finish_function(wasmHex), escrow::finish_function(wasmHex),
escrow::cancel_time(env.now() + 100s), escrow::cancel_time(env.now() + 30s),
escrow::condition(escrow::cb1), escrow::condition(escrow::cb1),
fee(txnFees)); fee(txnFees));
env.close(); env.close();
@@ -1784,7 +1785,7 @@ struct Escrow_test : public beast::unit_test::suite
// FinishFunction + FinishAfter + CancelAfter // FinishFunction + FinishAfter + CancelAfter
env(escrowCreate, env(escrowCreate,
escrow::finish_function(wasmHex), escrow::finish_function(wasmHex),
escrow::cancel_time(env.now() + 100s), escrow::cancel_time(env.now() + 40s),
escrow::finish_time(env.now() + 2s), escrow::finish_time(env.now() + 2s),
fee(txnFees)); fee(txnFees));
env.close(); env.close();
@@ -1793,7 +1794,7 @@ struct Escrow_test : public beast::unit_test::suite
// FinishFunction + FinishAfter + Condition + CancelAfter // FinishFunction + FinishAfter + Condition + CancelAfter
env(escrowCreate, env(escrowCreate,
escrow::finish_function(wasmHex), escrow::finish_function(wasmHex),
escrow::cancel_time(env.now() + 100s), escrow::cancel_time(env.now() + 50s),
escrow::condition(escrow::cb1), escrow::condition(escrow::cb1),
escrow::finish_time(env.now() + 2s), escrow::finish_time(env.now() + 2s),
fee(txnFees)); fee(txnFees));
@@ -1841,11 +1842,20 @@ struct Escrow_test : public beast::unit_test::suite
// FinishFunction 0 length // FinishFunction 0 length
env(escrowCreate, env(escrowCreate,
escrow::finish_function(""), escrow::finish_function(""),
escrow::cancel_time(env.now() + 100s), escrow::cancel_time(env.now() + 60s),
fee(txnFees), fee(txnFees),
ter(temMALFORMED)); ter(temMALFORMED));
env.close(); env.close();
} }
{
// Not enough fees
env(escrowCreate,
escrow::finish_function(wasmHex),
escrow::cancel_time(env.now() + 70s),
fee(txnFees - 1),
ter(telINSUF_FEE_P));
env.close();
}
{ {
// FinishFunction nonexistent host function // FinishFunction nonexistent host function
@@ -1890,7 +1900,8 @@ struct Escrow_test : public beast::unit_test::suite
// featureSmartEscrow disabled // featureSmartEscrow disabled
Env env(*this, features - featureSmartEscrow); Env env(*this, features - featureSmartEscrow);
env.fund(XRP(5000), alice, carol); env.fund(XRP(5000), alice, carol);
XRPAmount const txnFees = env.current()->fees().base + 1000; XRPAmount const txnFees =
env.current()->fees().base * 10 + wasmHex.size() / 2 * 5;
env(escrow::finish(carol, alice, 1), env(escrow::finish(carol, alice, 1),
fee(txnFees), fee(txnFees),
escrow::comp_allowance(4), escrow::comp_allowance(4),
@@ -1929,7 +1940,8 @@ struct Escrow_test : public beast::unit_test::suite
for (auto i = env.current()->seq(); i <= 257; ++i) for (auto i = env.current()->seq(); i <= 257; ++i)
env.close(); env.close();
XRPAmount const txnFees = env.current()->fees().base + 1000; XRPAmount const txnFees =
env.current()->fees().base * 10 + wasmHex.size() / 2 * 5;
env.fund(XRP(5000), alice, carol); env.fund(XRP(5000), alice, carol);
// create escrow // create escrow
@@ -1986,7 +1998,10 @@ struct Escrow_test : public beast::unit_test::suite
auto const allowance = 100; auto const allowance = 100;
env(escrow::finish(carol, alice, seq2), env(escrow::finish(carol, alice, seq2),
fee(env.current()->fees().base + allowance), fee(env.current()->fees().base +
(allowance * env.current()->fees().gasPrice) /
MICRO_DROPS_PER_DROP +
1),
escrow::comp_allowance(allowance), escrow::comp_allowance(allowance),
ter(tefNO_WASM)); ter(tefNO_WASM));
} }
@@ -2007,6 +2022,17 @@ struct Escrow_test : public beast::unit_test::suite
// getLedgerSqn() >= 5} // getLedgerSqn() >= 5}
auto const& wasmHex = ledgerSqnWasmHex; auto const& wasmHex = ledgerSqnWasmHex;
std::uint32_t const allowance = 66; std::uint32_t const allowance = 66;
auto escrowCreate = escrow::create(alice, carol, XRP(1000));
auto [createFee, finishFee] = [&]() {
Env env(*this, features);
auto createFee =
env.current()->fees().base * 10 + wasmHex.size() / 2 * 5;
auto finishFee = env.current()->fees().base +
(allowance * env.current()->fees().gasPrice) /
MICRO_DROPS_PER_DROP +
1;
return std::make_pair(createFee, finishFee);
}();
{ {
// basic FinishFunction situation // basic FinishFunction situation
@@ -2015,38 +2041,36 @@ struct Escrow_test : public beast::unit_test::suite
env.fund(XRP(5000), alice, carol); env.fund(XRP(5000), alice, carol);
auto const seq = env.seq(alice); auto const seq = env.seq(alice);
BEAST_EXPECT((*env.le(alice))[sfOwnerCount] == 0); BEAST_EXPECT((*env.le(alice))[sfOwnerCount] == 0);
auto escrowCreate = escrow::create(alice, carol, XRP(1000));
XRPAmount txnFees = env.current()->fees().base + 1000;
env(escrowCreate, env(escrowCreate,
escrow::finish_function(wasmHex), escrow::finish_function(wasmHex),
escrow::cancel_time(env.now() + 100s), escrow::cancel_time(env.now() + 100s),
fee(txnFees)); fee(createFee));
env.close(); env.close();
if (BEAST_EXPECT((*env.le(alice))[sfOwnerCount] == 2)) if (BEAST_EXPECT((*env.le(alice))[sfOwnerCount] == 2))
{ {
env.require(balance(alice, XRP(4000) - txnFees)); env.require(balance(alice, XRP(4000) - createFee));
env.require(balance(carol, XRP(5000))); env.require(balance(carol, XRP(5000)));
env(escrow::finish(carol, alice, seq), env(escrow::finish(carol, alice, seq),
escrow::comp_allowance(allowance), escrow::comp_allowance(allowance),
fee(txnFees), fee(finishFee),
ter(tecWASM_REJECTED)); ter(tecWASM_REJECTED));
env(escrow::finish(alice, alice, seq), env(escrow::finish(alice, alice, seq),
escrow::comp_allowance(allowance), escrow::comp_allowance(allowance),
fee(txnFees), fee(finishFee),
ter(tecWASM_REJECTED)); ter(tecWASM_REJECTED));
env(escrow::finish(alice, alice, seq), env(escrow::finish(alice, alice, seq),
escrow::comp_allowance(allowance), escrow::comp_allowance(allowance),
fee(txnFees), fee(finishFee),
ter(tecWASM_REJECTED)); ter(tecWASM_REJECTED));
env(escrow::finish(carol, alice, seq), env(escrow::finish(carol, alice, seq),
escrow::comp_allowance(allowance), escrow::comp_allowance(allowance),
fee(txnFees), fee(finishFee),
ter(tecWASM_REJECTED)); ter(tecWASM_REJECTED));
env(escrow::finish(carol, alice, seq), env(escrow::finish(carol, alice, seq),
escrow::comp_allowance(allowance), escrow::comp_allowance(allowance),
fee(txnFees), fee(finishFee),
ter(tecWASM_REJECTED)); ter(tecWASM_REJECTED));
env.close(); env.close();
@@ -2059,7 +2083,7 @@ struct Escrow_test : public beast::unit_test::suite
} }
env(escrow::finish(alice, alice, seq), env(escrow::finish(alice, alice, seq),
fee(txnFees), fee(finishFee),
escrow::comp_allowance(allowance), escrow::comp_allowance(allowance),
ter(tesSUCCESS)); ter(tesSUCCESS));
@@ -2084,34 +2108,31 @@ struct Escrow_test : public beast::unit_test::suite
BEAST_EXPECT((*env.le(alice))[sfOwnerCount] == 0); BEAST_EXPECT((*env.le(alice))[sfOwnerCount] == 0);
auto const seq = env.seq(alice); auto const seq = env.seq(alice);
// create escrow // create escrow
auto escrowCreate = escrow::create(alice, carol, XRP(1000));
XRPAmount const createFee = env.current()->fees().base + 1000;
env(escrowCreate, env(escrowCreate,
escrow::finish_function(wasmHex), escrow::finish_function(wasmHex),
escrow::condition(escrow::cb1), escrow::condition(escrow::cb1),
escrow::cancel_time(env.now() + 100s), escrow::cancel_time(env.now() + 100s),
fee(createFee)); fee(createFee));
env.close(); env.close();
auto const conditionFinishFee = finishFee +
env.current()->fees().base * (32 + (escrow::fb1.size() / 16));
if (BEAST_EXPECT((*env.le(alice))[sfOwnerCount] == 2)) if (BEAST_EXPECT((*env.le(alice))[sfOwnerCount] == 2))
{ {
env.require(balance(alice, XRP(4000) - createFee)); env.require(balance(alice, XRP(4000) - createFee));
env.require(balance(carol, XRP(5000))); env.require(balance(carol, XRP(5000)));
XRPAmount const txnFees =
env.current()->fees().base * 34 + 1000;
// no fulfillment provided, function fails // no fulfillment provided, function fails
env(escrow::finish(carol, alice, seq), env(escrow::finish(carol, alice, seq),
escrow::comp_allowance(allowance), escrow::comp_allowance(allowance),
fee(txnFees), fee(finishFee),
ter(tecCRYPTOCONDITION_ERROR)); ter(tecCRYPTOCONDITION_ERROR));
// fulfillment provided, function fails // fulfillment provided, function fails
env(escrow::finish(carol, alice, seq), env(escrow::finish(carol, alice, seq),
escrow::condition(escrow::cb1), escrow::condition(escrow::cb1),
escrow::fulfillment(escrow::fb1), escrow::fulfillment(escrow::fb1),
escrow::comp_allowance(allowance), escrow::comp_allowance(allowance),
fee(txnFees), fee(conditionFinishFee),
ter(tecWASM_REJECTED)); ter(tecWASM_REJECTED));
if (BEAST_EXPECT(env.meta()->isFieldPresent(sfGasUsed))) if (BEAST_EXPECT(env.meta()->isFieldPresent(sfGasUsed)))
BEAST_EXPECTS( BEAST_EXPECTS(
@@ -2121,21 +2142,21 @@ struct Escrow_test : public beast::unit_test::suite
// no fulfillment provided, function succeeds // no fulfillment provided, function succeeds
env(escrow::finish(alice, alice, seq), env(escrow::finish(alice, alice, seq),
escrow::comp_allowance(allowance), escrow::comp_allowance(allowance),
fee(txnFees), fee(conditionFinishFee),
ter(tecCRYPTOCONDITION_ERROR)); ter(tecCRYPTOCONDITION_ERROR));
// wrong fulfillment provided, function succeeds // wrong fulfillment provided, function succeeds
env(escrow::finish(alice, alice, seq), env(escrow::finish(alice, alice, seq),
escrow::condition(escrow::cb1), escrow::condition(escrow::cb1),
escrow::fulfillment(escrow::fb2), escrow::fulfillment(escrow::fb2),
escrow::comp_allowance(allowance), escrow::comp_allowance(allowance),
fee(txnFees), fee(conditionFinishFee),
ter(tecCRYPTOCONDITION_ERROR)); ter(tecCRYPTOCONDITION_ERROR));
// fulfillment provided, function succeeds, tx succeeds // fulfillment provided, function succeeds, tx succeeds
env(escrow::finish(alice, alice, seq), env(escrow::finish(alice, alice, seq),
escrow::condition(escrow::cb1), escrow::condition(escrow::cb1),
escrow::fulfillment(escrow::fb1), escrow::fulfillment(escrow::fb1),
escrow::comp_allowance(allowance), escrow::comp_allowance(allowance),
fee(txnFees), fee(conditionFinishFee),
ter(tesSUCCESS)); ter(tesSUCCESS));
auto const txMeta = env.meta(); auto const txMeta = env.meta();
@@ -2158,37 +2179,35 @@ struct Escrow_test : public beast::unit_test::suite
env.fund(XRP(5000), alice, carol); env.fund(XRP(5000), alice, carol);
auto const seq = env.seq(alice); auto const seq = env.seq(alice);
BEAST_EXPECT((*env.le(alice))[sfOwnerCount] == 0); BEAST_EXPECT((*env.le(alice))[sfOwnerCount] == 0);
auto escrowCreate = escrow::create(alice, carol, XRP(1000));
XRPAmount txnFees = env.current()->fees().base + 1000;
auto const ts = env.now() + 97s; auto const ts = env.now() + 97s;
env(escrowCreate, env(escrowCreate,
escrow::finish_function(wasmHex), escrow::finish_function(wasmHex),
escrow::finish_time(ts), escrow::finish_time(ts),
escrow::cancel_time(env.now() + 1000s), escrow::cancel_time(env.now() + 1000s),
fee(txnFees)); fee(createFee));
env.close(); env.close();
if (BEAST_EXPECT((*env.le(alice))[sfOwnerCount] == 2)) if (BEAST_EXPECT((*env.le(alice))[sfOwnerCount] == 2))
{ {
env.require(balance(alice, XRP(4000) - txnFees)); env.require(balance(alice, XRP(4000) - createFee));
env.require(balance(carol, XRP(5000))); env.require(balance(carol, XRP(5000)));
// finish time hasn't passed, function fails // finish time hasn't passed, function fails
env(escrow::finish(carol, alice, seq), env(escrow::finish(carol, alice, seq),
escrow::comp_allowance(allowance), escrow::comp_allowance(allowance),
fee(txnFees + 1), fee(finishFee + 1),
ter(tecNO_PERMISSION)); ter(tecNO_PERMISSION));
env.close(); env.close();
// finish time hasn't passed, function succeeds // finish time hasn't passed, function succeeds
for (; env.now() < ts; env.close()) for (; env.now() < ts; env.close())
env(escrow::finish(carol, alice, seq), env(escrow::finish(carol, alice, seq),
escrow::comp_allowance(allowance), escrow::comp_allowance(allowance),
fee(txnFees + 2), fee(finishFee + 2),
ter(tecNO_PERMISSION)); ter(tecNO_PERMISSION));
env(escrow::finish(carol, alice, seq), env(escrow::finish(carol, alice, seq),
escrow::comp_allowance(allowance), escrow::comp_allowance(allowance),
fee(txnFees + 1), fee(finishFee + 1),
ter(tesSUCCESS)); ter(tesSUCCESS));
auto const txMeta = env.meta(); auto const txMeta = env.meta();
@@ -2210,31 +2229,29 @@ struct Escrow_test : public beast::unit_test::suite
env.fund(XRP(5000), alice, carol); env.fund(XRP(5000), alice, carol);
auto const seq = env.seq(alice); auto const seq = env.seq(alice);
BEAST_EXPECT((*env.le(alice))[sfOwnerCount] == 0); BEAST_EXPECT((*env.le(alice))[sfOwnerCount] == 0);
auto escrowCreate = escrow::create(alice, carol, XRP(1000));
XRPAmount txnFees = env.current()->fees().base + 1000;
env(escrowCreate, env(escrowCreate,
escrow::finish_function(wasmHex), escrow::finish_function(wasmHex),
escrow::finish_time(env.now() + 2s), escrow::finish_time(env.now() + 2s),
escrow::cancel_time(env.now() + 100s), escrow::cancel_time(env.now() + 100s),
fee(txnFees)); fee(createFee));
// Don't close the ledger here // Don't close the ledger here
if (BEAST_EXPECT((*env.le(alice))[sfOwnerCount] == 2)) if (BEAST_EXPECT((*env.le(alice))[sfOwnerCount] == 2))
{ {
env.require(balance(alice, XRP(4000) - txnFees)); env.require(balance(alice, XRP(4000) - createFee));
env.require(balance(carol, XRP(5000))); env.require(balance(carol, XRP(5000)));
// finish time hasn't passed, function fails // finish time hasn't passed, function fails
env(escrow::finish(carol, alice, seq), env(escrow::finish(carol, alice, seq),
escrow::comp_allowance(allowance), escrow::comp_allowance(allowance),
fee(txnFees), fee(finishFee),
ter(tecNO_PERMISSION)); ter(tecNO_PERMISSION));
env.close(); env.close();
// finish time has passed, function fails // finish time has passed, function fails
env(escrow::finish(carol, alice, seq), env(escrow::finish(carol, alice, seq),
escrow::comp_allowance(allowance), escrow::comp_allowance(allowance),
fee(txnFees), fee(finishFee),
ter(tecWASM_REJECTED)); ter(tecWASM_REJECTED));
if (BEAST_EXPECT(env.meta()->isFieldPresent(sfGasUsed))) if (BEAST_EXPECT(env.meta()->isFieldPresent(sfGasUsed)))
BEAST_EXPECTS( BEAST_EXPECTS(
@@ -2244,7 +2261,7 @@ struct Escrow_test : public beast::unit_test::suite
// finish time has passed, function succeeds, tx succeeds // finish time has passed, function succeeds, tx succeeds
env(escrow::finish(carol, alice, seq), env(escrow::finish(carol, alice, seq),
escrow::comp_allowance(allowance), escrow::comp_allowance(allowance),
fee(txnFees), fee(finishFee),
ter(tesSUCCESS)); ter(tesSUCCESS));
auto const txMeta = env.meta(); auto const txMeta = env.meta();
@@ -2282,7 +2299,8 @@ struct Escrow_test : public beast::unit_test::suite
auto const seq = env.seq(alice); auto const seq = env.seq(alice);
BEAST_EXPECT((*env.le(alice))[sfOwnerCount] == 0); BEAST_EXPECT((*env.le(alice))[sfOwnerCount] == 0);
auto escrowCreate = escrow::create(alice, carol, XRP(1000)); auto escrowCreate = escrow::create(alice, carol, XRP(1000));
XRPAmount txnFees = env.current()->fees().base + 1000; XRPAmount txnFees =
env.current()->fees().base * 10 + wasmHex.size() / 2 * 5;
env(escrowCreate, env(escrowCreate,
escrow::finish_function(wasmHex), escrow::finish_function(wasmHex),
escrow::finish_time(env.now() + 11s), escrow::finish_time(env.now() + 11s),
@@ -2291,17 +2309,23 @@ struct Escrow_test : public beast::unit_test::suite
fee(txnFees)); fee(txnFees));
env.close(); env.close();
if (BEAST_EXPECT((*env.le(alice))[sfOwnerCount] == 2)) if (BEAST_EXPECT(
(*env.le(alice))[sfOwnerCount] ==
(1 + wasmHex.size() / 2 / 500)))
{ {
env.require(balance(alice, XRP(4000) - txnFees)); env.require(balance(alice, XRP(4000) - txnFees));
env.require(balance(carol, XRP(5000))); env.require(balance(carol, XRP(5000)));
auto const allowance = 1'000'000; auto const allowance = 1'000'000;
XRPAmount const finishFee = env.current()->fees().base +
(allowance * env.current()->fees().gasPrice) /
MICRO_DROPS_PER_DROP +
1;
// FinishAfter time hasn't passed // FinishAfter time hasn't passed
env(escrow::finish(carol, alice, seq), env(escrow::finish(carol, alice, seq),
escrow::comp_allowance(allowance), escrow::comp_allowance(allowance),
fee(txnFees), fee(finishFee),
ter(tecNO_PERMISSION)); ter(tecNO_PERMISSION));
env.close(); env.close();
env.close(); env.close();
@@ -2314,7 +2338,7 @@ struct Escrow_test : public beast::unit_test::suite
env(escrow::finish(alice, alice, seq), env(escrow::finish(alice, alice, seq),
escrow::comp_allowance(allowance), escrow::comp_allowance(allowance),
fee(txnFees), fee(finishFee),
ter(tesSUCCESS)); ter(tesSUCCESS));
auto const txMeta = env.meta(); auto const txMeta = env.meta();
@@ -2392,7 +2416,8 @@ struct Escrow_test : public beast::unit_test::suite
env.seq(alice) == 20, std::to_string(env.seq(alice)))) env.seq(alice) == 20, std::to_string(env.seq(alice))))
{ {
auto const seq = env.seq(alice); auto const seq = env.seq(alice);
XRPAmount txnFees = env.current()->fees().base + 1000; XRPAmount txnFees =
env.current()->fees().base * 10 + wasmHex.size() / 2 * 5;
env(escrow::create(alice, carol, XRP(1000)), env(escrow::create(alice, carol, XRP(1000)),
escrow::finish_function(wasmHex), escrow::finish_function(wasmHex),
escrow::finish_time(env.now() + 2s), escrow::finish_time(env.now() + 2s),
@@ -2403,10 +2428,13 @@ struct Escrow_test : public beast::unit_test::suite
env.close(); env.close();
auto const allowance = 137'596; auto const allowance = 137'596;
auto const finishFee = env.current()->fees().base +
(allowance * env.current()->fees().gasPrice) /
MICRO_DROPS_PER_DROP +
1;
env(escrow::finish(carol, alice, seq), env(escrow::finish(carol, alice, seq),
escrow::comp_allowance(allowance), escrow::comp_allowance(allowance),
fee(txnFees)); fee(finishFee));
env.close(); env.close();
auto const txMeta = env.meta(); auto const txMeta = env.meta();

View File

@@ -127,8 +127,9 @@ EscrowCreate::calculateBaseFee(ReadView const& view, STTx const& tx)
XRPAmount txnFees{Transactor::calculateBaseFee(view, tx)}; XRPAmount txnFees{Transactor::calculateBaseFee(view, tx)};
if (tx.isFieldPresent(sfFinishFunction)) if (tx.isFieldPresent(sfFinishFunction))
{ {
// TODO: make this fee increase based on the extra compute run // 10 base fees for the transaction (1 is in
txnFees += 1000; // `Transactor::calculateBaseFee`), plus 5 drops per byte
txnFees += 9 * view.fees().base + 5 * tx[sfFinishFunction].size();
} }
return txnFees; return txnFees;
} }
@@ -503,6 +504,17 @@ escrowLockApplyHelper<MPTIssue>(
return tesSUCCESS; return tesSUCCESS;
} }
template <class T>
static uint32_t
calculateAdditionalReserve(T const& finishFunction)
{
if (!finishFunction)
return 1;
// First 500 bytes included in the normal reserve
// Each additional 500 bytes requires an additional reserve
return 1 + (finishFunction->size() / 500);
}
TER TER
EscrowCreate::doApply() EscrowCreate::doApply()
{ {
@@ -546,9 +558,11 @@ EscrowCreate::doApply()
// Check reserve and funds availability // Check reserve and funds availability
STAmount const amount{ctx_.tx[sfAmount]}; STAmount const amount{ctx_.tx[sfAmount]};
auto const reserveToAdd =
calculateAdditionalReserve(ctx_.tx[~sfFinishFunction]);
auto const reserve = auto const reserve =
ctx_.view().fees().accountReserve((*sle)[sfOwnerCount] + 1); ctx_.view().fees().accountReserve((*sle)[sfOwnerCount] + reserveToAdd);
if (mSourceBalance < reserve) if (mSourceBalance < reserve)
return tecINSUFFICIENT_RESERVE; return tecINSUFFICIENT_RESERVE;
@@ -654,11 +668,7 @@ EscrowCreate::doApply()
// increment owner count // increment owner count
// TODO: determine actual reserve based on FinishFunction size // TODO: determine actual reserve based on FinishFunction size
adjustOwnerCount( adjustOwnerCount(ctx_.view(), sle, reserveToAdd, ctx_.journal);
ctx_.view(),
sle,
ctx_.tx.isFieldPresent(sfFinishFunction) ? 2 : 1,
ctx_.journal);
ctx_.view().update(sle); ctx_.view().update(sle);
return tesSUCCESS; return tesSUCCESS;
} }
@@ -773,7 +783,11 @@ EscrowFinish::calculateBaseFee(ReadView const& view, STTx const& tx)
} }
if (auto const allowance = tx[~sfComputationAllowance]; allowance) if (auto const allowance = tx[~sfComputationAllowance]; allowance)
{ {
extraFee += (*allowance) * view.fees().gasPrice / MICRO_DROPS_PER_DROP; // The extra fee is the allowance in drops, rounded up to the nearest
// whole drop.
// Integer math rounds down by default, so we add 1 to round up.
extraFee +=
((*allowance) * view.fees().gasPrice) / MICRO_DROPS_PER_DROP + 1;
} }
return Transactor::calculateBaseFee(view, tx) + extraFee; return Transactor::calculateBaseFee(view, tx) + extraFee;
} }
@@ -1375,13 +1389,12 @@ EscrowFinish::doApply()
ctx_.view().update(sled); ctx_.view().update(sled);
auto const reserveToSubtract =
calculateAdditionalReserve((*slep)[~sfFinishFunction]);
// Adjust source owner count // Adjust source owner count
auto const sle = ctx_.view().peek(keylet::account(account)); auto const sle = ctx_.view().peek(keylet::account(account));
adjustOwnerCount( adjustOwnerCount(ctx_.view(), sle, -1 * reserveToSubtract, ctx_.journal);
ctx_.view(),
sle,
slep->isFieldPresent(sfFinishFunction) ? -2 : -1,
ctx_.journal);
ctx_.view().update(sle); ctx_.view().update(sle);
// Remove escrow from ledger // Remove escrow from ledger
@@ -1592,11 +1605,9 @@ EscrowCancel::doApply()
} }
} }
adjustOwnerCount( auto const reserveToSubtract =
ctx_.view(), calculateAdditionalReserve((*slep)[~sfFinishFunction]);
sle, adjustOwnerCount(ctx_.view(), sle, -1 * reserveToSubtract, ctx_.journal);
slep->isFieldPresent(sfFinishFunction) ? -2 : -1,
ctx_.journal);
ctx_.view().update(sle); ctx_.view().update(sle);
// Remove escrow from ledger // Remove escrow from ledger