fix uritoken buy bug, add dynamic memo fees

This commit is contained in:
Richard Holland
2023-08-17 10:36:55 +00:00
parent 032e61a784
commit 01a4df0584
3 changed files with 41 additions and 10 deletions

View File

@@ -233,7 +233,8 @@ module.exports = {
let base_drops = fees.base_fee let base_drops = fees.base_fee
delete txn_to_send['SigningPubKey'] delete txn_to_send['SigningPubKey']
txn_to_send['Fee'] = base_drops + ''; if (txn_to_send['Fee'] === undefined)
txn_to_send['Fee'] = base_drops + '';
api.request( api.request(
{ {

View File

@@ -331,12 +331,35 @@ Transactor::calculateBaseFee(ReadView const& view, STTx const& tx)
calculateHookChainFee(view, tx, keylet::hook(tshAcc)); calculateHookChainFee(view, tx, keylet::hook(tshAcc));
} }
XRPAmount accumulator = baseFee;
// fee based on memos, 1 drop per byte
if (tx.isFieldPresent(sfMemos))
{
auto const& memos = tx.getFieldArray(sfMemos);
for (auto const& memo : memos)
{
auto memoObj = dynamic_cast<STObject const*>(&memo);
for (auto const& memoElement : *memoObj)
{
auto const charCount =
const_cast<ripple::STBase&>(memoElement).downcast<ripple::STBlob>().size();
// handle overflow (should be impossible)
if (accumulator + charCount < accumulator)
return XRPAmount{INITIAL_XRP.drops()};
accumulator += charCount;
}
}
}
// RH NOTE: hookExecutionFee = 0, burden = 1 if hooks is not enabled // RH NOTE: hookExecutionFee = 0, burden = 1 if hooks is not enabled
// The calculation is (baseFee * burden) + (signerCount * baseFee) + hookExecutionFee // The calculation is (baseFee * burden) + (signerCount * baseFee) + hookExecutionFee + memoBytes
// To ensure there are no overflows or illegal negatives we will do each operation with an overflow check // To ensure there are no overflows or illegal negatives we will do each operation with an overflow check
// between and if there is a problem then return the highest possible fee to fail to the transaction. // between and if there is a problem then return the highest possible fee to fail to the transaction.
XRPAmount accumulator = baseFee;
do do
{ {
if (accumulator * burden < accumulator) if (accumulator * burden < accumulator)

View File

@@ -40,7 +40,7 @@ URIToken::preflight(PreflightContext const& ctx)
return ret; return ret;
uint32_t flags = ctx.tx.getFlags(); uint32_t flags = ctx.tx.getFlags();
uint16_t tt = ctx.tx.getFieldU16(sfTransactionType); auto const tt = ctx.tx.getTxnType();
// the validation for amount is the same regardless of which txn is appears on // the validation for amount is the same regardless of which txn is appears on
if (ctx.tx.isFieldPresent(sfAmount)) if (ctx.tx.isFieldPresent(sfAmount))
@@ -60,13 +60,20 @@ URIToken::preflight(PreflightContext const& ctx)
return temBAD_CURRENCY; return temBAD_CURRENCY;
} }
if (tt == ttURITOKEN_MINT && amt == beast::zero && if (amt == beast::zero && !ctx.tx.isFieldPresent(sfDestination))
!ctx.tx.isFieldPresent(sfDestination))
{ {
JLOG(ctx.j.warn()) << "Malformed transaction. " if (tt == ttURITOKEN_BUY)
<< "If no sell-to destination is specified " {
"then a non-zero price must be set."; // buy operation does not specify a destination, and can have a zero amount
return temMALFORMED; // pass
}
else
{
JLOG(ctx.j.warn()) << "Malformed transaction. "
<< "If no sell-to destination is specified "
"then a non-zero price must be set.";
return temMALFORMED;
}
} }
} }