diff --git a/Builds/VisualStudio2012/RippleD.vcxproj b/Builds/VisualStudio2012/RippleD.vcxproj index 3ca3b980aa..65a2a23c15 100644 --- a/Builds/VisualStudio2012/RippleD.vcxproj +++ b/Builds/VisualStudio2012/RippleD.vcxproj @@ -1621,6 +1621,7 @@ + diff --git a/Builds/VisualStudio2012/RippleD.vcxproj.filters b/Builds/VisualStudio2012/RippleD.vcxproj.filters index f96cb148ea..0f34552a5b 100644 --- a/Builds/VisualStudio2012/RippleD.vcxproj.filters +++ b/Builds/VisualStudio2012/RippleD.vcxproj.filters @@ -2214,6 +2214,9 @@ [1] Ripple\peerfinder\impl + + [1] Ripple\json\api + diff --git a/src/beast/Builds/VisualStudio2012/beast.vcxproj b/src/beast/Builds/VisualStudio2012/beast.vcxproj index 51c503376a..c63d3621da 100644 --- a/src/beast/Builds/VisualStudio2012/beast.vcxproj +++ b/src/beast/Builds/VisualStudio2012/beast.vcxproj @@ -184,6 +184,7 @@ + @@ -569,6 +570,12 @@ true true + + true + true + true + true + true true diff --git a/src/beast/Builds/VisualStudio2012/beast.vcxproj.filters b/src/beast/Builds/VisualStudio2012/beast.vcxproj.filters index e6f5ed48b3..6b718eb5c9 100644 --- a/src/beast/Builds/VisualStudio2012/beast.vcxproj.filters +++ b/src/beast/Builds/VisualStudio2012/beast.vcxproj.filters @@ -1245,6 +1245,9 @@ beast + + beast\utility + @@ -1793,6 +1796,9 @@ beast\boost + + beast\utility\impl + diff --git a/src/beast/beast/Utility.h b/src/beast/beast/Utility.h index 403f78ee31..952d0c2252 100644 --- a/src/beast/beast/Utility.h +++ b/src/beast/beast/Utility.h @@ -25,6 +25,7 @@ #include "utility/Error.h" #include "utility/Journal.h" #include "utility/LeakChecked.h" +#include "utility/PropertyStream.h" #include "utility/StaticObject.h" #endif diff --git a/src/beast/beast/utility/PropertyStream.h b/src/beast/beast/utility/PropertyStream.h new file mode 100644 index 0000000000..a8fb8956c6 --- /dev/null +++ b/src/beast/beast/utility/PropertyStream.h @@ -0,0 +1,263 @@ +//------------------------------------------------------------------------------ +/* + This file is part of Beast: https://github.com/vinniefalco/Beast + Copyright 2013, Vinnie Falco + + 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 BEAST_UTILITY_PROPERTYSTREAM_H_INCLUDED +#define BEAST_UTILITY_PROPERTYSTREAM_H_INCLUDED + +#include "../CStdInt.h" +#include "../Uncopyable.h" +#include "../intrusive/List.h" +#include "../threads/SharedData.h" + +#include + +namespace beast { + +/** An output stream to procedurally generate an abstract property tree. */ +class PropertyStream +{ +private: + class Proxy; + +public: + class ScopedArray; + class ScopedObject; + class Source; + +private: + class Item : public List ::Node + { + public: + explicit Item (Source* source); + Source& source() const; + Source* operator-> () const; + Source& operator* () const; + private: + Source* m_source; + }; + +public: + //-------------------------------------------------------------------------- + + class Sink : Uncopyable + { + public: + // Object output + // + // Default implementations convert to string + // Json doesn't support 64 bit so we convert these to string + // if they are outside the range of the corresponding 32 bit int + virtual void begin_object (std::string const& key) = 0; + virtual void end_object () = 0; + template + void lexical_write (std::string const &key, Value value) + { + std::stringstream ss; + ss << value; + write (key, ss.str()); + } + virtual void write (std::string const& key, int32 value); + virtual void write (std::string const& key, uint32 value); + virtual void write (std::string const& key, int64 value); + virtual void write (std::string const& key, uint64 value); + virtual void write (std::string const& key, std::string const& value) = 0; + + // Array output + // + virtual void begin_array (std::string const& key) = 0; + virtual void end_array () = 0; + template + void lexical_write (Value value) + { + std::stringstream ss; + ss << value; + write (ss.str()); + } + virtual void write ( int32 value); + virtual void write (uint32 value); + virtual void write ( int64 value); + virtual void write (uint64 value); + virtual void write (std::string const& value) = 0; + }; + + //-------------------------------------------------------------------------- + + PropertyStream (); + PropertyStream (Sink& sink); + PropertyStream (PropertyStream const& other); + PropertyStream& operator= (PropertyStream const& other); + + /** Object output. + */ + /** @{ */ + void begin_object (std::string const& key) const; + void end_object () const; + + template + void write (std::string const& key, Value value) const + { + m_sink->write (key, value); + } + + template + void write (Key key, Value value) const + { + std::stringstream ss; + ss << key; + write (ss.str(), value); + } + + Proxy operator[] (std::string const& key) const; + + template + Proxy operator[] (Key key) const; + + /** @} */ + + /** Array output. + */ + /** @{ */ + void begin_array (std::string const& key) const; + void end_array () const; + + template + void append (Value value) const + { m_sink->write (value); } + + template + PropertyStream const& operator<< (Value value) const + { append (value); return &this; } + /** @} */ + +private: + static Sink& nullSink(); + + Sink* m_sink; +}; + +//------------------------------------------------------------------------------ + +class PropertyStream::Proxy +{ +private: + PropertyStream m_stream; + std::string m_key; + +public: + Proxy (PropertyStream stream, std::string const& key); + + template + Proxy& operator= (Value value) + { m_stream.write (m_key, value); return *this; } +}; + +//------------------------------------------------------------------------------ + +template +PropertyStream::Proxy PropertyStream::operator[] (Key key) const +{ + std::stringstream ss; + ss << key; + return operator[] (ss.str()); +} + +//------------------------------------------------------------------------------ + +class PropertyStream::ScopedObject +{ +private: + PropertyStream m_stream; + +public: + ScopedObject (std::string const& key, PropertyStream stream); + ~ScopedObject (); +}; + +//------------------------------------------------------------------------------ + +class PropertyStream::ScopedArray +{ +private: + PropertyStream m_stream; + +public: + ScopedArray (std::string const& key, PropertyStream stream); + ~ScopedArray (); +}; + +//------------------------------------------------------------------------------ + +/** Subclasses can be called to write to a stream and have children. */ +class PropertyStream::Source : public Uncopyable +{ +private: + struct State + { + explicit State (Source* source) + : item (source) + , parent (nullptr) + { } + Item item; + Source* parent; + List children; + }; + + typedef SharedData SharedState; + + std::string const m_name; + SharedState m_state; + + void remove (SharedState::Access& state, SharedState::Access& childState); + void removeAll (SharedState::Access& state); + +public: + explicit Source (std::string const& name); + ~Source (); + + /** Add a child source. */ + void add (Source& source); + + /** Add a child source by pointer. + This returns the passed source so it can be conveniently chained + in ctor-initializer lists. + */ + template + Derived* add (Derived* child) + { + add (*static_cast (child)); + return child; + } + + /** Remove a child source. */ + void remove (Source& child); + + /** Remove all child sources. */ + void removeAll (); + + void write (PropertyStream stream, bool includeChildren); + void write (std::string const& path, PropertyStream stream); + + virtual void onWrite (PropertyStream) { } +}; + +//------------------------------------------------------------------------------ + +} + +#endif diff --git a/src/beast/beast/utility/Utility.cpp b/src/beast/beast/utility/Utility.cpp index f66ea5a69a..e2b254bfdb 100644 --- a/src/beast/beast/utility/Utility.cpp +++ b/src/beast/beast/utility/Utility.cpp @@ -28,3 +28,4 @@ #include "impl/Journal.cpp" #include "impl/LeakChecked.cpp" #include "impl/StaticObject.cpp" +#include "impl/PropertyStream.cpp" diff --git a/src/beast/beast/utility/impl/PropertyStream.cpp b/src/beast/beast/utility/impl/PropertyStream.cpp new file mode 100644 index 0000000000..64d1164a1d --- /dev/null +++ b/src/beast/beast/utility/impl/PropertyStream.cpp @@ -0,0 +1,341 @@ +//------------------------------------------------------------------------------ +/* + This file is part of Beast: https://github.com/vinniefalco/Beast + Copyright 2013, Vinnie Falco + + 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. +*/ +//============================================================================== + +#include "../PropertyStream.h" + +#include + +namespace beast { + +PropertyStream::Item::Item (Source* source) + : m_source (source) +{ +} + +PropertyStream::Source& PropertyStream::Item::source() const +{ + return *m_source; +} + +PropertyStream::Source* PropertyStream::Item::operator-> () const +{ + return &source(); +} + +PropertyStream::Source& PropertyStream::Item::operator* () const +{ + return source(); +} + +//------------------------------------------------------------------------------ + +void PropertyStream::Sink::write (std::string const& key, int32 value) +{ + lexical_write (key, value); +} + +void PropertyStream::Sink::write (std::string const& key, uint32 value) +{ + lexical_write (key, value); +} + +void PropertyStream::Sink::write (std::string const& key, int64 value) +{ + if (value <= std::numeric_limits ::max() && + value >= std::numeric_limits ::min()) + { + write (key, int32(value)); + } + else + { + lexical_write (key, value); + } +} + +void PropertyStream::Sink::write (std::string const& key, uint64 value) +{ + if (value <= std::numeric_limits ::max() && + value >= std::numeric_limits ::min()) + { + write (key, uint32(value)); + } + else + { + lexical_write (key, value); + } +} + +void PropertyStream::Sink::write (int32 value) +{ + lexical_write (value); +} + +void PropertyStream::Sink::write (uint32 value) +{ + lexical_write (value); +} + +void PropertyStream::Sink::write (int64 value) +{ + if (value <= std::numeric_limits ::max() && + value >= std::numeric_limits ::min()) + { + write (int32(value)); + } + else + { + lexical_write (value); + } +} + +void PropertyStream::Sink::write (uint64 value) +{ + if (value <= std::numeric_limits ::max() && + value >= std::numeric_limits ::min()) + { + write (uint32(value)); + } + else + { + lexical_write (value); + } +} + +//------------------------------------------------------------------------------ + +PropertyStream::Proxy::Proxy (PropertyStream stream, std::string const& key) + : m_stream (stream) + , m_key (key) +{ +} + +//------------------------------------------------------------------------------ + +PropertyStream::ScopedObject::ScopedObject (std::string const& key, PropertyStream stream) + : m_stream (stream) +{ + m_stream.begin_object (key); +} + +PropertyStream::ScopedObject::~ScopedObject () +{ + m_stream.end_object (); +} + +//------------------------------------------------------------------------------ + +PropertyStream::Source::Source (std::string const& name) + : m_name (name) + , m_state (this) +{ +} + +PropertyStream::Source::~Source () +{ + SharedState::Access state (m_state); + if (state->parent != nullptr) + state->parent->remove (*this); + removeAll (state); +} + +void PropertyStream::Source::remove ( + SharedState::Access& state, SharedState::Access& childState) +{ + bassert (childState->parent == this); + state->children.erase ( + state->children.iterator_to ( + childState->item)); + childState->parent = nullptr; +} + +void PropertyStream::Source::removeAll (SharedState::Access& state) +{ + for (List ::iterator iter (state->children.begin()); + iter != state->children.end();) + { + SharedState::Access childState ((*iter)->m_state); + remove (state, childState); + } +} + +void PropertyStream::Source::add (Source& source) +{ + SharedState::Access state (m_state); + SharedState::Access childState (source.m_state); + bassert (childState->parent == nullptr); + state->children.push_back (childState->item); + childState->parent = this; +} + +void PropertyStream::Source::remove (Source& child) +{ + SharedState::Access state (m_state); + SharedState::Access childState (child.m_state); + remove (state, childState); +} + +void PropertyStream::Source::removeAll () +{ + SharedState::Access state (m_state); + removeAll (state); +} + +void PropertyStream::Source::write (PropertyStream stream, bool includeChildren) +{ + ScopedObject child (m_name, stream); + onWrite (stream); + + if (includeChildren) + { + SharedState::Access state (m_state); + for (List ::iterator iter (state->children.begin()); + iter != state->children.end(); ++iter) + { + (*iter)->write (stream, true); + } + } +} + +void PropertyStream::Source::write (std::string const& path, PropertyStream stream) +{ + struct Parser + { + Parser (std::string const& path) + : m_first (path.begin()) + , m_last (path.end()) + { + } + + std::string next () + { + std::string::const_iterator pos ( + std::find (m_first, m_last, '.')); + std::string const s (m_first, pos); + if (pos != m_last) + m_first = pos + 1; + else + m_first = pos; + return s; + } + + std::string::const_iterator m_first; + std::string::const_iterator m_last; + }; + + //----------------------------------------- + + if (path.empty ()) + { + write (stream, true); + return; + } + + Parser p (path); + Source* source (this); + if (p.next() != source->m_name) + return; + + for (;;) + { + std::string const s (p.next()); + + if (s.empty()) + { + source->write (stream, false); + break; + } + else if (s == "*") + { + source->write (stream, true); + break; + } + else + { + SharedState::Access state (source->m_state); + for (List ::iterator iter (state->children.begin());;) + { + if (iter->source().m_name == s) + { + source = &iter->source(); + break; + } + + if (++iter == state->children.end()) + return; + } + } + } +} + +//------------------------------------------------------------------------------ + +PropertyStream::PropertyStream () + : m_sink (&nullSink()) +{ +} + +PropertyStream::PropertyStream (Sink& sink) + : m_sink (&sink) +{ +} + +PropertyStream::PropertyStream (PropertyStream const& other) + : m_sink (other.m_sink) +{ +} + +PropertyStream& PropertyStream::operator= (PropertyStream const& other) +{ + m_sink = other.m_sink; + return *this; +} + +PropertyStream::Proxy PropertyStream::operator[] (std::string const& key) const +{ + return Proxy (*this, key); +} + +void PropertyStream::begin_object (std::string const& key) const +{ + m_sink->begin_object (key); +} + +void PropertyStream::end_object () const +{ + m_sink->end_object (); +} + +PropertyStream::Sink& PropertyStream::nullSink() +{ + struct NullSink : Sink + { + void begin_object (std::string const&) { } + void end_object () { } + void write (std::string const&, std::string const&) { } + void begin_array (std::string const&) { } + void end_array () { } + void write (std::string const&) { } + }; + + static NullSink sink; + + return sink; +} + +} diff --git a/src/ripple/json/api/JsonPropertyStreamSink.h b/src/ripple/json/api/JsonPropertyStreamSink.h new file mode 100644 index 0000000000..c0a79bf3bd --- /dev/null +++ b/src/ripple/json/api/JsonPropertyStreamSink.h @@ -0,0 +1,97 @@ +//------------------------------------------------------------------------------ +/* + This file is part of rippled: https://github.com/ripple/rippled + Copyright (c) 2012, 2013 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_JSONPROPERTYSTREAMSINK_H_INCLUDED +#define RIPPLE_JSONPROPERTYSTREAMSINK_H_INCLUDED + +#include "beast/beast/utility/PropertyStream.h" + +//#include "json_value.h" // ?? + +namespace ripple { +using namespace beast; + +/** A PropertyStream::Sink which produces a Json::Value. */ +class JsonPropertyStreamSink : public PropertyStream::Sink +{ +public: + explicit JsonPropertyStreamSink (Json::Value& root) + { + m_stack.push_back (&root); + } + + void begin_object (std::string const& key) + { + m_stack.push_back (&((*m_stack.back())[key] = Json::objectValue)); + } + + void end_object () + { + m_stack.pop_back (); + } + + void write (std::string const& key, int32 v) + { + (*m_stack.back())[key] = v; + } + + void write (std::string const& key, uint32 v) + { + (*m_stack.back())[key] = v; + } + + void write (std::string const& key, std::string const& v) + { + (*m_stack.back())[key] = v; + } + + void begin_array (std::string const& key) + { + m_stack.push_back (&((*m_stack.back())[key] = Json::arrayValue)); + } + + void end_array () + { + m_stack.pop_back (); + } + + void write (int32 v) + { + m_stack.back()->append (v); + } + + void write (uint32 v) + { + m_stack.back()->append (v); + } + + void write (std::string const& v) + { + m_stack.back()->append (v); + } + +private: + Json::Value m_value; + std::vector m_stack; +}; + +} + +#endif + diff --git a/src/ripple/json/ripple_json.h b/src/ripple/json/ripple_json.h index f50fc7b69f..3e32f9c402 100644 --- a/src/ripple/json/ripple_json.h +++ b/src/ripple/json/ripple_json.h @@ -17,7 +17,6 @@ */ //============================================================================== - #ifndef RIPPLE_JSON_H_INCLUDED #define RIPPLE_JSON_H_INCLUDED @@ -46,4 +45,6 @@ #include "api/json_reader.h" #include "api/json_writer.h" +#include "api/JsonPropertyStreamSink.h" + #endif diff --git a/src/ripple/peerfinder/api/Manager.h b/src/ripple/peerfinder/api/Manager.h index 1cd6a22f72..c42d7e8299 100644 --- a/src/ripple/peerfinder/api/Manager.h +++ b/src/ripple/peerfinder/api/Manager.h @@ -24,7 +24,9 @@ namespace ripple { namespace PeerFinder { /** Maintains a set of IP addresses used for getting into the network. */ -class Manager : public Stoppable +class Manager + : public Stoppable + , public PropertyStream::Source { protected: explicit Manager (Stoppable& parent); diff --git a/src/ripple/peerfinder/impl/Manager.cpp b/src/ripple/peerfinder/impl/Manager.cpp index d4d1cefa84..dd76d85cd2 100644 --- a/src/ripple/peerfinder/impl/Manager.cpp +++ b/src/ripple/peerfinder/impl/Manager.cpp @@ -290,6 +290,23 @@ public: m_queue.dispatch (bind (&Thread::signalThreadShouldExit, this)); } + //-------------------------------------------------------------------------- + // + // PropertyStream + // + + void onWrite (PropertyStream stream) + { + stream ["peers"] = m_logic.m_slots.peerCount; + stream ["in"] = m_logic.m_slots.inboundCount; + stream ["out"] = m_logic.m_slots.outboundCount; + stream ["out_desired"] = m_logic.m_slots.outDesired; + stream ["in_avail"] = m_logic.m_slots.inboundSlots; + stream ["in_max"] = m_logic.m_slots.inboundSlotsMaximum; + stream ["minutes"] = m_logic.m_slots.uptimeMinutes(); + stream ["round"] = m_logic.m_slots.roundUpwards(); + } + //-------------------------------------------------------------------------- void onDeadlineTimer (DeadlineTimer& timer) @@ -358,7 +375,8 @@ public: //------------------------------------------------------------------------------ Manager::Manager (Stoppable& parent) - : Stoppable ("PeerFinder", parent) + : PropertyStream::Source ("peerfinder") + , Stoppable ("PeerFinder", parent) { } diff --git a/src/ripple/peerfinder/impl/Slots.cpp b/src/ripple/peerfinder/impl/Slots.cpp index c2ed4763f7..54b7148f46 100644 --- a/src/ripple/peerfinder/impl/Slots.cpp +++ b/src/ripple/peerfinder/impl/Slots.cpp @@ -63,7 +63,7 @@ void Slots::update (Config const& config) void Slots::addPeer (Config const& config, bool inbound) { if (peerCount == 0) - startTime = Time::getCurrentTime(); + startTime = RelativeTime::fromStartup(); ++peerCount; if (inbound) @@ -83,15 +83,15 @@ void Slots::dropPeer (Config const& config, bool inbound) --outboundCount; if (peerCount == 0) - startTime = Time (0); + startTime = RelativeTime(0); update (config); } uint32 Slots::uptimeMinutes () const { - if (startTime.isNotNull()) - return (Time::getCurrentTime()-startTime).inMinutes(); + if (startTime.isNotZero()) + return (RelativeTime::fromStartup()-startTime).inMinutes(); return 0; } diff --git a/src/ripple/peerfinder/impl/Slots.h b/src/ripple/peerfinder/impl/Slots.h index d25f3e993b..f3b1ee14e7 100644 --- a/src/ripple/peerfinder/impl/Slots.h +++ b/src/ripple/peerfinder/impl/Slots.h @@ -31,10 +31,9 @@ public: void update (Config const& config); void addPeer (Config const& config, bool inbound); void dropPeer (Config const& config, bool inbound); - uint32 uptimeMinutes () const; // Most recent time when we went from 0 to 1 peers - Time startTime; + RelativeTime startTime; // Current total of connected peers that have HELLOed int peerCount; @@ -54,6 +53,16 @@ public: // The maximum number of incoming slots (calculated) int inboundSlotsMaximum; + // Returns the uptime in minutes + // Uptime is measured from the last we transitioned from not + // being connected to the network, to being connected. + // + uint32 uptimeMinutes () const; + + // Returns `true` if we round fractional slot availability upwards + bool roundUpwards () const + { return m_roundUpwards; } + private: bool m_roundUpwards; }; diff --git a/src/ripple/validators/api/Manager.h b/src/ripple/validators/api/Manager.h index 1c92bfdf2b..970865ac53 100644 --- a/src/ripple/validators/api/Manager.h +++ b/src/ripple/validators/api/Manager.h @@ -28,14 +28,17 @@ namespace Validators { the list of chosen validators is critical to the health of the network. All operations are performed asynchronously on an internal thread. */ -class Manager : public RPC::Service +class Manager : public PropertyStream::Source { +protected: + Manager(); + public: /** Create a new Manager object. @param parent The parent Stoppable. @param journal Where to send log output. */ - static Manager* New (Stoppable& parent, Journal journal); + static Manager* New (Stoppable& stoppableParent, Journal journal); /** Destroy the object. Any pending source fetch operations are aborted. This will block @@ -59,7 +62,7 @@ public: virtual void addStrings (String name, StringArray const& stringArray) = 0; virtual void addFile (File const& file) = 0; - virtual void addStaticSource (Source* source) = 0; + virtual void addStaticSource (Validators::Source* source) = 0; /** @} */ /** Add a live source of validators from a trusted URL. @@ -76,7 +79,7 @@ public: Thread safety: Can be called from any thread. */ - virtual void addSource (Source* source) = 0; + virtual void addSource (Validators::Source* source) = 0; //-------------------------------------------------------------------------- diff --git a/src/ripple/validators/impl/Logic.h b/src/ripple/validators/impl/Logic.h index 626bb0c882..de5d6d4215 100644 --- a/src/ripple/validators/impl/Logic.h +++ b/src/ripple/validators/impl/Logic.h @@ -406,72 +406,6 @@ public: return n; } - //---------------------------------------------------------------------- - // - // RPC Handlers - // - - // Return the current ChosenList as JSON - Json::Value rpcPrint (Json::Value const& args, int cpuPercent) - { - Json::Value results (Json::objectValue); - - Json::Value entries (Json::arrayValue); - { - results ["cpu"] = cpuPercent; - results ["count"] = int(m_validators.size()); - for (ValidatorTable::const_iterator iter (m_validators.begin()); - iter != m_validators.end(); ++iter) - { - Validator const& v (iter->second); - Json::Value entry (Json::objectValue); - Count const count (v.count ()); - - entry ["public"] = iter->first.to_string(); - entry ["received"] = int(count.received); - entry ["expected"] = int(count.expected); - entry ["closed"] = int(count.closed); - entry ["percent"] = count.percent(); - - entries.append (entry); - } - } - results ["validators"] = entries; - - return results; - } - - // Returns the list of sources - Json::Value rpcSources (Json::Value const& arg) - { - Json::Value results (Json::objectValue); - - Json::Value entries (Json::arrayValue); - for (SourceTable::const_iterator iter (m_sources.begin()); - iter != m_sources.end(); ++iter) - { - Json::Value entry (Json::objectValue); - SourceDesc const& desc (*iter); - entry ["name"] = desc.source->name(); - entry ["param"] = desc.source->createParam(); - - Json::Value results (Json::arrayValue); - for (int i = 0; i < desc.results.list.size(); ++i) - { - Json::Value info (Json::objectValue); - info ["key"] = "publicKey"; - info ["label"] = desc.results.list[i].label; - results.append (info); - } - entry ["results"] = results; - - entries.append (entry); - } - results ["sources"] = entries; - - return results; - } - //---------------------------------------------------------------------- // // Ripple interface diff --git a/src/ripple/validators/impl/Manager.cpp b/src/ripple/validators/impl/Manager.cpp index d53a32a277..60550b74a8 100644 --- a/src/ripple/validators/impl/Manager.cpp +++ b/src/ripple/validators/impl/Manager.cpp @@ -167,42 +167,6 @@ public: stopThread (); } - //-------------------------------------------------------------------------- - // - // RPC::Service - // - - Json::Value rpcPrint (Json::Value const& args) - { - int const cpuPercent (std::ceil (m_queue.getUtilizaton() * 100)); - return m_logic.rpcPrint (args, cpuPercent); - } - - Json::Value rpcRebuild (Json::Value const& args) - { - m_queue.dispatch (bind (&Logic::buildChosen, &m_logic)); - Json::Value result; - result ["chosen_list"] = "rebuilding"; - return result; - } - - Json::Value rpcSources (Json::Value const& args) - { - return m_logic.rpcSources(args); - } - - void addRPCHandlers() - { - addRPCHandler ("validators_print", beast::bind ( - &ManagerImp::rpcPrint, this, beast::_1)); - - addRPCHandler ("validators_rebuild", beast::bind ( - &ManagerImp::rpcRebuild, this, beast::_1)); - - addRPCHandler ("validators_sources", beast::bind ( - &ManagerImp::rpcSources, this, beast::_1)); - } - //-------------------------------------------------------------------------- // // Manager @@ -234,7 +198,7 @@ public: addStaticSource (SourceFile::New (file)); } - void addStaticSource (Source* source) + void addStaticSource (Validators::Source* source) { #if RIPPLE_USE_VALIDATORS m_queue.dispatch (bind (&Logic::addStatic, &m_logic, source)); @@ -248,7 +212,7 @@ public: addSource (SourceURL::New (url)); } - void addSource (Source* source) + void addSource (Validators::Source* source) { #if RIPPLE_USE_VALIDATORS m_queue.dispatch (bind (&Logic::add, &m_logic, source)); @@ -286,8 +250,6 @@ public: { #if RIPPLE_USE_VALIDATORS m_journal.info << "Validators preparing"; - - addRPCHandlers(); #endif } @@ -402,6 +364,11 @@ public: //------------------------------------------------------------------------------ +Manager::Manager () + : PropertyStream::Source ("validators") +{ +} + Validators::Manager* Validators::Manager::New (Stoppable& parent, Journal journal) { return new Validators::ManagerImp (parent, journal); diff --git a/src/ripple_app/main/Application.cpp b/src/ripple_app/main/Application.cpp index 1d0bbcd82f..7d45772aea 100644 --- a/src/ripple_app/main/Application.cpp +++ b/src/ripple_app/main/Application.cpp @@ -117,8 +117,8 @@ public: , m_txQueue (TxQueue::New ()) - , m_validators (Validators::Manager::New ( - *this, LogJournal::get ())) + , m_validators (add (Validators::Manager::New ( + *this, LogJournal::get ()))) , mFeatures (IFeatures::New (2 * 7 * 24 * 60 * 60, 200)) // two weeks, 200/256 @@ -472,7 +472,7 @@ public: // the creation of the peer SSL context and Peers object into // the conditional. // - m_peers = Peers::New (m_mainIoPool, m_mainIoPool, m_peerSSLContext->get ()); + m_peers = add (Peers::New (m_mainIoPool, m_mainIoPool, m_peerSSLContext->get ())); // If we're not in standalone mode, // prepare ourselves for networking @@ -642,8 +642,6 @@ public: void onPrepare () { - m_rpcServiceManager->add (*m_validators); - prepareValidators (); } @@ -670,7 +668,15 @@ public: stopped (); } + //------------------------------------------------------------------------------ // + // PropertyStream + // + + void onWrite (PropertyStream stream) + { + } + //------------------------------------------------------------------------------ void run () @@ -1201,6 +1207,11 @@ ApplicationImp* ApplicationImp::s_instance; //------------------------------------------------------------------------------ +Application::Application () + : PropertyStream::Source ("app") +{ +} + Application* Application::New () { return new ApplicationImp; diff --git a/src/ripple_app/main/Application.h b/src/ripple_app/main/Application.h index 0db7b24225..f19ffbcb0f 100644 --- a/src/ripple_app/main/Application.h +++ b/src/ripple_app/main/Application.h @@ -49,7 +49,7 @@ class DatabaseCon; typedef TaggedCacheType NodeCache; typedef TaggedCacheType SLECache; -class Application +class Application : public PropertyStream::Source { public: /* VFALCO NOTE @@ -68,24 +68,11 @@ public: virtual LockType& getMasterLock () = 0; -public: - struct State - { - // Stuff in here is accessed concurrently and requires a Access - }; - - typedef SharedData SharedState; - - SharedState& getSharedState () noexcept { return m_sharedState; } - - SharedState const& getSharedState () const noexcept { return m_sharedState; } - -private: - SharedState m_sharedState; - public: static Application* New (); + Application (); + virtual ~Application () { } virtual boost::asio::io_service& getIOService () = 0; @@ -97,7 +84,7 @@ public: virtual IFeatures& getFeatureTable () = 0; virtual IFeeVote& getFeeVote () = 0; virtual IHashRouter& getHashRouter () = 0; - virtual LoadFeeTrack& getFeeTrack () = 0; + virtual LoadFeeTrack& getFeeTrack () = 0; virtual LoadManager& getLoadManager () = 0; virtual Peers& getPeers () = 0; virtual ProofOfWorkFactory& getProofOfWorkFactory () = 0; diff --git a/src/ripple_app/peers/Peers.cpp b/src/ripple_app/peers/Peers.cpp index 015f580196..8581729d47 100644 --- a/src/ripple_app/peers/Peers.cpp +++ b/src/ripple_app/peers/Peers.cpp @@ -91,8 +91,8 @@ public: boost::asio::io_service& io_service, boost::asio::ssl::context& ssl_context) : Stoppable ("Peers", parent) - , m_peerFinder (PeerFinder::Manager::New ( - *this, *this, LogJournal::get ())) + , m_peerFinder (add (PeerFinder::Manager::New ( + *this, *this, LogJournal::get ()))) , m_io_service (io_service) , m_ssl_context (ssl_context) , mPeerLock (this, "PeersImp", __FILE__, __LINE__) @@ -223,6 +223,15 @@ public: stopped(); } + //-------------------------------------------------------------------------- + // + // PropertyStream + // + + void onWrite (PropertyStream stream) + { + } + //-------------------------------------------------------------------------- PeerFinder::Manager& getPeerFinder() @@ -1078,6 +1087,11 @@ void PeersImp::scanRefresh () //------------------------------------------------------------------------------ +Peers::Peers () + : PropertyStream::Source ("peers") +{ +} + Peers* Peers::New (Stoppable& parent, boost::asio::io_service& io_service, boost::asio::ssl::context& ssl_context) diff --git a/src/ripple_app/peers/Peers.h b/src/ripple_app/peers/Peers.h index 3614cf070a..7d38492162 100644 --- a/src/ripple_app/peers/Peers.h +++ b/src/ripple_app/peers/Peers.h @@ -25,13 +25,15 @@ class Manager; } /** Manages the set of connected peers. */ -class Peers +class Peers : public PropertyStream::Source { public: static Peers* New (Stoppable& parent, boost::asio::io_service& io_service, boost::asio::ssl::context& context); + Peers (); + virtual ~Peers () { } virtual PeerFinder::Manager& getPeerFinder() = 0; diff --git a/src/ripple_app/rpc/RPCHandler.cpp b/src/ripple_app/rpc/RPCHandler.cpp index 6dacc5b1d7..54215dbdb7 100644 --- a/src/ripple_app/rpc/RPCHandler.cpp +++ b/src/ripple_app/rpc/RPCHandler.cpp @@ -810,6 +810,24 @@ Json::Value RPCHandler::doPing (Json::Value, LoadType* loadType, Application::Sc return Json::Value (Json::objectValue); } +Json::Value RPCHandler::doPrint (Json::Value params, LoadType* loadType, Application::ScopedLockType& masterLockHolder) +{ + masterLockHolder.unlock (); + + Json::Value result (Json::objectValue); + JsonPropertyStreamSink sink (result); + if (params.isObject() && params["params"].isArray() && params["params"][0u].isString ()) + { + getApp().write (params["params"][0u].asString(), sink); + } + else + { + getApp().write (sink, true); + } + + return result; +} + // profile offers [submit] // profile 0:offers 1:pass_a 2:account_a 3:currency_offer_a 4:account_b 5:currency_offer_b 6: 7:[submit] // issuer is the offering account @@ -3822,12 +3840,13 @@ Json::Value RPCHandler::doCommand (const Json::Value& params, int iRole, LoadTyp { "ledger_header", &RPCHandler::doLedgerHeader, false, optCurrent }, { "log_level", &RPCHandler::doLogLevel, true, optNone }, { "logrotate", &RPCHandler::doLogRotate, true, optNone }, - // { "nickname_info", &RPCHandler::doNicknameInfo, false, optCurrent }, +// { "nickname_info", &RPCHandler::doNicknameInfo, false, optCurrent }, { "owner_info", &RPCHandler::doOwnerInfo, false, optCurrent }, { "peers", &RPCHandler::doPeers, true, optNone }, { "path_find", &RPCHandler::doPathFind, false, optCurrent }, { "ping", &RPCHandler::doPing, false, optNone }, - // { "profile", &RPCHandler::doProfile, false, optCurrent }, + { "print", &RPCHandler::doPrint, true, optNone }, +// { "profile", &RPCHandler::doProfile, false, optCurrent }, { "proof_create", &RPCHandler::doProofCreate, true, optNone }, { "proof_solve", &RPCHandler::doProofSolve, true, optNone }, { "proof_verify", &RPCHandler::doProofVerify, true, optNone }, @@ -3842,7 +3861,6 @@ Json::Value RPCHandler::doCommand (const Json::Value& params, int iRole, LoadTyp { "transaction_entry", &RPCHandler::doTransactionEntry, false, optCurrent }, { "tx", &RPCHandler::doTx, false, optNetwork }, { "tx_history", &RPCHandler::doTxHistory, false, optNone }, - { "unl_add", &RPCHandler::doUnlAdd, true, optNone }, { "unl_delete", &RPCHandler::doUnlDelete, true, optNone }, { "unl_list", &RPCHandler::doUnlList, true, optNone }, @@ -3850,10 +3868,8 @@ Json::Value RPCHandler::doCommand (const Json::Value& params, int iRole, LoadTyp { "unl_network", &RPCHandler::doUnlNetwork, true, optNone }, { "unl_reset", &RPCHandler::doUnlReset, true, optNone }, { "unl_score", &RPCHandler::doUnlScore, true, optNone }, - { "validation_create", &RPCHandler::doValidationCreate, true, optNone }, { "validation_seed", &RPCHandler::doValidationSeed, true, optNone }, - { "wallet_accounts", &RPCHandler::doWalletAccounts, false, optCurrent }, { "wallet_propose", &RPCHandler::doWalletPropose, true, optNone }, { "wallet_seed", &RPCHandler::doWalletSeed, true, optNone }, diff --git a/src/ripple_app/rpc/RPCHandler.h b/src/ripple_app/rpc/RPCHandler.h index 28818958a3..98341554e8 100644 --- a/src/ripple_app/rpc/RPCHandler.h +++ b/src/ripple_app/rpc/RPCHandler.h @@ -122,6 +122,7 @@ private: Json::Value doPathFind (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh); Json::Value doPeers (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh); Json::Value doPing (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh); + Json::Value doPrint (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh); Json::Value doProfile (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh); Json::Value doProofCreate (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh); Json::Value doProofSolve (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh); diff --git a/src/ripple_net/rpc/RPCCall.cpp b/src/ripple_net/rpc/RPCCall.cpp index 3db57cdac4..1993cb19c0 100644 --- a/src/ripple_net/rpc/RPCCall.cpp +++ b/src/ripple_net/rpc/RPCCall.cpp @@ -849,15 +849,16 @@ public: { "ledger_accept", &RPCParser::parseAsIs, 0, 0 }, { "ledger_closed", &RPCParser::parseAsIs, 0, 0 }, { "ledger_current", &RPCParser::parseAsIs, 0, 0 }, - // { "ledger_entry", &RPCParser::parseLedgerEntry, -1, -1 }, + // { "ledger_entry", &RPCParser::parseLedgerEntry, -1, -1 }, { "ledger_header", &RPCParser::parseLedgerId, 1, 1 }, { "log_level", &RPCParser::parseLogLevel, 0, 2 }, { "logrotate", &RPCParser::parseAsIs, 0, 0 }, - // { "nickname_info", &RPCParser::parseNicknameInfo, 1, 1 }, + // { "nickname_info", &RPCParser::parseNicknameInfo, 1, 1 }, { "owner_info", &RPCParser::parseAccountItems, 1, 2 }, { "peers", &RPCParser::parseAsIs, 0, 0 }, { "ping", &RPCParser::parseAsIs, 0, 0 }, - // { "profile", &RPCParser::parseProfile, 1, 9 }, + { "print", &RPCParser::parseAsIs, 0, 1 }, + // { "profile", &RPCParser::parseProfile, 1, 9 }, { "proof_create", &RPCParser::parseProofCreate, 0, 2 }, { "proof_solve", &RPCParser::parseProofSolve, 1, 1 }, { "proof_verify", &RPCParser::parseProofVerify, 2, 4 }, @@ -869,11 +870,10 @@ public: { "server_info", &RPCParser::parseAsIs, 0, 0 }, { "server_state", &RPCParser::parseAsIs, 0, 0 }, { "stop", &RPCParser::parseAsIs, 0, 0 }, - // { "transaction_entry", &RPCParser::parseTransactionEntry, -1, -1 }, + // { "transaction_entry", &RPCParser::parseTransactionEntry, -1, -1 }, { "tx", &RPCParser::parseTx, 1, 2 }, { "tx_account", &RPCParser::parseTxAccount, 1, 7 }, { "tx_history", &RPCParser::parseTxHistory, 1, 1 }, - { "unl_add", &RPCParser::parseUnlAdd, 1, 2 }, { "unl_delete", &RPCParser::parseUnlDelete, 1, 1 }, { "unl_list", &RPCParser::parseAsIs, 0, 0 }, @@ -881,14 +881,11 @@ public: { "unl_network", &RPCParser::parseAsIs, 0, 0 }, { "unl_reset", &RPCParser::parseAsIs, 0, 0 }, { "unl_score", &RPCParser::parseAsIs, 0, 0 }, - { "validation_create", &RPCParser::parseValidationCreate, 0, 1 }, { "validation_seed", &RPCParser::parseValidationSeed, 0, 1 }, - { "wallet_accounts", &RPCParser::parseWalletAccounts, 1, 1 }, { "wallet_propose", &RPCParser::parseWalletPropose, 0, 1 }, { "wallet_seed", &RPCParser::parseWalletSeed, 0, 1 }, - { "internal", &RPCParser::parseInternal, 1, -1 }, #if ENABLE_INSECURE