Use XRPAmount for fees and ledger headers

This commit is contained in:
Nik Bougalis
2015-08-22 01:13:29 -07:00
parent 94af42da44
commit acd03faee5
27 changed files with 141 additions and 141 deletions

View File

@@ -359,7 +359,7 @@ void Ledger::updateHash()
info_.hash = sha512Half( info_.hash = sha512Half(
HashPrefix::ledgerMaster, HashPrefix::ledgerMaster,
std::uint32_t(info_.seq), std::uint32_t(info_.seq),
std::uint64_t(info_.drops), std::uint64_t(info_.drops.drops ()),
info_.parentHash, info_.parentHash,
info_.txHash, info_.txHash,
info_.accountHash, info_.accountHash,
@@ -570,7 +570,7 @@ bool Ledger::saveValidatedLedger (bool current)
*db << boost::str ( *db << boost::str (
addLedger % addLedger %
to_string (getHash ()) % info_.seq % to_string (info_.parentHash) % 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_.parentCloseTime % info_.closeTimeResolution %
info_.closeFlags % to_string (info_.accountHash) % info_.closeFlags % to_string (info_.accountHash) %
to_string (info_.txHash)); to_string (info_.txHash));

View File

@@ -200,9 +200,9 @@ public:
SLE> const& sle) override; SLE> const& sle) override;
void void
rawDestroyXRP (std::uint64_t feeDrops) override rawDestroyXRP (XRPAmount const& fee) override
{ {
info_.drops -= feeDrops; info_.drops -= fee;
} }
// //

View File

@@ -23,6 +23,7 @@
#include <ripple/ledger/ApplyViewImpl.h> #include <ripple/ledger/ApplyViewImpl.h>
#include <ripple/core/Config.h> #include <ripple/core/Config.h>
#include <ripple/protocol/STTx.h> #include <ripple/protocol/STTx.h>
#include <ripple/protocol/XRPAmount.h>
#include <beast/utility/Journal.h> #include <beast/utility/Journal.h>
#include <boost/optional.hpp> #include <boost/optional.hpp>
#include <utility> #include <utility>
@@ -92,9 +93,9 @@ public:
std::shared_ptr <SLE const> const& after)> const& func); std::shared_ptr <SLE const> const& after)> const& func);
void void
destroyXRP (std::uint64_t feeDrops) destroyXRP (XRPAmount const& fee)
{ {
view_->rawDestroyXRP(feeDrops); view_->rawDestroyXRP(fee);
} }
private: private:

View File

@@ -38,10 +38,11 @@ Change::preflight (PreflightContext const& ctx)
return temBAD_SRC_ACCOUNT; 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) if (!fee.native () || fee != beast::zero)
{ {
JLOG(ctx.j.warning) << "Change: Non-zero fee"; JLOG(ctx.j.warning) << "Change: invalid fee";
return temBAD_FEE; return temBAD_FEE;
} }

View File

@@ -539,20 +539,6 @@ CreateOffer::format_amount (STAmount const& amount)
return txt; 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 void
CreateOffer::preCompute() CreateOffer::preCompute()
{ {
@@ -784,7 +770,22 @@ CreateOffer::applyGuts (ApplyView& view, ApplyView& view_cancel)
return { tesSUCCESS, true }; return { tesSUCCESS, true };
} }
if (mPriorBalance < getAccountReserve (sleCreator)) {
// Mon Aug 17 11:00:00am PDT
static NetClock::time_point const switchoverTime (
std::chrono::seconds (493149600));
XRPAmount reserve;
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 // If we are here, the signing account had an insufficient reserve
// *prior* to our processing. If something actually crossed, then // *prior* to our processing. If something actually crossed, then
@@ -797,6 +798,7 @@ CreateOffer::applyGuts (ApplyView& view, ApplyView& view_cancel)
return { result, true }; return { result, true };
} }
}
// We need to place the remainder of the offer into its order book. // We need to place the remainder of the offer into its order book.
auto const offer_index = getOfferIndex (account_, uSequence); auto const offer_index = getOfferIndex (account_, uSequence);

