@@ -576,34 +576,50 @@ td::Result<std::shared_ptr<ValidatorSet>> Config::unpack_validator_set(Ref<vm::C
576576 " maximal index in a validator set dictionary must be one less than the total number of validators" );
577577 }
578578 auto ptr = std::make_shared<ValidatorSet>(rec.utime_since , rec.utime_until , rec.total , rec.main );
579- for (int i = 0 ; i < rec.total ; i++) {
580- key_buffer.store_ulong (i);
581- auto descr_cs = dict.lookup (key_buffer.bits (), 16 );
582- if (descr_cs.is_null ()) {
583- return td::Status::Error (" indices in a validator set dictionary must be integers 0..total-1" );
584- }
579+
580+ std::vector<bool > seen_keys (rec.total );
581+ td::Status error;
582+
583+ auto validator_set_check_fn = [&](Ref<vm::CellSlice> descr_cs, td::ConstBitPtr key, int n) -> bool {
584+ int i = static_cast <int >(key.get_uint (n));
585+ CHECK (i >= 0 && i < rec.total && !seen_keys[i]);
586+ seen_keys[i] = true ;
587+
585588 gen::ValidatorDescr::Record_validator_addr descr;
586589 if (!tlb::csr_unpack (descr_cs, descr)) {
587590 descr.adnl_addr .set_zero ();
588591 if (!(gen::t_ValidatorDescr.unpack_validator (descr_cs.write (), descr.public_key , descr.weight ) &&
589592 descr_cs->empty_ext ())) {
590- return td::Status::Error (PSLICE () << " validator #" << i
591- << " has an invalid ValidatorDescr record in the validator set dictionary" );
593+ error = td::Status::Error (PSLICE () << " validator #" << i
594+ << " has an invalid ValidatorDescr record in the validator set dictionary" );
595+ return false ;
592596 }
593597 }
594598 gen::SigPubKey::Record sig_pubkey;
595599 if (!tlb::csr_unpack (std::move (descr.public_key ), sig_pubkey)) {
596- return td::Status::Error (PSLICE () << " validator #" << i
597- << " has no public key or its public key is in unsupported format" );
600+ error = td::Status::Error (PSLICE () << " validator #" << i
601+ << " has no public key or its public key is in unsupported format" );
602+ return false ;
598603 }
599604 if (!descr.weight ) {
600- return td::Status::Error (PSLICE () << " validator #" << i << " has zero weight" );
605+ error = td::Status::Error (PSLICE () << " validator #" << i << " has zero weight" );
606+ return false ;
601607 }
602608 if (descr.weight > ~(ptr->total_weight )) {
603- return td::Status::Error (" total weight of all validators in validator set exceeds 2^64" );
609+ error = td::Status::Error (" total weight of all validators in validator set exceeds 2^64" );
610+ return false ;
604611 }
605612 ptr->list .emplace_back (sig_pubkey.pubkey , descr.weight , ptr->total_weight , descr.adnl_addr );
606613 ptr->total_weight += descr.weight ;
614+ return true ;
615+ };
616+
617+ if (!dict.check_for_each (validator_set_check_fn)) {
618+ CHECK (error.is_error ());
619+ return error;
620+ }
621+ if (std::find (seen_keys.begin (), seen_keys.end (), false ) != seen_keys.end ()) {
622+ return td::Status::Error (" indices in a validator set dictionary must be integers 0..total-1" );
607623 }
608624 if (rec.total_weight && rec.total_weight != ptr->total_weight ) {
609625 return td::Status::Error (" validator set declares incorrect total weight" );
0 commit comments