diff --git a/src/Makefile.am b/src/Makefile.am index 6d0e1ed7b..0385ad902 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -80,6 +80,7 @@ BITCOIN_CORE_H = \ coincontrol.h \ coins.h \ compat.h \ + compressor.h \ core.h \ core/transaction.h \ core_io.h \ @@ -103,7 +104,6 @@ BITCOIN_CORE_H = \ rpcclient.h \ rpcprotocol.h \ rpcserver.h \ - script/compressor.h \ script/interpreter.h \ script/script.h \ script/sigcache.h \ @@ -214,6 +214,7 @@ libbitcoin_common_a_SOURCES = \ base58.cpp \ chainparams.cpp \ coins.cpp \ + compressor.cpp \ core.cpp \ core/transaction.cpp \ core_read.cpp \ @@ -223,7 +224,6 @@ libbitcoin_common_a_SOURCES = \ keystore.cpp \ netbase.cpp \ protocol.cpp \ - script/compressor.cpp \ script/interpreter.cpp \ script/script.cpp \ script/sigcache.cpp \ diff --git a/src/coins.h b/src/coins.h index 295b3d70d..ee9051562 100644 --- a/src/coins.h +++ b/src/coins.h @@ -6,8 +6,7 @@ #ifndef BITCOIN_COINS_H #define BITCOIN_COINS_H -#include "core.h" // Only for CTxOutCompressor -#include "core/transaction.h" +#include "compressor.h" #include "serialize.h" #include "uint256.h" #include "undo.h" diff --git a/src/script/compressor.cpp b/src/compressor.cpp similarity index 73% rename from src/script/compressor.cpp rename to src/compressor.cpp index af1acf48d..806175dd3 100644 --- a/src/script/compressor.cpp +++ b/src/compressor.cpp @@ -5,6 +5,7 @@ #include "compressor.h" +#include "hash.h" #include "key.h" #include "script/standard.h" @@ -128,3 +129,57 @@ bool CScriptCompressor::Decompress(unsigned int nSize, const std::vector= 1 && d <= 9); + n /= 10; + return 1 + (n*9 + d - 1)*10 + e; + } else { + return 1 + (n - 1)*10 + 9; + } +} + +uint64_t CTxOutCompressor::DecompressAmount(uint64_t x) +{ + // x = 0 OR x = 1+10*(9*n + d - 1) + e OR x = 1+10*(n - 1) + 9 + if (x == 0) + return 0; + x--; + // x = 10*(9*n + d - 1) + e + int e = x % 10; + x /= 10; + uint64_t n = 0; + if (e < 9) { + // x = 9*n + d - 1 + int d = (x % 9) + 1; + x /= 9; + // x = n + n = x*10 + d; + } else { + n = x+1; + } + while (e) { + n *= 10; + e--; + } + return n; +} diff --git a/src/script/compressor.h b/src/compressor.h similarity index 76% rename from src/script/compressor.h rename to src/compressor.h index 154e0b266..a612c3a88 100644 --- a/src/script/compressor.h +++ b/src/compressor.h @@ -3,9 +3,10 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#ifndef H_BITCOIN_SCRIPT_COMPRESSOR -#define H_BITCOIN_SCRIPT_COMPRESSOR +#ifndef H_BITCOIN_COMPRESSOR +#define H_BITCOIN_COMPRESSOR +#include "core/transaction.h" #include "script/script.h" #include "serialize.h" @@ -86,4 +87,33 @@ public: } }; -#endif // H_BITCOIN_SCRIPT_COMPRESSOR +/** wrapper for CTxOut that provides a more compact serialization */ +class CTxOutCompressor +{ +private: + CTxOut &txout; + +public: + static uint64_t CompressAmount(uint64_t nAmount); + static uint64_t DecompressAmount(uint64_t nAmount); + + CTxOutCompressor(CTxOut &txoutIn) : txout(txoutIn) { } + + ADD_SERIALIZE_METHODS; + + template + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { + if (!ser_action.ForRead()) { + uint64_t nVal = CompressAmount(txout.nValue); + READWRITE(VARINT(nVal)); + } else { + uint64_t nVal = 0; + READWRITE(VARINT(nVal)); + txout.nValue = DecompressAmount(nVal); + } + CScriptCompressor cscript(REF(txout.scriptPubKey)); + READWRITE(cscript); + } +}; + +#endif // H_BITCOIN_COMPRESSOR diff --git a/src/core.cpp b/src/core.cpp index 34188bca6..08139d542 100644 --- a/src/core.cpp +++ b/src/core.cpp @@ -9,60 +9,6 @@ #include "tinyformat.h" #include "utilstrencodings.h" -// Amount compression: -// * If the amount is 0, output 0 -// * first, divide the amount (in base units) by the largest power of 10 possible; call the exponent e (e is max 9) -// * if e<9, the last digit of the resulting number cannot be 0; store it as d, and drop it (divide by 10) -// * call the result n -// * output 1 + 10*(9*n + d - 1) + e -// * if e==9, we only know the resulting number is not zero, so output 1 + 10*(n - 1) + 9 -// (this is decodable, as d is in [1-9] and e is in [0-9]) - -uint64_t CTxOutCompressor::CompressAmount(uint64_t n) -{ - if (n == 0) - return 0; - int e = 0; - while (((n % 10) == 0) && e < 9) { - n /= 10; - e++; - } - if (e < 9) { - int d = (n % 10); - assert(d >= 1 && d <= 9); - n /= 10; - return 1 + (n*9 + d - 1)*10 + e; - } else { - return 1 + (n - 1)*10 + 9; - } -} - -uint64_t CTxOutCompressor::DecompressAmount(uint64_t x) -{ - // x = 0 OR x = 1+10*(9*n + d - 1) + e OR x = 1+10*(n - 1) + 9 - if (x == 0) - return 0; - x--; - // x = 10*(9*n + d - 1) + e - int e = x % 10; - x /= 10; - uint64_t n = 0; - if (e < 9) { - // x = 9*n + d - 1 - int d = (x % 9) + 1; - x /= 9; - // x = n - n = x*10 + d; - } else { - n = x+1; - } - while (e) { - n *= 10; - e--; - } - return n; -} - uint256 CBlockHeader::GetHash() const { return Hash(BEGIN(nVersion), END(nNonce)); diff --git a/src/core.h b/src/core.h index aeae9a191..b2288e24c 100644 --- a/src/core.h +++ b/src/core.h @@ -7,39 +7,9 @@ #define BITCOIN_CORE_H #include "core/transaction.h" -#include "script/compressor.h" #include "serialize.h" #include "uint256.h" -/** wrapper for CTxOut that provides a more compact serialization */ -class CTxOutCompressor -{ -private: - CTxOut &txout; - -public: - static uint64_t CompressAmount(uint64_t nAmount); - static uint64_t DecompressAmount(uint64_t nAmount); - - CTxOutCompressor(CTxOut &txoutIn) : txout(txoutIn) { } - - ADD_SERIALIZE_METHODS; - - template - inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { - if (!ser_action.ForRead()) { - uint64_t nVal = CompressAmount(txout.nValue); - READWRITE(VARINT(nVal)); - } else { - uint64_t nVal = 0; - READWRITE(VARINT(nVal)); - txout.nValue = DecompressAmount(nVal); - } - CScriptCompressor cscript(REF(txout.scriptPubKey)); - READWRITE(cscript); - } -}; - /** Nodes collect new transactions into a block, hash them into a hash tree, * and scan through nonce values to make the block's hash satisfy proof-of-work * requirements. When they solve the proof-of-work, they broadcast the block diff --git a/src/test/compress_tests.cpp b/src/test/compress_tests.cpp index 719955ba8..bf404cf0c 100644 --- a/src/test/compress_tests.cpp +++ b/src/test/compress_tests.cpp @@ -2,7 +2,7 @@ // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#include "main.h" +#include "compressor.h" #include "util.h" #include diff --git a/src/undo.h b/src/undo.h index 78e37f628..232c19342 100644 --- a/src/undo.h +++ b/src/undo.h @@ -6,7 +6,7 @@ #ifndef H_BITCOIN_TXUNDO #define H_BITCOIN_TXUNDO -#include "core.h" // Only for CTxOutCompressor +#include "compressor.h" #include "core/transaction.h" #include "serialize.h"