diff --git a/Builds/CMake/RippledCore.cmake b/Builds/CMake/RippledCore.cmake index 3bf641b38cb..35a015d5464 100644 --- a/Builds/CMake/RippledCore.cmake +++ b/Builds/CMake/RippledCore.cmake @@ -73,7 +73,6 @@ target_sources (xrpl_core PRIVATE src/ripple/protocol/impl/BuildInfo.cpp src/ripple/protocol/impl/ErrorCodes.cpp src/ripple/protocol/impl/Feature.cpp - src/ripple/protocol/impl/HashPrefix.cpp src/ripple/protocol/impl/Indexes.cpp src/ripple/protocol/impl/InnerObjectFormats.cpp src/ripple/protocol/impl/Issue.cpp diff --git a/src/ripple/app/ledger/impl/LedgerMaster.cpp b/src/ripple/app/ledger/impl/LedgerMaster.cpp index ddc8f507a74..20f52b4d2cf 100644 --- a/src/ripple/app/ledger/impl/LedgerMaster.cpp +++ b/src/ripple/app/ledger/impl/LedgerMaster.cpp @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -1497,7 +1498,7 @@ LedgerMaster::getCloseTimeByHash(LedgerHash const& ledgerHash, (node->getData().size() >= 120)) { SerialIter it (node->getData().data(), node->getData().size()); - if (it.get32() == HashPrefix::ledgerMaster) + if (safe_cast(it.get32()) == HashPrefix::ledgerMaster) { it.skip ( 4+8+32+ // seq drops parentHash diff --git a/src/ripple/nodestore/impl/codec.h b/src/ripple/nodestore/impl/codec.h index a262e6e2841..27d0d5478ce 100644 --- a/src/ripple/nodestore/impl/codec.h +++ b/src/ripple/nodestore/impl/codec.h @@ -24,6 +24,7 @@ #define LZ4_DISABLE_DEPRECATE_WARNINGS #include +#include #include #include #include @@ -240,7 +241,7 @@ nodeobject_compress (void const* in, read(is, unused); read (is, kind); read(is, prefix); - if (prefix == HashPrefix::innerNode) + if (safe_cast(prefix) == HashPrefix::innerNode) { std::size_t n = 0; std::uint16_t mask = 0; @@ -350,7 +351,7 @@ filter_inner (void* in, std::size_t in_size) read(is, unused); read (is, kind); read(is, prefix); - if (prefix == HashPrefix::innerNode) + if (safe_cast(prefix) == HashPrefix::innerNode) { ostream os(in, 9); write(os, 0); diff --git a/src/ripple/protocol/HashPrefix.h b/src/ripple/protocol/HashPrefix.h index 7e23ad5c642..2142b8a6f4d 100644 --- a/src/ripple/protocol/HashPrefix.h +++ b/src/ripple/protocol/HashPrefix.h @@ -25,6 +25,20 @@ namespace ripple { +namespace detail { + +constexpr +std::uint32_t +make_hash_prefix(char a, char b, char c) +{ + return + (static_cast(a) << 24) + + (static_cast(b) << 16) + + (static_cast(c) << 8); +} + +} + /** Prefix for hashing functions. These prefixes are inserted before the source material used to generate @@ -36,69 +50,43 @@ namespace ripple { three bytes formed from the ASCII equivalent of some arbitrary string. For example "TXN". - @note Hash prefixes are part of the Ripple protocol. - - @ingroup protocol + @note Hash prefixes are part of the protocol; you cannot, arbitrarily, + change the type or the value of any of these without causing breakage. */ -class HashPrefix +enum class HashPrefix : std::uint32_t { -private: - std::uint32_t m_prefix; - - HashPrefix (char a, char b, char c) - : m_prefix (0) - { - m_prefix = a; - m_prefix = (m_prefix << 8) + b; - m_prefix = (m_prefix << 8) + c; - m_prefix = m_prefix << 8; - } - -public: - HashPrefix(HashPrefix const&) = delete; - HashPrefix& operator=(HashPrefix const&) = delete; - - /** Returns the hash prefix associated with this object */ - operator std::uint32_t () const - { - return m_prefix; - } - - // VFALCO TODO Expand the description to complete, concise sentences. - // - /** transaction plus signature to give transaction ID */ - static HashPrefix const transactionID; + transactionID = detail::make_hash_prefix('T', 'X', 'N'), /** transaction plus metadata */ - static HashPrefix const txNode; + txNode = detail::make_hash_prefix('S', 'N', 'D'), /** account state */ - static HashPrefix const leafNode; + leafNode = detail::make_hash_prefix('M', 'L', 'N'), /** inner node in V1 tree */ - static HashPrefix const innerNode; + innerNode = detail::make_hash_prefix('M', 'I', 'N'), /** ledger master data for signing */ - static HashPrefix const ledgerMaster; + ledgerMaster = detail::make_hash_prefix('L', 'W', 'R'), /** inner transaction to sign */ - static HashPrefix const txSign; + txSign = detail::make_hash_prefix('S', 'T', 'X'), /** inner transaction to multi-sign */ - static HashPrefix const txMultiSign; + txMultiSign = detail::make_hash_prefix('S', 'M', 'T'), /** validation for signing */ - static HashPrefix const validation; + validation = detail::make_hash_prefix('V', 'A', 'L'), /** proposal for signing */ - static HashPrefix const proposal; + proposal = detail::make_hash_prefix('P', 'R', 'P'), /** Manifest */ - static HashPrefix const manifest; + manifest = detail::make_hash_prefix('M', 'A', 'N'), /** Payment Channel Claim */ - static HashPrefix const paymentChannelClaim; + paymentChannelClaim = detail::make_hash_prefix('C', 'L', 'M'), }; template diff --git a/src/ripple/protocol/STObject.h b/src/ripple/protocol/STObject.h index 97cd3611b9e..385cf20c766 100644 --- a/src/ripple/protocol/STObject.h +++ b/src/ripple/protocol/STObject.h @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -383,8 +384,8 @@ class STObject bool isFlag(std::uint32_t) const; std::uint32_t getFlags () const; - uint256 getHash (std::uint32_t prefix) const; - uint256 getSigningHash (std::uint32_t prefix) const; + uint256 getHash (HashPrefix prefix) const; + uint256 getSigningHash (HashPrefix prefix) const; const STBase& peekAtIndex (int offset) const { diff --git a/src/ripple/protocol/Serializer.h b/src/ripple/protocol/Serializer.h index 9944f95d58a..8249ecf60a9 100644 --- a/src/ripple/protocol/Serializer.h +++ b/src/ripple/protocol/Serializer.h @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -84,6 +85,7 @@ class Serializer int add8 (unsigned char byte); int add16 (std::uint16_t); int add32 (std::uint32_t); // ledger indexes, account sequence, timestamps + int add32 (HashPrefix); int add64 (std::uint64_t); // native currency amounts int add128 (const uint128&); // private key generators int add256 (uint256 const& ); // transaction and ledger hashes diff --git a/src/ripple/protocol/impl/HashPrefix.cpp b/src/ripple/protocol/impl/HashPrefix.cpp deleted file mode 100644 index 24f7c33dec2..00000000000 --- a/src/ripple/protocol/impl/HashPrefix.cpp +++ /dev/null @@ -1,39 +0,0 @@ -//------------------------------------------------------------------------------ -/* - 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. -*/ -//============================================================================== - -#include - -namespace ripple { - -// The prefix codes are part of the Ripple protocol -// and existing codes cannot be arbitrarily changed. - -HashPrefix const HashPrefix::transactionID ('T', 'X', 'N'); -HashPrefix const HashPrefix::txNode ('S', 'N', 'D'); -HashPrefix const HashPrefix::leafNode ('M', 'L', 'N'); -HashPrefix const HashPrefix::innerNode ('M', 'I', 'N'); -HashPrefix const HashPrefix::ledgerMaster ('L', 'W', 'R'); -HashPrefix const HashPrefix::txSign ('S', 'T', 'X'); -HashPrefix const HashPrefix::txMultiSign ('S', 'M', 'T'); -HashPrefix const HashPrefix::validation ('V', 'A', 'L'); -HashPrefix const HashPrefix::proposal ('P', 'R', 'P'); -HashPrefix const HashPrefix::manifest ('M', 'A', 'N'); -HashPrefix const HashPrefix::paymentChannelClaim ('C', 'L', 'M'); - -} // ripple diff --git a/src/ripple/protocol/impl/STObject.cpp b/src/ripple/protocol/impl/STObject.cpp index 7391651b369..d4aac10a79b 100644 --- a/src/ripple/protocol/impl/STObject.cpp +++ b/src/ripple/protocol/impl/STObject.cpp @@ -307,7 +307,7 @@ bool STObject::isEquivalent (const STBase& t) const }); } -uint256 STObject::getHash (std::uint32_t prefix) const +uint256 STObject::getHash (HashPrefix prefix) const { Serializer s; s.add32 (prefix); @@ -315,7 +315,7 @@ uint256 STObject::getHash (std::uint32_t prefix) const return s.getSHA512Half (); } -uint256 STObject::getSigningHash (std::uint32_t prefix) const +uint256 STObject::getSigningHash (HashPrefix prefix) const { Serializer s; s.add32 (prefix); diff --git a/src/ripple/protocol/impl/Serializer.cpp b/src/ripple/protocol/impl/Serializer.cpp index a14423276c6..5a3b74d7c69 100644 --- a/src/ripple/protocol/impl/Serializer.cpp +++ b/src/ripple/protocol/impl/Serializer.cpp @@ -21,6 +21,7 @@ #include #include #include +#include namespace ripple { @@ -52,6 +53,17 @@ int Serializer::add32 (std::uint32_t i) return ret; } + +int Serializer::add32 (HashPrefix p) +{ + // This should never trigger; the size & type of a hash prefix are + // integral parts of the protocol and unlikely to ever change. + static_assert(std::is_same_v>); + + return add32(safe_cast(p)); +} + int Serializer::add64 (std::uint64_t i) { int ret = mData.size (); diff --git a/src/ripple/shamap/impl/SHAMapTreeNode.cpp b/src/ripple/shamap/impl/SHAMapTreeNode.cpp index 4c66871b405..eea9d4f4807 100644 --- a/src/ripple/shamap/impl/SHAMapTreeNode.cpp +++ b/src/ripple/shamap/impl/SHAMapTreeNode.cpp @@ -21,8 +21,8 @@ #include #include #include +#include #include -#include #include #include #include @@ -194,7 +194,7 @@ SHAMapAbstractNode::make(Slice const& rawNode, std::uint32_t seq, SHANodeFormat prefix |= rawNode[3]; Serializer s (rawNode.data() + 4, rawNode.size() - 4); - if (prefix == HashPrefix::transactionID) + if (safe_cast(prefix) == HashPrefix::transactionID) { auto item = std::make_shared( sha512Half(rawNode), @@ -203,7 +203,7 @@ SHAMapAbstractNode::make(Slice const& rawNode, std::uint32_t seq, SHANodeFormat return std::make_shared(item, tnTRANSACTION_NM, seq, hash); return std::make_shared(item, tnTRANSACTION_NM, seq); } - else if (prefix == HashPrefix::leafNode) + else if (safe_cast(prefix) == HashPrefix::leafNode) { if (s.getLength () < 32) Throw ("short PLN node"); @@ -223,7 +223,7 @@ SHAMapAbstractNode::make(Slice const& rawNode, std::uint32_t seq, SHANodeFormat return std::make_shared(item, tnACCOUNT_STATE, seq, hash); return std::make_shared(item, tnACCOUNT_STATE, seq); } - else if (prefix == HashPrefix::innerNode) + else if (safe_cast(prefix) == HashPrefix::innerNode) { auto len = s.getLength(); @@ -246,7 +246,7 @@ SHAMapAbstractNode::make(Slice const& rawNode, std::uint32_t seq, SHANodeFormat ret->updateHash(); return ret; } - else if (prefix == HashPrefix::txNode) + else if (safe_cast(prefix) == HashPrefix::txNode) { // transaction with metadata if (s.getLength () < 32)