提交 42820ef0 编写于 作者: A arhag

limits on authority size to prevent accumulated weight overflow

Also, added a comment regarding a potential issue with
shared_authority::get_billable_size() which is relevant whenever new
public keys are to be added via hardfork after launch of a live network.
上级 88c52f60
......@@ -6,6 +6,8 @@
#include <chainbase/chainbase.hpp>
#include <eosio/chain/transaction.hpp>
#include <type_traits>
namespace eosio { namespace chain {
......@@ -59,6 +61,21 @@ struct shared_authority {
}
size_t get_billable_size() const {
/**
* public_key_type contains a static_variant and so its size could change if we later wanted to add a new public key type of
* of larger size, thus increasing the returned value from shared_authority::get_billable_size() for old authorities that
* do not even use the new public key type.
*
* Although adding a new public key type is a hardforking change anyway, the current implementation means we would need to:
* - track historical sizes of public_key_type,
* - branch on hardfork versions within this function, and
* - calculate billable size of the authority based on the appropriate historical size of public_key_type,
* all in order to avoid retroactively changing the billable size of authorities.
* TODO: Better implementation of get_billable_size()?
* Perhaps it would require changes to how public_key_type is stored in shared_authority?
* For example: change keys (of type shared_vector<key_weight>) to packed_keys (of type shared_vector<char>)
* which store the packed data of vector<key_weight>, and then charge based on that packed size.
*/
return keys.size() * sizeof(key_weight) + accounts.size() * sizeof(permission_level_weight);
}
};
......@@ -76,6 +93,15 @@ inline bool validate( const Authority& auth ) {
const key_weight* prev = nullptr;
decltype(auth.threshold) total_weight = 0;
static_assert( std::is_same<decltype(auth.threshold), uint32_t>::value &&
std::is_same<weight_type, uint16_t>::value &&
std::is_same<typename decltype(auth.keys)::value_type, key_weight>::value &&
std::is_same<typename decltype(auth.accounts)::value_type, permission_level_weight>::value,
"unexpected type for threshold and/or weight in authority" );
if( ( auth.keys.size() + auth.accounts.size() ) > (1 << 16) )
return false; // overflow protection (assumes weight_type is uint16_t and threshold is of type uint32_t)
for( const auto& k : auth.keys ) {
if( !prev ) prev = &k;
else if( prev->key < k.key ) return false;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册