From 3e38199cf36d5d59fde842b480504b05ec9bb7b5 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Sat, 8 Jul 2017 16:43:34 -0700 Subject: [PATCH] Move compressor utility functions out of class --- src/compressor.cpp | 30 +++++++++++++++++++----------- src/compressor.h | 37 ++++++++++++------------------------- src/test/compress_tests.cpp | 8 ++++---- 3 files changed, 35 insertions(+), 40 deletions(-) diff --git a/src/compressor.cpp b/src/compressor.cpp index a54f7ab6757fe..18d58649e33b5 100644 --- a/src/compressor.cpp +++ b/src/compressor.cpp @@ -10,7 +10,15 @@ #include "pubkey.h" #include "script/standard.h" -bool CScriptCompressor::IsToKeyID(CKeyID& hash) const +/* + * These check for scripts for which a special case with a shorter encoding is defined. + * They are implemented separately from the CScript test, as these test for exact byte + * sequence correspondences, and are more strict. For example, IsToPubKey also verifies + * whether the public key is valid (as invalid ones cannot be represented in compressed + * form). + */ + +static bool IsToKeyID(const CScript& script, CKeyID &hash) { if (script.size() == 25 && script[0] == OP_DUP && script[1] == OP_HASH160 && script[2] == 20 && script[23] == OP_EQUALVERIFY && script[24] == OP_CHECKSIG) { memcpy(&hash, &script[3], 20); @@ -19,7 +27,7 @@ bool CScriptCompressor::IsToKeyID(CKeyID& hash) const return false; } -bool CScriptCompressor::IsToScriptID(CScriptID& hash) const +static bool IsToScriptID(const CScript& script, CScriptID &hash) { if (script.size() == 23 && script[0] == OP_HASH160 && script[1] == 20 && script[22] == OP_EQUAL) { memcpy(&hash, &script[2], 20); @@ -28,7 +36,7 @@ bool CScriptCompressor::IsToScriptID(CScriptID& hash) const return false; } -bool CScriptCompressor::IsToPubKey(CPubKey& pubkey) const +static bool IsToPubKey(const CScript& script, CPubKey &pubkey) { if (script.size() == 35 && script[0] == 33 && script[34] == OP_CHECKSIG && (script[1] == 0x02 || script[1] == 0x03)) { pubkey.Set(&script[1], &script[34]); @@ -41,24 +49,24 @@ bool CScriptCompressor::IsToPubKey(CPubKey& pubkey) const return false; } -bool CScriptCompressor::Compress(std::vector& out) const +bool CompressScript(const CScript& script, std::vector &out) { CKeyID keyID; - if (IsToKeyID(keyID)) { + if (IsToKeyID(script, keyID)) { out.resize(21); out[0] = 0x00; memcpy(&out[1], &keyID, 20); return true; } CScriptID scriptID; - if (IsToScriptID(scriptID)) { + if (IsToScriptID(script, scriptID)) { out.resize(21); out[0] = 0x01; memcpy(&out[1], &scriptID, 20); return true; } CPubKey pubkey; - if (IsToPubKey(pubkey)) { + if (IsToPubKey(script, pubkey)) { out.resize(33); memcpy(&out[1], &pubkey[1], 32); if (pubkey[0] == 0x02 || pubkey[0] == 0x03) { @@ -72,7 +80,7 @@ bool CScriptCompressor::Compress(std::vector& out) const return false; } -unsigned int CScriptCompressor::GetSpecialSize(unsigned int nSize) const +unsigned int GetSpecialScriptSize(unsigned int nSize) { if (nSize == 0 || nSize == 1) return 20; @@ -81,7 +89,7 @@ unsigned int CScriptCompressor::GetSpecialSize(unsigned int nSize) const return 0; } -bool CScriptCompressor::Decompress(unsigned int nSize, const std::vector& in) +bool DecompressScript(CScript& script, unsigned int nSize, const std::vector &in) { switch (nSize) { case 0x00: @@ -135,7 +143,7 @@ bool CScriptCompressor::Decompress(unsigned int nSize, const std::vector &out); +unsigned int GetSpecialScriptSize(unsigned int nSize); +bool DecompressScript(CScript& script, unsigned int nSize, const std::vector &out); + +uint64_t CompressAmount(uint64_t nAmount); +uint64_t DecompressAmount(uint64_t nAmount); + /** Compact serializer for scripts. * * It detects common cases and encodes them much more efficiently. @@ -38,24 +45,7 @@ class CScriptCompressor */ static const unsigned int nSpecialScripts = 6; - CScript& script; - -protected: - /** - * These check for scripts for which a special case with a shorter encoding is defined. - * They are implemented separately from the CScript test, as these test for exact byte - * sequence correspondences, and are more strict. For example, IsToPubKey also verifies - * whether the public key is valid (as invalid ones cannot be represented in compressed - * form). - */ - bool IsToKeyID(CKeyID& hash) const; - bool IsToScriptID(CScriptID& hash) const; - bool IsToPubKey(CPubKey& pubkey) const; - - bool Compress(std::vector& out) const; - unsigned int GetSpecialSize(unsigned int nSize) const; - bool Decompress(unsigned int nSize, const std::vector& out); - + CScript &script; public: CScriptCompressor(CScript& scriptIn) : script(scriptIn) {} @@ -63,7 +53,7 @@ class CScriptCompressor void Serialize(Stream& s) const { std::vector compr; - if (Compress(compr)) { + if (CompressScript(script, compr)) { s << MakeSpan(compr); return; } @@ -78,9 +68,9 @@ class CScriptCompressor unsigned int nSize = 0; s >> VARINT(nSize); if (nSize < nSpecialScripts) { - std::vector vch(GetSpecialSize(nSize), 0x00); + std::vector vch(GetSpecialScriptSize(nSize), 0x00); s >> MakeSpan(vch); - Decompress(nSize, vch); + DecompressScript(script, nSize, vch); return; } nSize -= nSpecialScripts; @@ -102,10 +92,7 @@ class CTxOutCompressor CTxOut& txout; public: - static uint64_t CompressAmount(uint64_t nAmount); - static uint64_t DecompressAmount(uint64_t nAmount); - - CTxOutCompressor(CTxOut& txoutIn) : txout(txoutIn) {} + explicit CTxOutCompressor(CTxOut &txoutIn) : txout(txoutIn) { } ADD_SERIALIZE_METHODS; diff --git a/src/test/compress_tests.cpp b/src/test/compress_tests.cpp index c0bcbb7ba67bb..14dd6343b9af4 100644 --- a/src/test/compress_tests.cpp +++ b/src/test/compress_tests.cpp @@ -25,16 +25,16 @@ BOOST_FIXTURE_TEST_SUITE(compress_tests, BasicTestingSetup) bool static TestEncode(uint64_t in) { - return in == CTxOutCompressor::DecompressAmount(CTxOutCompressor::CompressAmount(in)); + return in == DecompressAmount(CompressAmount(in)); } bool static TestDecode(uint64_t in) { - return in == CTxOutCompressor::CompressAmount(CTxOutCompressor::DecompressAmount(in)); + return in == CompressAmount(DecompressAmount(in)); } bool static TestPair(uint64_t dec, uint64_t enc) { - return CTxOutCompressor::CompressAmount(dec) == enc && - CTxOutCompressor::DecompressAmount(enc) == dec; + return CompressAmount(dec) == enc && + DecompressAmount(enc) == dec; } BOOST_AUTO_TEST_CASE(compress_amounts)