mirror of
https://github.com/ton-blockchain/ton
synced 2025-03-09 15:40:10 +00:00
Add more headers corruption options
This commit is contained in:
parent
ed10909dcd
commit
833ef0a4f9
3 changed files with 132 additions and 26 deletions
|
@ -1,9 +1,34 @@
|
|||
#include "header_corrupter.hpp"
|
||||
|
||||
#include "block/block-parse.h"
|
||||
#include "block/block-auto.h"
|
||||
|
||||
namespace test::fisherman {
|
||||
|
||||
auto HeaderCorrupter::Config::fromJson(td::JsonValue jv) -> Config {
|
||||
return Config{};
|
||||
HeaderCorrupter::Config HeaderCorrupter::Config::fromJson(td::JsonValue jv) {
|
||||
Config cfg;
|
||||
CHECK(jv.type() == td::JsonValue::Type::Object);
|
||||
auto &obj = jv.get_object();
|
||||
|
||||
cfg.distort_timestamp = td::get_json_object_bool_field(obj, "distort_timestamp", true, false).move_as_ok();
|
||||
cfg.time_offset = td::get_json_object_int_field(obj, "time_offset", true, 999999999).move_as_ok();
|
||||
|
||||
cfg.mark_subshard_of_master =
|
||||
td::get_json_object_bool_field(obj, "mark_subshard_of_master", true, false).move_as_ok();
|
||||
cfg.invert_lt = td::get_json_object_bool_field(obj, "invert_lt", true, false).move_as_ok();
|
||||
cfg.mark_keyblock_on_shard = td::get_json_object_bool_field(obj, "mark_keyblock_on_shard", true, false).move_as_ok();
|
||||
|
||||
cfg.force_after_merge_for_mc = td::get_json_object_bool_field(obj, "force_after_merge_for_mc", true, false).move_as_ok();
|
||||
cfg.force_before_split_for_mc = td::get_json_object_bool_field(obj, "force_before_split_for_mc", true, false).move_as_ok();
|
||||
cfg.force_after_split_for_mc = td::get_json_object_bool_field(obj, "force_after_split_for_mc", true, false).move_as_ok();
|
||||
cfg.allow_both_after_merge_and_split =
|
||||
td::get_json_object_bool_field(obj, "allow_both_after_merge_and_split", true, false).move_as_ok();
|
||||
|
||||
cfg.shard_pfx_zero_yet_after_split =
|
||||
td::get_json_object_bool_field(obj, "shard_pfx_zero_yet_after_split", true, false).move_as_ok();
|
||||
|
||||
cfg.set_vert_seqno_incr = td::get_json_object_bool_field(obj, "set_vert_seqno_incr", true, false).move_as_ok();
|
||||
return cfg;
|
||||
}
|
||||
|
||||
HeaderCorrupter::HeaderCorrupter(Config config) : config_(std::move(config)) {
|
||||
|
@ -11,11 +36,81 @@ HeaderCorrupter::HeaderCorrupter(Config config) : config_(std::move(config)) {
|
|||
|
||||
void HeaderCorrupter::modify(block::gen::Block::Record &block) {
|
||||
block::gen::BlockInfo::Record info_rec;
|
||||
bool ok = block::gen::BlockInfo().cell_unpack(block.info, info_rec);
|
||||
CHECK(ok);
|
||||
info_rec.after_merge = true;
|
||||
info_rec.after_split = true;
|
||||
block::gen::BlockInfo().cell_pack(block.info, info_rec);
|
||||
CHECK(block::gen::t_BlockInfo.cell_unpack(block.info, info_rec));
|
||||
|
||||
// 1) distort_timestamp => сдвигаем info_rec.gen_utime
|
||||
if (config_.distort_timestamp) {
|
||||
info_rec.gen_utime += config_.time_offset;
|
||||
}
|
||||
|
||||
// 2) mark_subshard_of_master => если workchain == -1, делаем shard_pfx_bits != 0, то есть блок "подшард" MC
|
||||
if (config_.mark_subshard_of_master) {
|
||||
block::gen::ShardIdent::Record shard_rec;
|
||||
CHECK(block::gen::ShardIdent().unpack(info_rec.shard.write(), shard_rec));
|
||||
CHECK(shard_rec.workchain_id == -1 && !info_rec.not_master);
|
||||
if (shard_rec.shard_pfx_bits == 0) {
|
||||
shard_rec.shard_pfx_bits = 10;
|
||||
shard_rec.shard_prefix = 123456ULL;
|
||||
}
|
||||
vm::CellBuilder cb;
|
||||
CHECK(block::gen::t_ShardIdent.pack(cb, shard_rec));
|
||||
info_rec.shard = td::Ref<vm::CellSlice>{true, cb.finalize()};
|
||||
}
|
||||
|
||||
// 3) invert_lt => start_lt >= end_lt
|
||||
if (config_.invert_lt) {
|
||||
if (info_rec.start_lt < info_rec.end_lt) {
|
||||
auto tmp = info_rec.start_lt;
|
||||
info_rec.start_lt = info_rec.end_lt;
|
||||
info_rec.end_lt = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
// 4) mark_keyblock_on_shard => если "not_master" = true, то проставим key_block = true
|
||||
if (config_.mark_keyblock_on_shard) {
|
||||
CHECK(info_rec.not_master);
|
||||
info_rec.key_block = true;
|
||||
}
|
||||
|
||||
// 5) force_after_merge / force_before_split / force_after_split для MC
|
||||
if (config_.force_after_merge_for_mc) {
|
||||
CHECK(!info_rec.not_master);
|
||||
info_rec.after_merge = true;
|
||||
}
|
||||
if (config_.force_before_split_for_mc) {
|
||||
CHECK(!info_rec.not_master);
|
||||
info_rec.before_split = true;
|
||||
}
|
||||
if (config_.force_after_split_for_mc) {
|
||||
CHECK(!info_rec.not_master);
|
||||
info_rec.after_split = true;
|
||||
}
|
||||
|
||||
// 6) allow_both_after_merge_and_split => ставим after_merge=1 и after_split=1
|
||||
if (config_.allow_both_after_merge_and_split) {
|
||||
info_rec.after_merge = true;
|
||||
info_rec.after_split = true;
|
||||
}
|
||||
|
||||
// 7) shard_pfx_zero_yet_after_split => shard_pfx_bits=0, after_split=1
|
||||
if (config_.shard_pfx_zero_yet_after_split) {
|
||||
info_rec.after_split = true;
|
||||
block::gen::ShardIdent::Record shard_rec;
|
||||
CHECK(block::gen::ShardIdent().unpack(info_rec.shard.write(), shard_rec));
|
||||
shard_rec.shard_pfx_bits = 0;
|
||||
vm::CellBuilder cb;
|
||||
CHECK(block::gen::t_ShardIdent.pack(cb, shard_rec));
|
||||
info_rec.shard = td::Ref<vm::CellSlice>{true, cb.finalize()};
|
||||
}
|
||||
|
||||
// 8) set_vert_seqno_incr => vert_seqno_incr != 0 => ставим true
|
||||
if (config_.set_vert_seqno_incr) {
|
||||
info_rec.vert_seq_no = 1;
|
||||
info_rec.vert_seqno_incr = true;
|
||||
info_rec.prev_vert_ref = info_rec.prev_ref;
|
||||
}
|
||||
|
||||
CHECK(block::gen::t_BlockInfo.cell_pack(block.info, info_rec));
|
||||
}
|
||||
|
||||
} // namespace test::fisherman
|
||||
|
|
|
@ -1,20 +1,36 @@
|
|||
#pragma once
|
||||
|
||||
#include "base.hpp"
|
||||
|
||||
#include "td/utils/JsonBuilder.h"
|
||||
#include "block/block-auto.h"
|
||||
|
||||
namespace test::fisherman {
|
||||
|
||||
class HeaderCorrupter : public BaseManipulator {
|
||||
public:
|
||||
struct Config {
|
||||
// TODO: add corruption field and method
|
||||
bool distort_timestamp = false;
|
||||
td::int32 time_offset = 1'000'000'000;
|
||||
|
||||
static auto fromJson(td::JsonValue jv) -> Config;
|
||||
bool mark_subshard_of_master = false;
|
||||
bool invert_lt = false;
|
||||
bool mark_keyblock_on_shard = false;
|
||||
|
||||
bool force_after_merge_for_mc = false;
|
||||
bool force_before_split_for_mc = false;
|
||||
bool force_after_split_for_mc = false;
|
||||
bool allow_both_after_merge_and_split = false;
|
||||
|
||||
bool shard_pfx_zero_yet_after_split = false;
|
||||
|
||||
bool set_vert_seqno_incr = false;
|
||||
|
||||
static Config fromJson(td::JsonValue jv);
|
||||
};
|
||||
|
||||
explicit HeaderCorrupter(Config config);
|
||||
void modify(block::gen::Block::Record &block) final;
|
||||
void modify(block::gen::Block::Record &block) override;
|
||||
|
||||
private:
|
||||
Config config_;
|
||||
|
|
|
@ -6,6 +6,14 @@
|
|||
|
||||
using namespace test::fisherman;
|
||||
|
||||
void print_block(const block::gen::Block::Record &block_rec) {
|
||||
std::ostringstream os;
|
||||
td::Ref<vm::Cell> block_cell_pack;
|
||||
CHECK(block::gen::t_Block.cell_pack(block_cell_pack, block_rec));
|
||||
block::gen::t_Block.print_ref(os, block_cell_pack);
|
||||
LOG(INFO) << "Block = " << os.str();
|
||||
}
|
||||
|
||||
auto main(int argc, char **argv) -> int {
|
||||
if (argc < 3) {
|
||||
std::cerr << "Usage: " << argv[0] << " /path/to/rootdb config.json\n";
|
||||
|
@ -51,30 +59,17 @@ auto main(int argc, char **argv) -> int {
|
|||
}
|
||||
|
||||
auto blk_data = blk_data_result.move_as_ok();
|
||||
LOG(INFO) << "BlockId: " << blk_data->block_id().to_str();
|
||||
LOG(INFO) << "Block data size: " << blk_data->data().size() << " bytes";
|
||||
|
||||
LOG(INFO) << "Cell has block record = " << block::gen::Block().validate_ref(10000000, blk_data->root_cell()) << "\n";
|
||||
|
||||
std::ostringstream os;
|
||||
block::gen::Block().print_ref(os, blk_data->root_cell());
|
||||
LOG(INFO) << "Block = " << os.str();
|
||||
|
||||
block::gen::Block::Record block_rec;
|
||||
bool ok = block::gen::Block().cell_unpack(blk_data->root_cell(), block_rec);
|
||||
CHECK(ok);
|
||||
CHECK(block::gen::t_Block.cell_unpack(blk_data->root_cell(), block_rec));
|
||||
|
||||
block::gen::BlockInfo::Record info_rec;
|
||||
block::gen::BlockInfo().cell_unpack(block_rec.info, info_rec);
|
||||
LOG(INFO) << "Block.info after_merge=" << info_rec.after_merge << ", after_split=" << info_rec.after_split;
|
||||
print_block(block_rec);
|
||||
|
||||
auto manipulation_config = td::get_json_object_field(js_obj, "manipulation", td::JsonValue::Type::Object, false);
|
||||
CHECK(manipulation_config.is_ok());
|
||||
ManipulatorFactory().create(manipulation_config.move_as_ok())->modify(block_rec);
|
||||
|
||||
LOG(INFO) << "Block after manipulation:";
|
||||
block::gen::BlockInfo().cell_unpack(block_rec.info, info_rec);
|
||||
LOG(INFO) << "Block.info after_merge=" << info_rec.after_merge << ", after_split=" << info_rec.after_split;
|
||||
|
||||
print_block(block_rec);
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue