Tidying & Selectively forward manifests to peers:

* Do not forward manifests to peers that already know that manifest
* Do not forward historical manifests to peers
* Save/Load ValidatorManifests from a database
* Python test for setting ephmeral keys
* Cleanup manifest interface
This commit is contained in:
seelabs
2015-04-30 13:27:35 -07:00
parent 31d352b3aa
commit 1b4e0f5f48
18 changed files with 1382 additions and 221 deletions

View File

@@ -19,6 +19,7 @@
#include <BeastConfig.h>
#include <ripple/app/misc/IHashRouter.h>
#include <ripple/core/DatabaseCon.h>
#include <ripple/basics/Log.h>
#include <ripple/basics/make_SSLContext.h>
#include <ripple/protocol/JsonFields.h>
@@ -426,24 +427,24 @@ OverlayImpl::checkStopped ()
stopped();
}
static
void
prepareValidatorKeyManifests (ManifestCache& mc, beast::Journal const& journal)
OverlayImpl::setupValidatorKeyManifests (BasicConfig const& config,
DatabaseCon& db)
{
auto const validator_keys = getConfig().section("validator_keys");
auto const validation_manifest = getConfig().section("validation_manifest");
auto const validator_keys = config.section ("validator_keys");
auto const validation_manifest = config.section ("validation_manifest");
if (! validator_keys.lines().empty())
{
for (auto const& line : validator_keys.lines())
{
mc.configValidatorKey (line, journal);
manifestCache_.configValidatorKey (line, journal_);
}
}
else
{
if (journal.warning)
journal.warning << "[validator_keys] is empty";
if (journal_.warning)
journal_.warning << "[validator_keys] is empty";
}
if (! validation_manifest.lines().empty())
@@ -452,21 +453,33 @@ prepareValidatorKeyManifests (ManifestCache& mc, beast::Journal const& journal)
for (auto const& line : validation_manifest.lines())
s += beast::rfc2616::trim(line);
s = beast::base64_decode(s);
mc.configManifest(std::move(s), journal);
if (auto mo = make_Manifest (std::move (s)))
{
manifestCache_.configManifest (std::move (*mo), journal_);
}
else
{
throw std::runtime_error("Malformed manifest in config");
}
}
else
{
if (journal.warning)
journal.warning << "No [validation_manifest] section in config";
if (journal_.warning)
journal_.warning << "No [validation_manifest] section in config";
}
manifestCache_.load (db, journal_);
}
void
OverlayImpl::saveValidatorKeyManifests (DatabaseCon& db) const
{
manifestCache_.save (db);
}
void
OverlayImpl::onPrepare()
{
prepareValidatorKeyManifests (manifestCache_, journal_);
PeerFinder::Config config;
if (getConfig ().PEERS_MAX != 0)
@@ -617,53 +630,74 @@ OverlayImpl::onPeerDeactivate (Peer::id_t id,
void
OverlayImpl::onManifests (Job&,
std::shared_ptr<protocol::TMManifests> const& inbox,
std::shared_ptr<protocol::TMManifests> const& m,
std::shared_ptr<PeerImp> const& from)
{
auto& hashRouter = getApp().getHashRouter();
auto const n = inbox->list_size();
auto const n = m->list_size();
auto const& journal = from->pjournal();
if (journal.debug) journal.debug
<< "TMManifest, " << n << (n == 1 ? " item" : " items");
protocol::TMManifests outbox;
bool const history = m->history ();
for (std::size_t i = 0; i < n; ++i)
{
auto& s = inbox->list().Get(i).stobject();
auto& s = m->list ().Get (i).stobject ();
uint256 const hash = getSHA512Half (s);
auto const result = manifestCache_.applyManifest (s, journal);
if (result == ManifestDisposition::accepted)
if (auto mo = make_Manifest (s))
{
protocol::TMManifests outbox;
uint256 const hash = mo->hash ();
if (!hashRouter.addSuppressionPeer (hash, from->id ()))
continue;
outbox.add_list()->set_stobject(s);
auto const result =
manifestCache_.applyManifest (std::move (*mo), journal);
auto const msg = std::make_shared<Message>(outbox, protocol::mtMANIFESTS);
if (result == ManifestDisposition::accepted)
{
auto db = getApp ().getWalletDB ().checkoutDb ();
for_each( [&](std::shared_ptr<PeerImp> const& peer)
{
if (hashRouter.addSuppressionPeer (hash, peer->id()) && peer != from)
{
if (auto& j = peer->pjournal().warning)
j << "Forwarding manifest with hash " << hash;
peer->send(msg);
}
else if (peer != from)
{
if (auto& j = peer->pjournal().warning)
j << "Suppressed manifest with hash " << hash;
}
});
soci::transaction tr(*db);
static const char* const sql =
"INSERT INTO ValidatorManifests (RawData) VALUES (:rawData);";
soci::blob rawData(*db);
convert (mo->serialized, rawData);
*db << sql, soci::use (rawData);
tr.commit ();
}
if (history)
{
// Historical manifests are sent on initial peer connections.
// They do not need to be forwarded to other peers.
std::set<Peer::id_t> peers;
hashRouter.swapSet (hash, peers, SF_RELAYED);
continue;
}
if (result == ManifestDisposition::accepted)
{
protocol::TMManifests o;
o.add_list ()->set_stobject (s);
std::set<Peer::id_t> peers;
hashRouter.swapSet (hash, peers, SF_RELAYED);
foreach (send_if_not (
std::make_shared<Message>(o, protocol::mtMANIFESTS),
peer_in_set (peers)));
}
else
{
if (journal.info)
journal.info << "Bad manifest #" << i + 1;
}
}
else
{
if (journal.info) journal.info
<< "Bad manifest #" << i + 1;
if (journal.warning)
journal.warning << "Malformed manifest #" << i + 1;
continue;
}
}
}