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 
44  ApplyFlags flags, beast::Journal j)
45 {
46  // Check the quorum. A non-zero quorum means we're creating or replacing
47  // the list. A zero quorum means we're destroying the list.
48  auto const quorum = tx[sfSignerQuorum];
50  Operation op = unknown;
51 
52  bool const hasSignerEntries(tx.isFieldPresent(sfSignerEntries));
53  if (quorum && hasSignerEntries)
54  {
55  auto signers = SignerEntries::deserialize(tx, j, "transaction");
56 
57  if (signers.second != tesSUCCESS)
58  return std::make_tuple(signers.second, quorum, sign, op);
59 
60  std::sort(signers.first.begin(), signers.first.end());
61 
62  // Save deserialized list for later.
63  sign = std::move(signers.first);
64  op = set;
65  }
66  else if ((quorum == 0) && !hasSignerEntries)
67  {
68  op = destroy;
69  }
70 
71  return std::make_tuple(tesSUCCESS, quorum, sign, op);
72 }
73 
74 NotTEC
76 {
77  auto const ret = preflight1 (ctx);
78  if (!isTesSuccess (ret))
79  return ret;
80 
81  auto const result = determineOperation(ctx.tx, ctx.flags, ctx.j);
82  if (std::get<0>(result) != tesSUCCESS)
83  return std::get<0>(result);
84 
85  if (std::get<3>(result) == unknown)
86  {
87  // Neither a set nor a destroy. Malformed.
88  JLOG(ctx.j.trace()) <<
89  "Malformed transaction: Invalid signer set list format.";
90  return temMALFORMED;
91  }
92 
93  if (std::get<3>(result) == set)
94  {
95  // Validate our settings.
96  auto const account = ctx.tx.getAccountID(sfAccount);
97  NotTEC const ter =
98  validateQuorumAndSignerEntries(std::get<1>(result),
99  std::get<2>(result), account, ctx.j);
100  if (ter != tesSUCCESS)
101  {
102  return ter;
103  }
104  }
105 
106  return preflight2 (ctx);
107 }
108 
109 TER
111 {
112  // Perform the operation preCompute() decided on.
113  switch (do_)
114  {
115  case set:
116  return replaceSignerList ();
117 
118  case destroy:
119  return destroySignerList ();
120 
121  default:
122  break;
123  }
124  assert (false); // Should not be possible to get here.
125  return temMALFORMED;
126 }
127 
128 void
130 {
131  // Get the quorum and operation info.
132  auto result = determineOperation(ctx_.tx, view().flags(), j_);
133  assert(std::get<0>(result) == tesSUCCESS);
134  assert(std::get<3>(result) != unknown);
135 
136  quorum_ = std::get<1>(result);
137  signers_ = std::get<2>(result);
138  do_ = std::get<3>(result);
139 
140  return Transactor::preCompute();
141 }
142 
143 // The return type is signed so it is compatible with the 3rd argument
144 // of adjustOwnerCount() (which must be signed).
145 //
146 // NOTE: This way of computing the OwnerCount associated with a SignerList
147 // is valid until the featureMultiSignReserve amendment passes. Once it
148 // passes then just 1 OwnerCount is associated with a SignerList.
149 static int
151 {
152  // We always compute the full change in OwnerCount, taking into account:
153  // o The fact that we're adding/removing a SignerList and
154  // o Accounting for the number of entries in the list.
155  // We can get away with that because lists are not adjusted incrementally;
156  // we add or remove an entire list.
157  //
158  // The rule is:
159  // o Simply having a SignerList costs 2 OwnerCount units.
160  // o And each signer in the list costs 1 more OwnerCount unit.
161  // So, at a minimum, adding a SignerList with 1 entry costs 3 OwnerCount
162  // units. A SignerList with 8 entries would cost 10 OwnerCount units.
163  //
164  // The static_cast should always be safe since entryCount should always
165  // be in the range from 1 to 8. We've got a lot of room to grow.
166  assert (entryCount >= STTx::minMultiSigners);
167  assert (entryCount <= STTx::maxMultiSigners);
168  return 2 + static_cast<int>(entryCount);
169 }
170 
171 static TER
173  Application& app, ApplyView& view, Keylet const& accountKeylet,
174  Keylet const& ownerDirKeylet, Keylet const& signerListKeylet)
175 {
176  // We have to examine the current SignerList so we know how much to
177  // reduce the OwnerCount.
178  SLE::pointer signers = view.peek (signerListKeylet);
179 
180  // If the signer list doesn't exist we've already succeeded in deleting it.
181  if (!signers)
182  return tesSUCCESS;
183 
184  // There are two different ways that the OwnerCount could be managed.
185  // If the lsfOneOwnerCount bit is set then remove just one owner count.
186  // Otherwise use the pre-MultiSignReserve amendment calculation.
187  int removeFromOwnerCount = -1;
188  if ((signers->getFlags() & lsfOneOwnerCount) == 0)
189  {
190  STArray const& actualList = signers->getFieldArray (sfSignerEntries);
191  removeFromOwnerCount =
192  signerCountBasedOwnerCountDelta (actualList.size()) * -1;
193  }
194 
195  // Remove the node from the account directory.
196  auto const hint = (*signers)[sfOwnerNode];
197 
198  if (! view.dirRemove(
199  ownerDirKeylet, hint, signerListKeylet.key, false))
200  {
201  return tefBAD_LEDGER;
202  }
203 
204  adjustOwnerCount(view,
205  view.peek(accountKeylet), removeFromOwnerCount, app.journal("View"));
206 
207  view.erase (signers);
208 
209  return tesSUCCESS;
210 }
211 
212 TER
214  Application& app, ApplyView& view, AccountID const& account)
215 {
216  auto const accountKeylet = keylet::account (account);
217  auto const ownerDirKeylet = keylet::ownerDir (account);
218  auto const signerListKeylet = keylet::signers (account);
219 
220  return removeSignersFromLedger (
221  app, view, accountKeylet, ownerDirKeylet, signerListKeylet);
222 }
223 
224 NotTEC
226  std::uint32_t quorum,
228  AccountID const& account,
229  beast::Journal j)
230 {
231  // Reject if there are too many or too few entries in the list.
232  {
233  std::size_t const signerCount = signers.size ();
234  if ((signerCount < STTx::minMultiSigners)
235  || (signerCount > STTx::maxMultiSigners))
236  {
237  JLOG(j.trace()) << "Too many or too few signers in signer list.";
238  return temMALFORMED;
239  }
240  }
241 
242  // Make sure there are no duplicate signers.
243  assert(std::is_sorted(signers.begin(), signers.end()));
244  if (std::adjacent_find (
245  signers.begin (), signers.end ()) != signers.end ())
246  {
247  JLOG(j.trace()) << "Duplicate signers in signer list";
248  return temBAD_SIGNER;
249  }
250 
251  // Make sure no signers reference this account. Also make sure the
252  // quorum can be reached.
253  std::uint64_t allSignersWeight (0);
254  for (auto const& signer : signers)
255  {
256  std::uint32_t const weight = signer.weight;
257  if (weight <= 0)
258  {
259  JLOG(j.trace()) << "Every signer must have a positive weight.";
260  return temBAD_WEIGHT;
261  }
262 
263  allSignersWeight += signer.weight;
264 
265  if (signer.account == account)
266  {
267  JLOG(j.trace()) << "A signer may not self reference account.";
268  return temBAD_SIGNER;
269  }
270 
271  // Don't verify that the signer accounts exist. Non-existent accounts
272  // may be phantom accounts (which are permitted).
273  }
274  if ((quorum <= 0) || (allSignersWeight < quorum))
275  {
276  JLOG(j.trace()) << "Quorum is unreachable";
277  return temBAD_QUORUM;
278  }
279  return tesSUCCESS;
280 }
281 
282 TER
284 {
285  auto const accountKeylet = keylet::account (account_);
286  auto const ownerDirKeylet = keylet::ownerDir (account_);
287  auto const signerListKeylet = keylet::signers (account_);
288 
289  // This may be either a create or a replace. Preemptively remove any
290  // old signer list. May reduce the reserve, so this is done before
291  // checking the reserve.
292  if (TER const ter = removeSignersFromLedger (
293  ctx_.app, view(), accountKeylet, ownerDirKeylet, signerListKeylet))
294  return ter;
295 
296  auto const sle = view().peek(accountKeylet);
297  if (!sle)
298  return tefINTERNAL;
299 
300  // Compute new reserve. Verify the account has funds to meet the reserve.
301  std::uint32_t const oldOwnerCount {(*sle)[sfOwnerCount]};
302 
303  // The required reserve changes based on featureMultiSignReserve...
304  int addedOwnerCount {1};
307  {
308  addedOwnerCount = signerCountBasedOwnerCountDelta (signers_.size ());
309  flags = 0;
310  }
311 
312  XRPAmount const newReserve {
313  view().fees().accountReserve(oldOwnerCount + addedOwnerCount)};
314 
315  // We check the reserve against the starting balance because we want to
316  // allow dipping into the reserve to pay fees. This behavior is consistent
317  // with CreateTicket.
318  if (mPriorBalance < newReserve)
320 
321  // Everything's ducky. Add the ltSIGNER_LIST to the ledger.
322  auto signerList = std::make_shared<SLE>(signerListKeylet);
323  view().insert (signerList);
324  writeSignersToSLE (signerList, flags);
325 
326  auto viewJ = ctx_.app.journal ("View");
327  // Add the signer list to the account's directory.
328  auto const page = dirAdd (ctx_.view (), ownerDirKeylet,
329  signerListKeylet.key, false, describeOwnerDir (account_), viewJ);
330 
331  JLOG(j_.trace()) << "Create signer list for account " <<
332  toBase58 (account_) << ": " << (page ? "success" : "failure");
333 
334  if (!page)
335  return tecDIR_FULL;
336 
337  signerList->setFieldU64 (sfOwnerNode, *page);
338 
339  // If we succeeded, the new entry counts against the
340  // creator's reserve.
341  adjustOwnerCount(view(), sle, addedOwnerCount, viewJ);
342  return tesSUCCESS;
343 }
344 
345 TER
347 {
348  auto const accountKeylet = keylet::account (account_);
349  // Destroying the signer list is only allowed if either the master key
350  // is enabled or there is a regular key.
351  SLE::pointer ledgerEntry = view().peek (accountKeylet);
352  if (! ledgerEntry)
353  return tefINTERNAL;
354 
355  if ((ledgerEntry->isFlag (lsfDisableMaster)) &&
356  (!ledgerEntry->isFieldPresent (sfRegularKey)))
357  return tecNO_ALTERNATIVE_KEY;
358 
359  auto const ownerDirKeylet = keylet::ownerDir (account_);
360  auto const signerListKeylet = keylet::signers (account_);
362  ctx_.app, view(), accountKeylet, ownerDirKeylet, signerListKeylet);
363 }
364 
365 void
367  SLE::pointer const& ledgerEntry, std::uint32_t flags) const
368 {
369  // Assign the quorum, default SignerListID, and flags.
370  ledgerEntry->setFieldU32 (sfSignerQuorum, quorum_);
371  ledgerEntry->setFieldU32 (sfSignerListID, defaultSignerListID_);
372  if (flags) // Only set flags if they are non-default (default is zero).
373  ledgerEntry->setFieldU32 (sfFlags, flags);
374 
375  // Create the SignerListArray one SignerEntry at a time.
376  STArray toLedger (signers_.size ());
377  for (auto const& entry : signers_)
378  {
379  toLedger.emplace_back(sfSignerEntry);
380  STObject& obj = toLedger.back();
381  obj.reserve (2);
382  obj.setAccountID (sfAccount, entry.account);
383  obj.setFieldU16 (sfSignerWeight, entry.weight);
384  }
385 
386  // Assign the SignerEntries.
387  ledgerEntry->setFieldArray (sfSignerEntries, toLedger);
388 }
389 
390 } // namespace ripple
ripple::Application
Definition: Application.h:85
ripple::STObject::setAccountID
void setAccountID(SField const &field, AccountID const &)
Definition: STObject.cpp:626
ripple::sfRegularKey
const SF_Account sfRegularKey(access, STI_ACCOUNT, 8, "RegularKey")
Definition: SField.h:467
ripple::preflight2
NotTEC preflight2(PreflightContext const &ctx)
Checks whether the signature appears valid.
Definition: Transactor.cpp:90
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:153
ripple::keylet::signers
static const signers_t signers
Definition: Indexes.h:239
std::shared_ptr< STLedgerEntry >
ripple::STObject::setFieldU16
void setFieldU16(SField const &field, std::uint16_t)
Definition: STObject.cpp:596
beast::Journal::trace
Stream trace() const
Severity stream access functions.
Definition: Journal.h:287
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:136
ripple::describeOwnerDir
std::function< void(SLE::ref)> describeOwnerDir(AccountID const &account)
Definition: View.cpp:700
ripple::Transactor::j_
const beast::Journal j_
Definition: Transactor.h:82
ripple::isTesSuccess
bool isTesSuccess(TER x)
Definition: TER.h:501
ripple::SetSignerList::destroySignerList
TER destroySignerList()
Definition: SetSignerList.cpp:346
ripple::ApplyView::erase
virtual void erase(std::shared_ptr< SLE > const &sle)=0
Remove a peeked SLE.
ripple::sfSignerQuorum
const SF_U32 sfSignerQuorum(access, STI_UINT32, 35, "SignerQuorum")
Definition: SField.h:372
std::vector
STL class.
ripple::removeSignersFromLedger
static TER removeSignersFromLedger(Application &app, ApplyView &view, Keylet const &accountKeylet, Keylet const &ownerDirKeylet, Keylet const &signerListKeylet)
Definition: SetSignerList.cpp:172
ripple::ReadView::fees
virtual Fees const & fees() const =0
Returns the fees for the base ledger.
ripple::sfAccount
const SF_Account sfAccount(access, STI_ACCOUNT, 1, "Account")
Definition: SField.h:460
ripple::sfFlags
const SF_U32 sfFlags(access, STI_UINT32, 2, "Flags")
Definition: SField.h:338
ripple::ApplyFlags
ApplyFlags
Definition: ApplyView.h:30
ripple::toBase58
std::string toBase58(AccountID const &v)
Convert AccountID to base58 checked string.
Definition: AccountID.cpp:29
ripple::featureMultiSignReserve
const uint256 featureMultiSignReserve
Definition: Feature.cpp:172
std::tuple
Json::Value::end
const_iterator end() const
Definition: json_value.cpp:1107
ripple::sfOwnerNode
const SF_U64 sfOwnerNode(access, STI_UINT64, 4, "OwnerNode")
Definition: SField.h:382
ripple::SetSignerList::Operation
Operation
Definition: SetSignerList.h:45
ripple::sfSignerEntries
const SField sfSignerEntries(access, STI_ARRAY, 4, "SignerEntries")
Definition: SField.h:496
ripple::sfOwnerCount
const SF_U32 sfOwnerCount(access, STI_UINT32, 13, "OwnerCount")
Definition: SField.h:349
ripple::PreflightContext::j
const beast::Journal j
Definition: Transactor.h:39
ripple::SetSignerList::set
@ set
Definition: SetSignerList.h:45
ripple::SetSignerList::validateQuorumAndSignerEntries
static NotTEC validateQuorumAndSignerEntries(std::uint32_t quorum, std::vector< SignerEntries::SignerEntry > const &signers, AccountID const &account, beast::Journal j)
Definition: SetSignerList.cpp:225
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:56
ripple::ApplyView
Writeable view to a ledger, for applying a transaction.
Definition: ApplyView.h:150
std::is_sorted
T is_sorted(T... args)
ripple::ApplyContext::app
Application & app
Definition: ApplyContext.h:44
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:41
ripple::base_uint< 160, detail::AccountIDTag >
ripple::tefBAD_LEDGER
@ tefBAD_LEDGER
Definition: TER.h:150
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:629
ripple::tecNO_ALTERNATIVE_KEY
@ tecNO_ALTERNATIVE_KEY
Definition: TER.h:261
ripple::keylet::account
static const account_t account
Definition: Indexes.h:116
ripple::STObject::getAccountID
AccountID getAccountID(SField const &field) const
Definition: STObject.cpp:537
ripple::temBAD_SIGNER
@ temBAD_SIGNER
Definition: TER.h:113
ripple::SetSignerList::do_
Operation do_
Definition: SetSignerList.h:46
ripple::sfSignerListID
const SF_U32 sfSignerListID(access, STI_UINT32, 38, "SignerListID")
Definition: SField.h:375
ripple::TERSubset
Definition: TER.h:311
ripple::STArray
Definition: STArray.h:28
ripple::SetSignerList::unknown
@ unknown
Definition: SetSignerList.h:45
ripple::keylet::ownerDir
Keylet ownerDir(AccountID const &id)
The root page of an account's directory.
Definition: Indexes.cpp:318
ripple::TER
TERSubset< CanCvtToTER > TER
Definition: TER.h:477
Json::Value::size
UInt size() const
Number of values in array or object.
Definition: json_value.cpp:720
ripple::lsfOneOwnerCount
@ lsfOneOwnerCount
Definition: LedgerFormats.h:157
cstdint
ripple::STTx
Definition: STTx.h:43
ripple::sfSignerEntry
const SField sfSignerEntry(access, STI_OBJECT, 11, "SignerEntry")
Definition: SField.h:488
beast::Journal
A generic endpoint for log messages.
Definition: Journal.h:60
std::uint32_t
ripple::Rules::enabled
bool enabled(uint256 const &id) const
Returns true if a feature is enabled.
Definition: ReadView.cpp:107
ripple::STObject::reserve
void reserve(std::size_t n)
Definition: STObject.h:316
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:43
ripple::ApplyContext::view
ApplyView & view()
Definition: ApplyContext.h:51
ripple::STArray::back
STObject & back()
Definition: STArray.h:84
ripple::signerCountBasedOwnerCountDelta
static int signerCountBasedOwnerCountDelta(std::size_t entryCount)
Definition: SetSignerList.cpp:150
ripple::tecDIR_FULL
@ tecDIR_FULL
Definition: TER.h:252
ripple::dirAdd
boost::optional< std::uint64_t > dirAdd(ApplyView &view, Keylet const &dir, uint256 const &uLedgerIndex, bool strictOrder, std::function< void(SLE::ref)> fDescriber, beast::Journal j)
Definition: View.cpp:709
ripple::SetSignerList::doApply
TER doApply() override
Definition: SetSignerList.cpp:110
ripple::STObject
Definition: STObject.h:51
ripple::sfSignerWeight
const SF_U16 sfSignerWeight(access, STI_UINT16, 3, "SignerWeight")
Definition: SField.h:332
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:38
ripple::STTx::maxMultiSigners
static const std::size_t maxMultiSigners
Definition: STTx.h:51
ripple::Application::journal
virtual beast::Journal journal(std::string const &name)=0
ripple::SetSignerList::destroy
@ destroy
Definition: SetSignerList.h:45
ripple::SetSignerList::signers_
std::vector< SignerEntries::SignerEntry > signers_
Definition: SetSignerList.h:48
ripple::Transactor::view
ApplyView & view()
Definition: Transactor.h:98
ripple::sign
Buffer sign(PublicKey const &pk, SecretKey const &sk, Slice const &m)
Generate a signature for a message.
Definition: SecretKey.cpp:132
ripple::STArray::emplace_back
void emplace_back(Args &&... args)
Definition: STArray.h:90
ripple::Fees::accountReserve
XRPAmount accountReserve(std::size_t ownerCount) const
Returns the account reserve given the owner count, in drops.
Definition: ReadView.h:64
ripple::ReadView::rules
virtual Rules const & rules() const =0
Returns the tx processing rules.
ripple::STObject::isFieldPresent
bool isFieldPresent(SField const &field) const
Definition: STObject.cpp:392
ripple::SetSignerList::preCompute
void preCompute() override
Definition: SetSignerList.cpp:129
ripple::Transactor::mPriorBalance
XRPAmount mPriorBalance
Definition: Transactor.h:85
std::adjacent_find
T adjacent_find(T... args)
ripple::tecINSUFFICIENT_RESERVE
@ tecINSUFFICIENT_RESERVE
Definition: TER.h:272
ripple::STTx::minMultiSigners
static const std::size_t minMultiSigners
Definition: STTx.h:50
ripple::Transactor::ctx_
ApplyContext & ctx_
Definition: Transactor.h:81
ripple::Transactor::account_
AccountID account_
Definition: Transactor.h:84
ripple::SetSignerList::replaceSignerList
TER replaceSignerList()
Definition: SetSignerList.cpp:283
std::size_t
ripple::SignerEntries::deserialize
static std::pair< std::vector< SignerEntry >, NotTEC > deserialize(STObject const &obj, beast::Journal journal, std::string const &annotation)
Definition: SignerEntries.cpp:29
ripple::temMALFORMED
@ temMALFORMED
Definition: TER.h:85
ripple::STArray::size
size_type size() const
Definition: STArray.h:125
ripple::PreflightContext::tx
STTx const & tx
Definition: Transactor.h:36
ripple::PreflightContext
State information when preflighting a tx.
Definition: Transactor.h:32
ripple::SetSignerList::writeSignersToSLE
void writeSignersToSLE(SLE::pointer const &ledgerEntry, std::uint32_t flags) const
Definition: SetSignerList.cpp:366
Json::Value::begin
const_iterator begin() const
Definition: json_value.cpp:1089
ripple::tesSUCCESS
@ tesSUCCESS
Definition: TER.h:219
ripple::Transactor::preCompute
virtual void preCompute()
Definition: Transactor.cpp:295
ripple::SetSignerList::quorum_
std::uint32_t quorum_
Definition: SetSignerList.h:47
ripple::ApplyContext::tx
STTx const & tx
Definition: ApplyContext.h:45
ripple::temBAD_WEIGHT
@ temBAD_WEIGHT
Definition: TER.h:115
ripple::SetSignerList::preflight
static NotTEC preflight(PreflightContext const &ctx)
Definition: SetSignerList.cpp:75
ripple::XRPAmount
Definition: XRPAmount.h:46
ripple::NotTEC
TERSubset< CanCvtToNotTEC > NotTEC
Definition: TER.h:461
ripple::SetSignerList::removeFromLedger
static TER removeFromLedger(Application &app, ApplyView &view, AccountID const &account)
Definition: SetSignerList.cpp:213