diff --git a/src/ripple/overlay/impl/ConnectAttempt.cpp b/src/ripple/overlay/impl/ConnectAttempt.cpp index 8e4192292..0dce0f01d 100644 --- a/src/ripple/overlay/impl/ConnectAttempt.cpp +++ b/src/ripple/overlay/impl/ConnectAttempt.cpp @@ -492,7 +492,7 @@ ConnectAttempt::onReadBody (error_code ec, "Cluster name: " << name; auto const result = overlay_.peerFinder().activate ( - slot_, RipplePublicKey(publicKey), cluster); + slot_, publicKey.toPublicKey(), cluster); if (result != PeerFinder::Result::success) return fail("Outbound slots full"); @@ -605,7 +605,7 @@ ConnectAttempt::processResponse (beast::http::message const& m, "Cluster name: " << name; auto const result = overlay_.peerFinder().activate (slot_, - RipplePublicKey(publicKey), clusterNode); + publicKey.toPublicKey(), clusterNode); if (result != PeerFinder::Result::success) return fail("Outbound slots full"); diff --git a/src/ripple/overlay/impl/OverlayImpl.cpp b/src/ripple/overlay/impl/OverlayImpl.cpp index b0688c9d1..4bedcf394 100644 --- a/src/ripple/overlay/impl/OverlayImpl.cpp +++ b/src/ripple/overlay/impl/OverlayImpl.cpp @@ -270,7 +270,7 @@ OverlayImpl::onHandoff (std::unique_ptr && ssl_bundle, publicKey, name); auto const result = m_peerFinder->activate (slot, - RipplePublicKey(publicKey), cluster); + publicKey.toPublicKey(), cluster); if (result != PeerFinder::Result::success) { if (journal.trace) journal.trace << @@ -409,7 +409,7 @@ OverlayImpl::add_active (std::shared_ptr const& peer) journal_.debug << "activated " << peer->getRemoteAddress() << " (" << peer->id() << - ":" << RipplePublicKey(peer->getNodePublic()) << ")"; + ":" << peer->getNodePublic().toPublicKey() << ")"; // As we are not on the strand, run() must be called // while holding the lock, otherwise new I/O can be @@ -569,7 +569,7 @@ OverlayImpl::activate (std::shared_ptr const& peer) journal_.debug << "activated " << peer->getRemoteAddress() << " (" << peer->id() << - ":" << RipplePublicKey(peer->getNodePublic()) << ")"; + ":" << peer->getNodePublic().toPublicKey() << ")"; // We just accepted this peer so we have non-zero active peers assert(size() != 0); diff --git a/src/ripple/overlay/impl/PeerImp.cpp b/src/ripple/overlay/impl/PeerImp.cpp index af575bb62..241e38a10 100644 --- a/src/ripple/overlay/impl/PeerImp.cpp +++ b/src/ripple/overlay/impl/PeerImp.cpp @@ -800,7 +800,7 @@ PeerImp::onMessage (std::shared_ptr const& m) hello_ = *m; auto const result = overlay_.peerFinder().activate (slot_, - RipplePublicKey (publicKey_), cluster); + publicKey_.toPublicKey(), cluster); if (result == PeerFinder::Result::success) { diff --git a/src/ripple/peerfinder/impl/Counts.h b/src/ripple/peerfinder/impl/Counts.h index 58f772ff2..099111e47 100644 --- a/src/ripple/peerfinder/impl/Counts.h +++ b/src/ripple/peerfinder/impl/Counts.h @@ -22,6 +22,7 @@ #include #include +#include namespace ripple { namespace PeerFinder { diff --git a/src/ripple/protocol/RippleAddress.h b/src/ripple/protocol/RippleAddress.h index 49959dccc..938d1498b 100644 --- a/src/ripple/protocol/RippleAddress.h +++ b/src/ripple/protocol/RippleAddress.h @@ -22,13 +22,13 @@ #include #include +#include #include #include #include #include #include #include -#include #include namespace ripple { @@ -69,6 +69,12 @@ public: static void clearCache (); + /** Returns the public key. + Precondition: version == VER_NODE_PUBLIC + */ + RipplePublicKey + toPublicKey() const; + // // Node Public - Also used for Validators // @@ -115,15 +121,6 @@ public: Base58::Alphabet const& alphabet = Base58::getRippleAlphabet()); void setAccountID (Account const& hash160In); - #if 0 - static RippleAddress createAccountID (std::string const& strAccountID) - { - RippleAddress na; - na.setAccountID (strAccountID); - return na; - } - #endif - static RippleAddress createAccountID (Account const& uiAccountID); // @@ -287,17 +284,6 @@ operator>=(RippleAddress const& lhs, RippleAddress const& rhs) return !(lhs < rhs); } -/** RipplePublicKey */ -template <> -struct RipplePublicKeyTraits::assign -{ - void operator() (value_type& value, RippleAddress const& v) const - { - Blob const& b (v.getNodePublic ()); - construct (&b.front(), &b.back()+1, value); - } -}; - /** RipplePublicKeyHash */ template <> struct RipplePublicKeyHashTraits::assign diff --git a/src/ripple/protocol/impl/RippleAddress.cpp b/src/ripple/protocol/impl/RippleAddress.cpp index 1a20b3630..84e142a8f 100644 --- a/src/ripple/protocol/impl/RippleAddress.cpp +++ b/src/ripple/protocol/impl/RippleAddress.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -137,6 +138,13 @@ RippleAddress RippleAddress::createNodePublic (std::string const& strPublic) return naNew; } +RipplePublicKey +RippleAddress::toPublicKey() const +{ + assert (nVersion == VER_NODE_PUBLIC); + return RipplePublicKey (vchData.begin(), vchData.end()); +} + NodeID RippleAddress::getNodeID () const { switch (nVersion) @@ -969,7 +977,7 @@ public: expect (deprecatedPublicKey.humanNodePublic () == "n94a1u4jAz288pZLtw6yFWVbi89YamiC6JBXPVUj5zmExe5fTVg9", deprecatedPublicKey.humanNodePublic ()); - RipplePublicKey publicKey (deprecatedPublicKey); + RipplePublicKey publicKey = deprecatedPublicKey.toPublicKey(); expect (publicKey.to_string() == deprecatedPublicKey.humanNodePublic(), publicKey.to_string()); diff --git a/src/ripple/types/RipplePublicKey.h b/src/ripple/types/RipplePublicKey.h index b27275714..4f461abbd 100644 --- a/src/ripple/types/RipplePublicKey.h +++ b/src/ripple/types/RipplePublicKey.h @@ -20,26 +20,80 @@ #ifndef RIPPLE_TYPES_RIPPLEPUBLICKEY_H_INCLUDED #define RIPPLE_TYPES_RIPPLEPUBLICKEY_H_INCLUDED -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include // namespace ripple { -class RipplePublicKeyTraits - : public CryptoIdentifier <33, 28, true> +// Simplified public key that avoids the complexities of RippleAddress +class RipplePublicKey { +private: + std::array data_; + public: - template - struct assign + /** Construct from a range of unsigned char. */ + template ::value_type>::value>> + RipplePublicKey (FwdIt first, FwdIt last); + + template + std::string + to_string() const; + + friend + bool + operator< (RipplePublicKey const& lhs, RipplePublicKey const& rhs) { - void operator() (value_type& value, Other const& other) - { - value = other; - } - }; + return lhs.data_ < rhs.data_; + } + + friend + bool + operator== (RipplePublicKey const& lhs, RipplePublicKey const& rhs) + { + return lhs.data_ == rhs.data_; + } }; -typedef IdentifierType RipplePublicKey; +template +RipplePublicKey::RipplePublicKey (FwdIt first, FwdIt last) +{ + assert(std::distance(first, last) == data_.size()); + // VFALCO TODO Use 4-arg copy from C++14 + std::copy (first, last, data_.begin()); +} + +template +std::string +RipplePublicKey::to_string() const +{ + // The expanded form of the key is: + // + std::array e; + e[0] = 28; // node public key type + std::copy (data_.begin(), data_.end(), e.begin() + 1); + Base58::fourbyte_hash256 (&*(e.begin() + 34), e.data(), 34); + // Convert key + checksum to little endian with an extra pad byte + std::array le; + std::reverse_copy (e.begin(), e.end(), le.begin()); + le.back() = 0; // make BIGNUM positive + return Base58::raw_encode (le.data(), + le.data() + le.size(), Base58::getRippleAlphabet(), true); +} + +inline +std::ostream& +operator<< (std::ostream& os, RipplePublicKey const& k) +{ + return os << k.to_string(); +} }