diff --git a/rippled-example.cfg b/rippled-example.cfg index 6eb7172bf..f682966e7 100644 --- a/rippled-example.cfg +++ b/rippled-example.cfg @@ -219,7 +219,8 @@ # [cluster_nodes]: # To extend full trust to other nodes, place their node public keys here. # Generally, you should only do this for nodes under common administration. -# Node public keys start with an 'n'. +# Node public keys start with an 'n'. To give a node a name for identification +# place a space after the public key and then the name. # # [ledger_history]: # The number of past ledgers to acquire on server startup and the minimum to diff --git a/src/cpp/ripple/DBInit.cpp b/src/cpp/ripple/DBInit.cpp index b16ba0f41..bdc6c29b5 100644 --- a/src/cpp/ripple/DBInit.cpp +++ b/src/cpp/ripple/DBInit.cpp @@ -55,15 +55,16 @@ const char *LedgerDBInit[] = { );", "CREATE INDEX SeqLedger ON Ledgers(LedgerSeq);", - "CREATE TABLE LedgerValidations ( \ + "CREATE TABLE Validations ( \ LedgerHash CHARACTER(64), \ NodePubKey CHARACTER(56), \ - Flags BIGINT UNSIGNED, \ SignTime BIGINT UNSIGNED, \ - Signature BLOB \ + RawData BLOB \ );", - "CREATE INDEX ValidationByHash ON \ - LedgerValidations(LedgerHash);", + "CREATE INDEX ValidationsByHash ON \ + Validations(LedgerHash);", + "CREATE INDEX ValidationsByTime ON \ + Validations(SignTime);", "END TRANSACTION;" }; diff --git a/src/cpp/ripple/Ledger.cpp b/src/cpp/ripple/Ledger.cpp index 3f2124de3..406a5f4e5 100644 --- a/src/cpp/ripple/Ledger.cpp +++ b/src/cpp/ripple/Ledger.cpp @@ -547,7 +547,7 @@ uint256 Ledger::getHashByIndex(uint32 ledgerIndex) { uint256 ret; - std::string sql="SELECT LedgerHash FROM Ledgers WHERE LedgerSeq='"; + std::string sql="SELECT LedgerHash FROM Ledgers INDEXED BY SeqLedger WHERE LedgerSeq='"; sql.append(boost::lexical_cast(ledgerIndex)); sql.append("';"); diff --git a/src/cpp/ripple/Peer.cpp b/src/cpp/ripple/Peer.cpp index 7b686f3af..460f2108c 100644 --- a/src/cpp/ripple/Peer.cpp +++ b/src/cpp/ripple/Peer.cpp @@ -686,7 +686,7 @@ void Peer::recvHello(ripple::TMHello& packet) << "Peer speaks version " << (packet.protoversion() >> 16) << "." << (packet.protoversion() & 0xFF); mHello = packet; - if (theApp->getUNL().nodeInCluster(mNodePublic)) + if (theApp->getUNL().nodeInCluster(mNodePublic, mNodeName)) { mCluster = true; mLoad.setPrivileged(); @@ -1785,7 +1785,11 @@ Json::Value Peer::getJson() if (mInbound) ret["inbound"] = true; if (mCluster) + { ret["cluster"] = true; + if (!mNodeName.empty()) + ret["name"] = mNodeName; + } if (mHello.has_fullversion()) ret["version"] = mHello.fullversion(); diff --git a/src/cpp/ripple/Peer.h b/src/cpp/ripple/Peer.h index 2d3fb9527..f21e96b30 100644 --- a/src/cpp/ripple/Peer.h +++ b/src/cpp/ripple/Peer.h @@ -40,6 +40,7 @@ private: bool mActive; bool mCluster; // Node in our cluster RippleAddress mNodePublic; // Node public key of peer. + std::string mNodeName; ipPort mIpPort; ipPort mIpPortConnect; uint256 mCookieHash; diff --git a/src/cpp/ripple/UniqueNodeList.cpp b/src/cpp/ripple/UniqueNodeList.cpp index c0f4d8016..ff5622cb2 100644 --- a/src/cpp/ripple/UniqueNodeList.cpp +++ b/src/cpp/ripple/UniqueNodeList.cpp @@ -64,15 +64,6 @@ void UniqueNodeList::start() // Load information about when we last updated. bool UniqueNodeList::miscLoad() { - BOOST_FOREACH(const std::string& node, theConfig.CLUSTER_NODES) - { - RippleAddress a = RippleAddress::createNodePublic(node); - if (a.isValid()) - sClusterNodes.insert(a); - else - cLog(lsWARNING) << "Entry in cluster list invalid: '" << node << "'"; - } - boost::recursive_mutex::scoped_lock sl(theApp->getWalletDB()->getDBLock()); Database *db=theApp->getWalletDB()->getDB(); @@ -105,13 +96,18 @@ bool UniqueNodeList::miscSave() void UniqueNodeList::trustedLoad() { - BOOST_FOREACH(const std::string& node, theConfig.CLUSTER_NODES) + boost::regex rNode("\\`\\s*(\\S+)[\\s]*(.*)\\'"); + BOOST_FOREACH(const std::string& c, theConfig.CLUSTER_NODES) { - RippleAddress a = RippleAddress::createNodePublic(node); - if (a.isValid()) - sClusterNodes.insert(a); + boost::smatch match; + if (boost::regex_match(c, match, rNode)) + { + RippleAddress a = RippleAddress::createNodePublic(match[1]); + if (a.isValid()) + sClusterNodes.insert(std::make_pair(a, (match.size() > 1) ? match[2] : std::string(""))); + } else - cLog(lsWARNING) << "Entry in cluster list invalid: '" << node << "'"; + cLog(lsWARNING) << "Entry in cluster list invalid: '" << c << "'"; } Database* db=theApp->getWalletDB()->getDB(); @@ -1699,7 +1695,17 @@ bool UniqueNodeList::nodeInUNL(const RippleAddress& naNodePublic) bool UniqueNodeList::nodeInCluster(const RippleAddress& naNodePublic) { boost::recursive_mutex::scoped_lock sl(mUNLLock); - return sClusterNodes.count(naNodePublic) != 0; + return sClusterNodes.end() != sClusterNodes.find(naNodePublic); +} + +bool UniqueNodeList::nodeInCluster(const RippleAddress& naNodePublic, std::string& name) +{ + boost::recursive_mutex::scoped_lock sl(mUNLLock); + std::map::iterator it = sClusterNodes.find(naNodePublic); + if (it == sClusterNodes.end()) + return false; + name = it->second; + return true; } // vim:ts=4 diff --git a/src/cpp/ripple/UniqueNodeList.h b/src/cpp/ripple/UniqueNodeList.h index 9cf511d84..ee0770f79 100644 --- a/src/cpp/ripple/UniqueNodeList.h +++ b/src/cpp/ripple/UniqueNodeList.h @@ -88,7 +88,7 @@ private: std::vector viReferrals; } scoreNode; - std::set sClusterNodes; + std::map sClusterNodes; typedef boost::unordered_map strIndex; typedef std::pair ipPort; @@ -155,6 +155,7 @@ public: bool nodeInUNL(const RippleAddress& naNodePublic); bool nodeInCluster(const RippleAddress& naNodePublic); + bool nodeInCluster(const RippleAddress& naNodePublic, std::string& name); void nodeBootstrap(); bool nodeLoad(boost::filesystem::path pConfig); diff --git a/src/cpp/ripple/ValidationCollection.cpp b/src/cpp/ripple/ValidationCollection.cpp index 5d34e59ec..84dbc8f14 100644 --- a/src/cpp/ripple/ValidationCollection.cpp +++ b/src/cpp/ripple/ValidationCollection.cpp @@ -300,8 +300,8 @@ void ValidationCollection::condWrite() void ValidationCollection::doWrite() { LoadEvent::autoptr event(theApp->getJobQueue().getLoadEventAP(jtDISK)); - static boost::format insVal("INSERT INTO LedgerValidations " - "(LedgerHash,NodePubKey,Flags,SignTime,Signature) VALUES ('%s','%s','%u','%u',%s);"); + static boost::format insVal("INSERT INTO Validations " + "(LedgerHash,NodePubKey,SignTime,RawData) VALUES ('%s','%s','%u',%s);"); boost::mutex::scoped_lock sl(mValidationLock); assert(mWriting); @@ -314,11 +314,16 @@ void ValidationCollection::doWrite() Database *db = theApp->getLedgerDB()->getDB(); ScopedLock dbl(theApp->getLedgerDB()->getDBLock()); + Serializer s(1024); db->executeSQL("BEGIN TRANSACTION;"); BOOST_FOREACH(const SerializedValidation::pointer& it, vector) + { + s.erase(); + it->add(s); db->executeSQL(boost::str(insVal % it->getLedgerHash().GetHex() - % it->getSignerPublic().humanNodePublic() % it->getFlags() % it->getSignTime() - % sqlEscape(it->getSignature()))); + % it->getSignerPublic().humanNodePublic() % it->getSignTime() + % sqlEscape(s.peekData()))); + } db->executeSQL("END TRANSACTION;"); } sl.lock();