Skip to content

Commit

Permalink
Revert changes to name, except for removal of N()
Browse files Browse the repository at this point in the history
  • Loading branch information
swatanabe committed Jan 27, 2022
1 parent 8c567fd commit 00f30f8
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 55 deletions.
44 changes: 15 additions & 29 deletions libraries/chain/include/eosio/chain/name.hpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
#pragma once
#include <string>
#include <fc/reflect/reflect.hpp>
#include <fc/exception/exception.hpp>
#include <eosio/chain/exceptions.hpp>
#include <iosfwd>

namespace eosio::chain {
Expand All @@ -15,41 +13,29 @@ namespace fc {
} // fc

namespace eosio::chain {
constexpr uint64_t char_to_symbol( char c ) {
inline constexpr uint64_t char_to_symbol( char c ) {
if( c >= 'a' && c <= 'z' )
return (c - 'a') + 6;
if( c >= '1' && c <= '5' )
return (c - '1') + 1;
else if( c == '.')
return 0;
else
FC_THROW_EXCEPTION(name_type_exception, "Name contains invalid character: (${c}) ", ("c", std::string(1, c)));

//unreachable
return 0;
}

// true if std::string can be converted to name
bool is_string_valid_name(std::string_view str);

constexpr uint64_t string_to_uint64_t( std::string_view str ) {
EOS_ASSERT(str.size() <= 13, name_type_exception, "Name is longer than 13 characters (${name}) ", ("name", std::string(str)));

inline constexpr uint64_t string_to_uint64_t( std::string_view str ) {
uint64_t n = 0;
int i = (int) str.size();
if (i >= 13) {
// Only the first 12 characters can be full-range ([.1-5a-z]).
i = 12;

// The 13th character must be in the range [.1-5a-j] because it needs to be encoded
// using only four bits (64_bits - 5_bits_per_char * 12_chars).
n = char_to_symbol(str[12]);
EOS_ASSERT(n <= 0x0Full, name_type_exception, "invalid 13th character: (${c})", ("c", std::string(1, str[12])));
}
// Encode full-range characters.
while (--i >= 0) {
n |= char_to_symbol(str[i]) << (64 - 5 * (i + 1));
int i = 0;
for ( ; i < str.size() && i < 12; ++i) {
// NOTE: char_to_symbol() returns char type, and without this explicit
// expansion to uint64 type, the compilation fails at the point of usage
// of string_to_name(), where the usage requires constant (compile time) expression.
n |= (char_to_symbol(str[i]) & 0x1f) << (64 - 5 * (i + 1));
}

// The for-loop encoded up to 60 high bits into uint64 'name' variable,
// if (strlen(str) > 12) then encode str[12] into the low (remaining)
// 4 bits of 'name'
if (i < str.size() && i == 12)
n |= char_to_symbol(str[12]) & 0x0F;
return n;
}

Expand Down Expand Up @@ -95,7 +81,7 @@ namespace eosio::chain {
// to its 5-bit slot starting with the highest slot for the first char.
// The 13th char, if str is long enough, is encoded into 4-bit chunk
// and placed in the lowest 4 bits. 64 = 12 * 5 + 4
constexpr name string_to_name( std::string_view str )
inline constexpr name string_to_name( std::string_view str )
{
return name( string_to_uint64_t( str ) );
}
Expand Down
33 changes: 7 additions & 26 deletions libraries/chain/name.cpp
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
#include <eosio/chain/name.hpp>
#include <fc/variant.hpp>
#include <boost/algorithm/string.hpp>
#include <fc/exception/exception.hpp>
#include <eosio/chain/exceptions.hpp>

namespace eosio::chain {

void name::set( std::string_view str ) {
const auto len = str.size();
EOS_ASSERT(len <= 13, name_type_exception, "Name is longer than 13 characters (${name}) ", ("name", std::string(str)));
value = string_to_uint64_t(str);
EOS_ASSERT(to_string() == str, name_type_exception,

This comment has been minimized.

Copy link
@learnforpractice

learnforpractice Jan 27, 2022

Contributor

Name conversion is critical for Eos. I'm worried about this change will hurt the performance significantly.

This comment has been minimized.

Copy link
@tbfleming

tbfleming Jan 27, 2022

Contributor

This change, which came from 2.1, is reverted

This comment has been minimized.

Copy link
@tbfleming

tbfleming Jan 27, 2022

Contributor

Oops. I just read it backwards. This reverts the 2.1 change and puts it back in line with 2.0.

This comment has been minimized.

Copy link
@tbfleming

tbfleming Jan 27, 2022

Contributor

BTW, string-to-name conversion is not part of the critical path.

This comment has been minimized.

Copy link
@learnforpractice

learnforpractice Jan 27, 2022

Contributor

Yes, you are right. It may hurt the performance of some RPC APIs. Just think that it still has some space to improve the code.

"Name not properly normalized (name: ${name}, normalized: ${normalized}) ",
("name", std::string(str))("normalized", to_string()));
}

// keep in sync with name::to_string() in contract definition for name
Expand All @@ -25,32 +32,6 @@ namespace eosio::chain {
return str;
}

bool is_string_valid_name(std::string_view str)
{
size_t slen = str.size();
if( slen > 13)
return false;

size_t len = (slen <= 12) ? slen : 12;
for( size_t i = 0; i < len; ++i ) {
char c = str[i];
if ((c >= 'a' && c <= 'z') || (c >= '1' && c <= '5') || (c == '.'))
continue;
else
return false;
}

if( slen == 13) {
char c = str[12];
if ((c >= 'a' && c <= 'j') || (c >= '1' && c <= '5') || (c == '.'))
return true;
else
return false;
}

return true;
}

} // eosio::chain

namespace fc {
Expand Down

0 comments on commit 00f30f8

Please sign in to comment.