Skip to content

Commit 3cbdf81

Browse files
authored
Miscellaneous refactors and updates (#5590)
- Added a new Invariant: `ValidPseudoAccounts` which checks that all pseudo-accounts behave consistently through creation and updates, and that no "real" accounts look like pseudo-accounts (which means they don't have a 0 sequence). - `to_short_string(base_uint)`. Like `to_string`, but only returns the first 8 characters. (Similar to how a git commit ID can be abbreviated.) Used as a wrapped sink to prefix most transaction-related messages. More can be added later. - `XRPL_ASSERT_PARTS`. Convenience wrapper for `XRPL_ASSERT`, which takes the `function` and `description` as separate parameters. - `SField::sMD_PseudoAccount`. Metadata option for `SField` definitions to indicate that the field, if set in an `AccountRoot` indicates that account is a pseudo-account. Removes the need for hard-coded field lists all over the place. Added the flag to `AMMID` and `VaultID`. - Added functionality to `SField` ctor to detect both code and name collisions using asserts. And require all SFields to have a name - Convenience type aliases `STLedgerEntry::const_pointer` and `STLedgerEntry::const_ref`. (`SLE` is an alias to `STLedgerEntry`.) - Generalized `feeunit.h` (`TaggedFee`) into `unit.h` (`ValueUnit`) and added new "BIPS"-related tags for future use. Also refactored the type restrictions to use Concepts. - Restructured `transactions.macro` to do two big things 1. Include the `#include` directives for transactor header files directly in the macro file. Removes the need to update `applySteps.cpp` and the resulting conflicts. 2. Added a `privileges` parameter to the `TRANSACTION` macro, which specifies some of the operations a transaction is allowed to do. These `privileges` are enforced by invariant checks. Again, removed the need to update scattered lists of transaction types in various checks. - Unit tests: 1. Moved more helper functions into `TestHelpers.h` and `.cpp`. 2. Cleaned up the namespaces to prevent / mitigate random collisions and ambiguous symbols, particularly in unity builds. 3. Generalized `Env::balance` to add support for `MPTIssue` and `Asset`. 4. Added a set of helper classes to simplify `Env` transaction parameter classes: `JTxField`, `JTxFieldWrapper`, and a bunch of classes derived or aliased from it. For an example of how awesome it is, check the changes `src/test/jtx/escrow.h` for how much simpler the definitions are for `finish_time`, `cancel_time`, `condition`, and `fulfillment`. 5. Generalized several of the amount-related helper classes to understand `Asset`s. 6. `env.balance` for an MPT issuer will return a negative number (or 0) for consistency with IOUs.
1 parent bd834c8 commit 3cbdf81

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

65 files changed

+2149
-1211
lines changed

include/xrpl/basics/base_uint.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -632,6 +632,16 @@ to_string(base_uint<Bits, Tag> const& a)
632632
return strHex(a.cbegin(), a.cend());
633633
}
634634

635+
template <std::size_t Bits, class Tag>
636+
inline std::string
637+
to_short_string(base_uint<Bits, Tag> const& a)
638+
{
639+
static_assert(
640+
base_uint<Bits, Tag>::bytes > 4,
641+
"For 4 bytes or less, use a native type");
642+
return strHex(a.cbegin(), a.cbegin() + 4) + "...";
643+
}
644+
635645
template <std::size_t Bits, class Tag>
636646
inline std::ostream&
637647
operator<<(std::ostream& out, base_uint<Bits, Tag> const& u)

include/xrpl/basics/safe_cast.h

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,8 @@ namespace ripple {
2828
// the destination can hold all values of the source. This is particularly
2929
// handy when the source or destination is an enumeration type.
3030

31-
template <class Dest, class Src>
32-
static constexpr bool is_safetocasttovalue_v =
33-
(std::is_integral_v<Src> && std::is_integral_v<Dest>) &&
31+
template <class Src, class Dest>
32+
concept SafeToCast = (std::is_integral_v<Src> && std::is_integral_v<Dest>) &&
3433
(std::is_signed<Src>::value || std::is_unsigned<Dest>::value) &&
3534
(std::is_signed<Src>::value != std::is_signed<Dest>::value
3635
? sizeof(Dest) > sizeof(Src)
@@ -78,7 +77,7 @@ inline constexpr std::
7877
unsafe_cast(Src s) noexcept
7978
{
8079
static_assert(
81-
!is_safetocasttovalue_v<Dest, Src>,
80+
!SafeToCast<Src, Dest>,
8281
"Only unsafe if casting signed to unsigned or "
8382
"destination is too small");
8483
return static_cast<Dest>(s);

include/xrpl/beast/utility/instrumentation.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,16 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
3939
#endif
4040

4141
#define XRPL_ASSERT ALWAYS_OR_UNREACHABLE
42+
#define XRPL_ASSERT_PARTS(cond, function, description, ...) \
43+
XRPL_ASSERT(cond, function " : " description)
4244

4345
// How to use the instrumentation macros:
4446
//
4547
// * XRPL_ASSERT if cond must be true but the line might not be reached during
4648
// fuzzing. Same like `assert` in normal use.
49+
// * XRPL_ASSERT_PARTS is for convenience, and works like XRPL_ASSERT, but
50+
// splits the message param into "function" and "description", then joins
51+
// them with " : " before passing to XRPL_ASSERT.
4752
// * ALWAYS if cond must be true _and_ the line must be reached during fuzzing.
4853
// Same like `assert` in normal use.
4954
// * REACHABLE if the line must be reached during fuzzing

include/xrpl/ledger/View.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -561,12 +561,28 @@ createPseudoAccount(
561561
[[nodiscard]] bool
562562
isPseudoAccount(std::shared_ptr<SLE const> sleAcct);
563563

564+
// Returns the list of fields that define an ACCOUNT_ROOT as a pseudo-account if
565+
// set
566+
// Pseudo-account designator fields MUST be maintained by including the
567+
// SField::sMD_PseudoAccount flag in the SField definition. (Don't forget to
568+
// "| SField::sMD_Default"!) The fields do NOT need to be amendment-gated,
569+
// since a non-active amendment will not set any field, by definition.
570+
// Specific properties of a pseudo-account are NOT checked here, that's what
571+
// InvariantCheck is for.
572+
[[nodiscard]] std::vector<SField const*> const&
573+
getPseudoAccountFields();
574+
564575
[[nodiscard]] inline bool
565576
isPseudoAccount(ReadView const& view, AccountID accountId)
566577
{
567578
return isPseudoAccount(view.read(keylet::account(accountId)));
568579
}
569580

581+
[[nodiscard]] TER
582+
canAddHolding(ReadView const& view, Asset const& asset);
583+
584+
/// Any transactors that call addEmptyHolding() in doApply must call
585+
/// canAddHolding() in preflight with the same View and Asset
570586
[[nodiscard]] TER
571587
addEmptyHolding(
572588
ApplyView& view,

0 commit comments

Comments
 (0)