#pragma once #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace xrpl { /** * Open ledger construction tag. * * Views constructed with this tag will have the * rules of open ledgers applied during transaction * processing. */ inline constexpr struct OpenLedgerT { explicit constexpr OpenLedgerT() = default; } kOpenLedger{}; /** * Batch view construction tag. * * Views constructed with this tag are part of a stack of views * used during batch transaction application. */ inline constexpr struct BatchViewT { explicit constexpr BatchViewT() = default; } kBatchView{}; //------------------------------------------------------------------------------ /** * Writable ledger view that accumulates state and tx changes. * * @note Presented as ReadView to clients. */ class OpenView final : public ReadView, public TxsRawView { private: // Initial size for the monotonic_buffer_resource used for allocations // The size was chosen from the old `qalloc` code (which this replaces). // It is unclear how the size initially chosen in qalloc. static constexpr size_t kInitialBufferSize = kilobytes(256); class TxsIterImpl; struct TxData { std::shared_ptr txn; std::shared_ptr meta; // Constructor needed for emplacement in std::map TxData( std::shared_ptr const& txn, std::shared_ptr const& meta) : txn(txn), meta(meta) { } }; // List of tx, key order // Use boost::pmr functionality instead of std::pmr // functions b/c clang does not support pmr yet (as-of 9/2020) using txs_map = std::map< key_type, TxData, std::less<>, boost::container::pmr::polymorphic_allocator>>; // monotonic_resource_ must outlive `items_`. Make a pointer so it may be // easily moved. std::unique_ptr monotonicResource_; txs_map txs_; Rules rules_; LedgerHeader header_; ReadView const* base_; detail::RawStateTable items_; std::shared_ptr hold_; /** * In batch mode, the number of transactions already executed. */ std::size_t baseTxCount_ = 0; bool open_ = true; public: OpenView() = delete; OpenView& operator=(OpenView&&) = delete; OpenView& operator=(OpenView const&) = delete; OpenView(OpenView&&) = default; /** * Construct a shallow copy. * * Effects: * * Creates a new object with a copy of * the modification state table. * * The objects managed by shared pointers are * not duplicated but shared between instances. * Since the SLEs are immutable, calls on the * RawView interface cannot break invariants. */ OpenView(OpenView const&); /** * Construct an open ledger view. * * Effects: * * The sequence number is set to the * sequence number of parent plus one. * * The parentCloseTime is set to the * closeTime of parent. * * If `hold` is not nullptr, retains * ownership of a copy of `hold` until * the MetaView is destroyed. * * Calls to rules() will return the * rules provided on construction. * * The tx list starts empty and will contain * all newly inserted tx. */ OpenView( OpenLedgerT, ReadView const* base, Rules rules, std::shared_ptr hold = nullptr); OpenView(OpenLedgerT, Rules const& rules, std::shared_ptr const& base) : OpenView(kOpenLedger, &*base, rules, base) { } OpenView(BatchViewT, OpenView& base) : OpenView(std::addressof(base)) { baseTxCount_ = base.txCount(); } /** * Construct a new last closed ledger. * * Effects: * * The LedgerHeader is copied from the base. * * The rules are inherited from the base. * * The tx list starts empty and will contain * all newly inserted tx. */ OpenView(ReadView const* base, std::shared_ptr hold = nullptr); /** * Returns true if this reflects an open ledger. */ bool open() const override { return open_; } /** * Return the number of tx inserted since creation. * * This is used to set the "apply ordinal" * when calculating transaction metadata. */ std::size_t txCount() const; /** * Apply changes. */ void apply(TxsRawView& to) const; // ReadView LedgerHeader const& header() const override; Fees const& fees() const override; Rules const& rules() const override; bool exists(Keylet const& k) const override; std::optional succ(key_type const& key, std::optional const& last = std::nullopt) const override; SLE::const_pointer read(Keylet const& k) const override; std::unique_ptr slesBegin() const override; std::unique_ptr slesEnd() const override; std::unique_ptr slesUpperBound(uint256 const& key) const override; std::unique_ptr txsBegin() const override; std::unique_ptr txsEnd() const override; bool txExists(key_type const& key) const override; tx_type txRead(key_type const& key) const override; // RawView void rawErase(SLE::ref sle) override; void rawInsert(SLE::ref sle) override; void rawReplace(SLE::ref sle) override; void rawDestroyXRP(XRPAmount const& fee) override; // TxsRawView void rawTxInsert( key_type const& key, std::shared_ptr const& txn, std::shared_ptr const& metaData) override; }; } // namespace xrpl