Ton

Форк
0
/
dump-block.cpp 
351 строка · 14.5 Кб
1
/*
2
    This file is part of TON Blockchain source code.
3

4
    TON Blockchain is free software; you can redistribute it and/or
5
    modify it under the terms of the GNU General Public License
6
    as published by the Free Software Foundation; either version 2
7
    of the License, or (at your option) any later version.
8

9
    TON Blockchain is distributed in the hope that it will be useful,
10
    but WITHOUT ANY WARRANTY; without even the implied warranty of
11
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
    GNU General Public License for more details.
13

14
    You should have received a copy of the GNU General Public License
15
    along with TON Blockchain.  If not, see <http://www.gnu.org/licenses/>.
16

17
    In addition, as a special exception, the copyright holders give permission
18
    to link the code of portions of this program with the OpenSSL library.
19
    You must obey the GNU General Public License in all respects for all
20
    of the code used other than OpenSSL. If you modify file(s) with this
21
    exception, you may extend this exception to your version of the file(s),
22
    but you are not obligated to do so. If you do not wish to do so, delete this
23
    exception statement from your version. If you delete this exception statement
24
    from all source files in the program, then also delete it here.
25

26
    Copyright 2017-2020 Telegram Systems LLP
27
*/
28
#include "block/block.h"
29
#include "vm/boc.h"
30
#include <iostream>
31
#include "block-db.h"
32
#include "block-auto.h"
33
#include "block-parse.h"
34
#include "mc-config.h"
35
#include "vm/cp0.h"
36
#include <getopt.h>
37
#include "git.h"
38

39
using td::Ref;
40
using namespace std::literals::string_literals;
41

42
int verbosity;
43

44
struct IntError {
45
  std::string err_msg;
46
  IntError(std::string _msg) : err_msg(_msg) {
47
  }
48
  IntError(const char* _msg) : err_msg(_msg) {
49
  }
50
};
51

52
void throw_err(td::Status err) {
53
  if (err.is_error()) {
54
    throw IntError{err.to_string()};
55
  }
56
}
57

58
td::Ref<vm::Cell> load_boc(std::string filename) {
59
  std::cerr << "loading bag-of-cell file " << filename << std::endl;
60
  auto bytes_res = block::load_binary_file(filename);
61
  if (bytes_res.is_error()) {
62
    throw IntError{PSTRING() << "cannot load file `" << filename << "` : " << bytes_res.move_as_error()};
63
  }
64
  vm::BagOfCells boc;
65
  auto res = boc.deserialize(bytes_res.move_as_ok());
66
  if (res.is_error()) {
67
    throw IntError{PSTRING() << "cannot deserialize bag-of-cells " << res.move_as_error()};
68
  }
69
  if (res.move_as_ok() <= 0 || boc.get_root_cell().is_null()) {
70
    throw IntError{"cannot deserialize bag-of-cells "};
71
  }
72
  return boc.get_root_cell();
73
}
74

75
std::vector<Ref<vm::Cell>> loaded_boc;
76

