Skip to content

Commit

Permalink
refactor: key types
Browse files Browse the repository at this point in the history
Signed-off-by: Dmitriy Khaustov aka xDimon <[email protected]>
  • Loading branch information
xDimon committed Oct 6, 2023
1 parent 0f99a96 commit 2b86cd5
Show file tree
Hide file tree
Showing 19 changed files with 277 additions and 214 deletions.
28 changes: 14 additions & 14 deletions core/api/service/author/impl/author_api_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@
#include "transaction_pool/transaction_pool.hpp"

namespace kagome::api {
const std::vector<crypto::KnownKeyTypeId> kKeyTypes{
crypto::KEY_TYPE_BABE,
crypto::KEY_TYPE_GRAN,
crypto::KEY_TYPE_AUDI,
const std::vector<crypto::KeyType> kKeyTypes{
crypto::KeyType::BABE,
crypto::KeyType::GRANDPA,
crypto::KeyType::AUTHORITY_DISCOVERY,
};

AuthorApiImpl::AuthorApiImpl(sptr<runtime::SessionKeysApi> key_api,
Expand Down Expand Up @@ -61,43 +61,43 @@ namespace kagome::api {
}

outcome::result<void> AuthorApiImpl::insertKey(
crypto::KeyTypeId key_type,
crypto::KeyTypeId key_type_id,
const gsl::span<const uint8_t> &seed,
const gsl::span<const uint8_t> &public_key) {
if (std::find(kKeyTypes.begin(), kKeyTypes.end(), key_type)
if (std::find(kKeyTypes.begin(), kKeyTypes.end(), key_type_id)
== kKeyTypes.end()) {
std::string types;
for (auto &type : kKeyTypes) {
types.append(encodeKeyTypeIdToStr(type));
types.append(crypto::encodeKeyTypeIdToStr(type));
types.push_back(' ');
}
types.pop_back();
SL_INFO(logger_, "Unsupported key type, only [{}] are accepted", types);
return outcome::failure(crypto::CryptoStoreError::UNSUPPORTED_KEY_TYPE);
};
if (crypto::KEY_TYPE_BABE == key_type
or crypto::KEY_TYPE_AUDI == key_type) {
if (crypto::KeyType::BABE == key_type_id
or crypto::KeyType::AUTHORITY_DISCOVERY == key_type_id) {
OUTCOME_TRY(seed_typed, crypto::Sr25519Seed::fromSpan(seed));
OUTCOME_TRY(public_key_typed,
crypto::Sr25519PublicKey::fromSpan(public_key));
OUTCOME_TRY(keypair,
store_->generateSr25519Keypair(key_type, seed_typed));
store_->generateSr25519Keypair(key_type_id, seed_typed));
if (public_key_typed != keypair.public_key) {
return outcome::failure(crypto::CryptoStoreError::WRONG_PUBLIC_KEY);
}
}
if (crypto::KEY_TYPE_GRAN == key_type) {
if (crypto::KeyType::GRANDPA == key_type_id) {
OUTCOME_TRY(seed_typed, crypto::Ed25519Seed::fromSpan(seed));
OUTCOME_TRY(public_key_typed,
crypto::Ed25519PublicKey::fromSpan(public_key));
OUTCOME_TRY(
keypair,
store_->generateEd25519Keypair(crypto::KEY_TYPE_GRAN, seed_typed));
store_->generateEd25519Keypair(crypto::KeyType::GRANDPA, seed_typed));
if (public_key_typed != keypair.public_key) {
return outcome::failure(crypto::CryptoStoreError::WRONG_PUBLIC_KEY);
}
}
auto res = key_store_->saveKeyPair(key_type, public_key, seed);
auto res = key_store_->saveKeyPair(key_type_id, public_key, seed);
return res;
}

Expand All @@ -124,7 +124,7 @@ namespace kagome::api {
}
stream >> key;
if (store_->findEd25519Keypair(
crypto::KEY_TYPE_GRAN,
crypto::KeyType::GRANDPA,
crypto::Ed25519PublicKey(common::Blob<32>(key)))) {
unsigned count = 1;
while (stream.currentIndex() < keys.size()) {
Expand Down
2 changes: 1 addition & 1 deletion core/api/service/author/impl/author_api_impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ namespace kagome::api {
const primitives::Extrinsic &extrinsic) override;

outcome::result<void> insertKey(
crypto::KeyTypeId key_type,
crypto::KeyTypeId key_type_id,
const gsl::span<const uint8_t> &seed,
const gsl::span<const uint8_t> &public_key) override;

Expand Down
2 changes: 1 addition & 1 deletion core/authority_discovery/query/query_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ namespace kagome::authority_discovery {
authority_discovery_api_->authorities(block_tree_->bestBlock().hash));
OUTCOME_TRY(local_keys,
crypto_store_->getSr25519PublicKeys(
crypto::KnownKeyTypeId::KEY_TYPE_AUDI));
crypto::KeyType::AUTHORITY_DISCOVERY));
authorities.erase(
std::remove_if(authorities.begin(),
authorities.end(),
Expand Down
10 changes: 5 additions & 5 deletions core/authorship/impl/block_builder_factory_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,11 @@ namespace kagome::authorship {
BOOST_ASSERT(parent_number == parent.number);

auto number = parent.number + 1;
primitives::BlockHeader header;
header.number = number;
header.parent_hash = parent.hash;
header.digest = std::move(inherent_digest);

primitives::BlockHeader header{
.number = number,
.parent_hash = parent.hash,
.digest = std::move(inherent_digest),
};
if (auto res =
r_core_->initialize_block(header, std::move(changes_tracker));
not res) {
Expand Down
6 changes: 3 additions & 3 deletions core/crypto/crypto_store/key_file_storage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ namespace kagome::crypto {
KeyFileStorage::parseKeyFileName(std::string_view file_name) const {
OUTCOME_TRY(info, decodeKeyFileName(file_name));
auto key_type_str = file_name.substr(0, 8);
if (not isSupportedKeyType(info.first)) {
if (not KeyType::is_supported(info.first)) {
auto ascii_res = common::unhex(key_type_str);
if (ascii_res.has_value()) {
std::string_view ascii(
Expand All @@ -64,10 +64,10 @@ namespace kagome::crypto {
logger_->warn(
"key type <ascii: '{}', hex: {:08x}> is not officially supported",
ascii,
info.first);
(KeyTypeId)info.first);
} else {
logger_->warn("key type <hex: {:08x}> is not officially supported",
info.first);
(KeyTypeId)info.first);
}
}
return info;
Expand Down
32 changes: 8 additions & 24 deletions core/crypto/crypto_store/key_type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,36 +12,20 @@

namespace kagome::crypto {

bool isSupportedKeyType(KeyTypeId k) {
static const std::unordered_set<KeyTypeId> supported_types = {
KEY_TYPE_GRAN,
KEY_TYPE_BABE,
KEY_TYPE_IMON,
KEY_TYPE_PARA,
KEY_TYPE_ASGN,
KEY_TYPE_AUDI,
KEY_TYPE_ACCO,
KEY_TYPE_BEEF,
};

return supported_types.count(k) > 0;
}

std::string encodeKeyTypeIdToStr(KeyTypeId key_type_id) {
const auto *p = reinterpret_cast<const char *>(&key_type_id);
std::string res(p, p + sizeof(KeyTypeId));
return res;
std::string encodeKeyTypeIdToStr(KeyType key_type) {
const auto *p = reinterpret_cast<const char *>(&key_type);
return {p, p + sizeof(KeyTypeId)};
}

KeyTypeId decodeKeyTypeIdFromStr(std::string_view str) {
kagome::crypto::KeyTypeId res = 0;
KeyType decodeKeyTypeIdFromStr(std::string_view str) {
KeyTypeId res = 0;

if (str.size() == sizeof(KeyTypeId)) {
// string's data is aligned as KeyTypeId
if (reinterpret_cast<uintptr_t>(str.data())
% std::alignment_of_v<KeyTypeId>
== 0) {
res = *reinterpret_cast<const kagome::crypto::KeyTypeId *>(str.data());
res = *reinterpret_cast<const KeyTypeId *>(str.data());
} else {
memcpy(&res, str.data(), sizeof(KeyTypeId));
}
Expand All @@ -50,12 +34,12 @@ namespace kagome::crypto {
return res;
}

std::string encodeKeyFileName(KeyTypeId type, common::BufferView key) {
std::string encodeKeyFileName(KeyType type, common::BufferView key) {
return common::hex_lower(str2byte(encodeKeyTypeIdToStr(type)))
+ key.toHex();
}

outcome::result<std::pair<KeyTypeId, common::Buffer>> decodeKeyFileName(
outcome::result<std::pair<KeyType, common::Buffer>> decodeKeyFileName(
std::string_view name) {
std::string_view type_str = name;
std::string_view key_str;
Expand Down
99 changes: 73 additions & 26 deletions core/crypto/crypto_store/key_type.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,52 +16,99 @@ namespace kagome::crypto {
UNSUPPORTED_KEY_TYPE_ID,
};

/**
* @brief Key type identifier
*/
/// Key type identifier
using KeyTypeId = uint32_t;

/**
* Types are 32bit integers, which represent encoded 4-char strings
* Makes 32bit integer KeyTypeId which represent encoded 4-char strings
* Little-endian byte order is used
*/
enum KnownKeyTypeId : KeyTypeId {
// clang-format off
KEY_TYPE_BABE = 0x65626162u, // BABE, sr25519
KEY_TYPE_GRAN = 0x6e617267u, // GRANDPA, ed25519
KEY_TYPE_ACCO = 0x6f636361u, // Account control [sr25519, ed25519, secp256k1]
KEY_TYPE_IMON = 0x6e6f6d69u, // I'm Online, sr25519
KEY_TYPE_AUDI = 0x69647561u, // Account discovery [sr25519, ed25519, secp256k1]
KEY_TYPE_ASGN = 0x6e677361u, // ASGN
KEY_TYPE_PARA = 0x61726170u, // PARA
KEY_TYPE_BEEF = 0x66656562u, // Beefy, secp256k1
// clang-format on
constexpr KeyTypeId operator""_key(const char *s, std::size_t size) {
return (static_cast<KeyTypeId>(s[0]) << (CHAR_BIT * 0))
| (static_cast<KeyTypeId>(s[1]) << (CHAR_BIT * 1))
| (static_cast<KeyTypeId>(s[2]) << (CHAR_BIT * 2))
| (static_cast<KeyTypeId>(s[3]) << (CHAR_BIT * 3));
}

class KeyType {
public:
/// Key type for Babe module, built-in.
static constexpr KeyTypeId BABE = "babe"_key;
/// Key type for Sassafras module, built-in.
static constexpr KeyTypeId SASSAFRAS = "sass"_key;
/// Key type for Grandpa module, built-in.
static constexpr KeyTypeId GRANDPA = "gran"_key;
/// Key type for controlling an account in a Substrate runtime, built-in.
static constexpr KeyTypeId ACCOUNT = "acco"_key;
/// Key type for Aura module, built-in.
static constexpr KeyTypeId AURA = "aura"_key;
/// Key type for BEEFY module.
static constexpr KeyTypeId BEEFY = "beef"_key;
/// Key type for ImOnline module, built-in.
static constexpr KeyTypeId IM_ONLINE = "imon"_key;
/// Key type for AuthorityDiscovery module, built-in.
static constexpr KeyTypeId AUTHORITY_DISCOVERY = "audi"_key;
/// Key type for staking, built-in.
static constexpr KeyTypeId STAKING = "stak"_key;
/// A key type for signing statements
static constexpr KeyTypeId STATEMENT = "stmt"_key;
/// A key type ID useful for tests.
static constexpr KeyTypeId DUMMY = "dumy"_key;

static constexpr KeyTypeId KEY_TYPE_ASGN = "asgn"_key;
static constexpr KeyTypeId KEY_TYPE_PARA = "para"_key;

constexpr KeyType(KeyTypeId id) : id_(id){};

constexpr operator KeyTypeId() const {
return id_;
}

static constexpr bool is_supported(KeyTypeId id) {
switch (id) {
case BABE:
case SASSAFRAS:
case GRANDPA:
case ACCOUNT:
case AURA:
case BEEFY:
case IM_ONLINE:
case AUTHORITY_DISCOVERY:
case STAKING:
case STATEMENT:
case DUMMY:
case KEY_TYPE_ASGN:
case KEY_TYPE_PARA:
return true;
}
return false;
}

inline constexpr bool is_supported() const {
return is_supported(id_);
}

private:
KeyTypeId id_;
};

/**
* @brief makes string representation of KeyTypeId
* @param key_type_id KeyTypeId
* @return string representation of KeyTypeId
*/
std::string encodeKeyTypeIdToStr(KeyTypeId key_type_id);
std::string encodeKeyTypeIdToStr(KeyType key_type);

/**
* @brief restores KeyTypeId from its string representation
* @param param string representation of key type
* @return KeyTypeId
*/
KeyTypeId decodeKeyTypeIdFromStr(std::string_view str);

/**
* @brief checks whether key type value is supported
* @param k key type value
* @return true if supported, false otherwise
*/
bool isSupportedKeyType(KeyTypeId k);
KeyType decodeKeyTypeIdFromStr(std::string_view str);

std::string encodeKeyFileName(KeyTypeId type, common::BufferView key);
std::string encodeKeyFileName(KeyType type, common::BufferView key);

outcome::result<std::pair<KeyTypeId, common::Buffer>> decodeKeyFileName(
outcome::result<std::pair<KeyType, common::Buffer>> decodeKeyFileName(
std::string_view name);
} // namespace kagome::crypto

Expand Down
Loading

0 comments on commit 2b86cd5

Please sign in to comment.