mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-04 19:25:51 +00:00
Use XRPAmount for fees and ledger headers
This commit is contained in:
@@ -359,7 +359,7 @@ void Ledger::updateHash()
|
||||
info_.hash = sha512Half(
|
||||
HashPrefix::ledgerMaster,
|
||||
std::uint32_t(info_.seq),
|
||||
std::uint64_t(info_.drops),
|
||||
std::uint64_t(info_.drops.drops ()),
|
||||
info_.parentHash,
|
||||
info_.txHash,
|
||||
info_.accountHash,
|
||||
@@ -570,7 +570,7 @@ bool Ledger::saveValidatedLedger (bool current)
|
||||
*db << boost::str (
|
||||
addLedger %
|
||||
to_string (getHash ()) % info_.seq % to_string (info_.parentHash) %
|
||||
std::to_string (info_.drops) % info_.closeTime %
|
||||
to_string (info_.drops) % info_.closeTime %
|
||||
info_.parentCloseTime % info_.closeTimeResolution %
|
||||
info_.closeFlags % to_string (info_.accountHash) %
|
||||
to_string (info_.txHash));
|
||||
|
||||
@@ -200,9 +200,9 @@ public:
|
||||
SLE> const& sle) override;
|
||||
|
||||
void
|
||||
rawDestroyXRP (std::uint64_t feeDrops) override
|
||||
rawDestroyXRP (XRPAmount const& fee) override
|
||||
{
|
||||
info_.drops -= feeDrops;
|
||||
info_.drops -= fee;
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include <ripple/ledger/ApplyViewImpl.h>
|
||||
#include <ripple/core/Config.h>
|
||||
#include <ripple/protocol/STTx.h>
|
||||
#include <ripple/protocol/XRPAmount.h>
|
||||
#include <beast/utility/Journal.h>
|
||||
#include <boost/optional.hpp>
|
||||
#include <utility>
|
||||
@@ -92,9 +93,9 @@ public:
|
||||
std::shared_ptr <SLE const> const& after)> const& func);
|
||||
|
||||
void
|
||||
destroyXRP (std::uint64_t feeDrops)
|
||||
destroyXRP (XRPAmount const& fee)
|
||||
{
|
||||
view_->rawDestroyXRP(feeDrops);
|
||||
view_->rawDestroyXRP(fee);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@@ -38,10 +38,11 @@ Change::preflight (PreflightContext const& ctx)
|
||||
return temBAD_SRC_ACCOUNT;
|
||||
}
|
||||
|
||||
auto const fee = ctx.tx.getTransactionFee ();
|
||||
// No point in going any further if the transaction fee is malformed.
|
||||
auto const fee = ctx.tx.getFieldAmount (sfFee);
|
||||
if (!fee.native () || fee != beast::zero)
|
||||
{
|
||||
JLOG(ctx.j.warning) << "Change: Non-zero fee";
|
||||
JLOG(ctx.j.warning) << "Change: invalid fee";
|
||||
return temBAD_FEE;
|
||||
}
|
||||
|
||||
|
||||
@@ -539,20 +539,6 @@ CreateOffer::format_amount (STAmount const& amount)
|
||||
return txt;
|
||||
}
|
||||
|
||||
STAmount
|
||||
CreateOffer::getAccountReserve (SLE::pointer account)
|
||||
{
|
||||
// Mon Aug 17 11:00:00am PDT
|
||||
static NetClock::time_point const switchoverTime (
|
||||
std::chrono::seconds (493149600));
|
||||
if (ctx_.view().info().parentCloseTime <=
|
||||
switchoverTime.time_since_epoch().count())
|
||||
return STAmount (ctx_.view().fees().accountReserve(
|
||||
deprecatedWrongOwnerCount_+1));
|
||||
return STAmount (ctx_.view().fees().accountReserve(
|
||||
account->getFieldU32 (sfOwnerCount) + 1));
|
||||
}
|
||||
|
||||
void
|
||||
CreateOffer::preCompute()
|
||||
{
|
||||
@@ -784,18 +770,34 @@ CreateOffer::applyGuts (ApplyView& view, ApplyView& view_cancel)
|
||||
return { tesSUCCESS, true };
|
||||
}
|
||||
|
||||
if (mPriorBalance < getAccountReserve (sleCreator))
|
||||
{
|
||||
// If we are here, the signing account had an insufficient reserve
|
||||
// *prior* to our processing. If something actually crossed, then
|
||||
// we allow this; otherwise, we just claim a fee.
|
||||
if (!crossed)
|
||||
result = tecINSUF_RESERVE_OFFER;
|
||||
// Mon Aug 17 11:00:00am PDT
|
||||
static NetClock::time_point const switchoverTime (
|
||||
std::chrono::seconds (493149600));
|
||||
|
||||
if (result != tesSUCCESS)
|
||||
j_.debug << "final result: " << transToken (result);
|
||||
XRPAmount reserve;
|
||||
|
||||
return { result, true };
|
||||
if (ctx_.view().info().parentCloseTime <=
|
||||
switchoverTime.time_since_epoch().count())
|
||||
reserve = ctx_.view().fees().accountReserve(
|
||||
deprecatedWrongOwnerCount_+1);
|
||||
else
|
||||
reserve = ctx_.view().fees().accountReserve(
|
||||
sleCreator->getFieldU32 (sfOwnerCount) + 1);
|
||||
|
||||
if (mPriorBalance < reserve)
|
||||
{
|
||||
// If we are here, the signing account had an insufficient reserve
|
||||
// *prior* to our processing. If something actually crossed, then
|
||||
// we allow this; otherwise, we just claim a fee.
|
||||
if (!crossed)
|
||||
result = tecINSUF_RESERVE_OFFER;
|
||||
|
||||
if (result != tesSUCCESS)
|
||||
j_.debug << "final result: " << transToken (result);
|
||||
|
||||
return { result, true };
|
||||
}
|
||||
}
|
||||
|
||||
// We need to place the remainder of the offer into its order book.
|
||||
|
||||
@@ -49,11 +49,6 @@ public:
|
||||
TER
|
||||
preflight (PreflightContext const& ctx);
|
||||
|
||||
/** Returns the reserve the account would have if an offer was added. */
|
||||
// VFALCO This function is not needed just inline the behavior
|
||||
STAmount
|
||||
getAccountReserve (SLE::pointer account); // const?
|
||||
|
||||
void
|
||||
preCompute() override;
|
||||
|
||||
|
||||
@@ -50,22 +50,21 @@ CreateTicket::preflight (PreflightContext const& ctx)
|
||||
return preflight2 (ctx);
|
||||
}
|
||||
|
||||
STAmount
|
||||
CreateTicket::getAccountReserve (SLE::pointer account)
|
||||
{
|
||||
return STAmount (view().fees().accountReserve(
|
||||
account->getFieldU32 (sfOwnerCount) + 1));
|
||||
}
|
||||
|
||||
TER
|
||||
CreateTicket::doApply ()
|
||||
{
|
||||
auto const sle = view().peek(keylet::account(account_));
|
||||
|
||||
// A ticket counts against the reserve of the issuing account, but we
|
||||
// check the starting balance because we want to allow dipping into the
|
||||
// reserve to pay fees.
|
||||
if (mPriorBalance < STAmount(view().fees().accountReserve(
|
||||
view().read(keylet::account(account_))->getFieldU32(sfOwnerCount) + 1)))
|
||||
return tecINSUFFICIENT_RESERVE;
|
||||
{
|
||||
auto const reserve = view().fees().accountReserve(
|
||||
sle->getFieldU32(sfOwnerCount) + 1);
|
||||
|
||||
if (mPriorBalance < reserve)
|
||||
return tecINSUFFICIENT_RESERVE;
|
||||
}
|
||||
|
||||
std::uint32_t expiration (0);
|
||||
|
||||
@@ -124,8 +123,7 @@ CreateTicket::doApply ()
|
||||
sleTicket->setFieldU64(sfOwnerNode, hint);
|
||||
|
||||
// If we succeeded, the new entry counts agains the creator's reserve.
|
||||
adjustOwnerCount(view(), view().peek(
|
||||
keylet::account(account_)), 1);
|
||||
adjustOwnerCount(view(), sle, 1);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -40,11 +40,6 @@ public:
|
||||
TER
|
||||
preflight (PreflightContext const& ctx);
|
||||
|
||||
/** Returns the reserve the account would have if an offer was added. */
|
||||
// VFALCO Not needed, just inline the behavior.
|
||||
STAmount
|
||||
getAccountReserve (SLE::pointer account);
|
||||
|
||||
TER doApply () override;
|
||||
};
|
||||
|
||||
|
||||
@@ -380,6 +380,8 @@ Payment::doApply ()
|
||||
}
|
||||
else
|
||||
{
|
||||
assert (saDstAmount.native ());
|
||||
|
||||
// Direct XRP payment.
|
||||
|
||||
// uOwnerCount is the number of entries in this legder for this
|
||||
@@ -388,23 +390,22 @@ Payment::doApply ()
|
||||
keylet::account(account_))->getFieldU32 (sfOwnerCount);
|
||||
|
||||
// This is the total reserve in drops.
|
||||
auto const uReserve =
|
||||
view().fees().accountReserve(uOwnerCount);
|
||||
auto const reserve = view().fees().accountReserve(uOwnerCount);
|
||||
|
||||
// mPriorBalance is the balance on the sending account BEFORE the
|
||||
// fees were charged. We want to make sure we have enough reserve
|
||||
// to send. Allow final spend to use reserve for fee.
|
||||
auto const mmm = std::max(tx().getTransactionFee (),
|
||||
STAmount (uReserve));
|
||||
auto const mmm = std::max(reserve,
|
||||
tx().getFieldAmount (sfFee).xrp ());
|
||||
|
||||
if (mPriorBalance < saDstAmount + mmm)
|
||||
if (mPriorBalance < saDstAmount.xrp () + mmm)
|
||||
{
|
||||
// Vote no. However the transaction might succeed, if applied in
|
||||
// a different order.
|
||||
j_.trace << "Delay transaction: Insufficient funds: " <<
|
||||
" " << mPriorBalance.getText () <<
|
||||
" / " << (saDstAmount + mmm).getText () <<
|
||||
" (" << uReserve << ")";
|
||||
" " << to_string (mPriorBalance) <<
|
||||
" / " << to_string (saDstAmount.xrp () + mmm) <<
|
||||
" (" << to_string (reserve) << ")";
|
||||
|
||||
terResult = tecUNFUNDED_PAYMENT;
|
||||
}
|
||||
|
||||
@@ -119,8 +119,8 @@ SetTrust::doApply ()
|
||||
// to fund accounts in a way where there's no incentive to trick them
|
||||
// into creating an account you have no intention of using.
|
||||
|
||||
STAmount const reserveCreate ((uOwnerCount < 2)
|
||||
? 0
|
||||
XRPAmount const reserveCreate ((uOwnerCount < 2)
|
||||
? XRPAmount (zero)
|
||||
: view().fees().accountReserve(uOwnerCount + 1));
|
||||
|
||||
std::uint32_t uQualityIn (bQualityIn ? tx().getFieldU32 (sfQualityIn) : 0);
|
||||
|
||||
@@ -183,23 +183,22 @@ SusPayCreate::doApply()
|
||||
return tecNO_PERMISSION;
|
||||
}
|
||||
|
||||
XRPAmount const amount =
|
||||
STAmount(ctx_.tx[sfAmount]).mantissa();
|
||||
|
||||
auto const account = ctx_.tx[sfAccount];
|
||||
|
||||
auto const sle = ctx_.view().peek(
|
||||
keylet::account(account));
|
||||
|
||||
if (XRPAmount(STAmount((*sle)[sfBalance]).mantissa()) <
|
||||
XRPAmount(ctx_.view().fees().accountReserve(
|
||||
(*sle)[sfOwnerCount] + 1)))
|
||||
return tecINSUFFICIENT_RESERVE;
|
||||
// Check reserve and funds availability
|
||||
{
|
||||
auto const balance = STAmount((*sle)[sfBalance]).xrp();
|
||||
auto const reserve = ctx_.view().fees().accountReserve(
|
||||
(*sle)[sfOwnerCount] + 1);
|
||||
|
||||
if (XRPAmount(STAmount((*sle)[sfBalance]).mantissa()) <
|
||||
amount + XRPAmount(ctx_.view().fees().accountReserve(
|
||||
(*sle)[sfOwnerCount] + 1)))
|
||||
return tecUNFUNDED;
|
||||
if (balance < reserve)
|
||||
return tecINSUFFICIENT_RESERVE;
|
||||
|
||||
if (balance < reserve + STAmount(ctx_.tx[sfAmount]).xrp())
|
||||
return tecUNFUNDED;
|
||||
}
|
||||
|
||||
// Check destination account
|
||||
{
|
||||
|
||||
@@ -44,8 +44,8 @@ preflight1 (PreflightContext const& ctx)
|
||||
}
|
||||
|
||||
// No point in going any further if the transaction fee is malformed.
|
||||
auto const fee = ctx.tx.getTransactionFee ();
|
||||
if (!fee.native () || fee < beast::zero || !isLegalNet (fee))
|
||||
auto const fee = ctx.tx.getFieldAmount (sfFee);
|
||||
if (!fee.native () || fee.negative () || !isLegalAmount (fee.xrp ()))
|
||||
{
|
||||
JLOG(ctx.j.debug) << "preflight1: invalid fee";
|
||||
return temBAD_FEE;
|
||||
@@ -114,30 +114,29 @@ std::uint64_t Transactor::calculateBaseFee ()
|
||||
|
||||
TER Transactor::payFee ()
|
||||
{
|
||||
STAmount saPaid = tx().getTransactionFee ();
|
||||
|
||||
if (!isLegalNet (saPaid) || saPaid < zero)
|
||||
auto const feePaid = tx().getFieldAmount (sfFee).xrp ();
|
||||
if (!isLegalAmount (feePaid) || feePaid < beast::zero)
|
||||
return temBAD_FEE;
|
||||
|
||||
// Only check fee is sufficient when the ledger is open.
|
||||
if (view().open() && saPaid < mFeeDue)
|
||||
if (view().open() && feePaid < mFeeDue)
|
||||
{
|
||||
JLOG(j_.trace) << "Insufficient fee paid: " <<
|
||||
saPaid.getText () << "/" << mFeeDue.getText ();
|
||||
to_string (feePaid) << "/" << to_string (mFeeDue);
|
||||
return telINSUF_FEE_P;
|
||||
}
|
||||
|
||||
if (saPaid == zero)
|
||||
if (feePaid == zero)
|
||||
return tesSUCCESS;
|
||||
|
||||
auto const sle = view().peek(
|
||||
keylet::account(account_));
|
||||
|
||||
if (mSourceBalance < saPaid)
|
||||
if (mSourceBalance < feePaid)
|
||||
{
|
||||
JLOG(j_.trace) << "Insufficient balance:" <<
|
||||
" balance=" << mSourceBalance.getText () <<
|
||||
" paid=" << saPaid.getText ();
|
||||
" balance=" << to_string (mSourceBalance) <<
|
||||
" paid=" << to_string (feePaid);
|
||||
|
||||
if ((mSourceBalance > zero) && ! view().open())
|
||||
{
|
||||
@@ -151,7 +150,7 @@ TER Transactor::payFee ()
|
||||
// Deduct the fee, so it's not available during the transaction.
|
||||
// Will only write the account back, if the transaction succeeds.
|
||||
|
||||
mSourceBalance -= saPaid;
|
||||
mSourceBalance -= feePaid;
|
||||
sle->setFieldAmount (sfBalance, mSourceBalance);
|
||||
|
||||
// VFALCO Should we call view().rawDestroyXRP() here as well?
|
||||
@@ -227,12 +226,12 @@ TER Transactor::apply ()
|
||||
}
|
||||
|
||||
auto const& fees = view().fees();
|
||||
mFeeDue = STAmount (getApp().getFeeTrack().scaleFeeLoad(
|
||||
calculateBaseFee(), fees.base, fees.units, view().flags() & tapADMIN));
|
||||
mFeeDue = getApp().getFeeTrack().scaleFeeLoad(
|
||||
calculateBaseFee(), fees.base, fees.units, view().flags() & tapADMIN);
|
||||
|
||||
if (sle)
|
||||
{
|
||||
mPriorBalance = sle->getFieldAmount (sfBalance);
|
||||
mPriorBalance = STAmount ((*sle)[sfBalance]).xrp ();
|
||||
mSourceBalance = mPriorBalance;
|
||||
mHasAuthKey = sle->isFieldPresent (sfRegularKey);
|
||||
|
||||
@@ -550,7 +549,7 @@ Transactor::operator()()
|
||||
}
|
||||
|
||||
bool didApply = isTesSuccess (terResult);
|
||||
auto fee = tx().getTransactionFee ();
|
||||
auto fee = tx().getFieldAmount(sfFee).xrp ();
|
||||
|
||||
if (ctx_.size() > 5200)
|
||||
terResult = tecOVERSIZE;
|
||||
@@ -602,7 +601,7 @@ Transactor::operator()()
|
||||
terResult = tefPAST_SEQ;
|
||||
else
|
||||
{
|
||||
STAmount balance = txnAcct->getFieldAmount (sfBalance);
|
||||
auto const balance = txnAcct->getFieldAmount (sfBalance).xrp ();
|
||||
|
||||
// We retry/reject the transaction if the account
|
||||
// balance is zero or we're applying against an open
|
||||
@@ -645,23 +644,18 @@ Transactor::operator()()
|
||||
|
||||
if(view().closed())
|
||||
{
|
||||
// VFALCO Fix this nonsense with Amount
|
||||
// Charge whatever fee they specified. We break the
|
||||
// encapsulation of STAmount here and use "special
|
||||
// knowledge" - namely that a native amount is
|
||||
// stored fully in the mantissa:
|
||||
// Charge whatever fee they specified.
|
||||
|
||||
// The transactor guarantees these will never trigger
|
||||
if (!fee.native () || fee.negative ())
|
||||
// The transactor guarantees this will never trigger
|
||||
if (fee < zero)
|
||||
{
|
||||
// VFALCO Log to journal here
|
||||
// JLOG(journal.fatal) << "invalid fee";
|
||||
throw std::logic_error(
|
||||
"amount is negative!");
|
||||
throw std::logic_error("amount is negative!");
|
||||
}
|
||||
|
||||
if (fee != zero)
|
||||
ctx_.destroyXRP (fee.mantissa ());
|
||||
ctx_.destroyXRP (fee);
|
||||
}
|
||||
|
||||
ctx_.apply(terResult);
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#define RIPPLE_APP_TX_TRANSACTOR_H_INCLUDED
|
||||
|
||||
#include <ripple/app/tx/impl/ApplyContext.h>
|
||||
#include <ripple/protocol/XRPAmount.h>
|
||||
#include <beast/utility/Journal.h>
|
||||
|
||||
namespace ripple {
|
||||
@@ -57,9 +58,9 @@ protected:
|
||||
beast::Journal j_;
|
||||
|
||||
AccountID account_;
|
||||
STAmount mFeeDue;
|
||||
STAmount mPriorBalance; // Balance before fees.
|
||||
STAmount mSourceBalance; // Balance after fees.
|
||||
XRPAmount mFeeDue;
|
||||
XRPAmount mPriorBalance; // Balance before fees.
|
||||
XRPAmount mSourceBalance; // Balance after fees.
|
||||
bool mHasAuthKey;
|
||||
bool mSigMaster;
|
||||
RippleAddress mSigningPubKey;
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include <ripple/ledger/RawView.h>
|
||||
#include <ripple/ledger/ReadView.h>
|
||||
#include <ripple/ledger/detail/RawStateTable.h>
|
||||
#include <ripple/protocol/XRPAmount.h>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
@@ -209,7 +210,7 @@ public:
|
||||
|
||||
void
|
||||
rawDestroyXRP(
|
||||
std::uint64_t feeDrops) override;
|
||||
XRPAmount const& fee) override;
|
||||
|
||||
// TxsRawView
|
||||
|
||||
|
||||
@@ -85,7 +85,7 @@ public:
|
||||
*/
|
||||
virtual
|
||||
void
|
||||
rawDestroyXRP (std::uint64_t feeDrops) = 0;
|
||||
rawDestroyXRP (XRPAmount const& fee) = 0;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@@ -23,9 +23,11 @@
|
||||
#include <ripple/ledger/detail/ReadViewFwdRange.h>
|
||||
#include <ripple/basics/chrono.h>
|
||||
#include <ripple/protocol/Indexes.h>
|
||||
#include <ripple/protocol/IOUAmount.h>
|
||||
#include <ripple/protocol/Protocol.h>
|
||||
#include <ripple/protocol/STLedgerEntry.h>
|
||||
#include <ripple/protocol/STTx.h>
|
||||
#include <ripple/protocol/XRPAmount.h>
|
||||
#include <beast/hash/uhash.h>
|
||||
#include <boost/optional.hpp>
|
||||
#include <cassert>
|
||||
@@ -56,10 +58,10 @@ struct Fees
|
||||
The reserve is calculated as the reserve base plus
|
||||
the reserve increment times the number of increments.
|
||||
*/
|
||||
std::uint64_t
|
||||
XRPAmount
|
||||
accountReserve (std::size_t ownerCount) const
|
||||
{
|
||||
return reserve + ownerCount * increment;
|
||||
return { reserve + ownerCount * increment };
|
||||
}
|
||||
};
|
||||
|
||||
@@ -85,7 +87,8 @@ struct LedgerInfo
|
||||
uint256 txHash = zero;
|
||||
uint256 accountHash = zero;
|
||||
uint256 parentHash = zero;
|
||||
std::uint64_t drops = 0;
|
||||
|
||||
XRPAmount drops = zero;
|
||||
|
||||
// If validated is false, it means "not yet validated."
|
||||
// Once validated is true, it will never be set false at a later time.
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <ripple/ledger/ReadView.h>
|
||||
#include <ripple/ledger/TxMeta.h>
|
||||
#include <ripple/protocol/TER.h>
|
||||
#include <ripple/protocol/XRPAmount.h>
|
||||
#include <beast/utility/Journal.h>
|
||||
#include <memory>
|
||||
|
||||
@@ -50,7 +51,7 @@ private:
|
||||
std::pair<Action, std::shared_ptr<SLE>>>;
|
||||
|
||||
items_t items_;
|
||||
std::uint64_t dropsDestroyed_ = 0;
|
||||
XRPAmount dropsDestroyed_ = 0;
|
||||
|
||||
public:
|
||||
ApplyStateTable() = default;
|
||||
@@ -126,7 +127,7 @@ public:
|
||||
std::shared_ptr<SLE> const& sle);
|
||||
|
||||
void
|
||||
destroyXRP (std::uint64_t feeDrops);
|
||||
destroyXRP (XRPAmount const& fee);
|
||||
|
||||
private:
|
||||
using Mods = hash_map<key_type,
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include <ripple/ledger/OpenView.h>
|
||||
#include <ripple/ledger/ReadView.h>
|
||||
#include <ripple/ledger/detail/ApplyStateTable.h>
|
||||
#include <ripple/protocol/XRPAmount.h>
|
||||
|
||||
namespace ripple {
|
||||
namespace detail {
|
||||
@@ -130,13 +131,13 @@ public:
|
||||
|
||||
void
|
||||
rawDestroyXRP (
|
||||
std::uint64_t feeDrops) override;
|
||||
XRPAmount const& feeDrops) override;
|
||||
|
||||
protected:
|
||||
ApplyFlags flags_;
|
||||
ReadView const* base_;
|
||||
detail::ApplyStateTable items_;
|
||||
std::uint64_t dropsDestroyed_ = 0;
|
||||
XRPAmount dropsDestroyed_ = 0;
|
||||
};
|
||||
|
||||
} // detail
|
||||
|
||||
@@ -75,7 +75,7 @@ public:
|
||||
Keylet const& k) const;
|
||||
|
||||
void
|
||||
destroyXRP (std::uint64_t feeDrops);
|
||||
destroyXRP (XRPAmount const& fee);
|
||||
|
||||
std::unique_ptr<ReadView::sles_type::iter_base>
|
||||
slesBegin (ReadView const& base) const;
|
||||
@@ -97,7 +97,7 @@ private:
|
||||
std::pair<Action, std::shared_ptr<SLE>>>;
|
||||
|
||||
items_t items_;
|
||||
std::uint64_t dropsDestroyed_ = 0;
|
||||
XRPAmount dropsDestroyed_ = 0;
|
||||
};
|
||||
|
||||
} // detail
|
||||
|
||||
@@ -521,9 +521,9 @@ ApplyStateTable::update (ReadView const& base,
|
||||
}
|
||||
|
||||
void
|
||||
ApplyStateTable::destroyXRP(std::uint64_t feeDrops)
|
||||
ApplyStateTable::destroyXRP(XRPAmount const& fee)
|
||||
{
|
||||
dropsDestroyed_ += feeDrops;
|
||||
dropsDestroyed_ += fee;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@@ -173,9 +173,9 @@ ApplyViewBase::rawReplace(
|
||||
|
||||
void
|
||||
ApplyViewBase::rawDestroyXRP(
|
||||
std::uint64_t feeDrops)
|
||||
XRPAmount const& fee)
|
||||
{
|
||||
items_.destroyXRP(feeDrops);
|
||||
items_.destroyXRP(fee);
|
||||
}
|
||||
|
||||
} // detail
|
||||
|
||||
@@ -247,9 +247,9 @@ OpenView::rawReplace(
|
||||
|
||||
void
|
||||
OpenView::rawDestroyXRP(
|
||||
std::uint64_t feeDrops)
|
||||
XRPAmount const& fee)
|
||||
{
|
||||
items_.destroyXRP(feeDrops);
|
||||
items_.destroyXRP(fee);
|
||||
// VFALCO Deduct from info_.totalDrops ?
|
||||
// What about child views?
|
||||
}
|
||||
|
||||
@@ -333,9 +333,9 @@ RawStateTable::read (ReadView const& base,
|
||||
}
|
||||
|
||||
void
|
||||
RawStateTable::destroyXRP(std::uint64_t feeDrops)
|
||||
RawStateTable::destroyXRP(XRPAmount const& fee)
|
||||
{
|
||||
dropsDestroyed_ += feeDrops;
|
||||
dropsDestroyed_ += fee;
|
||||
}
|
||||
|
||||
std::unique_ptr<ReadView::sles_type::iter_base>
|
||||
|
||||
@@ -47,7 +47,7 @@ namespace ripple {
|
||||
void addRaw (LedgerInfo const& info, Serializer& s)
|
||||
{
|
||||
s.add32 (info.seq);
|
||||
s.add64 (info.drops);
|
||||
s.add64 (info.drops.drops ());
|
||||
s.add256 (info.parentHash);
|
||||
s.add256 (info.txHash);
|
||||
s.add256 (info.accountHash);
|
||||
@@ -109,10 +109,10 @@ accountHolds (ReadView const& view,
|
||||
auto const sle = view.read(
|
||||
keylet::account(account));
|
||||
auto const reserve =
|
||||
STAmount{view.fees().accountReserve(
|
||||
sle->getFieldU32(sfOwnerCount))};
|
||||
view.fees().accountReserve(
|
||||
sle->getFieldU32(sfOwnerCount));
|
||||
auto const balance =
|
||||
sle->getFieldAmount(sfBalance);
|
||||
sle->getFieldAmount(sfBalance).xrp ();
|
||||
if (balance < reserve)
|
||||
amount.clear ();
|
||||
else
|
||||
@@ -120,8 +120,8 @@ accountHolds (ReadView const& view,
|
||||
WriteLog (lsTRACE, View) << "accountHolds:" <<
|
||||
" account=" << to_string (account) <<
|
||||
" amount=" << amount.getFullText () <<
|
||||
" balance=" << balance.getFullText () <<
|
||||
" reserve=" << reserve.getFullText ();
|
||||
" balance=" << to_string (balance) <<
|
||||
" reserve=" << to_string (reserve);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -203,6 +203,12 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
STAmount& operator= (XRPAmount const& amount)
|
||||
{
|
||||
*this = STAmount (amount);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// Modification
|
||||
|
||||
@@ -88,14 +88,6 @@ public:
|
||||
{
|
||||
return tx_type_;
|
||||
}
|
||||
STAmount getTransactionFee () const
|
||||
{
|
||||
return getFieldAmount (sfFee);
|
||||
}
|
||||
void setTransactionFee (const STAmount & fee)
|
||||
{
|
||||
setFieldAmount (sfFee, fee);
|
||||
}
|
||||
|
||||
Blob getSigningPubKey () const
|
||||
{
|
||||
|
||||
@@ -1087,12 +1087,21 @@ Json::Value transactionSubmitMultiSigned (
|
||||
return RPC::make_error (rpcINVALID_PARAMS, err.str ());
|
||||
}
|
||||
|
||||
// The Fee field must be greater than zero.
|
||||
if (stpTrans->getFieldAmount (sfFee) <= 0)
|
||||
// The Fee field must be in XRP and greater than zero.
|
||||
auto const fee = stpTrans->getFieldAmount (sfFee);
|
||||
|
||||
if (!isLegalNet (fee))
|
||||
{
|
||||
std::ostringstream err;
|
||||
err << "Invalid " << sfFee.fieldName
|
||||
<< " field. Value must be greater than zero.";
|
||||
<< " field. Fees must be specified in XRP.";
|
||||
return RPC::make_error (rpcINVALID_PARAMS, err.str ());
|
||||
}
|
||||
if (fee <= 0)
|
||||
{
|
||||
std::ostringstream err;
|
||||
err << "Invalid " << sfFee.fieldName
|
||||
<< " field. Fees must be greater than zero.";
|
||||
return RPC::make_error (rpcINVALID_PARAMS, err.str ());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user