77
void test1() {
78
  block::ShardId id{ton::masterchainId}, id2{ton::basechainId, 0x11efULL << 48};
79
  std::cout << '[' << id << "][" << id2 << ']' << std::endl;
80
  vm::CellBuilder cb;
81
  cb << id << id2;
82
  std::cout << "ShardIdent.pack() = " << block::tlb::t_ShardIdent.pack(cb, {12, 3, 0x3aeULL << 52}) << std::endl;
83
  std::cout << cb << std::endl;
84
  auto cref = cb.finalize();
85
  td::Ref<vm::CellSlice> cs{true, cref}, cs2;
86
  block::ShardId id3{cs.write()}, id4, id5;
87
  cs >> id4 >> id5;
88
  std::cout << '[' << id3 << "][" << id4 << "][" << id5 << ']' << std::endl;
89
  vm::CellSlice csl{std::move(cref)};
90
  std::cout << "ShardIdent.get_size() = " << block::tlb::t_ShardIdent.get_size(csl) << std::endl;
91
  std::cout << "MsgAddress.get_size() = " << block::tlb::t_MsgAddress.get_size(csl) << std::endl;
92
  std::cout << "Grams.get_size() = " << block::tlb::t_Grams.get_size(csl) << std::endl;
93
  std::cout << "Grams.as_integer() = " << block::tlb::t_Grams.as_integer(csl) << std::endl;
94
  (csl + 8).print_rec(std::cout);
95
  std::cout << "Grams.get_size() = " << block::tlb::t_Grams.get_size(csl + 8) << std::endl;
96
  std::cout << "Grams.as_integer() = " << block::tlb::t_Grams.as_integer(csl + 8) << std::endl;
97

98
  vm::CellSlice csl2{csl};
99
  block::gen::ShardIdent::Record sh_id;
100
  for (int i = 0; i < 3; i++) {
101
    std::cout << csl2 << std::endl;
102
    bool ok = tlb::unpack(csl2, sh_id);
103
    std::cout << "block::gen::ShardIdent.unpack() = " << ok << std::endl;
104
    if (ok) {
105
      std::cout << "  (shard_ident shard_pfx_bits:" << sh_id.shard_pfx_bits << " workchain_id:" << sh_id.workchain_id
106
                << " shard_prefix:" << std::hex << sh_id.shard_prefix << std::dec << ")" << std::endl;
107
    }
108
  }
109

110
  block::tlb::ShardIdent::Record shard_id;
111
  for (int i = 0; i < 3; i++) {
112
    std::cout << "ShardIdent.validate() = " << block::tlb::t_ShardIdent.validate_upto(1024, csl) << std::endl;
113
    csl.print_rec(std::cerr);
114
    csl.dump(std::cerr, 7);
115
    std::cout << "ShardIdent.unpack() = " << block::tlb::t_ShardIdent.unpack(csl, shard_id) << std::endl;
116
    if (shard_id.is_valid()) {
117
      std::cout << "shard_pfx_bits:" << shard_id.shard_pfx_bits << " workchain_id:" << shard_id.workchain_id
118
                << " shard_prefix:" << shard_id.shard_prefix << std::endl;
119
    }
120
  }
121
  std::cout << "ShardIdent.skip_validate() = " << block::tlb::t_ShardIdent.validate_skip_upto(1024, csl) << std::endl;
122
  std::cout << "ShardIdent.skip_validate() = " << block::tlb::t_ShardIdent.validate_skip_upto(1024, csl) << std::endl;
123
  std::cout << "ShardIdent.skip_validate() = " << block::tlb::t_ShardIdent.validate_skip_upto(1024, csl) << std::endl;
124
  using namespace td::literals;
125
  std::cout << "Grams.store_intval(239) = " << block::tlb::t_Grams.store_integer_value(cb, "239"_i256) << std::endl;
126
  std::cout << "Grams.store_intval(17239) = " << block::tlb::t_Grams.store_integer_value(cb, "17239"_i256) << std::endl;
127
  std::cout << "Grams.store_intval(-17) = " << block::tlb::t_Grams.store_integer_value(cb, "-17"_i256) << std::endl;
128
  std::cout << "Grams.store_intval(0) = " << block::tlb::t_Grams.store_integer_value(cb, "0"_i256) << std::endl;
129
  std::cout << cb << std::endl;
130
  cs = td::Ref<vm::CellSlice>{true, cb.finalize()};
131
  std::cout << "Grams.store_intval(666) = " << block::tlb::t_Grams.store_integer_value(cb, "666"_i256) << std::endl;
132
  std::cout << cb << std::endl;
133
  cs2 = td::Ref<vm::CellSlice>{true, cb.finalize()};
134
  std::cout << "Grams.validate(cs) = " << block::tlb::t_Grams.validate_upto(1024, *cs) << std::endl;
135
  std::cout << "Grams.validate(cs2) = " << block::tlb::t_Grams.validate_upto(1024, *cs2) << std::endl;
136
  //
137
  block::gen::SplitMergeInfo::Record data;
138
  block::gen::Grams::Record data2;
139
  std::cout << "block::gen::Grams.validate(cs) = " << block::gen::t_Grams.validate_upto(1024, *cs) << std::endl;
140
  std::cout << "block::gen::Grams.validate(cs2) = " << block::gen::t_Grams.validate_upto(1024, *cs2) << std::endl;
141
  std::cout << "[cs = " << cs << "]" << std::endl;
142
  bool ok = tlb::csr_unpack_inexact(cs, data);
143
  std::cout << "block::gen::SplitMergeInfo.unpack(cs, data) = " << ok << std::endl;
144
  if (ok) {
145
    std::cout << "  cur_shard_pfx_len = " << data.cur_shard_pfx_len << "; acc_split_depth = " << data.acc_split_depth
146
              << "; this_addr = " << data.this_addr << "; sibling_addr = " << data.sibling_addr << std::endl;
147
  }
148
  ok = tlb::csr_unpack_inexact(cs, data2);
149
  std::cout << "block::gen::Grams.unpack(cs, data2) = " << ok << std::endl;
150
  if (ok) {
151
    std::cout << "  amount = " << data2.amount << std::endl;
152
    block::gen::VarUInteger::Record data3;
153
    ok = tlb::csr_type_unpack(data2.amount, block::gen::t_VarUInteger_16, data3);
154
    std::cout << "  block::gen::VarUInteger16.unpack(amount, data3) = " << ok << std::endl;
155
    if (ok) {
156
      std::cout << "    len = " << data3.len << "; value = " << data3.value << std::endl;
157
      vm::CellBuilder cb;
158
      std::cout << "    block::gen::VarUInteger16.pack(cb, data3) = "
159
                << tlb::type_pack(cb, block::gen::t_VarUInteger_16, data3) << std::endl;
160
      std::cout << "    cb = " << cb.finalize() << std::endl;
161
    }
162
  }
163
  /*
164
  {
165
    vm::CellBuilder cb;
166
    td::BitArray<256> hash;
167
    std::memset(hash.data(), 0x69, 32);
168
    bool ok = tlb::pack(
169
        cb, block::gen::Test::Record{1000000000000, {170239, -888, {239017, "1000000000000000000"_ri256}, hash}, 17});
170
    std::cout << "  block::gen::Test::pack(cb, {1000000000000, ...}) = " << ok << std::endl;
171
    std::cout << "  cb = " << cb << std::endl;
172
    auto cell = cb.finalize();
173
    vm::CellSlice cs{cell};
174
    cs.print_rec(std::cout);
175
    block::gen::Test::Record data;
176
    std::cout << "  block::gen::Test::validate_ref(cell) = " << block::gen::t_Test.validate_ref(cell) << std::endl;
177
    ok = tlb::unpack(cs, data);
178
    std::cout << "  block::gen::Test::unpack(cs, data) = " << ok << std::endl;
179
    if (ok) {
180
      std::cout << "a:" << data.a << " b:" << data.r1.b << " c:" << data.r1.c << " d:" << data.r1.r1.d
181
                << " e:" << data.r1.r1.e << " f:" << data.r1.f << " g:" << data.g << std::endl;
182
    }
183
    std::cout << "  block::gen::Test::print_ref(cell) = ";
184
    block::gen::t_Test.print_ref(std::cout, cell, 2);
185
    block::gen::t_CurrencyCollection.print_ref(std::cout, cell, 2);
186
    std::cout << std::endl;
187
  }
188
  */
189
  std::cout << "Grams.add_values() = " << block::tlb::t_Grams.add_values(cb, cs.write(), cs2.write()) << std::endl;
190
  std::cout << cb << std::endl;
191
  std::cout << "block::gen::t_HashmapAug_64_...print_type() = "
192
            << block::gen::t_HashmapAug_64_Ref_Transaction_CurrencyCollection << std::endl;
193
}
194

