mirror of
https://github.com/dashpay/dash.git
synced 2024-12-26 20:42:59 +01:00
Merge pull request #5510
a0ae79d
Replace CBlockHeader::GetHash with call to SerializeHash (Wladimir J. van der Laan)62b30f0
Add serialize float/double tests (Wladimir J. van der Laan)9f4fac9
src/txmempool.cpp: make numEntries a uint32_t (Wladimir J. van der Laan)f4e6487
src/arith_256.cpp: bigendian compatibility (Wladimir J. van der Laan)aac3205
src/netbase.h: Fix endian in CNetAddr serialization (Wladimir J. van der Laan)01f9c34
src/serialize.h: base serialization level endianness neutrality (Wladimir J. van der Laan)4e853aa
src/script/script.h: endian compatibility for PUSHDATA sizes (Wladimir J. van der Laan)4f92773
src/primitives/transaction.h: endian compatibility in serialization (Wladimir J. van der Laan)81aeb28
src/primitives/block.cpp: endian compatibility in GetHash (Wladimir J. van der Laan)dec84ca
src/net.cpp: endian compatibility in EndMessage (Wladimir J. van der Laan)556814e
src/main.cpp: endian compatibility in packet checksum check (Wladimir J. van der Laan)3ca5852
src/hash.cpp: endian compatibility (Wladimir J. van der Laan)4414f5f
build: Endian compatibility (Wladimir J. van der Laan)
This commit is contained in:
commit
7c3fbc34ae
13
configure.ac
13
configure.ac
@ -350,8 +350,8 @@ if test x$use_lcov = xyes; then
|
||||
[AC_MSG_ERROR("lcov testing requested but --coverage flag does not work")])
|
||||
fi
|
||||
|
||||
dnl Require little endian
|
||||
AC_C_BIGENDIAN([AC_MSG_ERROR("Big Endian not supported")])
|
||||
dnl Check for endianness
|
||||
AC_C_BIGENDIAN
|
||||
|
||||
dnl Check for pthread compile/link requirements
|
||||
AX_PTHREAD
|
||||
@ -438,17 +438,22 @@ if test x$TARGET_OS = xdarwin; then
|
||||
AX_CHECK_LINK_FLAG([[-Wl,-dead_strip]], [LDFLAGS="$LDFLAGS -Wl,-dead_strip"])
|
||||
fi
|
||||
|
||||
AC_CHECK_HEADERS([endian.h stdio.h stdlib.h unistd.h strings.h sys/types.h sys/stat.h sys/select.h sys/prctl.h])
|
||||
AC_CHECK_HEADERS([endian.h byteswap.h stdio.h stdlib.h unistd.h strings.h sys/types.h sys/stat.h sys/select.h sys/prctl.h])
|
||||
AC_SEARCH_LIBS([getaddrinfo_a], [anl], [AC_DEFINE(HAVE_GETADDRINFO_A, 1, [Define this symbol if you have getaddrinfo_a])])
|
||||
AC_SEARCH_LIBS([inet_pton], [nsl resolv], [AC_DEFINE(HAVE_INET_PTON, 1, [Define this symbol if you have inet_pton])])
|
||||
|
||||
AC_CHECK_DECLS([strnlen])
|
||||
|
||||
AC_CHECK_DECLS([le32toh, le64toh, htole32, htole64, be32toh, be64toh, htobe32, htobe64],,,
|
||||
AC_CHECK_DECLS([le16toh, le32toh, le64toh, htole16, htole32, htole64, be16toh, be32toh, be64toh, htobe16, htobe32, htobe64],,,
|
||||
[#if HAVE_ENDIAN_H
|
||||
#include <endian.h>
|
||||
#endif])
|
||||
|
||||
AC_CHECK_DECLS([bswap_16, bswap_32, bswap_64],,,
|
||||
[#if HAVE_BYTESWAP_H
|
||||
#include <byteswap.h>
|
||||
#endif])
|
||||
|
||||
dnl Check for MSG_NOSIGNAL
|
||||
AC_MSG_CHECKING(for MSG_NOSIGNAL)
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/socket.h>]],
|
||||
|
@ -141,6 +141,8 @@ BITCOIN_CORE_H = \
|
||||
walletdb.h \
|
||||
wallet.h \
|
||||
wallet_ismine.h \
|
||||
compat/byteswap.h \
|
||||
compat/endian.h \
|
||||
compat/sanity.h
|
||||
|
||||
JSON_H = \
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
#include "uint256.h"
|
||||
#include "utilstrencodings.h"
|
||||
#include "crypto/common.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
@ -246,14 +247,14 @@ uint32_t arith_uint256::GetCompact(bool fNegative) const
|
||||
uint256 ArithToUint256(const arith_uint256 &a)
|
||||
{
|
||||
uint256 b;
|
||||
// TODO: needs bswap32 on big-endian
|
||||
memcpy(b.begin(), a.pn, a.size());
|
||||
for(int x=0; x<a.WIDTH; ++x)
|
||||
WriteLE32(b.begin() + x*4, a.pn[x]);
|
||||
return b;
|
||||
}
|
||||
arith_uint256 UintToArith256(const uint256 &a)
|
||||
{
|
||||
arith_uint256 b;
|
||||
// TODO: needs bswap32 on big-endian
|
||||
memcpy(b.pn, a.begin(), a.size());
|
||||
for(int x=0; x<b.WIDTH; ++x)
|
||||
b.pn[x] = ReadLE32(a.begin() + x*4);
|
||||
return b;
|
||||
}
|
||||
|
47
src/compat/byteswap.h
Normal file
47
src/compat/byteswap.h
Normal file
@ -0,0 +1,47 @@
|
||||
// Copyright (c) 2014 The Bitcoin developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#ifndef BITCOIN_COMPAT_BYTESWAP_H
|
||||
#define BITCOIN_COMPAT_BYTESWAP_H
|
||||
|
||||
#if defined(HAVE_CONFIG_H)
|
||||
#include "config/bitcoin-config.h"
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#if defined(HAVE_BYTESWAP_H)
|
||||
#include <byteswap.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_DECL_BSWAP_16 == 0
|
||||
inline uint16_t bswap_16(uint16_t x)
|
||||
{
|
||||
return (x >> 8) | ((x & 0x00ff) << 8);
|
||||
}
|
||||
#endif // HAVE_DECL_BSWAP16
|
||||
|
||||
#if HAVE_DECL_BSWAP_32 == 0
|
||||
inline uint32_t bswap_32(uint32_t x)
|
||||
{
|
||||
return (((x & 0xff000000U) >> 24) | ((x & 0x00ff0000U) >> 8) |
|
||||
((x & 0x0000ff00U) << 8) | ((x & 0x000000ffU) << 24));
|
||||
}
|
||||
#endif // HAVE_DECL_BSWAP32
|
||||
|
||||
#if HAVE_DECL_BSWAP_64 == 0
|
||||
inline uint64_t bswap_64(uint64_t x)
|
||||
{
|
||||
return (((x & 0xff00000000000000ull) >> 56)
|
||||
| ((x & 0x00ff000000000000ull) >> 40)
|
||||
| ((x & 0x0000ff0000000000ull) >> 24)
|
||||
| ((x & 0x000000ff00000000ull) >> 8)
|
||||
| ((x & 0x00000000ff000000ull) << 8)
|
||||
| ((x & 0x0000000000ff0000ull) << 24)
|
||||
| ((x & 0x000000000000ff00ull) << 40)
|
||||
| ((x & 0x00000000000000ffull) << 56));
|
||||
}
|
||||
#endif // HAVE_DECL_BSWAP64
|
||||
|
||||
#endif // BITCOIN_COMPAT_BYTESWAP_H
|
194
src/compat/endian.h
Normal file
194
src/compat/endian.h
Normal file
@ -0,0 +1,194 @@
|
||||
// Copyright (c) 2014 The Bitcoin developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#ifndef BITCOIN_COMPAT_ENDIAN_H
|
||||
#define BITCOIN_COMPAT_ENDIAN_H
|
||||
|
||||
#if defined(HAVE_CONFIG_H)
|
||||
#include "config/bitcoin-config.h"
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "compat/byteswap.h"
|
||||
|
||||
#if defined(HAVE_ENDIAN_H)
|
||||
#include <endian.h>
|
||||
#endif
|
||||
|
||||
#if defined(WORDS_BIGENDIAN)
|
||||
|
||||
#if HAVE_DECL_HTOBE16 == 0
|
||||
inline uint16_t htobe16(uint16_t host_16bits)
|
||||
{
|
||||
return host_16bits;
|
||||
}
|
||||
#endif // HAVE_DECL_HTOBE16
|
||||
|
||||
#if HAVE_DECL_HTOLE16 == 0
|
||||
inline uint16_t htole16(uint16_t host_16bits)
|
||||
{
|
||||
return bswap_16(host_16bits);
|
||||
}
|
||||
#endif // HAVE_DECL_HTOLE16
|
||||
|
||||
#if HAVE_DECL_BE16TOH == 0
|
||||
inline uint16_t be16toh(uint16_t big_endian_16bits)
|
||||
{
|
||||
return big_endian_16bits;
|
||||
}
|
||||
#endif // HAVE_DECL_BE16TOH
|
||||
|
||||
#if HAVE_DECL_LE16TOH == 0
|
||||
inline uint16_t le16toh(uint16_t little_endian_16bits)
|
||||
{
|
||||
return bswap_16(little_endian_16bits);
|
||||
}
|
||||
#endif // HAVE_DECL_LE16TOH
|
||||
|
||||
#if HAVE_DECL_HTOBE32 == 0
|
||||
inline uint32_t htobe32(uint32_t host_32bits)
|
||||
{
|
||||
return host_32bits;
|
||||
}
|
||||
#endif // HAVE_DECL_HTOBE32
|
||||
|
||||
#if HAVE_DECL_HTOLE32 == 0
|
||||
inline uint32_t htole32(uint32_t host_32bits)
|
||||
{
|
||||
return bswap_32(host_32bits);
|
||||
}
|
||||
#endif // HAVE_DECL_HTOLE32
|
||||
|
||||
#if HAVE_DECL_BE32TOH == 0
|
||||
inline uint32_t be32toh(uint32_t big_endian_32bits)
|
||||
{
|
||||
return big_endian_32bits;
|
||||
}
|
||||
#endif // HAVE_DECL_BE32TOH
|
||||
|
||||
#if HAVE_DECL_LE32TOH == 0
|
||||
inline uint32_t le32toh(uint32_t little_endian_32bits)
|
||||
{
|
||||
return bswap_32(little_endian_32bits);
|
||||
}
|
||||
#endif // HAVE_DECL_LE32TOH
|
||||
|
||||
#if HAVE_DECL_HTOBE64 == 0
|
||||
inline uint64_t htobe64(uint64_t host_64bits)
|
||||
{
|
||||
return host_64bits;
|
||||
}
|
||||
#endif // HAVE_DECL_HTOBE64
|
||||
|
||||
#if HAVE_DECL_HTOLE64 == 0
|
||||
inline uint64_t htole64(uint64_t host_64bits)
|
||||
{
|
||||
return bswap_64(host_64bits);
|
||||
}
|
||||
#endif // HAVE_DECL_HTOLE64
|
||||
|
||||
#if HAVE_DECL_BE64TOH == 0
|
||||
inline uint64_t be64toh(uint64_t big_endian_64bits)
|
||||
{
|
||||
return big_endian_64bits;
|
||||
}
|
||||
#endif // HAVE_DECL_BE64TOH
|
||||
|
||||
#if HAVE_DECL_LE64TOH == 0
|
||||
inline uint64_t le64toh(uint64_t little_endian_64bits)
|
||||
{
|
||||
return bswap_64(little_endian_64bits);
|
||||
}
|
||||
#endif // HAVE_DECL_LE64TOH
|
||||
|
||||
#else // WORDS_BIGENDIAN
|
||||
|
||||
#if HAVE_DECL_HTOBE16 == 0
|
||||
inline uint16_t htobe16(uint16_t host_16bits)
|
||||
{
|
||||
return bswap_16(host_16bits);
|
||||
}
|
||||
#endif // HAVE_DECL_HTOBE16
|
||||
|
||||
#if HAVE_DECL_HTOLE16 == 0
|
||||
inline uint16_t htole16(uint16_t host_16bits)
|
||||
{
|
||||
return host_16bits;
|
||||
}
|
||||
#endif // HAVE_DECL_HTOLE16
|
||||
|
||||
#if HAVE_DECL_BE16TOH == 0
|
||||
inline uint16_t be16toh(uint16_t big_endian_16bits)
|
||||
{
|
||||
return bswap_16(big_endian_16bits);
|
||||
}
|
||||
#endif // HAVE_DECL_BE16TOH
|
||||
|
||||
#if HAVE_DECL_LE16TOH == 0
|
||||
inline uint16_t le16toh(uint16_t little_endian_16bits)
|
||||
{
|
||||
return little_endian_16bits;
|
||||
}
|
||||
#endif // HAVE_DECL_LE16TOH
|
||||
|
||||
#if HAVE_DECL_HTOBE32 == 0
|
||||
inline uint32_t htobe32(uint32_t host_32bits)
|
||||
{
|
||||
return bswap_32(host_32bits);
|
||||
}
|
||||
#endif // HAVE_DECL_HTOBE32
|
||||
|
||||
#if HAVE_DECL_HTOLE32 == 0
|
||||
inline uint32_t htole32(uint32_t host_32bits)
|
||||
{
|
||||
return host_32bits;
|
||||
}
|
||||
#endif // HAVE_DECL_HTOLE32
|
||||
|
||||
#if HAVE_DECL_BE32TOH == 0
|
||||
inline uint32_t be32toh(uint32_t big_endian_32bits)
|
||||
{
|
||||
return bswap_32(big_endian_32bits);
|
||||
}
|
||||
#endif // HAVE_DECL_BE32TOH
|
||||
|
||||
#if HAVE_DECL_LE32TOH == 0
|
||||
inline uint32_t le32toh(uint32_t little_endian_32bits)
|
||||
{
|
||||
return little_endian_32bits;
|
||||
}
|
||||
#endif // HAVE_DECL_LE32TOH
|
||||
|
||||
#if HAVE_DECL_HTOBE64 == 0
|
||||
inline uint64_t htobe64(uint64_t host_64bits)
|
||||
{
|
||||
return bswap_64(host_64bits);
|
||||
}
|
||||
#endif // HAVE_DECL_HTOBE64
|
||||
|
||||
#if HAVE_DECL_HTOLE64 == 0
|
||||
inline uint64_t htole64(uint64_t host_64bits)
|
||||
{
|
||||
return host_64bits;
|
||||
}
|
||||
#endif // HAVE_DECL_HTOLE64
|
||||
|
||||
#if HAVE_DECL_BE64TOH == 0
|
||||
inline uint64_t be64toh(uint64_t big_endian_64bits)
|
||||
{
|
||||
return bswap_64(big_endian_64bits);
|
||||
}
|
||||
#endif // HAVE_DECL_BE64TOH
|
||||
|
||||
#if HAVE_DECL_LE64TOH == 0
|
||||
inline uint64_t le64toh(uint64_t little_endian_64bits)
|
||||
{
|
||||
return little_endian_64bits;
|
||||
}
|
||||
#endif // HAVE_DECL_LE64TOH
|
||||
|
||||
#endif // WORDS_BIGENDIAN
|
||||
|
||||
#endif // BITCOIN_COMPAT_ENDIAN_H
|
@ -11,110 +11,56 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#if defined(HAVE_ENDIAN_H)
|
||||
#include <endian.h>
|
||||
#endif
|
||||
#include "compat/endian.h"
|
||||
|
||||
uint16_t static inline ReadLE16(const unsigned char* ptr)
|
||||
{
|
||||
return le16toh(*((uint16_t*)ptr));
|
||||
}
|
||||
|
||||
uint32_t static inline ReadLE32(const unsigned char* ptr)
|
||||
{
|
||||
#if HAVE_DECL_LE32TOH == 1
|
||||
return le32toh(*((uint32_t*)ptr));
|
||||
#elif !defined(WORDS_BIGENDIAN)
|
||||
return *((uint32_t*)ptr);
|
||||
#else
|
||||
return ((uint32_t)ptr[3] << 24 | (uint32_t)ptr[2] << 16 | (uint32_t)ptr[1] << 8 | (uint32_t)ptr[0]);
|
||||
#endif
|
||||
}
|
||||
|
||||
uint64_t static inline ReadLE64(const unsigned char* ptr)
|
||||
{
|
||||
#if HAVE_DECL_LE64TOH == 1
|
||||
return le64toh(*((uint64_t*)ptr));
|
||||
#elif !defined(WORDS_BIGENDIAN)
|
||||
return *((uint64_t*)ptr);
|
||||
#else
|
||||
return ((uint64_t)ptr[7] << 56 | (uint64_t)ptr[6] << 48 | (uint64_t)ptr[5] << 40 | (uint64_t)ptr[4] << 32 |
|
||||
(uint64_t)ptr[3] << 24 | (uint64_t)ptr[2] << 16 | (uint64_t)ptr[1] << 8 | (uint64_t)ptr[0]);
|
||||
#endif
|
||||
}
|
||||
|
||||
void static inline WriteLE16(unsigned char* ptr, uint16_t x)
|
||||
{
|
||||
*((uint16_t*)ptr) = htole16(x);
|
||||
}
|
||||
|
||||
void static inline WriteLE32(unsigned char* ptr, uint32_t x)
|
||||
{
|
||||
#if HAVE_DECL_HTOLE32 == 1
|
||||
*((uint32_t*)ptr) = htole32(x);
|
||||
#elif !defined(WORDS_BIGENDIAN)
|
||||
*((uint32_t*)ptr) = x;
|
||||
#else
|
||||
ptr[3] = x >> 24;
|
||||
ptr[2] = x >> 16;
|
||||
ptr[1] = x >> 8;
|
||||
ptr[0] = x;
|
||||
#endif
|
||||
}
|
||||
|
||||
void static inline WriteLE64(unsigned char* ptr, uint64_t x)
|
||||
{
|
||||
#if HAVE_DECL_HTOLE64 == 1
|
||||
*((uint64_t*)ptr) = htole64(x);
|
||||
#elif !defined(WORDS_BIGENDIAN)
|
||||
*((uint64_t*)ptr) = x;
|
||||
#else
|
||||
ptr[7] = x >> 56;
|
||||
ptr[6] = x >> 48;
|
||||
ptr[5] = x >> 40;
|
||||
ptr[4] = x >> 32;
|
||||
ptr[3] = x >> 24;
|
||||
ptr[2] = x >> 16;
|
||||
ptr[1] = x >> 8;
|
||||
ptr[0] = x;
|
||||
#endif
|
||||
}
|
||||
|
||||
uint32_t static inline ReadBE32(const unsigned char* ptr)
|
||||
{
|
||||
#if HAVE_DECL_BE32TOH == 1
|
||||
return be32toh(*((uint32_t*)ptr));
|
||||
#else
|
||||
return ((uint32_t)ptr[0] << 24 | (uint32_t)ptr[1] << 16 | (uint32_t)ptr[2] << 8 | (uint32_t)ptr[3]);
|
||||
#endif
|
||||
}
|
||||
|
||||
uint64_t static inline ReadBE64(const unsigned char* ptr)
|
||||
{
|
||||
#if HAVE_DECL_BE64TOH == 1
|
||||
return be64toh(*((uint64_t*)ptr));
|
||||
#else
|
||||
return ((uint64_t)ptr[0] << 56 | (uint64_t)ptr[1] << 48 | (uint64_t)ptr[2] << 40 | (uint64_t)ptr[3] << 32 |
|
||||
(uint64_t)ptr[4] << 24 | (uint64_t)ptr[5] << 16 | (uint64_t)ptr[6] << 8 | (uint64_t)ptr[7]);
|
||||
#endif
|
||||
}
|
||||
|
||||
void static inline WriteBE32(unsigned char* ptr, uint32_t x)
|
||||
{
|
||||
#if HAVE_DECL_HTOBE32 == 1
|
||||
*((uint32_t*)ptr) = htobe32(x);
|
||||
#else
|
||||
ptr[0] = x >> 24;
|
||||
ptr[1] = x >> 16;
|
||||
ptr[2] = x >> 8;
|
||||
ptr[3] = x;
|
||||
#endif
|
||||
}
|
||||
|
||||
void static inline WriteBE64(unsigned char* ptr, uint64_t x)
|
||||
{
|
||||
#if HAVE_DECL_HTOBE64 == 1
|
||||
*((uint64_t*)ptr) = htobe64(x);
|
||||
#else
|
||||
ptr[0] = x >> 56;
|
||||
ptr[1] = x >> 48;
|
||||
ptr[2] = x >> 40;
|
||||
ptr[3] = x >> 32;
|
||||
ptr[4] = x >> 24;
|
||||
ptr[5] = x >> 16;
|
||||
ptr[6] = x >> 8;
|
||||
ptr[7] = x;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif // BITCOIN_CRYPTO_COMMON_H
|
||||
|
@ -3,8 +3,10 @@
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "hash.h"
|
||||
#include "crypto/common.h"
|
||||
#include "crypto/hmac_sha512.h"
|
||||
|
||||
|
||||
inline uint32_t ROTL32(uint32_t x, int8_t r)
|
||||
{
|
||||
return (x << r) | (x >> (32 - r));
|
||||
@ -23,10 +25,10 @@ unsigned int MurmurHash3(unsigned int nHashSeed, const std::vector<unsigned char
|
||||
|
||||
//----------
|
||||
// body
|
||||
const uint32_t* blocks = (const uint32_t*)(&vDataToHash[0] + nblocks * 4);
|
||||
const uint8_t* blocks = &vDataToHash[0] + nblocks * 4;
|
||||
|
||||
for (int i = -nblocks; i; i++) {
|
||||
uint32_t k1 = blocks[i];
|
||||
uint32_t k1 = ReadLE32(blocks + i*4);
|
||||
|
||||
k1 *= c1;
|
||||
k1 = ROTL32(k1, 15);
|
||||
|
@ -4318,8 +4318,7 @@ bool ProcessMessages(CNode* pfrom)
|
||||
// Checksum
|
||||
CDataStream& vRecv = msg.vRecv;
|
||||
uint256 hash = Hash(vRecv.begin(), vRecv.begin() + nMessageSize);
|
||||
unsigned int nChecksum = 0;
|
||||
memcpy(&nChecksum, &hash, sizeof(nChecksum));
|
||||
unsigned int nChecksum = ReadLE32((unsigned char*)&hash);
|
||||
if (nChecksum != hdr.nChecksum)
|
||||
{
|
||||
LogPrintf("ProcessMessages(%s, %u bytes): CHECKSUM ERROR nChecksum=%08x hdr.nChecksum=%08x\n",
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "clientversion.h"
|
||||
#include "primitives/transaction.h"
|
||||
#include "ui_interface.h"
|
||||
#include "crypto/common.h"
|
||||
|
||||
#ifdef WIN32
|
||||
#include <string.h>
|
||||
@ -2007,7 +2008,7 @@ void CNode::EndMessage() UNLOCK_FUNCTION(cs_vSend)
|
||||
|
||||
// Set the size
|
||||
unsigned int nSize = ssSend.size() - CMessageHeader::HEADER_SIZE;
|
||||
memcpy((char*)&ssSend[CMessageHeader::MESSAGE_SIZE_OFFSET], &nSize, sizeof(nSize));
|
||||
WriteLE32((uint8_t*)&ssSend[CMessageHeader::MESSAGE_SIZE_OFFSET], nSize);
|
||||
|
||||
// Set the checksum
|
||||
uint256 hash = Hash(ssSend.begin() + CMessageHeader::HEADER_SIZE, ssSend.end());
|
||||
|
@ -162,7 +162,7 @@ class CService : public CNetAddr
|
||||
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
|
||||
READWRITE(FLATDATA(ip));
|
||||
unsigned short portN = htons(port);
|
||||
READWRITE(portN);
|
||||
READWRITE(FLATDATA(portN));
|
||||
if (ser_action.ForRead())
|
||||
port = ntohs(portN);
|
||||
}
|
||||
|
@ -8,10 +8,11 @@
|
||||
#include "hash.h"
|
||||
#include "tinyformat.h"
|
||||
#include "utilstrencodings.h"
|
||||
#include "crypto/common.h"
|
||||
|
||||
uint256 CBlockHeader::GetHash() const
|
||||
{
|
||||
return Hash(BEGIN(nVersion), END(nNonce));
|
||||
return SerializeHash(*this);
|
||||
}
|
||||
|
||||
uint256 CBlock::BuildMerkleTree(bool* fMutated) const
|
||||
|
@ -25,7 +25,8 @@ public:
|
||||
|
||||
template <typename Stream, typename Operation>
|
||||
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
|
||||
READWRITE(FLATDATA(*this));
|
||||
READWRITE(hash);
|
||||
READWRITE(n);
|
||||
}
|
||||
|
||||
void SetNull() { hash.SetNull(); n = (uint32_t) -1; }
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include <string.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "crypto/common.h"
|
||||
|
||||
static const unsigned int MAX_SCRIPT_ELEMENT_SIZE = 520; // bytes
|
||||
|
||||
@ -416,14 +417,16 @@ public:
|
||||
else if (b.size() <= 0xffff)
|
||||
{
|
||||
insert(end(), OP_PUSHDATA2);
|
||||
unsigned short nSize = b.size();
|
||||
insert(end(), (unsigned char*)&nSize, (unsigned char*)&nSize + sizeof(nSize));
|
||||
uint8_t data[2];
|
||||
WriteLE16(data, b.size());
|
||||
insert(end(), data, data + sizeof(data));
|
||||
}
|
||||
else
|
||||
{
|
||||
insert(end(), OP_PUSHDATA4);
|
||||
unsigned int nSize = b.size();
|
||||
insert(end(), (unsigned char*)&nSize, (unsigned char*)&nSize + sizeof(nSize));
|
||||
uint8_t data[4];
|
||||
WriteLE32(data, b.size());
|
||||
insert(end(), data, data + sizeof(data));
|
||||
}
|
||||
insert(end(), b.begin(), b.end());
|
||||
return *this;
|
||||
@ -496,15 +499,14 @@ public:
|
||||
{
|
||||
if (end() - pc < 2)
|
||||
return false;
|
||||
nSize = 0;
|
||||
memcpy(&nSize, &pc[0], 2);
|
||||
nSize = ReadLE16(&pc[0]);
|
||||
pc += 2;
|
||||
}
|
||||
else if (opcode == OP_PUSHDATA4)
|
||||
{
|
||||
if (end() - pc < 4)
|
||||
return false;
|
||||
memcpy(&nSize, &pc[0], 4);
|
||||
nSize = ReadLE32(&pc[0]);
|
||||
pc += 4;
|
||||
}
|
||||
if (end() - pc < 0 || (unsigned int)(end() - pc) < nSize)
|
||||
|
197
src/serialize.h
197
src/serialize.h
@ -18,6 +18,8 @@
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "compat/endian.h"
|
||||
|
||||
class CScript;
|
||||
|
||||
static const unsigned int MAX_SIZE = 0x02000000;
|
||||
@ -71,6 +73,79 @@ inline const T* end_ptr(const std::vector<T,TAl>& v)
|
||||
return v.empty() ? NULL : (&v[0] + v.size());
|
||||
}
|
||||
|
||||
/*
|
||||
* Lowest-level serialization and conversion.
|
||||
* @note Sizes of these types are verified in the tests
|
||||
*/
|
||||
template<typename Stream> inline void ser_writedata8(Stream &s, uint8_t obj)
|
||||
{
|
||||
s.write((char*)&obj, 1);
|
||||
}
|
||||
template<typename Stream> inline void ser_writedata16(Stream &s, uint16_t obj)
|
||||
{
|
||||
obj = htole16(obj);
|
||||
s.write((char*)&obj, 2);
|
||||
}
|
||||
template<typename Stream> inline void ser_writedata32(Stream &s, uint32_t obj)
|
||||
{
|
||||
obj = htole32(obj);
|
||||
s.write((char*)&obj, 4);
|
||||
}
|
||||
template<typename Stream> inline void ser_writedata64(Stream &s, uint64_t obj)
|
||||
{
|
||||
obj = htole64(obj);
|
||||
s.write((char*)&obj, 8);
|
||||
}
|
||||
template<typename Stream> inline uint8_t ser_readdata8(Stream &s)
|
||||
{
|
||||
uint8_t obj;
|
||||
s.read((char*)&obj, 1);
|
||||
return obj;
|
||||
}
|
||||
template<typename Stream> inline uint16_t ser_readdata16(Stream &s)
|
||||
{
|
||||
uint16_t obj;
|
||||
s.read((char*)&obj, 2);
|
||||
return le16toh(obj);
|
||||
}
|
||||
template<typename Stream> inline uint32_t ser_readdata32(Stream &s)
|
||||
{
|
||||
uint32_t obj;
|
||||
s.read((char*)&obj, 4);
|
||||
return le32toh(obj);
|
||||
}
|
||||
template<typename Stream> inline uint64_t ser_readdata64(Stream &s)
|
||||
{
|
||||
uint64_t obj;
|
||||
s.read((char*)&obj, 8);
|
||||
return le64toh(obj);
|
||||
}
|
||||
inline uint64_t ser_double_to_uint64(double x)
|
||||
{
|
||||
union { double x; uint64_t y; } tmp;
|
||||
tmp.x = x;
|
||||
return tmp.y;
|
||||
}
|
||||
inline uint32_t ser_float_to_uint32(float x)
|
||||
{
|
||||
union { float x; uint32_t y; } tmp;
|
||||
tmp.x = x;
|
||||
return tmp.y;
|
||||
}
|
||||
inline double ser_uint64_to_double(uint64_t y)
|
||||
{
|
||||
union { double x; uint64_t y; } tmp;
|
||||
tmp.y = y;
|
||||
return tmp.x;
|
||||
}
|
||||
inline float ser_uint32_to_float(uint32_t y)
|
||||
{
|
||||
union { float x; uint32_t y; } tmp;
|
||||
tmp.y = y;
|
||||
return tmp.x;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Templates for serializing to anything that looks like a stream,
|
||||
@ -108,59 +183,48 @@ enum
|
||||
SerializationOp(s, CSerActionUnserialize(), nType, nVersion); \
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Basic Types
|
||||
*/
|
||||
#define WRITEDATA(s, obj) s.write((char*)&(obj), sizeof(obj))
|
||||
#define READDATA(s, obj) s.read((char*)&(obj), sizeof(obj))
|
||||
inline unsigned int GetSerializeSize(char a, int, int=0) { return 1; }
|
||||
inline unsigned int GetSerializeSize(int8_t a, int, int=0) { return 1; }
|
||||
inline unsigned int GetSerializeSize(uint8_t a, int, int=0) { return 1; }
|
||||
inline unsigned int GetSerializeSize(int16_t a, int, int=0) { return 2; }
|
||||
inline unsigned int GetSerializeSize(uint16_t a, int, int=0) { return 2; }
|
||||
inline unsigned int GetSerializeSize(int32_t a, int, int=0) { return 4; }
|
||||
inline unsigned int GetSerializeSize(uint32_t a, int, int=0) { return 4; }
|
||||
inline unsigned int GetSerializeSize(int64_t a, int, int=0) { return 8; }
|
||||
inline unsigned int GetSerializeSize(uint64_t a, int, int=0) { return 8; }
|
||||
inline unsigned int GetSerializeSize(float a, int, int=0) { return 4; }
|
||||
inline unsigned int GetSerializeSize(double a, int, int=0) { return 8; }
|
||||
|
||||
inline unsigned int GetSerializeSize(char a, int, int=0) { return sizeof(a); }
|
||||
inline unsigned int GetSerializeSize(signed char a, int, int=0) { return sizeof(a); }
|
||||
inline unsigned int GetSerializeSize(unsigned char a, int, int=0) { return sizeof(a); }
|
||||
inline unsigned int GetSerializeSize(signed short a, int, int=0) { return sizeof(a); }
|
||||
inline unsigned int GetSerializeSize(unsigned short a, int, int=0) { return sizeof(a); }
|
||||
inline unsigned int GetSerializeSize(signed int a, int, int=0) { return sizeof(a); }
|
||||
inline unsigned int GetSerializeSize(unsigned int a, int, int=0) { return sizeof(a); }
|
||||
inline unsigned int GetSerializeSize(signed long a, int, int=0) { return sizeof(a); }
|
||||
inline unsigned int GetSerializeSize(unsigned long a, int, int=0) { return sizeof(a); }
|
||||
inline unsigned int GetSerializeSize(signed long long a, int, int=0) { return sizeof(a); }
|
||||
inline unsigned int GetSerializeSize(unsigned long long a, int, int=0) { return sizeof(a); }
|
||||
inline unsigned int GetSerializeSize(float a, int, int=0) { return sizeof(a); }
|
||||
inline unsigned int GetSerializeSize(double a, int, int=0) { return sizeof(a); }
|
||||
template<typename Stream> inline void Serialize(Stream& s, char a, int, int=0) { ser_writedata8(s, a); } // TODO Get rid of bare char
|
||||
template<typename Stream> inline void Serialize(Stream& s, int8_t a, int, int=0) { ser_writedata8(s, a); }
|
||||
template<typename Stream> inline void Serialize(Stream& s, uint8_t a, int, int=0) { ser_writedata8(s, a); }
|
||||
template<typename Stream> inline void Serialize(Stream& s, int16_t a, int, int=0) { ser_writedata16(s, a); }
|
||||
template<typename Stream> inline void Serialize(Stream& s, uint16_t a, int, int=0) { ser_writedata16(s, a); }
|
||||
template<typename Stream> inline void Serialize(Stream& s, int32_t a, int, int=0) { ser_writedata32(s, a); }
|
||||
template<typename Stream> inline void Serialize(Stream& s, uint32_t a, int, int=0) { ser_writedata32(s, a); }
|
||||
template<typename Stream> inline void Serialize(Stream& s, int64_t a, int, int=0) { ser_writedata64(s, a); }
|
||||
template<typename Stream> inline void Serialize(Stream& s, uint64_t a, int, int=0) { ser_writedata64(s, a); }
|
||||
template<typename Stream> inline void Serialize(Stream& s, float a, int, int=0) { ser_writedata32(s, ser_float_to_uint32(a)); }
|
||||
template<typename Stream> inline void Serialize(Stream& s, double a, int, int=0) { ser_writedata64(s, ser_double_to_uint64(a)); }
|
||||
|
||||
template<typename Stream> inline void Serialize(Stream& s, char a, int, int=0) { WRITEDATA(s, a); }
|
||||
template<typename Stream> inline void Serialize(Stream& s, signed char a, int, int=0) { WRITEDATA(s, a); }
|
||||
template<typename Stream> inline void Serialize(Stream& s, unsigned char a, int, int=0) { WRITEDATA(s, a); }
|
||||
template<typename Stream> inline void Serialize(Stream& s, signed short a, int, int=0) { WRITEDATA(s, a); }
|
||||
template<typename Stream> inline void Serialize(Stream& s, unsigned short a, int, int=0) { WRITEDATA(s, a); }
|
||||
template<typename Stream> inline void Serialize(Stream& s, signed int a, int, int=0) { WRITEDATA(s, a); }
|
||||
template<typename Stream> inline void Serialize(Stream& s, unsigned int a, int, int=0) { WRITEDATA(s, a); }
|
||||
template<typename Stream> inline void Serialize(Stream& s, signed long a, int, int=0) { WRITEDATA(s, a); }
|
||||
template<typename Stream> inline void Serialize(Stream& s, unsigned long a, int, int=0) { WRITEDATA(s, a); }
|
||||
template<typename Stream> inline void Serialize(Stream& s, signed long long a, int, int=0) { WRITEDATA(s, a); }
|
||||
template<typename Stream> inline void Serialize(Stream& s, unsigned long long a, int, int=0) { WRITEDATA(s, a); }
|
||||
template<typename Stream> inline void Serialize(Stream& s, float a, int, int=0) { WRITEDATA(s, a); }
|
||||
template<typename Stream> inline void Serialize(Stream& s, double a, int, int=0) { WRITEDATA(s, a); }
|
||||
|
||||
template<typename Stream> inline void Unserialize(Stream& s, char& a, int, int=0) { READDATA(s, a); }
|
||||
template<typename Stream> inline void Unserialize(Stream& s, signed char& a, int, int=0) { READDATA(s, a); }
|
||||
template<typename Stream> inline void Unserialize(Stream& s, unsigned char& a, int, int=0) { READDATA(s, a); }
|
||||
template<typename Stream> inline void Unserialize(Stream& s, signed short& a, int, int=0) { READDATA(s, a); }
|
||||
template<typename Stream> inline void Unserialize(Stream& s, unsigned short& a, int, int=0) { READDATA(s, a); }
|
||||
template<typename Stream> inline void Unserialize(Stream& s, signed int& a, int, int=0) { READDATA(s, a); }
|
||||
template<typename Stream> inline void Unserialize(Stream& s, unsigned int& a, int, int=0) { READDATA(s, a); }
|
||||
template<typename Stream> inline void Unserialize(Stream& s, signed long& a, int, int=0) { READDATA(s, a); }
|
||||
template<typename Stream> inline void Unserialize(Stream& s, unsigned long& a, int, int=0) { READDATA(s, a); }
|
||||
template<typename Stream> inline void Unserialize(Stream& s, signed long long& a, int, int=0) { READDATA(s, a); }
|
||||
template<typename Stream> inline void Unserialize(Stream& s, unsigned long long& a, int, int=0) { READDATA(s, a); }
|
||||
template<typename Stream> inline void Unserialize(Stream& s, float& a, int, int=0) { READDATA(s, a); }
|
||||
template<typename Stream> inline void Unserialize(Stream& s, double& a, int, int=0) { READDATA(s, a); }
|
||||
template<typename Stream> inline void Unserialize(Stream& s, char& a, int, int=0) { a = ser_readdata8(s); } // TODO Get rid of bare char
|
||||
template<typename Stream> inline void Unserialize(Stream& s, int8_t& a, int, int=0) { a = ser_readdata8(s); }
|
||||
template<typename Stream> inline void Unserialize(Stream& s, uint8_t& a, int, int=0) { a = ser_readdata8(s); }
|
||||
template<typename Stream> inline void Unserialize(Stream& s, int16_t& a, int, int=0) { a = ser_readdata16(s); }
|
||||
template<typename Stream> inline void Unserialize(Stream& s, uint16_t& a, int, int=0) { a = ser_readdata16(s); }
|
||||
template<typename Stream> inline void Unserialize(Stream& s, int32_t& a, int, int=0) { a = ser_readdata32(s); }
|
||||
template<typename Stream> inline void Unserialize(Stream& s, uint32_t& a, int, int=0) { a = ser_readdata32(s); }
|
||||
template<typename Stream> inline void Unserialize(Stream& s, int64_t& a, int, int=0) { a = ser_readdata64(s); }
|
||||
template<typename Stream> inline void Unserialize(Stream& s, uint64_t& a, int, int=0) { a = ser_readdata64(s); }
|
||||
template<typename Stream> inline void Unserialize(Stream& s, float& a, int, int=0) { a = ser_uint32_to_float(ser_readdata32(s)); }
|
||||
template<typename Stream> inline void Unserialize(Stream& s, double& a, int, int=0) { a = ser_uint64_to_double(ser_readdata64(s)); }
|
||||
|
||||
inline unsigned int GetSerializeSize(bool a, int, int=0) { return sizeof(char); }
|
||||
template<typename Stream> inline void Serialize(Stream& s, bool a, int, int=0) { char f=a; WRITEDATA(s, f); }
|
||||
template<typename Stream> inline void Unserialize(Stream& s, bool& a, int, int=0) { char f; READDATA(s, f); a=f; }
|
||||
template<typename Stream> inline void Serialize(Stream& s, bool a, int, int=0) { char f=a; ser_writedata8(s, f); }
|
||||
template<typename Stream> inline void Unserialize(Stream& s, bool& a, int, int=0) { char f=ser_readdata8(s); a=f; }
|
||||
|
||||
|
||||
|
||||
@ -187,29 +251,22 @@ void WriteCompactSize(Stream& os, uint64_t nSize)
|
||||
{
|
||||
if (nSize < 253)
|
||||
{
|
||||
unsigned char chSize = nSize;
|
||||
WRITEDATA(os, chSize);
|
||||
ser_writedata8(os, nSize);
|
||||
}
|
||||
else if (nSize <= std::numeric_limits<unsigned short>::max())
|
||||
{
|
||||
unsigned char chSize = 253;
|
||||
unsigned short xSize = nSize;
|
||||
WRITEDATA(os, chSize);
|
||||
WRITEDATA(os, xSize);
|
||||
ser_writedata8(os, 253);
|
||||
ser_writedata16(os, nSize);
|
||||
}
|
||||
else if (nSize <= std::numeric_limits<unsigned int>::max())
|
||||
{
|
||||
unsigned char chSize = 254;
|
||||
unsigned int xSize = nSize;
|
||||
WRITEDATA(os, chSize);
|
||||
WRITEDATA(os, xSize);
|
||||
ser_writedata8(os, 254);
|
||||
ser_writedata32(os, nSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned char chSize = 255;
|
||||
uint64_t xSize = nSize;
|
||||
WRITEDATA(os, chSize);
|
||||
WRITEDATA(os, xSize);
|
||||
ser_writedata8(os, 255);
|
||||
ser_writedata64(os, nSize);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -217,8 +274,7 @@ void WriteCompactSize(Stream& os, uint64_t nSize)
|
||||
template<typename Stream>
|
||||
uint64_t ReadCompactSize(Stream& is)
|
||||
{
|
||||
unsigned char chSize;
|
||||
READDATA(is, chSize);
|
||||
uint8_t chSize = ser_readdata8(is);
|
||||
uint64_t nSizeRet = 0;
|
||||
if (chSize < 253)
|
||||
{
|
||||
@ -226,25 +282,19 @@ uint64_t ReadCompactSize(Stream& is)
|
||||
}
|
||||
else if (chSize == 253)
|
||||
{
|
||||
unsigned short xSize;
|
||||
READDATA(is, xSize);
|
||||
nSizeRet = xSize;
|
||||
nSizeRet = ser_readdata16(is);
|
||||
if (nSizeRet < 253)
|
||||
throw std::ios_base::failure("non-canonical ReadCompactSize()");
|
||||
}
|
||||
else if (chSize == 254)
|
||||
{
|
||||
unsigned int xSize;
|
||||
READDATA(is, xSize);
|
||||
nSizeRet = xSize;
|
||||
nSizeRet = ser_readdata32(is);
|
||||
if (nSizeRet < 0x10000u)
|
||||
throw std::ios_base::failure("non-canonical ReadCompactSize()");
|
||||
}
|
||||
else
|
||||
{
|
||||
uint64_t xSize;
|
||||
READDATA(is, xSize);
|
||||
nSizeRet = xSize;
|
||||
nSizeRet = ser_readdata64(is);
|
||||
if (nSizeRet < 0x100000000ULL)
|
||||
throw std::ios_base::failure("non-canonical ReadCompactSize()");
|
||||
}
|
||||
@ -303,7 +353,7 @@ void WriteVarInt(Stream& os, I n)
|
||||
len++;
|
||||
}
|
||||
do {
|
||||
WRITEDATA(os, tmp[len]);
|
||||
ser_writedata8(os, tmp[len]);
|
||||
} while(len--);
|
||||
}
|
||||
|
||||
@ -312,8 +362,7 @@ I ReadVarInt(Stream& is)
|
||||
{
|
||||
I n = 0;
|
||||
while(true) {
|
||||
unsigned char chData;
|
||||
READDATA(is, chData);
|
||||
unsigned char chData = ser_readdata8(is);
|
||||
n = (n << 7) | (chData & 0x7F);
|
||||
if (chData & 0x80)
|
||||
n++;
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
#include "serialize.h"
|
||||
#include "streams.h"
|
||||
#include "hash.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
@ -13,6 +14,119 @@ using namespace std;
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(serialize_tests)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(sizes)
|
||||
{
|
||||
BOOST_CHECK_EQUAL(sizeof(char), GetSerializeSize(char(0), 0));
|
||||
BOOST_CHECK_EQUAL(sizeof(int8_t), GetSerializeSize(int8_t(0), 0));
|
||||
BOOST_CHECK_EQUAL(sizeof(uint8_t), GetSerializeSize(uint8_t(0), 0));
|
||||
BOOST_CHECK_EQUAL(sizeof(int16_t), GetSerializeSize(int16_t(0), 0));
|
||||
BOOST_CHECK_EQUAL(sizeof(uint16_t), GetSerializeSize(uint16_t(0), 0));
|
||||
BOOST_CHECK_EQUAL(sizeof(int32_t), GetSerializeSize(int32_t(0), 0));
|
||||
BOOST_CHECK_EQUAL(sizeof(uint32_t), GetSerializeSize(uint32_t(0), 0));
|
||||
BOOST_CHECK_EQUAL(sizeof(int64_t), GetSerializeSize(int64_t(0), 0));
|
||||
BOOST_CHECK_EQUAL(sizeof(uint64_t), GetSerializeSize(uint64_t(0), 0));
|
||||
BOOST_CHECK_EQUAL(sizeof(float), GetSerializeSize(float(0), 0));
|
||||
BOOST_CHECK_EQUAL(sizeof(double), GetSerializeSize(double(0), 0));
|
||||
// Bool is serialized as char
|
||||
BOOST_CHECK_EQUAL(sizeof(char), GetSerializeSize(bool(0), 0));
|
||||
|
||||
// Sanity-check GetSerializeSize and c++ type matching
|
||||
BOOST_CHECK_EQUAL(GetSerializeSize(char(0), 0), 1);
|
||||
BOOST_CHECK_EQUAL(GetSerializeSize(int8_t(0), 0), 1);
|
||||
BOOST_CHECK_EQUAL(GetSerializeSize(uint8_t(0), 0), 1);
|
||||
BOOST_CHECK_EQUAL(GetSerializeSize(int16_t(0), 0), 2);
|
||||
BOOST_CHECK_EQUAL(GetSerializeSize(uint16_t(0), 0), 2);
|
||||
BOOST_CHECK_EQUAL(GetSerializeSize(int32_t(0), 0), 4);
|
||||
BOOST_CHECK_EQUAL(GetSerializeSize(uint32_t(0), 0), 4);
|
||||
BOOST_CHECK_EQUAL(GetSerializeSize(int64_t(0), 0), 8);
|
||||
BOOST_CHECK_EQUAL(GetSerializeSize(uint64_t(0), 0), 8);
|
||||
BOOST_CHECK_EQUAL(GetSerializeSize(float(0), 0), 4);
|
||||
BOOST_CHECK_EQUAL(GetSerializeSize(double(0), 0), 8);
|
||||
BOOST_CHECK_EQUAL(GetSerializeSize(bool(0), 0), 1);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(floats_conversion)
|
||||
{
|
||||
// Choose values that map unambigiously to binary floating point to avoid
|
||||
// rounding issues at the compiler side.
|
||||
BOOST_CHECK_EQUAL(ser_uint32_to_float(0x00000000), 0.0F);
|
||||
BOOST_CHECK_EQUAL(ser_uint32_to_float(0x3f000000), 0.5F);
|
||||
BOOST_CHECK_EQUAL(ser_uint32_to_float(0x3f800000), 1.0F);
|
||||
BOOST_CHECK_EQUAL(ser_uint32_to_float(0x40000000), 2.0F);
|
||||
BOOST_CHECK_EQUAL(ser_uint32_to_float(0x40800000), 4.0F);
|
||||
BOOST_CHECK_EQUAL(ser_uint32_to_float(0x44444444), 785.066650390625F);
|
||||
|
||||
BOOST_CHECK_EQUAL(ser_float_to_uint32(0.0F), 0x00000000);
|
||||
BOOST_CHECK_EQUAL(ser_float_to_uint32(0.5F), 0x3f000000);
|
||||
BOOST_CHECK_EQUAL(ser_float_to_uint32(1.0F), 0x3f800000);
|
||||
BOOST_CHECK_EQUAL(ser_float_to_uint32(2.0F), 0x40000000);
|
||||
BOOST_CHECK_EQUAL(ser_float_to_uint32(4.0F), 0x40800000);
|
||||
BOOST_CHECK_EQUAL(ser_float_to_uint32(785.066650390625F), 0x44444444);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(doubles_conversion)
|
||||
{
|
||||
// Choose values that map unambigiously to binary floating point to avoid
|
||||
// rounding issues at the compiler side.
|
||||
BOOST_CHECK_EQUAL(ser_uint64_to_double(0x0000000000000000ULL), 0.0);
|
||||
BOOST_CHECK_EQUAL(ser_uint64_to_double(0x3fe0000000000000ULL), 0.5);
|
||||
BOOST_CHECK_EQUAL(ser_uint64_to_double(0x3ff0000000000000ULL), 1.0);
|
||||
BOOST_CHECK_EQUAL(ser_uint64_to_double(0x4000000000000000ULL), 2.0);
|
||||
BOOST_CHECK_EQUAL(ser_uint64_to_double(0x4010000000000000ULL), 4.0);
|
||||
BOOST_CHECK_EQUAL(ser_uint64_to_double(0x4088888880000000ULL), 785.066650390625);
|
||||
|
||||
BOOST_CHECK_EQUAL(ser_double_to_uint64(0.0), 0x0000000000000000ULL);
|
||||
BOOST_CHECK_EQUAL(ser_double_to_uint64(0.5), 0x3fe0000000000000ULL);
|
||||
BOOST_CHECK_EQUAL(ser_double_to_uint64(1.0), 0x3ff0000000000000ULL);
|
||||
BOOST_CHECK_EQUAL(ser_double_to_uint64(2.0), 0x4000000000000000ULL);
|
||||
BOOST_CHECK_EQUAL(ser_double_to_uint64(4.0), 0x4010000000000000ULL);
|
||||
BOOST_CHECK_EQUAL(ser_double_to_uint64(785.066650390625), 0x4088888880000000ULL);
|
||||
}
|
||||
/*
|
||||
Python code to generate the below hashes:
|
||||
|
||||
def reversed_hex(x):
|
||||
return binascii.hexlify(''.join(reversed(x)))
|
||||
def dsha256(x):
|
||||
return hashlib.sha256(hashlib.sha256(x).digest()).digest()
|
||||
|
||||
reversed_hex(dsha256(''.join(struct.pack('<f', x) for x in range(0,1000)))) == '8e8b4cf3e4df8b332057e3e23af42ebc663b61e0495d5e7e32d85099d7f3fe0c'
|
||||
reversed_hex(dsha256(''.join(struct.pack('<d', x) for x in range(0,1000)))) == '43d0c82591953c4eafe114590d392676a01585d25b25d433557f0d7878b23f96'
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(floats)
|
||||
{
|
||||
CDataStream ss(SER_DISK, 0);
|
||||
// encode
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
ss << float(i);
|
||||
}
|
||||
BOOST_CHECK(Hash(ss.begin(), ss.end()) == uint256S("8e8b4cf3e4df8b332057e3e23af42ebc663b61e0495d5e7e32d85099d7f3fe0c"));
|
||||
|
||||
// decode
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
float j;
|
||||
ss >> j;
|
||||
BOOST_CHECK_MESSAGE(i == j, "decoded:" << j << " expected:" << i);
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(doubles)
|
||||
{
|
||||
CDataStream ss(SER_DISK, 0);
|
||||
// encode
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
ss << double(i);
|
||||
}
|
||||
BOOST_CHECK(Hash(ss.begin(), ss.end()) == uint256S("43d0c82591953c4eafe114590d392676a01585d25b25d433557f0d7878b23f96"));
|
||||
|
||||
// decode
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
double j;
|
||||
ss >> j;
|
||||
BOOST_CHECK_MESSAGE(i == j, "decoded:" << j << " expected:" << i);
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(varints)
|
||||
{
|
||||
// encode
|
||||
|
@ -337,7 +337,7 @@ public:
|
||||
void Write(CAutoFile& fileout) const
|
||||
{
|
||||
fileout << nBestSeenHeight;
|
||||
fileout << history.size();
|
||||
fileout << (uint32_t)history.size();
|
||||
BOOST_FOREACH(const CBlockAverage& entry, history)
|
||||
{
|
||||
entry.Write(fileout);
|
||||
@ -348,7 +348,7 @@ public:
|
||||
{
|
||||
int nFileBestSeenHeight;
|
||||
filein >> nFileBestSeenHeight;
|
||||
size_t numEntries;
|
||||
uint32_t numEntries;
|
||||
filein >> numEntries;
|
||||
if (numEntries <= 0 || numEntries > 10000)
|
||||
throw runtime_error("Corrupt estimates file. Must have between 1 and 10k entries.");
|
||||
|
Loading…
Reference in New Issue
Block a user