Files
rippled/src/test/csf/CollectorRef.h
Brad Chase 2c13d9eb57 Redesign CSF framework (RIPD-1361):
- Separate `Scheduler` from `BasicNetwork`.
- Add an event/collector framework for monitoring invariants and calculating statistics.
- Allow distinct network and trust connections between Peers.
- Add a simple routing strategy to support broadcasting arbitrary messages.
- Add a common directed graph (`Digraph`) class for representing network and trust topologies.
- Add a `PeerGroup` class for simpler specification of the trust and network topologies.
- Add a `LedgerOracle` class to ensure distinct ledger histories and simplify branch checking.
- Add a `Submitter` to send transactions in at fixed or random intervals to fixed or random peers.

Co-authored-by: Joseph McGee
2017-12-01 14:15:04 -05:00

347 lines
9.1 KiB
C++

//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2012-2017 Ripple Labs Inc
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef RIPPLE_TEST_CSF_COLLECTOREF_H_INCLUDED
#define RIPPLE_TEST_CSF_COLLECTOREF_H_INCLUDED
#include <test/csf/events.h>
#include <test/csf/SimTime.h>
namespace ripple {
namespace test {
namespace csf {
/** Holds a type-erased reference to an arbitray collector.
A collector is any class that implements
on(NodeID, SimTime, Event)
for all events emitted by a Peer.
This class is used to type-erase the actual collector used by each peer in
the simulation. The idea is to compose complicated and typed collectors using
the helpers in collectors.h, then only type erase at the higher-most level
when adding to the simulation.
The example code below demonstrates the reason for storing the collector
as a reference. The collector's lifetime will generally be be longer than
the simulation; perhaps several simulations are run for a single collector
instance. The collector potentially stores lots of data as well, so the
simulation needs to point to the single instance, rather than requiring
collectors to manage copying that data efficiently in their design.
@code
// Initialize a specific collector that might write to a file.
SomeFancyCollector collector{"out.file"};
// Setup your simulation
Sim sim(trustgraph, topology, collector);
// Run the simulation
sim.run(100);
// do any reported related to the collector
collector.report();
@endcode
@note If a new event type is added, it needs to be added to the interfaces
below.
*/
class CollectorRef
{
using tp = SimTime;
// Interface for type-erased collector instance
struct ICollector
{
virtual ~ICollector() = default;
virtual void
on(PeerID node, tp when, Share<Tx> const&) = 0;
virtual void
on(PeerID node, tp when, Share<TxSet> const&) = 0;
virtual void
on(PeerID node, tp when, Share<Validation> const&) = 0;
virtual void
on(PeerID node, tp when, Share<Ledger> const&) = 0;
virtual void
on(PeerID node, tp when, Share<Proposal> const&) = 0;
virtual void
on(PeerID node, tp when, Receive<Tx> const&) = 0;
virtual void
on(PeerID node, tp when, Receive<TxSet> const&) = 0;
virtual void
on(PeerID node, tp when, Receive<Validation> const&) = 0;
virtual void
on(PeerID node, tp when, Receive<Ledger> const&) = 0;
virtual void
on(PeerID node, tp when, Receive<Proposal> const&) = 0;
virtual void
on(PeerID node, tp when, Relay<Tx> const&) = 0;
virtual void
on(PeerID node, tp when, Relay<TxSet> const&) = 0;
virtual void
on(PeerID node, tp when, Relay<Validation> const&) = 0;
virtual void
on(PeerID node, tp when, Relay<Ledger> const&) = 0;
virtual void
on(PeerID node, tp when, Relay<Proposal> const&) = 0;
virtual void
on(PeerID node, tp when, SubmitTx const&) = 0;
virtual void
on(PeerID node, tp when, StartRound const&) = 0;
virtual void
on(PeerID node, tp when, CloseLedger const&) = 0;
virtual void
on(PeerID node, tp when, AcceptLedger const&) = 0;
virtual void
on(PeerID node, tp when, WrongPrevLedger const&) = 0;
virtual void
on(PeerID node, tp when, FullyValidateLedger const&) = 0;
};
// Bridge between type-ful collector T and type erased instance
template <class T>
class Any final : public ICollector
{
T & t_;
public:
Any(T & t) : t_{t}
{
}
// Can't copy
Any(Any const & ) = delete;
Any& operator=(Any const & ) = delete;
Any(Any && ) = default;
Any& operator=(Any && ) = default;
virtual void
on(PeerID node, tp when, Share<Tx> const& e) override
{
t_.on(node, when, e);
}
virtual void
on(PeerID node, tp when, Share<TxSet> const& e) override
{
t_.on(node, when, e);
}
virtual void
on(PeerID node, tp when, Share<Validation> const& e) override
{
t_.on(node, when, e);
}
virtual void
on(PeerID node, tp when, Share<Ledger> const& e) override
{
t_.on(node, when, e);
}
virtual void
on(PeerID node, tp when, Share<Proposal> const& e) override
{
t_.on(node, when, e);
}
void
on(PeerID node, tp when, Receive<Tx> const& e) override
{
t_.on(node, when, e);
}
virtual void
on(PeerID node, tp when, Receive<TxSet> const& e) override
{
t_.on(node, when, e);
}
virtual void
on(PeerID node, tp when, Receive<Validation> const& e) override
{
t_.on(node, when, e);
}
virtual void
on(PeerID node, tp when, Receive<Ledger> const& e) override
{
t_.on(node, when, e);
}
virtual void
on(PeerID node, tp when, Receive<Proposal> const& e) override
{
t_.on(node, when, e);
}
void
on(PeerID node, tp when, Relay<Tx> const& e) override
{
t_.on(node, when, e);
}
virtual void
on(PeerID node, tp when, Relay<TxSet> const& e) override
{
t_.on(node, when, e);
}
virtual void
on(PeerID node, tp when, Relay<Validation> const& e) override
{
t_.on(node, when, e);
}
virtual void
on(PeerID node, tp when, Relay<Ledger> const& e) override
{
t_.on(node, when, e);
}
virtual void
on(PeerID node, tp when, Relay<Proposal> const& e) override
{
t_.on(node, when, e);
}
virtual void
on(PeerID node, tp when, SubmitTx const& e) override
{
t_.on(node, when, e);
}
virtual void
on(PeerID node, tp when, StartRound const& e) override
{
t_.on(node, when, e);
}
virtual void
on(PeerID node, tp when, CloseLedger const& e) override
{
t_.on(node, when, e);
}
virtual void
on(PeerID node, tp when, AcceptLedger const& e) override
{
t_.on(node, when, e);
}
virtual void
on(PeerID node, tp when, WrongPrevLedger const& e) override
{
t_.on(node, when, e);
}
virtual void
on(PeerID node, tp when, FullyValidateLedger const& e) override
{
t_.on(node, when, e);
}
};
std::unique_ptr<ICollector> impl_;
public:
template <class T>
CollectorRef(T& t) : impl_{new Any<T>(t)}
{
}
// Non-copyable
CollectorRef(CollectorRef const& c) = delete;
CollectorRef& operator=(CollectorRef& c) = delete;
CollectorRef(CollectorRef&&) = default;
CollectorRef& operator=(CollectorRef&&) = default;
template <class E>
void
on(PeerID node, tp when, E const& e)
{
impl_->on(node, when, e);
}
};
/** A container of CollectorRefs
A set of CollectorRef instances that process the same events. An event is
processed by collectors in the order the collectors were added.
This class type-erases the collector instances. By contract, the
Collectors/collectors class/helper in collectors.h are not type erased and
offer an opportunity for type transformations and combinations with
improved compiler optimizations.
*/
class CollectorRefs
{
std::vector<CollectorRef> collectors_;
public:
template <class Collector>
void add(Collector & collector)
{
collectors_.emplace_back(collector);
}
template <class E>
void
on(PeerID node, SimTime when, E const& e)
{
for (auto & c : collectors_)
{
c.on(node, when, e);
}
}
};
} // namespace csf
} // namespace test
} // namespace ripple
#endif