rippled
SetSignerList.cpp
1 //------------------------------------------------------------------------------
2 /*
3  This file is part of rippled: https://github.com/ripple/rippled
4  Copyright (c) 2014 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/app/tx/impl/SetSignerList.h>
21 
22 #include <ripple/app/ledger/Ledger.h>
23 #include <ripple/basics/Log.h>
24 #include <ripple/ledger/ApplyView.h>
25 #include <ripple/protocol/Feature.h>
26 #include <ripple/protocol/Indexes.h>
27 #include <ripple/protocol/STArray.h>
28 #include <ripple/protocol/STObject.h>
29 #include <ripple/protocol/STTx.h>
30 #include <algorithm>
31 #include <cstdint>
32 
33 namespace ripple {
34 
35 // We're prepared for there to be multiple signer lists in the future,
36 // but we don't need them yet. So for the time being we're manually
37 // setting the sfSignerListID to zero in all cases.
39 
41  NotTEC,
46  STTx const& tx,
47  ApplyFlags flags,
49 {
50  // Check the quorum. A non-zero quorum means we're creating or replacing
51  // the list. A zero quorum means we're destroying the list.
52  auto const quorum = tx[sfSignerQuorum];
54  Operation op = unknown;
55 
56  bool const hasSignerEntries(tx.isFieldPresent(sfSignerEntries));
57  if (quorum && hasSignerEntries)
58  {
59  auto signers = SignerEntries::deserialize(tx, j, "transaction");
60 
61  if (!signers)
62  return std::make_tuple(signers.error(), quorum, sign, op);
63 
64  std::sort(signers->begin(), signers->end());
65 
66  // Save deserialized list for later.
67  sign = std::move(*signers);
68  op = set;
69  }
70  else if ((quorum == 0) && !hasSignerEntries)
71  {
72  op = destroy;
73  }
74 
75  return std::make_tuple(tesSUCCESS, quorum, sign, op);
76 }
77 
78 NotTEC
80 {
81  if (auto const ret = preflight1(ctx); !isTesSuccess(ret))
82  return ret;
83 
84  auto const result = determineOperation(ctx.tx, ctx.flags, ctx.j);
85 
86  if (std::get<0>(result) != tesSUCCESS)
87  return std::get<0>(result);
88 
89  if (std::get<3>(result) == unknown)
90  {
91  // Neither a set nor a destroy. Malformed.
92  JLOG(ctx.j.trace())
93  << "Malformed transaction: Invalid signer set list format.";
94  return temMALFORMED;
95  }
96 
97  if (std::get<3>(result) == set)
98  {
99  // Validate our settings.
100  auto const account = ctx.tx.getAccountID(sfAccount);
102  std::get<1>(result),
103  std::get<2>(result),
104  account,
105  ctx.j,
106  ctx.rules);
107  if (ter != tesSUCCESS)
108  {
109  return ter;
110  }
111  }
112 
113  return preflight2(ctx);
114 }
115 
116 TER
118 {
119  // Perform the operation preCompute() decided on.
120  switch (do_)
121  {
122  case set:
123  return replaceSignerList();
124 
125  case destroy:
126  return destroySignerList();
127 
128  default:
129  break;
130  }
131  assert(false); // Should not be possible to get here.
132  return temMALFORMED;
133 }
134 
135 void
137 {
138  // Get the quorum and operation info.
139  auto result = determineOperation(ctx_.tx, view().flags(), j_);
140  assert(std::get<0>(result) == tesSUCCESS);
141  assert(std::get<3>(result) != unknown);
142 
143  quorum_ = std::get<1>(result);
144  signers_ = std::get<2>(result);
145  do_ = std::get<3>(result);
146 
147  return Transactor::preCompute();
148 }
149 
150 // The return type is signed so it is compatible with the 3rd argument
151 // of adjustOwnerCount() (which must be signed).
152 //
153 // NOTE: This way of computing the OwnerCount associated with a SignerList
154 // is valid until the featureMultiSignReserve amendment passes. Once it
155 // passes then just 1 OwnerCount is associated with a SignerList.
156 static int
158 {
159  // We always compute the full change in OwnerCount, taking into account:
160  // o The fact that we're adding/removing a SignerList and
161  // o Accounting for the number of entries in the list.
162  // We can get away with that because lists are not adjusted incrementally;
163  // we add or remove an entire list.
164  //
165  // The rule is:
166  // o Simply having a SignerList costs 2 OwnerCount units.
167  // o And each signer in the list costs 1 more OwnerCount unit.
168  // So, at a minimum, adding a SignerList with 1 entry costs 3 OwnerCount
169  // units. A SignerList with 8 entries would cost 10 OwnerCount units.
170  //
171  // The static_cast should always be safe since entryCount should always
172  // be in the range from 1 to 8 (or 32 if ExpandedSignerList is enabled).
173  // We've got a lot of room to grow.
174  assert(entryCount >= STTx::minMultiSigners);
175  assert(entryCount <= STTx::maxMultiSigners(&rules));
176  return 2 + static_cast<int>(entryCount);
177 }
178 
179 static TER
181  Application& app,
182  ApplyView& view,
183  Keylet const& accountKeylet,
184  Keylet const& ownerDirKeylet,
185  Keylet const& signerListKeylet,
186  beast::Journal j)
187 {
188  // We have to examine the current SignerList so we know how much to
189  // reduce the OwnerCount.
190  SLE::pointer signers = view.peek(signerListKeylet);
191 
192  // If the signer list doesn't exist we've already succeeded in deleting it.
193  if (!signers)
194  return tesSUCCESS;
195 
196  // There are two different ways that the OwnerCount could be managed.
197  // If the lsfOneOwnerCount bit is set then remove just one owner count.
198  // Otherwise use the pre-MultiSignReserve amendment calculation.
199  int removeFromOwnerCount = -1;
200  if ((signers->getFlags() & lsfOneOwnerCount) == 0)
201  {
202  STArray const& actualList = signers->getFieldArray(sfSignerEntries);
203  removeFromOwnerCount =
204  signerCountBasedOwnerCountDelta(actualList.size(), view.rules()) *
205  -1;
206  }
207 
208  // Remove the node from the account directory.
209  auto const hint = (*signers)[sfOwnerNode];
210 
211  if (!view.dirRemove(ownerDirKeylet, hint, signerListKeylet.key, false))
212  {
213  JLOG(j.fatal()) << "Unable to delete SignerList from owner.";
214  return tefBAD_LEDGER;
215  }
216 
218  view,
219  view.peek(accountKeylet),
220  removeFromOwnerCount,
221  app.journal("View"));
222 
223  view.erase(signers);
224 
225  return tesSUCCESS;
226 }
227 
228 TER
230  Application& app,
231  ApplyView& view,
232  AccountID const& account,
233  beast::Journal j)
234 {
235  auto const accountKeylet = keylet::account(account);
236  auto const ownerDirKeylet = keylet::ownerDir(account);
237  auto const signerListKeylet = keylet::signers(account);
238 
240  app, view, accountKeylet, ownerDirKeylet, signerListKeylet, j);
241 }
242 
243 NotTEC
245  std::uint32_t quorum,
247  AccountID const& account,
248  beast::Journal j,
249  Rules const& rules)
250 {
251  // Reject if there are too many or too few entries in the list.
252  {
253  std::size_t const signerCount = signers.size();
254  if ((signerCount < STTx::minMultiSigners) ||
255  (signerCount > STTx::maxMultiSigners(&rules)))
256  {
257  JLOG(j.trace()) << "Too many or too few signers in signer list.";
258  return temMALFORMED;
259  }
260  }
261 
262  // Make sure there are no duplicate signers.
263  assert(std::is_sorted(signers.begin(), signers.end()));
264  if (std::adjacent_find(signers.begin(), signers.end()) != signers.end())
265  {
266  JLOG(j.trace()) << "Duplicate signers in signer list";
267  return temBAD_SIGNER;
268  }
269 
270  // Is the ExpandedSignerList amendment active?
271  bool const expandedSignerList = rules.enabled(featureExpandedSignerList);
272 
273  // Make sure no signers reference this account. Also make sure the
274  // quorum can be reached.
275  std::uint64_t allSignersWeight(0);
276  for (auto const& signer : signers)
277  {
278  std::uint32_t const weight = signer.weight;
279  if (weight <= 0)
280  {
281  JLOG(j.trace()) << "Every signer must have a positive weight.";
282  return temBAD_WEIGHT;
283  }
284 
285  allSignersWeight += signer.weight;
286 
287  if (signer.account == account)
288  {
289  JLOG(j.trace()) << "A signer may not self reference account.";
290  return temBAD_SIGNER;
291  }
292 
293  if (signer.tag && !expandedSignerList)
294  {
295  JLOG(j.trace()) << "Malformed transaction: sfWalletLocator "
296  "specified in SignerEntry "
297  << "but featureExpandedSignerList is not enabled.";
298  return temMALFORMED;
299  }
300 
301  // Don't verify that the signer accounts exist. Non-existent accounts
302  // may be phantom accounts (which are permitted).
303  }
304  if ((quorum <= 0) || (allSignersWeight < quorum))
305  {
306  JLOG(j.trace()) << "Quorum is unreachable";
307  return temBAD_QUORUM;
308  }
309  return tesSUCCESS;
310 }
311 
312 TER
314 {
315  auto const accountKeylet = keylet::account(account_);
316  auto const ownerDirKeylet = keylet::ownerDir(account_);
317  auto const signerListKeylet = keylet::signers(account_);
318 
319  // This may be either a create or a replace. Preemptively remove any
320  // old signer list. May reduce the reserve, so this is done before
321  // checking the reserve.
322  if (TER const ter = removeSignersFromLedger(
323  ctx_.app,
324  view(),
325  accountKeylet,
326  ownerDirKeylet,
327  signerListKeylet,
328  j_))
329  return ter;
330 
331  auto const sle = view().peek(accountKeylet);
332  if (!sle)
333  return tefINTERNAL;
334 
335  // Compute new reserve. Verify the account has funds to meet the reserve.
336  std::uint32_t const oldOwnerCount{(*sle)[sfOwnerCount]};
337 
338  // The required reserve changes based on featureMultiSignReserve...
339  int addedOwnerCount{1};
342  {
343  addedOwnerCount = signerCountBasedOwnerCountDelta(
344  signers_.size(), ctx_.view().rules());
345  flags = 0;
346  }
347 
348  XRPAmount const newReserve{
349  view().fees().accountReserve(oldOwnerCount + addedOwnerCount)};
350 
351  // We check the reserve against the starting balance because we want to
352  // allow dipping into the reserve to pay fees. This behavior is consistent
353  // with CreateTicket.
354  if (mPriorBalance < newReserve)
356 
357  // Everything's ducky. Add the ltSIGNER_LIST to the ledger.
358  auto signerList = std::make_shared<SLE>(signerListKeylet);
359  view().insert(signerList);
360  writeSignersToSLE(signerList, flags);
361 
362  auto viewJ = ctx_.app.journal("View");
363  // Add the signer list to the account's directory.
364  auto const page = ctx_.view().dirInsert(
365  ownerDirKeylet, signerListKeylet, describeOwnerDir(account_));
366 
367  JLOG(j_.trace()) << "Create signer list for account " << toBase58(account_)
368  << ": " << (page ? "success" : "failure");
369 
370  if (!page)
371  return tecDIR_FULL;
372 
373  signerList->setFieldU64(sfOwnerNode, *page);
374 
375  // If we succeeded, the new entry counts against the
376  // creator's reserve.
377  adjustOwnerCount(view(), sle, addedOwnerCount, viewJ);
378  return tesSUCCESS;
379 }
380 
381 TER
383 {
384  auto const accountKeylet = keylet::account(account_);
385  // Destroying the signer list is only allowed if either the master key
386  // is enabled or there is a regular key.
387  SLE::pointer ledgerEntry = view().peek(accountKeylet);
388  if (!ledgerEntry)
389  return tefINTERNAL;
390 
391  if ((ledgerEntry->isFlag(lsfDisableMaster)) &&
392  (!ledgerEntry->isFieldPresent(sfRegularKey)))
393  return tecNO_ALTERNATIVE_KEY;
394 
395  auto const ownerDirKeylet = keylet::ownerDir(account_);
396  auto const signerListKeylet = keylet::signers(account_);
398  ctx_.app, view(), accountKeylet, ownerDirKeylet, signerListKeylet, j_);
399 }
400 
401 void
403  SLE::pointer const& ledgerEntry,
404  std::uint32_t flags) const
405 {
406  // Assign the quorum, default SignerListID, and flags.
407  ledgerEntry->setFieldU32(sfSignerQuorum, quorum_);
408  ledgerEntry->setFieldU32(sfSignerListID, defaultSignerListID_);
409  if (flags) // Only set flags if they are non-default (default is zero).
410  ledgerEntry->setFieldU32(sfFlags, flags);
411 
412  bool const expandedSignerList =
414 
415  // Create the SignerListArray one SignerEntry at a time.
416  STArray toLedger(signers_.size());
417  for (auto const& entry : signers_)
418  {
419  toLedger.emplace_back(sfSignerEntry);
420  STObject& obj = toLedger.back();
421  obj.reserve(2);
422  obj.setAccountID(sfAccount, entry.account);
423  obj.setFieldU16(sfSignerWeight, entry.weight);
424 
425  // This is a defensive check to make absolutely sure we will never write
426  // a tag into the ledger while featureExpandedSignerList is not enabled
427  if (expandedSignerList && entry.tag)
428  obj.setFieldH256(sfWalletLocator, *(entry.tag));
429  }
430 
431  // Assign the SignerEntries.
432  ledgerEntry->setFieldArray(sfSignerEntries, toLedger);
433 }
434 
435 } // namespace ripple
beast::Journal::fatal
Stream fatal() const
Definition: Journal.h:339
ripple::STArray::size
size_type size() const
Definition: STArray.h:248
ripple::SetSignerList::validateQuorumAndSignerEntries
static NotTEC validateQuorumAndSignerEntries(std::uint32_t quorum, std::vector< SignerEntries::SignerEntry > const &signers, AccountID const &account, beast::Journal j, Rules const &)
Definition: SetSignerList.cpp:244
ripple::sfSignerListID
const SF_UINT32 sfSignerListID
ripple::keylet::ownerDir
Keylet ownerDir(AccountID const &id) noexcept
The root page of an account's directory.
Definition: Indexes.cpp:303
ripple::sfOwnerCount
const SF_UINT32 sfOwnerCount
ripple::Application
Definition: Application.h:115
ripple::STObject::setAccountID
void setAccountID(SField const &field, AccountID const &)
Definition: STObject.cpp:689
ripple::sfSignerWeight
const SF_UINT16 sfSignerWeight
ripple::preflight2
NotTEC preflight2(PreflightContext const &ctx)
Checks whether the signature appears valid.
Definition: Transactor.cpp:130
std::make_tuple
T make_tuple(T... args)
ripple::Keylet
A pair of SHAMap key and LedgerEntryType.
Definition: Keylet.h:38
ripple::tefINTERNAL
@ tefINTERNAL
Definition: TER.h:155
ripple::Rules::enabled
bool enabled(uint256 const &feature) const
Returns true if a feature is enabled.
Definition: Rules.cpp:94
std::shared_ptr< STLedgerEntry >
ripple::sfOwnerNode
const SF_UINT64 sfOwnerNode
ripple::STObject::setFieldU16
void setFieldU16(SField const &field, std::uint16_t)
Definition: STObject.cpp:653
beast::Journal::trace
Stream trace() const
Severity stream access functions.
Definition: Journal.h:309
ripple::ApplyView::peek
virtual std::shared_ptr< SLE > peek(Keylet const &k)=0
Prepare to modify the SLE associated with key.
ripple::lsfDisableMaster
@ lsfDisableMaster
Definition: LedgerFormats.h:229
ripple::describeOwnerDir
std::function< void(SLE::ref)> describeOwnerDir(AccountID const &account)
Definition: View.cpp:731
ripple::SignerEntries::deserialize
static Expected< std::vector< SignerEntry >, NotTEC > deserialize(STObject const &obj, beast::Journal journal, std::string const &annotation)
Definition: SignerEntries.cpp:30
ripple::Transactor::j_
const beast::Journal j_
Definition: Transactor.h:89
ripple::isTesSuccess
bool isTesSuccess(TER x)
Definition: TER.h:597
ripple::sfRegularKey
const SF_ACCOUNT sfRegularKey
ripple::SetSignerList::destroySignerList
TER destroySignerList()
Definition: SetSignerList.cpp:382
ripple::ApplyView::erase
virtual void erase(std::shared_ptr< SLE > const &sle)=0
Remove a peeked SLE.
std::vector
STL class.
ripple::ReadView::fees
virtual Fees const & fees() const =0
Returns the fees for the base ledger.
ripple::ApplyFlags
ApplyFlags
Definition: ApplyView.h:29
ripple::toBase58
std::string toBase58(AccountID const &v)
Convert AccountID to base58 checked string.
Definition: AccountID.cpp:104
ripple::featureMultiSignReserve
const uint256 featureMultiSignReserve
std::tuple
ripple::SetSignerList::Operation
Operation
Definition: SetSignerList.h:46
ripple::PreflightContext::j
const beast::Journal j
Definition: Transactor.h:38
ripple::SetSignerList::set
@ set
Definition: SetSignerList.h:46
std::sort
T sort(T... args)
algorithm
ripple::defaultSignerListID_
static const std::uint32_t defaultSignerListID_
Definition: SetSignerList.cpp:38
ripple::preflight1
NotTEC preflight1(PreflightContext const &ctx)
Performs early sanity checks on the account and fee fields.
Definition: Transactor.cpp:78
ripple::ApplyView
Writeable view to a ledger, for applying a transaction.
Definition: ApplyView.h:134
std::is_sorted
T is_sorted(T... args)
ripple::ApplyContext::app
Application & app
Definition: ApplyContext.h:47
ripple::sfSignerQuorum
const SF_UINT32 sfSignerQuorum
ripple::ApplyView::dirRemove
bool dirRemove(Keylet const &directory, std::uint64_t page, uint256 const &key, bool keepRoot)
Remove an entry from a directory.
Definition: ApplyView.cpp:189
ripple::Keylet::key
uint256 key
Definition: Keylet.h:40
ripple::base_uint< 160, detail::AccountIDTag >
ripple::tefBAD_LEDGER
@ tefBAD_LEDGER
Definition: TER.h:152
ripple::temBAD_QUORUM
@ temBAD_QUORUM
Definition: TER.h:114
ripple::adjustOwnerCount
void adjustOwnerCount(ApplyView &view, std::shared_ptr< SLE > const &sle, std::int32_t amount, beast::Journal j)
Adjust the owner count up or down.
Definition: View.cpp:713
ripple::tecNO_ALTERNATIVE_KEY
@ tecNO_ALTERNATIVE_KEY
Definition: TER.h:263
ripple::featureExpandedSignerList
const uint256 featureExpandedSignerList
ripple::keylet::account
Keylet account(AccountID const &id) noexcept
AccountID root.
Definition: Indexes.cpp:133
ripple::STObject::getAccountID
AccountID getAccountID(SField const &field) const
Definition: STObject.cpp:589
ripple::temBAD_SIGNER
@ temBAD_SIGNER
Definition: TER.h:113
ripple::SetSignerList::do_
Operation do_
Definition: SetSignerList.h:47
ripple::STObject::setFieldH256
void setFieldH256(SField const &field, uint256 const &)
Definition: STObject.cpp:677
ripple::TERSubset
Definition: TER.h:340
ripple::STArray
Definition: STArray.h:28
ripple::SetSignerList::unknown
@ unknown
Definition: SetSignerList.h:46
ripple::TER
TERSubset< CanCvtToTER > TER
Definition: TER.h:568
ripple::signerCountBasedOwnerCountDelta
static int signerCountBasedOwnerCountDelta(std::size_t entryCount, Rules const &rules)
Definition: SetSignerList.cpp:157
ripple::lsfOneOwnerCount
@ lsfOneOwnerCount
Definition: LedgerFormats.h:262
cstdint
ripple::STTx
Definition: STTx.h:45
ripple::SetSignerList::removeFromLedger
static TER removeFromLedger(Application &app, ApplyView &view, AccountID const &account, beast::Journal j)
Definition: SetSignerList.cpp:229
beast::Journal
A generic endpoint for log messages.
Definition: Journal.h:58
ripple::STTx::maxMultiSigners
static std::size_t maxMultiSigners(Rules const *rules=0)
Definition: STTx.h:55
std::uint32_t
ripple::STObject::reserve
void reserve(std::size_t n)
Definition: STObject.h:877
ripple::SetSignerList::determineOperation
static std::tuple< NotTEC, std::uint32_t, std::vector< SignerEntries::SignerEntry >, Operation > determineOperation(STTx const &tx, ApplyFlags flags, beast::Journal j)
Definition: SetSignerList.cpp:45
ripple::sfSignerEntry
const SField sfSignerEntry
ripple::ApplyContext::view
ApplyView & view()
Definition: ApplyContext.h:54
ripple::tecDIR_FULL
@ tecDIR_FULL
Definition: TER.h:254
ripple::SetSignerList::doApply
TER doApply() override
Definition: SetSignerList.cpp:117
ripple::sfSignerEntries
const SField sfSignerEntries
ripple::STObject
Definition: STObject.h:51
ripple::ApplyView::insert
virtual void insert(std::shared_ptr< SLE > const &sle)=0
Insert a new state SLE.
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::PreflightContext::flags
ApplyFlags flags
Definition: Transactor.h:37
ripple::Application::journal
virtual beast::Journal journal(std::string const &name)=0
ripple::SetSignerList::destroy
@ destroy
Definition: SetSignerList.h:46
ripple::sfWalletLocator
const SF_UINT256 sfWalletLocator
ripple::SetSignerList::signers_
std::vector< SignerEntries::SignerEntry > signers_
Definition: SetSignerList.h:49
ripple::Transactor::view
ApplyView & view()
Definition: Transactor.h:107
ripple::sign
Buffer sign(PublicKey const &pk, SecretKey const &sk, Slice const &m)
Generate a signature for a message.
Definition: SecretKey.cpp:238
ripple::STArray::emplace_back
void emplace_back(Args &&... args)
Definition: STArray.h:206
ripple::Fees::accountReserve
XRPAmount accountReserve(std::size_t ownerCount) const
Returns the account reserve given the owner count, in drops.
Definition: ReadView.h:66
ripple::ReadView::rules
virtual Rules const & rules() const =0
Returns the tx processing rules.
ripple::sfFlags
const SF_UINT32 sfFlags
ripple::STObject::isFieldPresent
bool isFieldPresent(SField const &field) const
Definition: STObject.cpp:428
ripple::SetSignerList::preCompute
void preCompute() override
Definition: SetSignerList.cpp:136
ripple::Transactor::mPriorBalance
XRPAmount mPriorBalance
Definition: Transactor.h:92
std::adjacent_find
T adjacent_find(T... args)
ripple::tecINSUFFICIENT_RESERVE
@ tecINSUFFICIENT_RESERVE
Definition: TER.h:274
ripple::Rules
Rules controlling protocol behavior.
Definition: Rules.h:33
ripple::STTx::minMultiSigners
static const std::size_t minMultiSigners
Definition: STTx.h:51
ripple::removeSignersFromLedger
static TER removeSignersFromLedger(Application &app, ApplyView &view, Keylet const &accountKeylet, Keylet const &ownerDirKeylet, Keylet const &signerListKeylet, beast::Journal j)
Definition: SetSignerList.cpp:180
ripple::Transactor::ctx_
ApplyContext & ctx_
Definition: Transactor.h:88
ripple::STArray::back
STObject & back()
Definition: STArray.h:193
ripple::SetSignerList::replaceSignerList
TER replaceSignerList()
Definition: SetSignerList.cpp:313
std::size_t
ripple::sfAccount
const SF_ACCOUNT sfAccount
ripple::temMALFORMED
@ temMALFORMED
Definition: TER.h:85
ripple::PreflightContext::tx
STTx const & tx
Definition: Transactor.h:35
ripple::PreflightContext
State information when preflighting a tx.
Definition: Transactor.h:31
ripple::keylet::signers
static Keylet signers(AccountID const &account, std::uint32_t page) noexcept
Definition: Indexes.cpp:268
ripple::ApplyView::dirInsert
std::optional< std::uint64_t > dirInsert(Keylet const &directory, uint256 const &key, std::function< void(std::shared_ptr< SLE > const &)> const &describe)
Insert an entry to a directory.
Definition: ApplyView.h:306
ripple::SetSignerList::writeSignersToSLE
void writeSignersToSLE(SLE::pointer const &ledgerEntry, std::uint32_t flags) const
Definition: SetSignerList.cpp:402
ripple::PreflightContext::rules
const Rules rules
Definition: Transactor.h:36
ripple::tesSUCCESS
@ tesSUCCESS
Definition: TER.h:222
ripple::Transactor::account_
const AccountID account_
Definition: Transactor.h:91
ripple::Transactor::preCompute
virtual void preCompute()
Definition: Transactor.cpp:437
ripple::SetSignerList::quorum_
std::uint32_t quorum_
Definition: SetSignerList.h:48
ripple::ApplyContext::tx
STTx const & tx
Definition: ApplyContext.h:48
ripple::temBAD_WEIGHT
@ temBAD_WEIGHT
Definition: TER.h:115
ripple::SetSignerList::preflight
static NotTEC preflight(PreflightContext const &ctx)
Definition: SetSignerList.cpp:79
ripple::XRPAmount
Definition: XRPAmount.h:46
ripple::NotTEC
TERSubset< CanCvtToNotTEC > NotTEC
Definition: TER.h:528