Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Use check_for_each for iterating over validator set #1553

Open
wants to merge 1 commit into
base: testnet
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 28 additions & 12 deletions crypto/block/mc-config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -516,34 +516,50 @@ td::Result<std::unique_ptr<ValidatorSet>> Config::unpack_validator_set(Ref<vm::C
"maximal index in a validator set dictionary must be one less than the total number of validators");
}
auto ptr = std::make_unique<ValidatorSet>(rec.utime_since, rec.utime_until, rec.total, rec.main);
for (int i = 0; i < rec.total; i++) {
key_buffer.store_ulong(i);
auto descr_cs = dict.lookup(key_buffer.bits(), 16);
if (descr_cs.is_null()) {
return td::Status::Error("indices in a validator set dictionary must be integers 0..total-1");
}

std::vector<bool> seen_keys(rec.total);
td::Status error;

auto validator_set_check_fn = [&](Ref<vm::CellSlice> descr_cs, td::ConstBitPtr key, int n) -> bool {
int i = static_cast<int>(key.get_int(n));
CHECK(i >= 0 && i < rec.total && !seen_keys[i]);
seen_keys[i] = true;

gen::ValidatorDescr::Record_validator_addr descr;
if (!tlb::csr_unpack(descr_cs, descr)) {
descr.adnl_addr.set_zero();
if (!(gen::t_ValidatorDescr.unpack_validator(descr_cs.write(), descr.public_key, descr.weight) &&
descr_cs->empty_ext())) {
return td::Status::Error(PSLICE() << "validator #" << i
<< " has an invalid ValidatorDescr record in the validator set dictionary");
error = td::Status::Error(PSLICE() << "validator #" << i
<< " has an invalid ValidatorDescr record in the validator set dictionary");
return false;
}
}
gen::SigPubKey::Record sig_pubkey;
if (!tlb::csr_unpack(std::move(descr.public_key), sig_pubkey)) {
return td::Status::Error(PSLICE() << "validator #" << i
<< " has no public key or its public key is in unsupported format");
error = td::Status::Error(PSLICE() << "validator #" << i
<< " has no public key or its public key is in unsupported format");
return false;
}
if (!descr.weight) {
return td::Status::Error(PSLICE() << "validator #" << i << " has zero weight");
error = td::Status::Error(PSLICE() << "validator #" << i << " has zero weight");
return false;
}
if (descr.weight > ~(ptr->total_weight)) {
return td::Status::Error("total weight of all validators in validator set exceeds 2^64");
error = td::Status::Error("total weight of all validators in validator set exceeds 2^64");
return false;
}
ptr->list.emplace_back(sig_pubkey.pubkey, descr.weight, ptr->total_weight, descr.adnl_addr);
ptr->total_weight += descr.weight;
return true;
};

if (!dict.check_for_each(validator_set_check_fn)) {
CHECK(error.is_error());
return error;
}
if (std::find(seen_keys.begin(), seen_keys.end(), false) != seen_keys.end()) {
return td::Status::Error("indices in a validator set dictionary must be integers 0..total-1");
}
if (rec.total_weight && rec.total_weight != ptr->total_weight) {
return td::Status::Error("validator set declares incorrect total weight");
Expand Down