diff --git a/core/authority_discovery/publisher/address_publisher.cpp b/core/authority_discovery/publisher/address_publisher.cpp index db481bebf4..949db26936 100644 --- a/core/authority_discovery/publisher/address_publisher.cpp +++ b/core/authority_discovery/publisher/address_publisher.cpp @@ -27,10 +27,10 @@ std::vector pbEncodeVec(const T &v) { namespace kagome::authority_discovery { constexpr std::chrono::seconds kIntervalInitial{2}; - constexpr std::chrono::hours kIntervalMax{1}; + constexpr std::chrono::minutes kIntervalMax{5}; // TODO(kamilsa): #2351, remove this variable when resolved - constexpr bool kAudiDisableTimestamp = true; + constexpr bool kAudiDisableTimestamp = false; static const metrics::GaugeHelper metric_amount_addresses_last_published{ "kagome_authority_discovery_amount_external_addresses_last_published", @@ -118,14 +118,18 @@ namespace kagome::authority_discovery { return outcome::success(); } + // check if we have authority discovery keys in the keystore, that exist in + // authorities list OUTCOME_TRY( authorities, authority_discovery_api_->authorities(block_tree_->bestBlock().hash)); - auto audi_key = keys_->getAudiKeyPair(authorities); - if (not audi_key) { - SL_WARN(log_, "No authority discovery key"); - return outcome::success(); + auto audi_keys = keys_->getAudiKeyPairs(authorities); + if (audi_keys.empty()) { + SL_WARN(log_, "No authority discovery keys found for authorities"); + // if we have no authority discovery keys, we publish anyway with all keys + // from the keystore + audi_keys = keys_->getAudiKeyPairs(); } std::optional now = @@ -133,17 +137,24 @@ namespace kagome::authority_discovery { if (kAudiDisableTimestamp) { now.reset(); } - OUTCOME_TRY(raw, - audiEncode(ed_crypto_provider_, - sr_crypto_provider_, - *libp2p_key_, - *libp2p_key_pb_, - peer_info, - *audi_key, - now)); - auto r = kademlia_->putValue(std::move(raw.first), std::move(raw.second)); - MetricDhtEventReceived::get().putResult(r.has_value()); - return r; + for (const auto &audi_key : audi_keys) { + OUTCOME_TRY(raw, + audiEncode(ed_crypto_provider_, + sr_crypto_provider_, + *libp2p_key_, + *libp2p_key_pb_, + peer_info, + audi_key, + now)); + auto r = kademlia_->putValue(std::move(raw.first), std::move(raw.second)); + MetricDhtEventReceived::get().putResult(r.has_value()); + if (not r) { + SL_ERROR(log_, "Failed to put value to kademlia: {}", r.error()); + return r.error(); + } + } + + return outcome::success(); } outcome::result> audiEncode( @@ -168,9 +179,19 @@ namespace kagome::authority_discovery { } metric_amount_addresses_last_published->set(addresses.size()); ::authority_discovery_v3::AuthorityRecord record; + std::string peer_addresses; for (const auto &address : addresses) { PB_SPAN_ADD(record, addresses, address.getBytesAddress()); + if (not peer_addresses.empty()) { + peer_addresses.append(", "); + } + peer_addresses.append(address.getStringAddress()); } + auto log = log::createLogger("AddressPublisher", "authority_discovery"); + SL_DEBUG(log, + "Publishing authority discovery record for {} with addresses: {}", + audi_key.public_key.toHex(), + peer_addresses); if (now) { Timestamp time{now->count()}; OUTCOME_TRY(encoded_time, scale::encode(time)); diff --git a/core/crypto/key_store/session_keys.cpp b/core/crypto/key_store/session_keys.cpp index ffa5e6ea0e..a6568bcc8a 100644 --- a/core/crypto/key_store/session_keys.cpp +++ b/core/crypto/key_store/session_keys.cpp @@ -131,16 +131,55 @@ namespace kagome::crypto { std::equal_to{}); } - std::shared_ptr SessionKeysImpl::getAudiKeyPair( + std::vector SessionKeysImpl::getAudiKeyPairs( const std::vector &authorities) { - if (auto res = find(audi_key_pair_, - KeyTypes::AUTHORITY_DISCOVERY, - store_->sr25519(), - authorities, - std::equal_to{})) { - return std::move(res->first); + if (not roles_.isAuthority()) { + return {}; } - return nullptr; + + std::vector result; + auto keys_res = + store_->sr25519().getPublicKeys(KeyTypes::AUTHORITY_DISCOVERY); + if (not keys_res) { + return result; + } + + auto &keys = keys_res.value(); + for (auto &pubkey : keys) { + auto it = std::ranges::find_if( + authorities.begin(), authorities.end(), [&](const auto &authority) { + return pubkey == authority; + }); + + if (it != authorities.end()) { + auto keypair_opt = store_->sr25519().findKeypair( + KeyTypes::AUTHORITY_DISCOVERY, pubkey); + if (keypair_opt) { + result.push_back(keypair_opt.value()); + } + } + } + + return result; + } + + std::vector SessionKeysImpl::getAudiKeyPairs() { + std::vector keypairs; + auto keys_res = + store_->sr25519().getPublicKeys(KeyTypes::AUTHORITY_DISCOVERY); + if (not keys_res || keys_res.value().empty()) { + return keypairs; + } + + for (const auto &pubkey : keys_res.value()) { + auto keypair_opt = + store_->sr25519().findKeypair(KeyTypes::AUTHORITY_DISCOVERY, pubkey); + if (keypair_opt) { + keypairs.push_back(keypair_opt.value()); + } + } + + return keypairs; } SessionKeys::KeypairWithIndexOpt @@ -152,4 +191,5 @@ namespace kagome::crypto { authorities, std::equal_to{}); } + } // namespace kagome::crypto diff --git a/core/crypto/key_store/session_keys.hpp b/core/crypto/key_store/session_keys.hpp index 0e2d6d2249..5d671aa4a6 100644 --- a/core/crypto/key_store/session_keys.hpp +++ b/core/crypto/key_store/session_keys.hpp @@ -73,11 +73,17 @@ namespace kagome::crypto { const std::vector &authorities) = 0; /** - * @return current AUDI session key pair + * @return all AUDI session key pairs from storage that exist in authorities + * list */ - virtual std::shared_ptr getAudiKeyPair( + virtual std::vector getAudiKeyPairs( const std::vector &authorities) = 0; + /** + * @return all AUDI session key pairs from storage without checking + */ + virtual std::vector getAudiKeyPairs() = 0; + /** * @return current BEEF session key pair */ @@ -126,10 +132,12 @@ namespace kagome::crypto { KeypairWithIndexOpt getParaKeyPair( const std::vector &authorities) override; - std::shared_ptr getAudiKeyPair( + std::vector getAudiKeyPairs( const std::vector &authorities) override; + std::vector getAudiKeyPairs() override; + KeypairWithIndexOpt getBeefKeyPair( const std::vector &authorities) override; }; diff --git a/core/parachain/validator/signer.cpp b/core/parachain/validator/signer.cpp index 82400c945b..e96ecfaf1f 100644 --- a/core/parachain/validator/signer.cpp +++ b/core/parachain/validator/signer.cpp @@ -77,11 +77,16 @@ namespace kagome::parachain { return std::nullopt; } - auto keys = session_keys_->getAudiKeyPair(session_info->discovery_keys); - if (keys != nullptr) { + auto keypairs = + session_keys_->getAudiKeyPairs(session_info->discovery_keys); + if (not keypairs.empty()) { + // Find the index of the first keypair that matches any discovery key. + for (ValidatorIndex i = 0; i < session_info->discovery_keys.size(); ++i) { - if (keys->public_key == session_info->discovery_keys[i]) { - return i; + for (const auto &keypair : keypairs) { + if (keypair.public_key == session_info->discovery_keys[i]) { + return i; + } } } } diff --git a/test/mock/core/crypto/session_keys_mock.hpp b/test/mock/core/crypto/session_keys_mock.hpp index c3a7345c99..0f2effd9b3 100644 --- a/test/mock/core/crypto/session_keys_mock.hpp +++ b/test/mock/core/crypto/session_keys_mock.hpp @@ -38,11 +38,13 @@ namespace kagome::crypto { (const std::vector &), (override)); - MOCK_METHOD(std::shared_ptr, - getAudiKeyPair, + MOCK_METHOD(std::vector, + getAudiKeyPairs, (const std::vector &), (override)); + MOCK_METHOD(std::vector, getAudiKeyPairs, (), (override)); + MOCK_METHOD(KeypairWithIndexOpt, getBeefKeyPair, (const std::vector &),