message: 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.
diff: #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;
  