rippled
FeeVoteImpl.cpp
1 //------------------------------------------------------------------------------
2 /*
3  This file is part of rippled: https://github.com/ripple/rippled
4  Copyright (c) 2012, 2013 Ripple Labs Inc.
5 
6  Permission to use, copy, modify, and/or distribute this software for any
7  purpose with or without fee is hereby granted, provided that the above
8  copyright notice and this permission notice appear in all copies.
9 
10  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18 //==============================================================================
19 
20 #include <ripple/protocol/st.h>
21 #include <ripple/app/misc/FeeVote.h>
22 #include <ripple/app/main/Application.h>
23 #include <ripple/protocol/STValidation.h>
24 #include <ripple/basics/BasicConfig.h>
25 #include <ripple/beast/utility/Journal.h>
26 
27 namespace ripple {
28 
29 namespace detail {
30 
32 {
33 private:
35  value_type const mCurrent; // The current setting
36  value_type const mTarget; // The setting we want
38 
39 public:
41  : mCurrent (current)
42  , mTarget (target)
43  {
44  // Add our vote
45  ++mVoteMap[mTarget];
46  }
47 
48  void
50  {
51  ++mVoteMap[vote];
52  }
53 
54  void
56  {
57  addVote (mCurrent);
58  }
59 
61  getVotes() const;
62 };
63 
64 auto
66  -> value_type
67 {
68  value_type ourVote = mCurrent;
69  int weight = 0;
70  for (auto const& [key, val] : mVoteMap)
71  {
72  // Take most voted value between current and target, inclusive
73  if ((key <= std::max (mTarget, mCurrent)) &&
74  (key >= std::min (mTarget, mCurrent)) &&
75  (val > weight))
76  {
77  ourVote = key;
78  weight = val;
79  }
80  }
81 
82  return ourVote;
83 }
84 
85 }
86 
87 //------------------------------------------------------------------------------
88 
89 class FeeVoteImpl : public FeeVote
90 {
91 private:
92  Setup target_;
94 
95 public:
96  FeeVoteImpl (Setup const& setup, beast::Journal journal);
97 
98  void
99  doValidation (std::shared_ptr<ReadView const> const& lastClosedLedger,
100  STValidation::FeeSettings& fees) override;
101 
102  void
103  doVoting (std::shared_ptr<ReadView const> const& lastClosedLedger,
104  std::vector<STValidation::pointer> const& parentValidations,
105  std::shared_ptr<SHAMap> const& initialPosition) override;
106 };
107 
108 //--------------------------------------------------------------------------
109 
110 FeeVoteImpl::FeeVoteImpl (Setup const& setup, beast::Journal journal)
111  : target_ (setup)
112  , journal_ (journal)
113 {
114 }
115 
116 void
118  std::shared_ptr<ReadView const> const& lastClosedLedger,
120 {
121  if (lastClosedLedger->fees().base != target_.reference_fee)
122  {
123  JLOG(journal_.info()) <<
124  "Voting for base fee of " << target_.reference_fee;
125 
127  }
128 
129  if (lastClosedLedger->fees().accountReserve(0) != target_.account_reserve)
130  {
131  JLOG(journal_.info()) <<
132  "Voting for base reserve of " << target_.account_reserve;
133 
135  }
136 
137  if (lastClosedLedger->fees().increment != target_.owner_reserve)
138  {
139  JLOG(journal_.info()) <<
140  "Voting for reserve increment of " << target_.owner_reserve;
141 
143  }
144 }
145 
146 void
148  std::shared_ptr<ReadView const> const& lastClosedLedger,
150  std::shared_ptr<SHAMap> const& initialPosition)
151 {
152  // LCL must be flag ledger
153  assert ((lastClosedLedger->info().seq % 256) == 0);
154 
155  detail::VotableValue baseFeeVote (
156  lastClosedLedger->fees().base,
158 
159  detail::VotableValue baseReserveVote(
160  lastClosedLedger->fees().accountReserve(0),
162 
163  detail::VotableValue incReserveVote (
164  lastClosedLedger->fees().increment,
166 
167  for (auto const& val : set)
168  {
169  if (val->isTrusted ())
170  {
171  if (val->isFieldPresent (sfBaseFee))
172  {
173  using xrptype = XRPAmount::value_type;
174  auto const vote = val->getFieldU64 (sfBaseFee);
175  if (vote <= std::numeric_limits<xrptype>::max() &&
176  isLegalAmount(XRPAmount{unsafe_cast<xrptype>(vote)}))
177  baseFeeVote.addVote(XRPAmount{
178  unsafe_cast<XRPAmount::value_type>(vote)});
179  else
180  // Invalid amounts will be treated as if they're
181  // not provided. Don't throw because this value is
182  // provided by an external entity.
183  baseFeeVote.noVote();
184  }
185  else
186  {
187  baseFeeVote.noVote ();
188  }
189 
190  if (val->isFieldPresent (sfReserveBase))
191  {
192  baseReserveVote.addVote(XRPAmount{
193  val->getFieldU32(sfReserveBase)});
194  }
195  else
196  {
197  baseReserveVote.noVote ();
198  }
199 
200  if (val->isFieldPresent (sfReserveIncrement))
201  {
202  incReserveVote.addVote (XRPAmount{
203  val->getFieldU32 (sfReserveIncrement)});
204  }
205  else
206  {
207  incReserveVote.noVote ();
208  }
209  }
210  }
211 
212  // choose our positions
213  // If any of the values are invalid, send the current values.
214  auto const baseFee = baseFeeVote.getVotes ().dropsAs<std::uint64_t>(
215  lastClosedLedger->fees().base);
216  auto const baseReserve = baseReserveVote.getVotes ().dropsAs<std::uint32_t>(
217  lastClosedLedger->fees().accountReserve(0));
218  auto const incReserve = incReserveVote.getVotes ().dropsAs<std::uint32_t>(
219  lastClosedLedger->fees().increment);
220  constexpr FeeUnit32 feeUnits = Setup::reference_fee_units;
221  auto const seq = lastClosedLedger->info().seq + 1;
222 
223  // add transactions to our position
224  if ((baseFee != lastClosedLedger->fees().base) ||
225  (baseReserve != lastClosedLedger->fees().accountReserve(0)) ||
226  (incReserve != lastClosedLedger->fees().increment))
227  {
228  JLOG(journal_.warn()) <<
229  "We are voting for a fee change: " << baseFee <<
230  "/" << baseReserve <<
231  "/" << incReserve;
232 
233  STTx feeTx (ttFEE,
234  [seq,baseFee,baseReserve,incReserve,feeUnits](auto& obj)
235  {
236  obj[sfAccount] = AccountID();
237  obj[sfLedgerSequence] = seq;
238  obj[sfBaseFee] = baseFee;
239  obj[sfReserveBase] = baseReserve;
240  obj[sfReserveIncrement] = incReserve;
241  obj[sfReferenceFeeUnits] = feeUnits.fee();
242  });
243 
244  uint256 txID = feeTx.getTransactionID ();
245 
246  JLOG(journal_.warn()) <<
247  "Vote: " << txID;
248 
249  Serializer s;
250  feeTx.add (s);
251 
252  auto tItem = std::make_shared<SHAMapItem> (txID, s.peekData ());
253 
254  if (!initialPosition->addGiveItem (tItem, true, false))
255  {
256  JLOG(journal_.warn()) <<
257  "Ledger already had fee change";
258  }
259  }
260 }
261 
262 //------------------------------------------------------------------------------
263 
265 setup_FeeVote (Section const& section)
266 {
267  FeeVote::Setup setup;
268  {
269  std::uint64_t temp;
270  if (set(temp, "reference_fee", section) &&
272  setup.reference_fee = temp;
273  }
274  {
275  std::uint32_t temp;
276  if (set(temp, "account_reserve", section))
277  setup.account_reserve = temp;
278  if (set(temp, "owner_reserve", section))
279  setup.owner_reserve = temp;
280  }
281  return setup;
282 }
283 
286 {
287  return std::make_unique<FeeVoteImpl> (setup, journal);
288 }
289 
290 } // ripple
ripple::setup_FeeVote
FeeVote::Setup setup_FeeVote(Section const &section)
Build FeeVote::Setup from a config section.
Definition: FeeVoteImpl.cpp:265
ripple::Section
Holds a collection of configuration values.
Definition: BasicConfig.h:43
ripple::FeeVote::Setup::owner_reserve
XRPAmount owner_reserve
The per-owned item reserve requirement in drops.
Definition: FeeVote.h:52
ripple::FeeVoteImpl::doValidation
void doValidation(std::shared_ptr< ReadView const > const &lastClosedLedger, STValidation::FeeSettings &fees) override
Add local fee preference to validation.
Definition: FeeVoteImpl.cpp:117
ripple::STValidation::FeeSettings::reserveBase
boost::optional< XRPAmount > reserveBase
Definition: STValidation.h:105
std::shared_ptr
STL class.
ripple::isLegalAmount
bool isLegalAmount(XRPAmount const &amount)
Returns true if the amount does not exceed the initial XRP in existence.
Definition: SystemParameters.h:49
ripple::make_FeeVote
std::unique_ptr< FeeVote > make_FeeVote(FeeVote::Setup const &setup, beast::Journal journal)
Create an instance of the FeeVote logic.
Definition: FeeVoteImpl.cpp:285
ripple::FeeVote
Manager to process fee votes.
Definition: FeeVote.h:32
ripple::FeeVote::Setup::reference_fee
XRPAmount reference_fee
The cost of a reference transaction in drops.
Definition: FeeVote.h:43
std::vector
STL class.
ripple::detail::VotableValue::noVote
void noVote()
Definition: FeeVoteImpl.cpp:55
ripple::sfAccount
const SF_Account sfAccount(access, STI_ACCOUNT, 1, "Account")
Definition: SField.h:460
ripple::AccountID
base_uint< 160, detail::AccountIDTag > AccountID
A 160-bit unsigned that uniquely identifies an account.
Definition: AccountID.h:48
beast::Journal::warn
Stream warn() const
Definition: Journal.h:302
ripple::FeeVote::Setup
Fee schedule to vote for.
Definition: FeeVote.h:40
ripple::detail::VotableValue::VotableValue
VotableValue(value_type current, value_type target)
Definition: FeeVoteImpl.cpp:40
ripple::sfReserveBase
const SF_U32 sfReserveBase(access, STI_UINT32, 31, "ReserveBase")
Definition: SField.h:368
ripple::FeeVoteImpl
Definition: FeeVoteImpl.cpp:89
ripple::FeeVoteImpl::doVoting
void doVoting(std::shared_ptr< ReadView const > const &lastClosedLedger, std::vector< STValidation::pointer > const &parentValidations, std::shared_ptr< SHAMap > const &initialPosition) override
Cast our local vote on the fee.
Definition: FeeVoteImpl.cpp:147
ripple::ttFEE
@ ttFEE
Definition: TxFormats.h:61
ripple::base_uint< 256 >
ripple::detail::VotableValue::mCurrent
const value_type mCurrent
Definition: FeeVoteImpl.cpp:35
ripple::detail::VotableValue::value_type
XRPAmount value_type
Definition: FeeVoteImpl.cpp:34
ripple::FeeVoteImpl::journal_
const beast::Journal journal_
Definition: FeeVoteImpl.cpp:93
ripple::XRPAmount::value_type
std::int64_t value_type
Definition: XRPAmount.h:54
ripple::detail::VotableValue::mTarget
const value_type mTarget
Definition: FeeVoteImpl.cpp:36
ripple::FeeVote::Setup::account_reserve
XRPAmount account_reserve
The account reserve requirement in drops.
Definition: FeeVote.h:49
ripple::detail::VotableValue
Definition: FeeVoteImpl.cpp:31
ripple::set
bool set(T &target, std::string const &name, Section const &section)
Set a value from a configuration Section If the named value is not found or doesn't parse as a T,...
Definition: BasicConfig.h:271
ripple::sfLedgerSequence
const SF_U32 sfLedgerSequence(access, STI_UINT32, 6, "LedgerSequence")
Definition: SField.h:342
beast::Journal::info
Stream info() const
Definition: Journal.h:297
ripple::sfReferenceFeeUnits
const SF_U32 sfReferenceFeeUnits(access, STI_UINT32, 30, "ReferenceFeeUnits")
Definition: SField.h:367
ripple::STTx
Definition: STTx.h:43
ripple::FeeVoteImpl::FeeVoteImpl
FeeVoteImpl(Setup const &setup, beast::Journal journal)
Definition: FeeVoteImpl.cpp:110
ripple::FeeVoteImpl::target_
Setup target_
Definition: FeeVoteImpl.cpp:92
ripple::ValStatus::current
@ current
This was a new validation and was added.
beast::Journal
A generic endpoint for log messages.
Definition: Journal.h:60
std::uint64_t
ripple::feeunit::TaggedFee
Definition: FeeUnits.h:72
std::map
STL class.
ripple::FeeVote::Setup::reference_fee_units
static constexpr FeeUnit32 reference_fee_units
The cost of a reference transaction in fee units.
Definition: FeeVote.h:46
ripple::detail::VotableValue::mVoteMap
std::map< value_type, int > mVoteMap
Definition: FeeVoteImpl.cpp:37
std::min
T min(T... args)
ripple::Serializer
Definition: Serializer.h:43
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::detail::VotableValue::getVotes
value_type getVotes() const
Definition: FeeVoteImpl.cpp:65
ripple::STValidation::FeeSettings::baseFee
boost::optional< XRPAmount > baseFee
Definition: STValidation.h:104
ripple::sfReserveIncrement
const SF_U32 sfReserveIncrement(access, STI_UINT32, 32, "ReserveIncrement")
Definition: SField.h:369
ripple::Serializer::peekData
Blob const & peekData() const
Definition: Serializer.h:173
std::max
T max(T... args)
ripple::STValidation::FeeSettings::reserveIncrement
boost::optional< XRPAmount > reserveIncrement
Definition: STValidation.h:106
ripple::sfBaseFee
const SF_U64 sfBaseFee(access, STI_UINT64, 5, "BaseFee")
Definition: SField.h:383
std::unique_ptr
STL class.
ripple::XRPAmount::dropsAs
boost::optional< Dest > dropsAs() const
Definition: XRPAmount.h:196
ripple::STValidation::FeeSettings
Fees to set when issuing a new validation.
Definition: STValidation.h:101
ripple::detail::VotableValue::addVote
void addVote(value_type vote)
Definition: FeeVoteImpl.cpp:49
std::numeric_limits
ripple::XRPAmount
Definition: XRPAmount.h:46