mirror of
https://github.com/XRPLF/rippled.git
synced 2025-12-06 17:27:55 +00:00
Add manifests subscriptions
Add verify method to manifest script to check signature
This commit is contained in:
committed by
Edward Hennis
parent
a67e4ab9f1
commit
749b4adc7c
@@ -436,6 +436,10 @@ public:
|
||||
bool subBook (InfoSub::ref ispListener, Book const&) override;
|
||||
bool unsubBook (std::uint64_t uListener, Book const&) override;
|
||||
|
||||
bool subManifests (InfoSub::ref ispListener) override;
|
||||
bool unsubManifests (std::uint64_t uListener) override;
|
||||
void pubManifest (Manifest const&) override;
|
||||
|
||||
bool subTransactions (InfoSub::ref ispListener) override;
|
||||
bool unsubTransactions (std::uint64_t uListener) override;
|
||||
|
||||
@@ -526,6 +530,7 @@ private:
|
||||
subRpcMapType mRpcSubMap;
|
||||
|
||||
SubMapType mSubLedger; // Accepted ledgers.
|
||||
SubMapType mSubManifests; // Received validator manifests.
|
||||
SubMapType mSubServer; // When server changes connectivity state.
|
||||
SubMapType mSubTransactions; // All accepted transactions.
|
||||
SubMapType mSubRTTransactions; // All proposed and accepted transactions.
|
||||
@@ -1507,6 +1512,36 @@ void NetworkOPsImp::consensusViewChange ()
|
||||
setMode (omCONNECTED);
|
||||
}
|
||||
|
||||
void NetworkOPsImp::pubManifest (Manifest const& mo)
|
||||
{
|
||||
// VFALCO consider std::shared_mutex
|
||||
ScopedLockType sl (mSubLock);
|
||||
|
||||
if (!mSubManifests.empty ())
|
||||
{
|
||||
Json::Value jvObj (Json::objectValue);
|
||||
|
||||
jvObj [jss::type] = "manifestReceived";
|
||||
jvObj [jss::master_key] = toBase58(TokenType::TOKEN_NODE_PUBLIC, mo.masterKey);
|
||||
jvObj [jss::signing_key] = toBase58(TokenType::TOKEN_NODE_PUBLIC, mo.signingKey);
|
||||
jvObj [jss::seq] = Json::UInt (mo.sequence);
|
||||
jvObj [jss::signature] = strHex (mo.getSignature ());
|
||||
|
||||
for (auto i = mSubManifests.begin (); i != mSubManifests.end (); )
|
||||
{
|
||||
if (auto p = i->second.lock())
|
||||
{
|
||||
p->send (jvObj, true);
|
||||
++i;
|
||||
}
|
||||
else
|
||||
{
|
||||
i = mSubManifests.erase (i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NetworkOPsImp::pubServer ()
|
||||
{
|
||||
// VFALCO TODO Don't hold the lock across calls to send...make a copy of the
|
||||
@@ -1568,9 +1603,7 @@ void NetworkOPsImp::pubValidation (STValidation::ref val)
|
||||
|
||||
for (auto i = mSubValidations.begin (); i != mSubValidations.end (); )
|
||||
{
|
||||
InfoSub::pointer p = i->second.lock ();
|
||||
|
||||
if (p)
|
||||
if (auto p = i->second.lock())
|
||||
{
|
||||
p->send (jvObj, true);
|
||||
++i;
|
||||
@@ -2538,6 +2571,20 @@ bool NetworkOPsImp::unsubLedger (std::uint64_t uSeq)
|
||||
return mSubLedger.erase (uSeq);
|
||||
}
|
||||
|
||||
// <-- bool: true=added, false=already there
|
||||
bool NetworkOPsImp::subManifests (InfoSub::ref isrListener)
|
||||
{
|
||||
ScopedLockType sl (mSubLock);
|
||||
return mSubManifests.emplace (isrListener->getSeq (), isrListener).second;
|
||||
}
|
||||
|
||||
// <-- bool: true=erased, false=was not there
|
||||
bool NetworkOPsImp::unsubManifests (std::uint64_t uSeq)
|
||||
{
|
||||
ScopedLockType sl (mSubLock);
|
||||
return mSubManifests.erase (uSeq);
|
||||
}
|
||||
|
||||
// <-- bool: true=added, false=already there
|
||||
bool NetworkOPsImp::subServer (InfoSub::ref isrListener, Json::Value& jvResult,
|
||||
bool admin)
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
|
||||
#include <ripple/basics/CountedObject.h>
|
||||
#include <ripple/json/json_value.h>
|
||||
#include <ripple/overlay/impl/Manifest.h>
|
||||
#include <ripple/resource/Consumer.h>
|
||||
#include <ripple/protocol/Book.h>
|
||||
#include <beast/threads/Stoppable.h>
|
||||
@@ -84,6 +85,10 @@ public:
|
||||
virtual bool subLedger (ref ispListener, Json::Value& jvResult) = 0;
|
||||
virtual bool unsubLedger (std::uint64_t uListener) = 0;
|
||||
|
||||
virtual bool subManifests (ref ispListener) = 0;
|
||||
virtual bool unsubManifests (std::uint64_t uListener) = 0;
|
||||
virtual void pubManifest (Manifest const&) = 0;
|
||||
|
||||
virtual bool subServer (ref ispListener, Json::Value& jvResult,
|
||||
bool admin) = 0;
|
||||
virtual bool unsubServer (std::uint64_t uListener) = 0;
|
||||
|
||||
@@ -56,6 +56,7 @@ InfoSub::~InfoSub ()
|
||||
m_source.unsubTransactions (mSeq);
|
||||
m_source.unsubRTTransactions (mSeq);
|
||||
m_source.unsubLedger (mSeq);
|
||||
m_source.unsubManifests (mSeq);
|
||||
m_source.unsubServer (mSeq);
|
||||
m_source.unsubValidations (mSeq);
|
||||
m_source.unsubPeerStatus (mSeq);
|
||||
|
||||
@@ -119,6 +119,14 @@ bool Manifest::revoked () const
|
||||
return sequence == std::numeric_limits<std::uint32_t>::max ();
|
||||
}
|
||||
|
||||
Blob Manifest::getSignature () const
|
||||
{
|
||||
STObject st (sfGeneric);
|
||||
SerialIter sit (serialized.data (), serialized.size ());
|
||||
st.set (sit);
|
||||
return st.getFieldVL (sfSignature);
|
||||
}
|
||||
|
||||
void
|
||||
ManifestCache::configValidatorKey(
|
||||
std::string const& line, beast::Journal journal)
|
||||
|
||||
@@ -98,6 +98,7 @@ struct Manifest
|
||||
bool verify () const;
|
||||
uint256 hash () const;
|
||||
bool revoked () const;
|
||||
Blob getSignature () const;
|
||||
};
|
||||
|
||||
boost::optional<Manifest> make_Manifest(std::string s);
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
#include <BeastConfig.h>
|
||||
#include <ripple/app/misc/HashRouter.h>
|
||||
#include <ripple/app/misc/NetworkOPs.h>
|
||||
#include <ripple/core/DatabaseCon.h>
|
||||
#include <ripple/basics/contract.h>
|
||||
#include <ripple/basics/Log.h>
|
||||
@@ -695,6 +696,10 @@ OverlayImpl::onManifests (
|
||||
app_.validators(),
|
||||
journal);
|
||||
|
||||
if (result == ManifestDisposition::accepted ||
|
||||
result == ManifestDisposition::untrusted)
|
||||
app_.getOPs().pubManifest (*make_Manifest(serialized));
|
||||
|
||||
if (result == ManifestDisposition::accepted)
|
||||
{
|
||||
auto db = app_.getWalletDB ().checkoutDb ();
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
#include <BeastConfig.h>
|
||||
#include <ripple/basics/contract.h>
|
||||
#include <ripple/basics/StringUtilities.h>
|
||||
#include <ripple/basics/TestSuite.h>
|
||||
#include <ripple/overlay/impl/Manifest.h>
|
||||
#include <ripple/core/DatabaseCon.h>
|
||||
@@ -93,9 +94,9 @@ public:
|
||||
auto const pk = derivePublicKey(type, sk);
|
||||
|
||||
STObject st(sfGeneric);
|
||||
set(st, sfSequence, seq);
|
||||
set(st, sfPublicKey, pk);
|
||||
set(st, sfSigningPubKey, spk);
|
||||
st[sfSequence] = seq;
|
||||
st[sfPublicKey] = pk;
|
||||
st[sfSigningPubKey] = spk;
|
||||
|
||||
sign(st, HashPrefix::manifest, type, sk);
|
||||
expect(verify(st, HashPrefix::manifest, pk, true));
|
||||
@@ -179,6 +180,26 @@ public:
|
||||
boost::filesystem::path (dbName));
|
||||
}
|
||||
|
||||
void testGetSignature()
|
||||
{
|
||||
testcase ("getSignature");
|
||||
auto const sk = randomSecretKey();
|
||||
auto const pk = derivePublicKey(KeyType::ed25519, sk);
|
||||
auto const kp = randomKeyPair(KeyType::secp256k1);
|
||||
auto const m = make_Manifest (KeyType::ed25519, sk, kp.first, 0);
|
||||
|
||||
STObject st(sfGeneric);
|
||||
st[sfSequence] = 0;
|
||||
st[sfPublicKey] = pk;
|
||||
st[sfSigningPubKey] = kp.first;
|
||||
Serializer ss;
|
||||
ss.add32(HashPrefix::manifest);
|
||||
st.addWithoutSigningFields(ss);
|
||||
auto const sig = sign(KeyType::ed25519, sk, ss.slice());
|
||||
|
||||
expect (strHex(sig) == strHex(m.getSignature()));
|
||||
}
|
||||
|
||||
void
|
||||
run() override
|
||||
{
|
||||
@@ -227,6 +248,7 @@ public:
|
||||
expect (cache.applyManifest (clone (s_b2), *unl, journal) == invalid);
|
||||
}
|
||||
testLoadStore (cache, *unl);
|
||||
testGetSignature ();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -341,6 +341,7 @@ JSS ( server_state ); // out: NetworkOPs
|
||||
JSS ( server_status ); // out: NetworkOPs
|
||||
JSS ( severity ); // in: LogLevel
|
||||
JSS ( signature ); // out: NetworkOPs
|
||||
JSS ( signing_key ); // out: NetworkOPs
|
||||
JSS ( signer_list ); // in: AccountObjects
|
||||
JSS ( snapshot ); // in: Subscribe
|
||||
JSS ( source_account ); // in: PathRequest, RipplePathFind
|
||||
|
||||
@@ -124,6 +124,10 @@ Json::Value doSubscribe (RPC::Context& context)
|
||||
{
|
||||
context.netOps.subLedger (ispSub, jvResult);
|
||||
}
|
||||
else if (streamName == "manifests")
|
||||
{
|
||||
context.netOps.subManifests (ispSub);
|
||||
}
|
||||
else if (streamName == "transactions")
|
||||
{
|
||||
context.netOps.subTransactions (ispSub);
|
||||
|
||||
@@ -77,6 +77,10 @@ Json::Value doUnsubscribe (RPC::Context& context)
|
||||
{
|
||||
context.netOps.unsubLedger (ispSub->getSeq ());
|
||||
}
|
||||
else if (streamName == "manifests")
|
||||
{
|
||||
context.netOps.unsubManifests (ispSub->getSeq ());
|
||||
}
|
||||
else if (streamName == "transactions")
|
||||
{
|
||||
context.netOps.unsubTransactions (ispSub->getSeq ());
|
||||
|
||||
Reference in New Issue
Block a user