View File

@@ -49,11 +49,6 @@ public:
TER TER
preflight (PreflightContext const& ctx); 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 void
preCompute() override; preCompute() override;

View File

@@ -50,22 +50,21 @@ CreateTicket::preflight (PreflightContext const& ctx)
return preflight2 (ctx); return preflight2 (ctx);
} }
STAmount
CreateTicket::getAccountReserve (SLE::pointer account)
{
return STAmount (view().fees().accountReserve(
account->getFieldU32 (sfOwnerCount) + 1));
}
TER TER
CreateTicket::doApply () CreateTicket::doApply ()
{ {
auto const sle = view().peek(keylet::account(account_));
// A ticket counts against the reserve of the issuing account, but we // A ticket counts against the reserve of the issuing account, but we
// check the starting balance because we want to allow dipping into the // check the starting balance because we want to allow dipping into the
// reserve to pay fees. // reserve to pay fees.
if (mPriorBalance < STAmount(view().fees().accountReserve( {
view().read(keylet::account(account_))->getFieldU32(sfOwnerCount) + 1))) auto const reserve = view().fees().accountReserve(
sle->getFieldU32(sfOwnerCount) + 1);
if (mPriorBalance < reserve)
return tecINSUFFICIENT_RESERVE; return tecINSUFFICIENT_RESERVE;
}
std::uint32_t expiration (0); std::uint32_t expiration (0);
@@ -124,8 +123,7 @@ CreateTicket::doApply ()
sleTicket->setFieldU64(sfOwnerNode, hint); sleTicket->setFieldU64(sfOwnerNode, hint);
// If we succeeded, the new entry counts agains the creator's reserve. // If we succeeded, the new entry counts agains the creator's reserve.
adjustOwnerCount(view(), view().peek( adjustOwnerCount(view(), sle, 1);
keylet::account(account_)), 1);
return result; return result;
} }

View File

@@ -40,11 +40,6 @@ public:
TER TER
preflight (PreflightContext const& ctx); 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; TER doApply () override;
}; };

View File

@@ -380,6 +380,8 @@ Payment::doApply ()
} }
else else
{ {
assert (saDstAmount.native ());
// Direct XRP payment. // Direct XRP payment.
// uOwnerCount is the number of entries in this legder for this // uOwnerCount is the number of entries in this legder for this
@@ -388,23 +390,22 @@ Payment::doApply ()
keylet::account(account_))->getFieldU32 (sfOwnerCount); keylet::account(account_))->getFieldU32 (sfOwnerCount);
// This is the total reserve in drops. // This is the total reserve in drops.
auto const uReserve = auto const reserve = view().fees().accountReserve(uOwnerCount);
view().fees().accountReserve(uOwnerCount);
// mPriorBalance is the balance on the sending account BEFORE the // mPriorBalance is the balance on the sending account BEFORE the
// fees were charged. We want to make sure we have enough reserve // fees were charged. We want to make sure we have enough reserve
// to send. Allow final spend to use reserve for fee. // to send. Allow final spend to use reserve for fee.
auto const mmm = std::max(tx().getTransactionFee (), auto const mmm = std::max(reserve,
STAmount (uReserve)); tx().getFieldAmount (sfFee).xrp ());
if (mPriorBalance < saDstAmount + mmm) if (mPriorBalance < saDstAmount.xrp () + mmm)
{ {
// Vote no. However the transaction might succeed, if applied in // Vote no. However the transaction might succeed, if applied in
// a different order. // a different order.
j_.trace << "Delay transaction: Insufficient funds: " << j_.trace << "Delay transaction: Insufficient funds: " <<
" " << mPriorBalance.getText () << " " << to_string (mPriorBalance) <<
" / " << (saDstAmount + mmm).getText () << " / " << to_string (saDstAmount.xrp () + mmm) <<
" (" << uReserve << ")"; " (" << to_string (reserve) << ")";
terResult = tecUNFUNDED_PAYMENT; terResult = tecUNFUNDED_PAYMENT;
} }

