1
0
Fork 0
mirror of https://github.com/ton-blockchain/ton synced 2025-03-09 15:40:10 +00:00
This commit is contained in:
ton 2020-04-10 23:06:01 +04:00
parent 8be3fc99ed
commit be9c34c62d
699 changed files with 1171 additions and 978 deletions

View file

@ -310,8 +310,7 @@ td::Status Config::visit_validator_params() const {
ton::ValidatorSessionConfig Config::get_consensus_config() const {
auto cc = get_config_param(29);
ton::ValidatorSessionConfig c;
block::gen::ConsensusConfig::Record r;
if (cc.not_null() && tlb::unpack_cell(cc, r)) {
auto set = [&c](auto& r, bool new_cc_ids) {
c.catchain_idle_timeout = r.consensus_timeout_ms * 0.001;
c.catchain_max_deps = r.catchain_max_deps;
c.round_candidates = r.round_candidates;
@ -320,6 +319,13 @@ ton::ValidatorSessionConfig Config::get_consensus_config() const {
c.max_round_attempts = r.fast_attempts;
c.max_block_size = r.max_block_bytes;
c.max_collated_data_size = r.max_collated_bytes;
c.new_catchain_ids = new_cc_ids;
return true;
};
if (cc.not_null()) {
block::gen::ConsensusConfig::Record_consensus_config_new r1;
block::gen::ConsensusConfig::Record_consensus_config r0;
(tlb::unpack_cell(cc, r1) && set(r1, r1.new_catchain_ids)) || (tlb::unpack_cell(cc, r0) && set(r0, false));
}
return c;
}
@ -671,14 +677,20 @@ td::Result<MsgPrices> Config::get_msg_prices(bool is_masterchain) const {
}
CatchainValidatorsConfig Config::unpack_catchain_validators_config(Ref<vm::Cell> cell) {
block::gen::CatchainConfig::Record cfg;
if (cell.is_null() || !tlb::unpack_cell(std::move(cell), cfg)) {
return {default_mc_catchain_lifetime, default_shard_catchain_lifetime, default_shard_validators_lifetime,
default_shard_validators_num};
} else {
return {cfg.mc_catchain_lifetime, cfg.shard_catchain_lifetime, cfg.shard_validators_lifetime,
cfg.shard_validators_num};
if (cell.not_null()) {
block::gen::CatchainConfig::Record_catchain_config cfg;
if (tlb::unpack_cell(cell, cfg)) {
return {cfg.mc_catchain_lifetime, cfg.shard_catchain_lifetime, cfg.shard_validators_lifetime,
cfg.shard_validators_num};
}
block::gen::CatchainConfig::Record_catchain_config_new cfg2;
if (tlb::unpack_cell(std::move(cell), cfg2)) {
return {cfg2.mc_catchain_lifetime, cfg2.shard_catchain_lifetime, cfg2.shard_validators_lifetime,
cfg2.shard_validators_num, cfg2.shuffle_mc_validators};
}
}
return {default_mc_catchain_lifetime, default_shard_catchain_lifetime, default_shard_validators_lifetime,
default_shard_validators_num};
}
CatchainValidatorsConfig Config::get_catchain_validators_config() const {
@ -1215,47 +1227,47 @@ std::vector<ton::BlockId> ShardConfig::get_shard_hash_ids(
std::vector<ton::BlockId> res;
bool mcout = mc_shard_hash_.is_null() || !mc_shard_hash_->seqno(); // include masterchain as a shard if seqno > 0
bool ok = shard_hashes_dict_->check_for_each(
[&res, &mcout, mc_shard_hash_ = mc_shard_hash_, &filter ](Ref<vm::CellSlice> cs_ref, td::ConstBitPtr key, int n)
->bool {
int workchain = (int)key.get_int(n);
if (workchain >= 0 && !mcout) {
if (filter(ton::ShardIdFull{ton::masterchainId}, true)) {
res.emplace_back(mc_shard_hash_->blk_.id);
}
mcout = true;
}
if (!cs_ref->have_refs()) {
[&res, &mcout, mc_shard_hash_ = mc_shard_hash_, &filter](Ref<vm::CellSlice> cs_ref, td::ConstBitPtr key,
int n) -> bool {
int workchain = (int)key.get_int(n);
if (workchain >= 0 && !mcout) {
if (filter(ton::ShardIdFull{ton::masterchainId}, true)) {
res.emplace_back(mc_shard_hash_->blk_.id);
}
mcout = true;
}
if (!cs_ref->have_refs()) {
return false;
}
std::stack<std::pair<Ref<vm::Cell>, unsigned long long>> stack;
stack.emplace(cs_ref->prefetch_ref(), ton::shardIdAll);
while (!stack.empty()) {
vm::CellSlice cs{vm::NoVmOrd(), std::move(stack.top().first)};
unsigned long long shard = stack.top().second;
stack.pop();
int t = (int)cs.fetch_ulong(1);
if (t < 0) {
return false;
}
if (!filter(ton::ShardIdFull{workchain, shard}, !t)) {
continue;
}
if (!t) {
if (!(cs.advance(4) && cs.have(32))) {
return false;
}
std::stack<std::pair<Ref<vm::Cell>, unsigned long long>> stack;
stack.emplace(cs_ref->prefetch_ref(), ton::shardIdAll);
while (!stack.empty()) {
vm::CellSlice cs{vm::NoVmOrd(), std::move(stack.top().first)};
unsigned long long shard = stack.top().second;
stack.pop();
int t = (int)cs.fetch_ulong(1);
if (t < 0) {
return false;
}
if (!filter(ton::ShardIdFull{workchain, shard}, !t)) {
continue;
}
if (!t) {
if (!(cs.advance(4) && cs.have(32))) {
return false;
}
res.emplace_back(workchain, shard, (int)cs.prefetch_ulong(32));
continue;
}
unsigned long long delta = (td::lower_bit64(shard) >> 1);
if (!delta || cs.size_ext() != 0x20000) {
return false;
}
stack.emplace(cs.prefetch_ref(1), shard + delta);
stack.emplace(cs.prefetch_ref(0), shard - delta);
}
return true;
},
res.emplace_back(workchain, shard, (int)cs.prefetch_ulong(32));
continue;
}
unsigned long long delta = (td::lower_bit64(shard) >> 1);
if (!delta || cs.size_ext() != 0x20000) {
return false;
}
stack.emplace(cs.prefetch_ref(1), shard + delta);
stack.emplace(cs.prefetch_ref(0), shard - delta);
}
return true;
},
true);
if (!ok) {
return {};
@ -1611,8 +1623,8 @@ td::Result<std::vector<ton::StdSmcAddress>> Config::get_special_smartcontracts(b
return td::Status::Error(-666, "configuration loaded without fundamental smart contract list");
}
std::vector<ton::StdSmcAddress> res;
if (!special_smc_dict->check_for_each([&res, &without_config, conf_addr = config_addr.bits() ](
Ref<vm::CellSlice> cs_ref, td::ConstBitPtr key, int n) {
if (!special_smc_dict->check_for_each([&res, &without_config, conf_addr = config_addr.bits()](
Ref<vm::CellSlice> cs_ref, td::ConstBitPtr key, int n) {
if (cs_ref->size_ext() || n != 256) {
return false;
}
@ -1786,18 +1798,32 @@ std::vector<ton::ValidatorDescr> Config::do_compute_validator_set(const block::C
return {}; // no validators?
}
nodes.reserve(count);
ValidatorSetPRNG gen{shard, cc_seqno}; // use zero seed (might use a non-trivial seed from ccv_conf in the future)
if (is_mc) {
// simply take needed number of validators from the head of the list
// TODO: write a more clever validator list selection algorithm
// (if we really need one for the masterchain)
for (unsigned i = 0; i < count; i++) {
const auto& v = vset.list[i];
nodes.emplace_back(v.pubkey, v.weight, v.adnl_addr);
if (ccv_conf.shuffle_mc_val) {
// shuffle mc validators from the head of the list
std::vector<unsigned> idx(count);
CHECK(idx.size() == count);
for (unsigned i = 0; i < count; i++) {
unsigned j = (unsigned)gen.next_ranged(i + 1); // number 0 .. i
CHECK(j <= i);
idx[i] = idx[j];
idx[j] = i;
}
for (unsigned i = 0; i < count; i++) {
const auto& v = vset.list[idx[i]];
nodes.emplace_back(v.pubkey, v.weight, v.adnl_addr);
}
} else {
// simply take needed number of validators from the head of the list
for (unsigned i = 0; i < count; i++) {
const auto& v = vset.list[i];
nodes.emplace_back(v.pubkey, v.weight, v.adnl_addr);
}
}
return nodes;
}
// this is the "true" algorithm for generating shardchain validator subgroups
ValidatorSetPRNG gen{shard, cc_seqno}; // use zero seed (might use a non-trivial seed from ccv_conf in the future)
std::vector<std::pair<td::uint64, td::uint64>> holes;
holes.reserve(count);
td::uint64 total_wt = vset.total_weight;