Kagome
Polkadot Runtime Engine in C++17
uncompress_code_if_needed.cpp
Go to the documentation of this file.
1 
7 
8 #include <zstd.h>
9 
12  switch (e) {
13  case E::ZSTD_ERROR:
14  return "WASM code not compressed by zstd!";
15  }
16  return "Unknown error";
17 }
18 
19 namespace kagome::runtime {
20 
21  // @see
22  // https://github.com/paritytech/substrate/blob/polkadot-v0.9.8/primitives/maybe-compressed-blob/src/lib.rs#L28
23  constexpr uint8_t kZstdPrefixSize = 8;
24  constexpr uint8_t kZstdPrefix[kZstdPrefixSize] = {
25  0x52, 0xBC, 0x53, 0x76, 0x46, 0xDB, 0x8E, 0x05};
26  // @see
27  // https://github.com/paritytech/substrate/blob/polkadot-v0.9.8/primitives/maybe-compressed-blob/src/lib.rs#L35
28  constexpr size_t kCodeBlobBombLimit = 50 * 1024 * 1024;
29 
30  outcome::result<void> uncompressCodeIfNeeded(common::BufferView buf,
31  common::Buffer &res) {
32  if (buf.size() > kZstdPrefixSize
33  && std::equal(buf.begin(),
34  buf.begin() + kZstdPrefixSize,
35  std::begin(kZstdPrefix),
36  std::end(kZstdPrefix))) {
37  // here we can check that blob is really ZSTD compressed
38  // but we don't use the result size, it's unknown for the WASM blob
39  // @see ZSTD_CONTENTSIZE_UNKNOWN
40  auto check_size = ZSTD_getFrameContentSize(buf.data() + kZstdPrefixSize,
41  buf.size() - kZstdPrefixSize);
42  if (check_size == ZSTD_CONTENTSIZE_ERROR) {
44  }
45  res.resize(kCodeBlobBombLimit);
46  auto size = ZSTD_decompress(res.data(),
48  buf.data() + kZstdPrefixSize,
49  buf.size() - kZstdPrefixSize);
50  res.resize(size);
51  } else {
52  res = common::Buffer{buf};
53  }
54  return outcome::success();
55  }
56 
57 } // namespace kagome::runtime
Class represents arbitrary (including empty) byte buffer.
Definition: buffer.hpp:29
constexpr size_t kCodeBlobBombLimit
SLBuffer & resize(size_t size)
Definition: buffer.hpp:66
constexpr uint8_t kZstdPrefixSize
OUTCOME_CPP_DEFINE_CATEGORY(kagome::runtime, UncompressError, e)
constexpr uint8_t kZstdPrefix[kZstdPrefixSize]
outcome::result< void > uncompressCodeIfNeeded(common::BufferView buf, common::Buffer &res)