Files
rippled/src/test/csf/Tx.h
Bart 1d42c4f6de refactor: Remove unnecessary copyright notices already covered by LICENSE.md (#5929)
Per XLS-0095, we are taking steps to rename ripple(d) to xrpl(d).

This change specifically removes all copyright notices referencing Ripple, XRPLF, and certain affiliated contributors upon mutual agreement, so the notice in the LICENSE.md file applies throughout. Copyright notices referencing external contributions remain as-is. Duplicate verbiage is also removed.
2025-11-04 08:33:42 +00:00

216 lines
4.1 KiB
C++

#ifndef XRPL_TEST_CSF_TX_H_INCLUDED
#define XRPL_TEST_CSF_TX_H_INCLUDED
#include <xrpl/beast/hash/hash_append.h>
#include <xrpl/beast/hash/uhash.h>
#include <boost/container/flat_set.hpp>
#include <boost/iterator/function_output_iterator.hpp>
#include <algorithm>
#include <map>
#include <ostream>
#include <sstream>
#include <string>
#include <type_traits>
namespace ripple {
namespace test {
namespace csf {
//! A single transaction
class Tx
{
public:
using ID = std::uint32_t;
Tx(ID i) : id_{i}
{
}
template <typename T, typename = std::enable_if_t<std::is_same_v<T, Tx>>>
Tx(T const* t) : id_{t->id_}
{
}
ID const&
id() const
{
return id_;
}
bool
operator<(Tx const& o) const
{
return id_ < o.id_;
}
bool
operator==(Tx const& o) const
{
return id_ == o.id_;
}
private:
ID id_;
};
//!-------------------------------------------------------------------------
//! All sets of Tx are represented as a flat_set for performance.
using TxSetType = boost::container::flat_set<Tx>;
//! TxSet is a set of transactions to consider including in the ledger
class TxSet
{
public:
using ID = beast::uhash<>::result_type;
using Tx = csf::Tx;
static ID
calcID(TxSetType const& txs)
{
return beast::uhash<>{}(txs);
}
class MutableTxSet
{
friend class TxSet;
TxSetType txs_;
public:
MutableTxSet(TxSet const& s) : txs_{s.txs_}
{
}
bool
insert(Tx const& t)
{
return txs_.insert(t).second;
}
bool
erase(Tx::ID const& txId)
{
return txs_.erase(Tx{txId}) > 0;
}
};
TxSet() = default;
TxSet(TxSetType const& s) : txs_{s}, id_{calcID(txs_)}
{
}
TxSet(MutableTxSet&& m) : txs_{std::move(m.txs_)}, id_{calcID(txs_)}
{
}
bool
exists(Tx::ID const txId) const
{
auto it = txs_.find(Tx{txId});
return it != txs_.end();
}
Tx const*
find(Tx::ID const& txId) const
{
auto it = txs_.find(Tx{txId});
if (it != txs_.end())
return &(*it);
return nullptr;
}
TxSetType const&
txs() const
{
return txs_;
}
ID
id() const
{
return id_;
}
/** @return Map of Tx::ID that are missing. True means
it was in this set and not other. False means
it was in the other set and not this
*/
std::map<Tx::ID, bool>
compare(TxSet const& other) const
{
std::map<Tx::ID, bool> res;
auto populate_diffs = [&res](auto const& a, auto const& b, bool s) {
auto populator = [&](auto const& tx) { res[tx.id()] = s; };
std::set_difference(
a.begin(),
a.end(),
b.begin(),
b.end(),
boost::make_function_output_iterator(std::ref(populator)));
};
populate_diffs(txs_, other.txs_, true);
populate_diffs(other.txs_, txs_, false);
return res;
}
private:
//! The set contains the actual transactions
TxSetType txs_;
//! The unique ID of this tx set
ID id_;
};
//------------------------------------------------------------------------------
// Helper functions for debug printing
inline std::ostream&
operator<<(std::ostream& o, Tx const& t)
{
return o << t.id();
}
template <class T>
inline std::ostream&
operator<<(std::ostream& o, boost::container::flat_set<T> const& ts)
{
o << "{ ";
bool do_comma = false;
for (auto const& t : ts)
{
if (do_comma)
o << ", ";
else
do_comma = true;
o << t;
}
o << " }";
return o;
}
inline std::string
to_string(TxSetType const& txs)
{
std::stringstream ss;
ss << txs;
return ss.str();
}
template <class Hasher>
inline void
hash_append(Hasher& h, Tx const& tx)
{
using beast::hash_append;
hash_append(h, tx.id());
}
} // namespace csf
} // namespace test
} // namespace ripple
#endif