195
void test2(vm::CellSlice& cs) {
196
  std::cout << "Bool.validate() = " << block::tlb::t_Bool.validate_upto(1024, cs) << std::endl;
197
  std::cout << "UInt16.validate() = " << block::tlb::t_uint16.validate_upto(1024, cs) << std::endl;
198
  std::cout << "HashmapE(32,UInt16).validate() = "
199
            << block::tlb::HashmapE(32, block::tlb::t_uint16).validate_upto(1024, cs) << std::endl;
200
  std::cout << "block::gen::HashmapE(32,UInt16).validate() = "
201
            << block::gen::HashmapE{32, block::gen::t_uint16}.validate_upto(1024, cs) << std::endl;
202
}
203

204
td::Status test_vset() {
205
  if (loaded_boc.size() != 2) {
206
    return td::Status::Error(
207
        "must have exactly two boc files (with a masterchain Block and with ConfigParams) for vset compute test");
208
  }
209
  std::cerr << "running test_vset()\n";
210
  TRY_RESULT(config, block::Config::unpack_config(vm::load_cell_slice_ref(loaded_boc[1])));
211
  std::cerr << "config unpacked\n";
212
  auto cv_root = config->get_config_param(34);
213
  if (cv_root.is_null()) {
214
    return td::Status::Error("no config parameter 34");
215
  }
216
  std::cerr << "config param #34 obtained\n";
217
  TRY_RESULT(cur_validators, block::Config::unpack_validator_set(std::move(cv_root)));
218
  // auto vconf = config->get_catchain_validators_config();
219
  std::cerr << "validator set unpacked\n";
220
  std::cerr << "unpacking ShardHashes\n";
221
  block::ShardConfig shards;
222
  if (!shards.unpack(vm::load_cell_slice_ref(loaded_boc[0]))) {
223
    return td::Status::Error("cannot unpack ShardConfig");
224
  }
225
  std::cerr << "ShardHashes initialized\n";
226
  ton::ShardIdFull shard{0, 0x6e80000000000000};
227
  ton::CatchainSeqno cc_seqno = std::max(48763, 48763) + 1 + 1;
228
  ton::UnixTime now = 1586169666;
229
  cc_seqno = shards.get_shard_cc_seqno(shard);
230
  std::cerr << "shard=" << shard.to_str() << " cc_seqno=" << cc_seqno << " time=" << now << std::endl;
231
  if (cc_seqno == ~0U) {
232
    return td::Status::Error("cannot compute cc_seqno for shard "s + shard.to_str());
233
  }
234
  auto nodes = config->compute_validator_set(shard, *cur_validators, now, cc_seqno);
235
  if (nodes.empty()) {
236
    return td::Status::Error(PSTRING() << "compute_validator_set() for " << shard.to_str() << "," << now << ","
237
                                       << cc_seqno << " returned empty list");
238
  }
239
  for (auto& x : nodes) {
240
    std::cout << "weight=" << x.weight << " key=" << x.key.as_bits256().to_hex() << " addr=" << x.addr.to_hex()
241
              << std::endl;
242
  }
243
  // ...
244
  return td::Status::OK();
245
}
246