View File

@@ -119,8 +119,8 @@ SetTrust::doApply ()
// to fund accounts in a way where there's no incentive to trick them // to fund accounts in a way where there's no incentive to trick them
// into creating an account you have no intention of using. // into creating an account you have no intention of using.
STAmount const reserveCreate ((uOwnerCount < 2) XRPAmount const reserveCreate ((uOwnerCount < 2)
? 0 ? XRPAmount (zero)
: view().fees().accountReserve(uOwnerCount + 1)); : view().fees().accountReserve(uOwnerCount + 1));
std::uint32_t uQualityIn (bQualityIn ? tx().getFieldU32 (sfQualityIn) : 0); std::uint32_t uQualityIn (bQualityIn ? tx().getFieldU32 (sfQualityIn) : 0);

View File

@@ -183,23 +183,22 @@ SusPayCreate::doApply()
return tecNO_PERMISSION; return tecNO_PERMISSION;
} }
XRPAmount const amount =
STAmount(ctx_.tx[sfAmount]).mantissa();
auto const account = ctx_.tx[sfAccount]; auto const account = ctx_.tx[sfAccount];
auto const sle = ctx_.view().peek( auto const sle = ctx_.view().peek(
keylet::account(account)); keylet::account(account));
if (XRPAmount(STAmount((*sle)[sfBalance]).mantissa()) < // Check reserve and funds availability
XRPAmount(ctx_.view().fees().accountReserve( {
(*sle)[sfOwnerCount] + 1))) auto const balance = STAmount((*sle)[sfBalance]).xrp();
auto const reserve = ctx_.view().fees().accountReserve(
(*sle)[sfOwnerCount] + 1);
if (balance < reserve)
return tecINSUFFICIENT_RESERVE; return tecINSUFFICIENT_RESERVE;
if (XRPAmount(STAmount((*sle)[sfBalance]).mantissa()) < if (balance < reserve + STAmount(ctx_.tx[sfAmount]).xrp())
amount + XRPAmount(ctx_.view().fees().accountReserve(
(*sle)[sfOwnerCount] + 1)))
return tecUNFUNDED; return tecUNFUNDED;
}
// Check destination account // Check destination account
{ {

View File

@@ -44,8 +44,8 @@ preflight1 (PreflightContext const& ctx)
} }
// No point in going any further if the transaction fee is malformed. // No point in going any further if the transaction fee is malformed.
auto const fee = ctx.tx.getTransactionFee (); auto const fee = ctx.tx.getFieldAmount (sfFee);
if (!fee.native () || fee < beast::zero || !isLegalNet (fee)) if (!fee.native () || fee.negative () || !isLegalAmount (fee.xrp ()))
{ {
JLOG(ctx.j.debug) << "preflight1: invalid fee"; JLOG(ctx.j.debug) << "preflight1: invalid fee";
return temBAD_FEE; return temBAD_FEE;
@@ -114,30 +114,29 @@ std::uint64_t Transactor::calculateBaseFee ()
TER Transactor::payFee () TER Transactor::payFee ()
{ {
STAmount saPaid = tx().getTransactionFee (); auto const feePaid = tx().getFieldAmount (sfFee).xrp ();
if (!isLegalAmount (feePaid) || feePaid < beast::zero)
if (!isLegalNet (saPaid) || saPaid < zero)
return temBAD_FEE; return temBAD_FEE;
// Only check fee is sufficient when the ledger is open. // 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: " << JLOG(j_.trace) << "Insufficient fee paid: " <<
saPaid.getText () << "/" << mFeeDue.getText (); to_string (feePaid) << "/" << to_string (mFeeDue);
return telINSUF_FEE_P; return telINSUF_FEE_P;
} }
if (saPaid == zero) if (feePaid == zero)
return tesSUCCESS; return tesSUCCESS;
auto const sle = view().peek( auto const sle = view().peek(
keylet::account(account_)); keylet::account(account_));
if (mSourceBalance < saPaid) if (mSourceBalance < feePaid)
{ {
JLOG(j_.trace) << "Insufficient balance:" << JLOG(j_.trace) << "Insufficient balance:" <<
" balance=" << mSourceBalance.getText () << " balance=" << to_string (mSourceBalance) <<
" paid=" << saPaid.getText (); " paid=" << to_string (feePaid);
if ((mSourceBalance > zero) && ! view().open()) if ((mSourceBalance > zero) && ! view().open())
{ {
@@ -151,7 +150,7 @@ TER Transactor::payFee ()
// Deduct the fee, so it's not available during the transaction. // Deduct the fee, so it's not available during the transaction.
// Will only write the account back, if the transaction succeeds. // Will only write the account back, if the transaction succeeds.
mSourceBalance -= saPaid; mSourceBalance -= feePaid;
sle->setFieldAmount (sfBalance, mSourceBalance); sle->setFieldAmount (sfBalance, mSourceBalance);
// VFALCO Should we call view().rawDestroyXRP() here as well? // VFALCO Should we call view().rawDestroyXRP() here as well?
@@ -227,12 +226,12 @@ TER Transactor::apply ()
} }
auto const& fees = view().fees(); auto const& fees = view().fees();
mFeeDue = STAmount (getApp().getFeeTrack().scaleFeeLoad( mFeeDue = getApp().getFeeTrack().scaleFeeLoad(
calculateBaseFee(), fees.base, fees.units, view().flags() & tapADMIN)); calculateBaseFee(), fees.base, fees.units, view().flags() & tapADMIN);
if (sle) if (sle)
{ {
mPriorBalance = sle->getFieldAmount (sfBalance); mPriorBalance = STAmount ((*sle)[sfBalance]).xrp ();
mSourceBalance = mPriorBalance; mSourceBalance = mPriorBalance;
mHasAuthKey = sle->isFieldPresent (sfRegularKey); mHasAuthKey = sle->isFieldPresent (sfRegularKey);
@@ -550,7 +549,7 @@ Transactor::operator()()
} }
bool didApply = isTesSuccess (terResult); bool didApply = isTesSuccess (terResult);
auto fee = tx().getTransactionFee (); auto fee = tx().getFieldAmount(sfFee).xrp ();
if (ctx_.size() > 5200) if (ctx_.size() > 5200)
terResult = tecOVERSIZE; terResult = tecOVERSIZE;
@@ -602,7 +601,7 @@ Transactor::operator()()
terResult = tefPAST_SEQ; terResult = tefPAST_SEQ;
else else
{ {
STAmount balance = txnAcct->getFieldAmount (sfBalance); auto const balance = txnAcct->getFieldAmount (sfBalance).xrp ();
// We retry/reject the transaction if the account // We retry/reject the transaction if the account
// balance is zero or we're applying against an open // balance is zero or we're applying against an open
@@ -645,23 +644,18 @@ Transactor::operator()()
if(view().closed()) if(view().closed())
{ {
// VFALCO Fix this nonsense with Amount // Charge whatever fee they specified.
// 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:
// The transactor guarantees these will never trigger // The transactor guarantees this will never trigger
if (!fee.native () || fee.negative ()) if (fee < zero)
{ {
// VFALCO Log to journal here // VFALCO Log to journal here
// JLOG(journal.fatal) << "invalid fee"; // JLOG(journal.fatal) << "invalid fee";
throw std::logic_error( throw std::logic_error("amount is negative!");
"amount is negative!");
} }
if (fee != zero) if (fee != zero)
ctx_.destroyXRP (fee.mantissa ()); ctx_.destroyXRP (fee);
} }
ctx_.apply(terResult); ctx_.apply(terResult);

View File

@@ -21,6 +21,7 @@
#define RIPPLE_APP_TX_TRANSACTOR_H_INCLUDED #define RIPPLE_APP_TX_TRANSACTOR_H_INCLUDED
#include <ripple/app/tx/impl/ApplyContext.h> #include <ripple/app/tx/impl/ApplyContext.h>
#include <ripple/protocol/XRPAmount.h>
#include <beast/utility/Journal.h> #include <beast/utility/Journal.h>
namespace ripple { namespace ripple {
@@ -57,9 +58,9 @@ protected:
beast::Journal j_; beast::Journal j_;
AccountID account_; AccountID account_;
STAmount mFeeDue; XRPAmount mFeeDue;
STAmount mPriorBalance; // Balance before fees. XRPAmount mPriorBalance; // Balance before fees.
STAmount mSourceBalance; // Balance after fees. XRPAmount mSourceBalance; // Balance after fees.
bool mHasAuthKey; bool mHasAuthKey;
bool mSigMaster; bool mSigMaster;
RippleAddress mSigningPubKey; RippleAddress mSigningPubKey;

View File

@@ -23,6 +23,7 @@
#include <ripple/ledger/RawView.h> #include <ripple/ledger/RawView.h>
#include <ripple/ledger/ReadView.h> #include <ripple/ledger/ReadView.h>
#include <ripple/ledger/detail/RawStateTable.h> #include <ripple/ledger/detail/RawStateTable.h>
#include <ripple/protocol/XRPAmount.h>
namespace ripple { namespace ripple {
@@ -209,7 +210,7 @@ public:
void void
rawDestroyXRP( rawDestroyXRP(
std::uint64_t feeDrops) override; XRPAmount const& fee) override;
// TxsRawView // TxsRawView

View File

@@ -85,7 +85,7 @@ public:
*/ */
virtual virtual
void void
rawDestroyXRP (std::uint64_t feeDrops) = 0; rawDestroyXRP (XRPAmount const& fee) = 0;
}; };
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------

View File

@@ -23,9 +23,11 @@
#include <ripple/ledger/detail/ReadViewFwdRange.h> #include <ripple/ledger/detail/ReadViewFwdRange.h>
#include <ripple/basics/chrono.h> #include <ripple/basics/chrono.h>
#include <ripple/protocol/Indexes.h> #include <ripple/protocol/Indexes.h>
#include <ripple/protocol/IOUAmount.h>
#include <ripple/protocol/Protocol.h> #include <ripple/protocol/Protocol.h>
#include <ripple/protocol/STLedgerEntry.h> #include <ripple/protocol/STLedgerEntry.h>
#include <ripple/protocol/STTx.h> #include <ripple/protocol/STTx.h>
#include <ripple/protocol/XRPAmount.h>
#include <beast/hash/uhash.h> #include <beast/hash/uhash.h>
#include <boost/optional.hpp> #include <boost/optional.hpp>
#include <cassert> #include <cassert>
@@ -56,10 +58,10 @@ struct Fees
The reserve is calculated as the reserve base plus The reserve is calculated as the reserve base plus
the reserve increment times the number of increments. the reserve increment times the number of increments.
*/ */
std::uint64_t XRPAmount
accountReserve (std::size_t ownerCount) const accountReserve (std::size_t ownerCount) const
{ {
return reserve + ownerCount * increment; return { reserve + ownerCount * increment };
} }
}; };
@@ -85,7 +87,8 @@ struct LedgerInfo
uint256 txHash = zero; uint256 txHash = zero;
uint256 accountHash = zero; uint256 accountHash = zero;
uint256 parentHash = zero; uint256 parentHash = zero;
std::uint64_t drops = 0;
XRPAmount drops = zero;
// If validated is false, it means "not yet validated." // If validated is false, it means "not yet validated."
// Once validated is true, it will never be set false at a later time. // Once validated is true, it will never be set false at a later time.

View File

@@ -25,6 +25,7 @@
#include <ripple/ledger/ReadView.h> #include <ripple/ledger/ReadView.h>
#include <ripple/ledger/TxMeta.h> #include <ripple/ledger/TxMeta.h>
#include <ripple/protocol/TER.h> #include <ripple/protocol/TER.h>
#include <ripple/protocol/XRPAmount.h>
#include <beast/utility/Journal.h> #include <beast/utility/Journal.h>
#include <memory> #include <memory>
@@ -50,7 +51,7 @@ private:
std::pair<Action, std::shared_ptr<SLE>>>; std::pair<Action, std::shared_ptr<SLE>>>;
items_t items_; items_t items_;
std::uint64_t dropsDestroyed_ = 0; XRPAmount dropsDestroyed_ = 0;
public: public:
ApplyStateTable() = default; ApplyStateTable() = default;
@@ -126,7 +127,7 @@ public:
std::shared_ptr<SLE> const& sle); std::shared_ptr<SLE> const& sle);
void void
destroyXRP (std::uint64_t feeDrops); destroyXRP (XRPAmount const& fee);
private: private:
using Mods = hash_map<key_type, using Mods = hash_map<key_type,

View File

@@ -24,6 +24,7 @@
#include <ripple/ledger/OpenView.h> #include <ripple/ledger/OpenView.h>
#include <ripple/ledger/ReadView.h> #include <ripple/ledger/ReadView.h>
#include <ripple/ledger/detail/ApplyStateTable.h> #include <ripple/ledger/detail/ApplyStateTable.h>
#include <ripple/protocol/XRPAmount.h>
namespace ripple { namespace ripple {
namespace detail { namespace detail {
@@ -130,13 +131,13 @@ public:
void void
rawDestroyXRP ( rawDestroyXRP (
std::uint64_t feeDrops) override; XRPAmount const& feeDrops) override;
protected: protected:
ApplyFlags flags_; ApplyFlags flags_;
ReadView const* base_; ReadView const* base_;
detail::ApplyStateTable items_; detail::ApplyStateTable items_;
std::uint64_t dropsDestroyed_ = 0; XRPAmount dropsDestroyed_ = 0;
}; };
} // detail } // detail

View File

@@ -75,7 +75,7 @@ public:
Keylet const& k) const; Keylet const& k) const;
void void
destroyXRP (std::uint64_t feeDrops); destroyXRP (XRPAmount const& fee);
std::unique_ptr<ReadView::sles_type::iter_base> std::unique_ptr<ReadView::sles_type::iter_base>
slesBegin (ReadView const& base) const; slesBegin (ReadView const& base) const;
@@ -97,7 +97,7 @@ private:
std::pair<Action, std::shared_ptr<SLE>>>; std::pair<Action, std::shared_ptr<SLE>>>;
items_t items_; items_t items_;
std::uint64_t dropsDestroyed_ = 0; XRPAmount dropsDestroyed_ = 0;
}; };
} // detail } // detail

