LCOV - code coverage report
Current view: top level - src - compressor.h (source / functions) Hit Total Coverage
Test: total_coverage.info Lines: 29 29 100.0 %
Date: 2025-02-23 09:33:43 Functions: 13 13 100.0 %

          Line data    Source code
       1             : // Copyright (c) 2009-2010 Satoshi Nakamoto
       2             : // Copyright (c) 2009-2014 The Bitcoin developers
       3             : // Copyright (c) 2017-2020 The PIVX Core developers
       4             : // Distributed under the MIT software license, see the accompanying
       5             : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
       6             : 
       7             : #ifndef PIVX_COMPRESSOR_H
       8             : #define PIVX_COMPRESSOR_H
       9             : 
      10             : #include "primitives/transaction.h"
      11             : #include "script/script.h"
      12             : #include "serialize.h"
      13             : #include "span.h"
      14             : 
      15             : bool CompressScript(const CScript& script, std::vector<unsigned char> &out);
      16             : unsigned int GetSpecialScriptSize(unsigned int nSize);
      17             : bool DecompressScript(CScript& script, unsigned int nSize, const std::vector<unsigned char> &out);
      18             : 
      19             : uint64_t CompressAmount(uint64_t nAmount);
      20             : uint64_t DecompressAmount(uint64_t nAmount);
      21             : 
      22             : /** Compact serializer for scripts.
      23             :  *
      24             :  *  It detects common cases and encodes them much more efficiently.
      25             :  *  3 special cases are defined:
      26             :  *  * Pay to pubkey hash (encoded as 21 bytes)
      27             :  *  * Pay to script hash (encoded as 21 bytes)
      28             :  *  * Pay to pubkey starting with 0x02, 0x03 or 0x04 (encoded as 33 bytes)
      29             :  *
      30             :  *  Other scripts up to 121 bytes require 1 byte + script length. Above
      31             :  *  that, scripts up to 16505 bytes require 2 bytes + script length.
      32             :  */
      33             : struct ScriptCompression
      34             : {
      35             :     /**
      36             :      * make this static for now (there are only 6 special scripts defined)
      37             :      * this can potentially be extended together with a new nVersion for
      38             :      * transactions, in which case this value becomes dependent on nVersion
      39             :      * and nHeight of the enclosing transaction.
      40             :      */
      41             :     static const unsigned int nSpecialScripts = 6;
      42             : 
      43             :     template<typename Stream>
      44     2563127 :     void Ser(Stream &s, const CScript& script) {
      45      122631 :         std::vector<unsigned char> compr;
      46     2563127 :         if (CompressScript(script, compr)) {
      47     2440496 :             s << MakeSpan(compr);
      48     4880990 :             return;
      49             :         }
      50      122913 :         unsigned int nSize = script.size() + nSpecialScripts;
      51      122631 :         s << VARINT(nSize);
      52      122631 :         s << MakeSpan(script);
      53             :     }
      54             : 
      55             :     template<typename Stream>
      56     7152755 :     void Unser(Stream &s, CScript& script) {
      57     7152755 :         unsigned int nSize = 0;
      58     7152755 :         s >> VARINT(nSize);
      59     7152755 :         if (nSize < nSpecialScripts) {
      60    14291046 :             std::vector<unsigned char> vch(GetSpecialScriptSize(nSize), 0x00);
      61     7145513 :             s >> MakeSpan(vch);
      62     7145513 :             DecompressScript(script, nSize, vch);
      63     7145513 :             return;
      64             :         }
      65        7244 :         nSize -= nSpecialScripts;
      66        7244 :         if (nSize > MAX_SCRIPT_SIZE) {
      67             :             // Overly long script, replace with a short invalid one
      68           1 :             script << OP_RETURN;
      69           1 :             s.ignore(nSize);
      70             :         } else {
      71        7243 :             script.resize(nSize);
      72        7243 :             s >> MakeSpan(script);
      73             :         }
      74             :     }
      75             : };
      76             : 
      77             : struct AmountCompression
      78             : {
      79     2563131 :     template<typename Stream, typename I> void Ser(Stream& s, I val)
      80             :     {
      81     2563131 :         s << VARINT(CompressAmount(val));
      82      466998 :     }
      83     7152755 :     template<typename Stream, typename I> void Unser(Stream& s, I& val)
      84             :     {
      85             :         uint64_t v;
      86     7152755 :         s >> VARINT(v);
      87     7152755 :         val = DecompressAmount(v);
      88             :     }
      89             : };
      90             : 
      91             : /** wrapper for CTxOut that provides a more compact serialization */
      92             : struct TxOutCompression
      93             : {
      94    19431772 :     FORMATTER_METHODS(CTxOut, obj) { READWRITE(Using<AmountCompression>(obj.nValue), Using<ScriptCompression>(obj.scriptPubKey)); }
      95             : };
      96             : 
      97             : #endif // PIVX_COMPRESSOR_H

Generated by: LCOV version 1.14