diff --git a/crypto/block/block.tlb b/crypto/block/block.tlb index 2e43815e..4393c6e2 100644 --- a/crypto/block/block.tlb +++ b/crypto/block/block.tlb @@ -478,6 +478,18 @@ shard_descr#b seq_no:uint32 reg_mc_seqno:uint32 fees_collected:CurrencyCollection funds_created:CurrencyCollection = ShardDescr; +shard_descr_new#a seq_no:uint32 reg_mc_seqno:uint32 + start_lt:uint64 end_lt:uint64 + root_hash:bits256 file_hash:bits256 + before_split:Bool before_merge:Bool + want_split:Bool want_merge:Bool + nx_cc_updated:Bool flags:(## 3) { flags = 0 } + next_catchain_seqno:uint32 next_validator_shard:uint64 + min_ref_mc_seqno:uint32 gen_utime:uint32 + split_merge_at:FutureSplitMerge + ^[ fees_collected:CurrencyCollection + funds_created:CurrencyCollection ] = ShardDescr; + _ (HashmapE 32 ^(BinTree ShardDescr)) = ShardHashes; bta_leaf$0 {X:Type} {Y:Type} extra:Y leaf:X = BinTreeAug X Y; diff --git a/crypto/block/mc-config.cpp b/crypto/block/mc-config.cpp index b202b60c..20334582 100644 --- a/crypto/block/mc-config.cpp +++ b/crypto/block/mc-config.cpp @@ -43,6 +43,16 @@ namespace block { using namespace std::literals::string_literals; using td::Ref; +#define DBG(__n) dbg(__n)&& +#define DSTART int __dcnt = 0; +#define DEB DBG(++__dcnt) + +static inline bool dbg(int c) TD_UNUSED; +static inline bool dbg(int c) { + std::cerr << '[' << (char)('0' + c / 10) << (char)('0' + c % 10) << ']'; + return true; +} + Config::Config(Ref config_root, const td::Bits256& config_addr, int _mode) : mode(_mode), config_addr(config_addr), config_root(std::move(config_root)) { } @@ -691,29 +701,51 @@ void McShardHash::set_fsm(FsmState fsm, ton::UnixTime fsm_utime, ton::UnixTime f } Ref McShardHash::unpack(vm::CellSlice& cs, ton::ShardIdFull id) { - gen::ShardDescr::Record descr; - CurrencyCollection fees_collected, funds_created; - if (!(tlb::unpack_exact(cs, descr) && fees_collected.unpack(descr.fees_collected) && - funds_created.unpack(descr.funds_created))) { - return {}; // throw ? + int tag = gen::t_ShardDescr.get_tag(cs); + if (tag < 0) { + return {}; + } + auto create = [&id](auto& descr, Ref fees, Ref funds) { + CurrencyCollection fees_collected, funds_created; + if (!(fees_collected.unpack(std::move(fees)) && funds_created.unpack(std::move(funds)))) { + return Ref{}; + } + return td::make_ref(ton::BlockId{id, (unsigned)descr.seq_no}, descr.start_lt, descr.end_lt, + descr.gen_utime, descr.root_hash, descr.file_hash, fees_collected, funds_created, + descr.reg_mc_seqno, descr.min_ref_mc_seqno, descr.next_catchain_seqno, + descr.next_validator_shard, /* descr.nx_cc_updated */ false, descr.before_split, + descr.before_merge, descr.want_split, descr.want_merge); + }; + Ref res; + Ref fsm_cs; + if (tag == gen::ShardDescr::shard_descr) { + gen::ShardDescr::Record_shard_descr descr; + if (tlb::unpack_exact(cs, descr)) { + fsm_cs = std::move(descr.split_merge_at); + res = create(descr, std::move(descr.fees_collected), std::move(descr.funds_created)); + } + } else { + gen::ShardDescr::Record_shard_descr_new descr; + if (tlb::unpack_exact(cs, descr)) { + fsm_cs = std::move(descr.split_merge_at); + res = create(descr, std::move(descr.r1.fees_collected), std::move(descr.r1.funds_created)); + } + } + if (res.is_null()) { + return res; } - auto res = Ref(true, ton::BlockId{id, (unsigned)descr.seq_no}, descr.start_lt, descr.end_lt, - descr.gen_utime, descr.root_hash, descr.file_hash, fees_collected, funds_created, - descr.reg_mc_seqno, descr.min_ref_mc_seqno, descr.next_catchain_seqno, - descr.next_validator_shard, /* descr.nx_cc_updated */ false, descr.before_split, - descr.before_merge, descr.want_split, descr.want_merge); McShardHash& sh = res.unique_write(); - switch (gen::t_FutureSplitMerge.get_tag(*(descr.split_merge_at))) { + switch (gen::t_FutureSplitMerge.get_tag(*fsm_cs)) { case gen::FutureSplitMerge::fsm_none: return res; case gen::FutureSplitMerge::fsm_split: - if (gen::t_FutureSplitMerge.unpack_fsm_split(descr.split_merge_at.write(), sh.fsm_utime_, sh.fsm_interval_)) { + if (gen::t_FutureSplitMerge.unpack_fsm_split(fsm_cs.write(), sh.fsm_utime_, sh.fsm_interval_)) { sh.fsm_ = FsmState::fsm_split; return res; } break; case gen::FutureSplitMerge::fsm_merge: - if (gen::t_FutureSplitMerge.unpack_fsm_merge(descr.split_merge_at.write(), sh.fsm_utime_, sh.fsm_interval_)) { + if (gen::t_FutureSplitMerge.unpack_fsm_merge(fsm_cs.write(), sh.fsm_utime_, sh.fsm_interval_)) { sh.fsm_ = FsmState::fsm_merge; return res; } @@ -726,7 +758,7 @@ Ref McShardHash::unpack(vm::CellSlice& cs, ton::ShardIdFull id) { bool McShardHash::pack(vm::CellBuilder& cb) const { if (!(is_valid() // (validate) - && cb.store_long_bool(11, 4) // shard_descr#b + && cb.store_long_bool(10, 4) // shard_descr_new#a && cb.store_long_bool(blk_.id.seqno, 32) // seq_no:uint32 && cb.store_long_bool(reg_mc_seqno_, 32) // reg_mc_seqno:uint32 && cb.store_long_bool(start_lt_, 64) // start_lt:uint64 @@ -760,9 +792,11 @@ bool McShardHash::pack(vm::CellBuilder& cb) const { default: return false; } - return ok // split_merge_at:FutureSplitMerge - && fees_collected_.store_or_zero(cb) // fees_collected:CurrencyCollection - && funds_created_.store_or_zero(cb); // funds_created:CurrencyCollection = ShardDescr; + vm::CellBuilder cb2; + return ok // split_merge_at:FutureSplitMerge + && fees_collected_.store_or_zero(cb2) // ^[ fees_collected:CurrencyCollection + && funds_created_.store_or_zero(cb2) // funds_created:CurrencyCollection ] + && cb.store_builder_ref_bool(std::move(cb2)); // = ShardDescr; } Ref McShardHash::from_block(Ref block_root, const ton::FileHash& fhash, bool init_fees) { @@ -982,27 +1016,45 @@ Ref ShardConfig::get_shard_hash(ton::ShardIdFull id, bool exact) co } } +bool McShardHash::extract_cc_seqno(vm::CellSlice& cs, ton::CatchainSeqno* cc) { + auto get = [&cs, cc](auto& rec) { + if (tlb::unpack_exact(cs, rec)) { + *cc = rec.next_catchain_seqno; + return true; + } else { + *cc = std::numeric_limits::max(); + return false; + } + }; + if (block::gen::t_ShardDescr.get_tag(cs) == block::gen::ShardDescr::shard_descr) { + gen::ShardDescr::Record_shard_descr rec; + return get(rec); + } else { + gen::ShardDescr::Record_shard_descr_new rec; + return get(rec); + } +} + ton::CatchainSeqno ShardConfig::get_shard_cc_seqno(ton::ShardIdFull shard) const { if (shard.is_masterchain() || !shard.is_valid()) { return std::numeric_limits::max(); } ton::ShardIdFull true_id; - gen::ShardDescr::Record info; + ton::CatchainSeqno cc_seqno, cc_seqno2; vm::CellSlice cs; if (!(get_shard_hash_raw(cs, shard - 1, true_id, false) && (ton::shard_is_ancestor(true_id, shard) || ton::shard_is_parent(shard, true_id)) && - tlb::unpack_exact(cs, info))) { + McShardHash::extract_cc_seqno(cs, &cc_seqno))) { return std::numeric_limits::max(); } - ton::CatchainSeqno cc_seqno = info.next_catchain_seqno; if (ton::shard_is_ancestor(true_id, shard)) { return cc_seqno; } if (!(get_shard_hash_raw(cs, shard + 1, true_id, false) && ton::shard_is_parent(shard, true_id) && - tlb::unpack_exact(cs, info))) { + McShardHash::extract_cc_seqno(cs, &cc_seqno2))) { return std::numeric_limits::max(); } - return std::max(cc_seqno, info.next_catchain_seqno) + 1; + return std::max(cc_seqno, cc_seqno2) + 1; } ton::LogicalTime ShardConfig::get_shard_end_lt_ext(ton::AccountIdPrefixFull acc, ton::ShardIdFull& actual_shard) const { @@ -1147,9 +1199,10 @@ bool ShardConfig::process_sibling_shard_hashes(std::function root; ok = ok && (n == 32) && csr->size_ext() == 0x10000 && std::move(csr)->prefetch_ref_to(root) && process_workchain_sibling_shard_hashes(root, Ref{}, ton::ShardIdFull{(int)key.get_int(32)}, func) >= - 0 && - cb.store_ref_bool(std::move(root)); - return true; + 0; + bool f = cb.store_ref_bool(std::move(root)); + ok &= f; + return f; }); return ok; } diff --git a/crypto/block/mc-config.h b/crypto/block/mc-config.h index 467b7c8a..d0c51b5a 100644 --- a/crypto/block/mc-config.h +++ b/crypto/block/mc-config.h @@ -273,6 +273,7 @@ struct McShardHash : public McShardHashI { bool pack(vm::CellBuilder& cb) const; static Ref unpack(vm::CellSlice& cs, ton::ShardIdFull id); static Ref from_block(Ref block_root, const ton::FileHash& _fhash, bool init_fees = false); + static bool extract_cc_seqno(vm::CellSlice& cs, ton::CatchainSeqno* cc); McShardHash* make_copy() const override { return new McShardHash(*this); } diff --git a/validator/impl/collator.cpp b/validator/impl/collator.cpp index dd349e66..06d81897 100644 --- a/validator/impl/collator.cpp +++ b/validator/impl/collator.cpp @@ -3024,7 +3024,27 @@ bool Collator::create_mc_state_extra() { return fatal_error(wset_res.move_as_error()); } bool update_shard_cc = is_key_block_ || (now_ / ccvc.shard_cc_lifetime > prev_now_ / ccvc.shard_cc_lifetime); + // temp debug + if (verbosity >= 3 * 1) { + auto csr = shard_conf_->get_root_csr(); + LOG(INFO) << "new shard configuration before post-processing is"; + std::ostringstream os; + csr->print_rec(os); + block::gen::t_ShardHashes.print(os, csr.write()); + LOG(INFO) << os.str(); + } + // end (temp debug) if (!update_shard_config(wset_res.move_as_ok(), ccvc, update_shard_cc)) { + auto csr = shard_conf_->get_root_csr(); + if (csr.is_null()) { + LOG(WARNING) << "new shard configuration is null (!)"; + } else { + LOG(WARNING) << "invalid new shard configuration is"; + std::ostringstream os; + csr->print_rec(os); + block::gen::t_ShardHashes.print(os, csr.write()); + LOG(WARNING) << os.str(); + } return fatal_error("cannot post-process shard configuration"); } // 3. save new shard_hashes