View File

@@ -521,9 +521,9 @@ ApplyStateTable::update (ReadView const& base,
} }
void void
ApplyStateTable::destroyXRP(std::uint64_t feeDrops) ApplyStateTable::destroyXRP(XRPAmount const& fee)
{ {
dropsDestroyed_ += feeDrops; dropsDestroyed_ += fee;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------

View File

@@ -173,9 +173,9 @@ ApplyViewBase::rawReplace(
void void
ApplyViewBase::rawDestroyXRP( ApplyViewBase::rawDestroyXRP(
std::uint64_t feeDrops) XRPAmount const& fee)
{ {
items_.destroyXRP(feeDrops); items_.destroyXRP(fee);
} }
} // detail } // detail

View File

@@ -247,9 +247,9 @@ OpenView::rawReplace(
void void
OpenView::rawDestroyXRP( OpenView::rawDestroyXRP(
std::uint64_t feeDrops) XRPAmount const& fee)
{ {
items_.destroyXRP(feeDrops); items_.destroyXRP(fee);
// VFALCO Deduct from info_.totalDrops ? // VFALCO Deduct from info_.totalDrops ?
// What about child views? // What about child views?
} }

View File

@@ -333,9 +333,9 @@ RawStateTable::read (ReadView const& base,
} }
void void
RawStateTable::destroyXRP(std::uint64_t feeDrops) RawStateTable::destroyXRP(XRPAmount const& fee)
{ {
dropsDestroyed_ += feeDrops; dropsDestroyed_ += fee;
} }
std::unique_ptr<ReadView::sles_type::iter_base> std::unique_ptr<ReadView::sles_type::iter_base>

View File

@@ -47,7 +47,7 @@ namespace ripple {
void addRaw (LedgerInfo const& info, Serializer& s) void addRaw (LedgerInfo const& info, Serializer& s)
{ {
s.add32 (info.seq); s.add32 (info.seq);
s.add64 (info.drops); s.add64 (info.drops.drops ());
s.add256 (info.parentHash); s.add256 (info.parentHash);
s.add256 (info.txHash); s.add256 (info.txHash);
s.add256 (info.accountHash); s.add256 (info.accountHash);
@@ -109,10 +109,10 @@ accountHolds (ReadView const& view,
auto const sle = view.read( auto const sle = view.read(
keylet::account(account)); keylet::account(account));
auto const reserve = auto const reserve =
STAmount{view.fees().accountReserve( view.fees().accountReserve(
sle->getFieldU32(sfOwnerCount))}; sle->getFieldU32(sfOwnerCount));
auto const balance = auto const balance =
sle->getFieldAmount(sfBalance); sle->getFieldAmount(sfBalance).xrp ();
if (balance < reserve) if (balance < reserve)
amount.clear (); amount.clear ();
else else
@@ -120,8 +120,8 @@ accountHolds (ReadView const& view,
WriteLog (lsTRACE, View) << "accountHolds:" << WriteLog (lsTRACE, View) << "accountHolds:" <<
" account=" << to_string (account) << " account=" << to_string (account) <<
" amount=" << amount.getFullText () << " amount=" << amount.getFullText () <<
" balance=" << balance.getFullText () << " balance=" << to_string (balance) <<
" reserve=" << reserve.getFullText (); " reserve=" << to_string (reserve);
} }
else else
{ {

View File

@@ -203,6 +203,12 @@ public:
return *this; return *this;
} }
STAmount& operator= (XRPAmount const& amount)
{
*this = STAmount (amount);
return *this;
}
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
// //
// Modification // Modification

View File

@@ -88,14 +88,6 @@ public:
{ {
return tx_type_; return tx_type_;
} }
STAmount getTransactionFee () const
{
return getFieldAmount (sfFee);
}
void setTransactionFee (const STAmount & fee)
{
setFieldAmount (sfFee, fee);
}
Blob getSigningPubKey () const Blob getSigningPubKey () const
{ {

View File

@@ -1087,12 +1087,21 @@ Json::Value transactionSubmitMultiSigned (
return RPC::make_error (rpcINVALID_PARAMS, err.str ()); return RPC::make_error (rpcINVALID_PARAMS, err.str ());
} }
// The Fee field must be greater than zero. // The Fee field must be in XRP and greater than zero.
if (stpTrans->getFieldAmount (sfFee) <= 0) auto const fee = stpTrans->getFieldAmount (sfFee);
if (!isLegalNet (fee))
{ {
std::ostringstream err; std::ostringstream err;
err << "Invalid " << sfFee.fieldName 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 ()); return RPC::make_error (rpcINVALID_PARAMS, err.str ());
} }
} }