247
void usage() {
248
  std::cout << "usage: dump-block [-t<typename>][-S][<boc-file>]\n\tor dump-block -h\n\tDumps specified blockchain "
249
               "block or state "
250
               "from <boc-file>, or runs some tests\n\t-S\tDump a blockchain state instead of a block\n"
251
               "\t-V<version>\tShow fift build information\n";
252
  std::exit(2);
253
}
254

255
int main(int argc, char* const argv[]) {
256
  int i;
257
  int new_verbosity_level = VERBOSITY_NAME(INFO);
258
  const char* tname = nullptr;
259
  const tlb::TLB* type = &block::gen::t_Block;
260
  bool vset_compute_test = false;
261
  bool store_loaded = false;
262
  int dump = 3;
263
  auto zerostate = std::make_unique<block::ZerostateInfo>();
264
  while ((i = getopt(argc, argv, "CSt:hqv:V")) != -1) {
265
    switch (i) {
266
      case 'C':
267
        type = &block::gen::t_VmCont;
268
        break;
269
      case 'S':
270
        type = &block::gen::t_ShardStateUnsplit;
271
        break;
272
      case 't':
273
        tname = optarg;
274
        type = nullptr;
275
        break;
276
      case 'v':
277
        new_verbosity_level = VERBOSITY_NAME(FATAL) + (verbosity = td::to_integer<int>(td::Slice(optarg)));
278
        break;
279
      case 'q':
280
        type = &block::gen::t_ShardHashes;
281
        vset_compute_test = true;
282
        store_loaded = true;
283
        dump = 0;
284
        break;
285
      case 'V':
286
        std::cout << "dump-block build information: [ Commit: " << GitMetadata::CommitSHA1() << ", Date: " << GitMetadata::CommitDate() << "]\n";
287
        std::exit(0);
288
        break;
289
      case 'h':
290
        usage();
291
        std::exit(2);
292
      default:
293
        usage();
294
        std::exit(2);
295
    }
296
  }
297
  SET_VERBOSITY_LEVEL(new_verbosity_level);
298
  try {
299
    int loaded = 0;
300
    while (optind < argc) {
301
      auto boc = load_boc(argv[optind++]);
302
      if (boc.is_null()) {
303
        std::cerr << "(invalid boc in file" << argv[optind - 1] << ")" << std::endl;
304
        std::exit(2);
305
      } else {
306
        if (store_loaded) {
307
          loaded_boc.push_back(boc);
308
        }
309
        ++loaded;
310
        if (dump & 1) {
311
          vm::CellSlice cs{vm::NoVm(), boc};
312
          cs.print_rec(std::cout);
313
          std::cout << std::endl;
314
        }
315
        if (!type) {
316
          tlb::TypenameLookup dict(block::gen::register_simple_types);
317
          type = dict.lookup(tname);
318
          if (!type) {
319
            std::cerr << "unknown TL-B type " << tname << std::endl;
320
            std::exit(3);
321
          }
322
        }
323
        if (dump & 2) {
324
          type->print_ref(std::cout, boc);
325
          std::cout << std::endl;
326
        }
327
        bool ok = type->validate_ref(1048576, boc);
328
        std::cout << "(" << (ok ? "" : "in") << "valid " << *type << ")" << std::endl;
329
        if (vset_compute_test) {
330
          if (!ok || loaded > 2) {
331
            std::cerr << "fatal: validity check failed\n";
332
            exit(3);
333
          }
334
          type = &block::gen::t_ConfigParams;
335
        }
336
      }
337
    }
338
    if (vset_compute_test) {
339
      throw_err(test_vset());
340
    } else if (!loaded) {
341
      test1();
342
    }
343
  } catch (IntError& err) {
344
    std::cerr << "internal error: " << err.err_msg << std::endl;
345
    return 1;
346
  } catch (vm::VmError& err) {
347
    std::cerr << "vm error: " << err.get_msg() << std::endl;
348
    return 1;
349
  }
350
  return 0;
351
}
352

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.