1#include <xrpl/basics/Log.h>
2#include <xrpl/ledger/AmendmentTable.h>
3#include <xrpl/ledger/Sandbox.h>
4#include <xrpl/protocol/Feature.h>
5#include <xrpl/protocol/Indexes.h>
6#include <xrpl/protocol/TxFlags.h>
7#include <xrpl/server/NetworkOPs.h>
8#include <xrpl/tx/transactors/system/Change.h>
27 if (account != beast::zero)
29 JLOG(ctx.
j.
warn()) <<
"Change: Bad source id";
35 if (!fee.native() || fee != beast::zero)
37 JLOG(ctx.
j.
warn()) <<
"Change: invalid fee";
44 JLOG(ctx.
j.
warn()) <<
"Change: Bad signature";
50 JLOG(ctx.
j.
warn()) <<
"Change: Bad sequence";
64 JLOG(ctx.
j.
warn()) <<
"Change transaction against open ledger";
130 UNREACHABLE(
"xrpl::Change::doApply : invalid transaction type");
139 XRPL_ASSERT(
account_ == beast::zero,
"xrpl::Change::preCompute : zero account");
151 if (!amendmentObject)
157 STVector256 amendments = amendmentObject->getFieldV256(sfAmendments);
159 if (
std::find(amendments.begin(), amendments.end(), amendment) != amendments.end())
164 bool const gotMajority = (flags & tfGotMajority) != 0;
165 bool const lostMajority = (flags & tfLostMajority) != 0;
167 if (gotMajority && lostMajority)
170 STArray newMajorities(sfMajorities);
173 if (amendmentObject->isFieldPresent(sfMajorities))
175 STArray const& oldMajorities = amendmentObject->getFieldArray(sfMajorities);
176 for (
auto const& majority : oldMajorities)
178 if (majority.getFieldH256(sfAmendment) == amendment)
192 if (!found && lostMajority)
199 auto& entry = newMajorities.
back();
200 entry[sfAmendment] = amendment;
203 if (!
ctx_.
registry.get().getAmendmentTable().isSupported(amendment))
205 JLOG(
j_.
warn()) <<
"Unsupported amendment " << amendment <<
" received a majority.";
208 else if (!lostMajority)
211 amendments.push_back(amendment);
212 amendmentObject->setFieldV256(sfAmendments, amendments);
214 ctx_.
registry.get().getAmendmentTable().enable(amendment);
216 if (!
ctx_.
registry.get().getAmendmentTable().isSupported(amendment))
218 JLOG(
j_.
error()) <<
"Unsupported amendment " << amendment
219 <<
" activated: server blocked.";
224 if (newMajorities.
empty())
226 amendmentObject->makeFieldAbsent(sfMajorities);
230 amendmentObject->setFieldArray(sfMajorities, newMajorities);
251 feeObject->at(field) = tx[field];
256 set(feeObject,
ctx_.
tx, sfReserveBaseDrops);
257 set(feeObject,
ctx_.
tx, sfReserveIncrementDrops);
259 feeObject->makeFieldAbsent(sfBaseFee);
260 feeObject->makeFieldAbsent(sfReferenceFeeUnits);
261 feeObject->makeFieldAbsent(sfReserveBase);
262 feeObject->makeFieldAbsent(sfReserveIncrement);
267 set(feeObject,
ctx_.
tx, sfReferenceFeeUnits);
269 set(feeObject,
ctx_.
tx, sfReserveIncrement);
274 JLOG(
j_.
warn()) <<
"Fees have been changed";
283 JLOG(
j_.
warn()) <<
"N-UNL: applyUNLModify, not a flag ledger, seq=" <<
view().
seq();
291 JLOG(
j_.
warn()) <<
"N-UNL: applyUNLModify, wrong Tx format.";
297 if (seq !=
view().seq())
299 JLOG(
j_.
warn()) <<
"N-UNL: applyUNLModify, wrong ledger seq=" << seq;
306 JLOG(
j_.
warn()) <<
"N-UNL: applyUNLModify, bad validator key";
310 JLOG(
j_.
info()) <<
"N-UNL: applyUNLModify, " << (disabling ?
"ToDisable" :
"ToReEnable")
311 <<
" seq=" << seq <<
" validator data:" <<
strHex(validator);
321 bool const found = [&] {
322 if (negUnlObject->isFieldPresent(sfDisabledValidators))
324 auto const& negUnl = negUnlObject->getFieldArray(sfDisabledValidators);
325 for (
auto const& v : negUnl)
327 if (v.isFieldPresent(sfPublicKey) && v.getFieldVL(sfPublicKey) == validator)
337 if (negUnlObject->isFieldPresent(sfValidatorToDisable))
339 JLOG(
j_.
warn()) <<
"N-UNL: applyUNLModify, already has ToDisable";
344 if (negUnlObject->isFieldPresent(sfValidatorToReEnable))
346 if (negUnlObject->getFieldVL(sfValidatorToReEnable) == validator)
348 JLOG(
j_.
warn()) <<
"N-UNL: applyUNLModify, ToDisable is same as ToReEnable";
356 JLOG(
j_.
warn()) <<
"N-UNL: applyUNLModify, ToDisable already in negative UNL";
360 negUnlObject->setFieldVL(sfValidatorToDisable, validator);
365 if (negUnlObject->isFieldPresent(sfValidatorToReEnable))
367 JLOG(
j_.
warn()) <<
"N-UNL: applyUNLModify, already has ToReEnable";
372 if (negUnlObject->isFieldPresent(sfValidatorToDisable))
374 if (negUnlObject->getFieldVL(sfValidatorToDisable) == validator)
376 JLOG(
j_.
warn()) <<
"N-UNL: applyUNLModify, ToReEnable is same as ToDisable";
384 JLOG(
j_.
warn()) <<
"N-UNL: applyUNLModify, ToReEnable is not in negative UNL";
388 negUnlObject->setFieldVL(sfValidatorToReEnable, validator);
std::reference_wrapper< ServiceRegistry > registry
virtual void update(std::shared_ptr< SLE > const &sle)=0
Indicate changes to a peeked SLE.
virtual void insert(std::shared_ptr< SLE > const &sle)=0
Insert a new state SLE.
virtual std::shared_ptr< SLE > peek(Keylet const &k)=0
Prepare to modify the SLE associated with key.
static TER preclaim(PreclaimContext const &ctx)
void preCompute() override
virtual Rules const & rules() const =0
Returns the tx processing rules.
NetClock::time_point parentCloseTime() const
Returns the close time of the previous ledger.
virtual bool open() const =0
Returns true if this reflects an open ledger.
LedgerIndex seq() const
Returns the sequence number of the base ledger.
bool enabled(uint256 const &feature) const
Returns true if a feature is enabled.
void push_back(STObject const &object)
Blob getFieldVL(SField const &field) const
unsigned char getFieldU8(SField const &field) const
std::uint32_t getFieldU32(SField const &field) const
bool isFieldPresent(SField const &field) const
uint256 getFieldH256(SField const &field) const
static STObject makeInnerObject(SField const &name)
AccountID getAccountID(SField const &field) const
STAmount const & getFieldAmount(SField const &field) const
std::uint32_t getFlags() const
static Blob getSignature(STObject const &sigObject)
TxType getTxnType() const
Blob getSigningPubKey() const
Keylet const & negativeUNL() noexcept
The (fixed) index of the object containing the ledger negativeUNL.
Keylet const & amendments() noexcept
The index of the amendment table.
Keylet const & fees() noexcept
The (fixed) index of the object containing the ledger fees.
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
bool set(T &target, std::string const &name, Section const §ion)
Set a value from a configuration Section If the named value is not found or doesn't parse as a T,...
bool isFlagLedger(LedgerIndex seq)
Returns true if the given ledgerIndex is a flag ledgerIndex.
std::string strHex(FwdIt begin, FwdIt end)
std::optional< KeyType > publicKeyType(Slice const &slice)
Returns the type of public key.
NotTEC preflight0(PreflightContext const &ctx, std::uint32_t flagMask)
Performs early sanity checks on the txid and flags.
std::enable_if_t< std::is_same< T, char >::value||std::is_same< T, unsigned char >::value, Slice > makeSlice(std::array< T, N > const &a)
State information when determining if a tx is likely to claim a fee.
State information when preflighting a tx.
T time_since_epoch(T... args)