Bitcoin Core  27.99.0
P2P Digital Currency
compressor.h
Go to the documentation of this file.
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2021 The Bitcoin Core developers
3 // Distributed under the MIT software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 
6 #ifndef BITCOIN_COMPRESSOR_H
7 #define BITCOIN_COMPRESSOR_H
8 
9 #include <prevector.h>
10 #include <primitives/transaction.h>
11 #include <script/script.h>
12 #include <serialize.h>
13 #include <span.h>
14 
24 
25 
26 bool CompressScript(const CScript& script, CompressedScript& out);
27 unsigned int GetSpecialScriptSize(unsigned int nSize);
28 bool DecompressScript(CScript& script, unsigned int nSize, const CompressedScript& in);
29 
39 uint64_t CompressAmount(uint64_t nAmount);
40 
41 uint64_t DecompressAmount(uint64_t nAmount);
42 
55 {
62  static const unsigned int nSpecialScripts = 6;
63 
64  template<typename Stream>
65  void Ser(Stream &s, const CScript& script) {
66  CompressedScript compr;
67  if (CompressScript(script, compr)) {
68  s << Span{compr};
69  return;
70  }
71  unsigned int nSize = script.size() + nSpecialScripts;
72  s << VARINT(nSize);
73  s << Span{script};
74  }
75 
76  template<typename Stream>
77  void Unser(Stream &s, CScript& script) {
78  unsigned int nSize = 0;
79  s >> VARINT(nSize);
80  if (nSize < nSpecialScripts) {
81  CompressedScript vch(GetSpecialScriptSize(nSize), 0x00);
82  s >> Span{vch};
83  DecompressScript(script, nSize, vch);
84  return;
85  }
86  nSize -= nSpecialScripts;
87  if (nSize > MAX_SCRIPT_SIZE) {
88  // Overly long script, replace with a short invalid one
89  script << OP_RETURN;
90  s.ignore(nSize);
91  } else {
92  script.resize(nSize);
93  s >> Span{script};
94  }
95  }
96 };
97 
99 {
100  template<typename Stream, typename I> void Ser(Stream& s, I val)
101  {
102  s << VARINT(CompressAmount(val));
103  }
104  template<typename Stream, typename I> void Unser(Stream& s, I& val)
105  {
106  uint64_t v;
107  s >> VARINT(v);
108  val = DecompressAmount(v);
109  }
110 };
111 
114 {
115  FORMATTER_METHODS(CTxOut, obj) { READWRITE(Using<AmountCompression>(obj.nValue), Using<ScriptCompression>(obj.scriptPubKey)); }
116 };
117 
118 #endif // BITCOIN_COMPRESSOR_H
Serialized script, used inside transaction inputs and outputs.
Definition: script.h:414
An output of a transaction.
Definition: transaction.h:150
A Span is an object that can refer to a contiguous sequence of objects.
Definition: span.h:98
Implements a drop-in replacement for std::vector<T> which stores up to N elements directly (without h...
Definition: prevector.h:37
size_type size() const
Definition: prevector.h:296
void resize(size_type new_size)
Definition: prevector.h:330
bool DecompressScript(CScript &script, unsigned int nSize, const CompressedScript &in)
Definition: compressor.cpp:95
bool CompressScript(const CScript &script, CompressedScript &out)
Definition: compressor.cpp:55
uint64_t DecompressAmount(uint64_t nAmount)
Definition: compressor.cpp:168
uint64_t CompressAmount(uint64_t nAmount)
Compress amount.
Definition: compressor.cpp:149
unsigned int GetSpecialScriptSize(unsigned int nSize)
Definition: compressor.cpp:86
static const int MAX_SCRIPT_SIZE
Definition: script.h:39
@ OP_RETURN
Definition: script.h:110
#define VARINT(obj)
Definition: serialize.h:513
#define READWRITE(...)
Definition: serialize.h:156
void Unser(Stream &s, I &val)
Definition: compressor.h:104
void Ser(Stream &s, I val)
Definition: compressor.h:100
Compact serializer for scripts.
Definition: compressor.h:55
void Unser(Stream &s, CScript &script)
Definition: compressor.h:77
static const unsigned int nSpecialScripts
make this static for now (there are only 6 special scripts defined) this can potentially be extended ...
Definition: compressor.h:62
void Ser(Stream &s, const CScript &script)
Definition: compressor.h:65
wrapper for CTxOut that provides a more compact serialization
Definition: compressor.h:114
FORMATTER_METHODS(CTxOut, obj)
Definition: compressor.h:115