Skip to content

Conversation

Pedrozo
Copy link
Contributor

@Pedrozo Pedrozo commented Nov 6, 2024

This PR introduces a family of "view" types and new algorithms for byte manipulation.

Changes:

  • Introduced View<Address>, View<Hash>, View<Signature>, and View<Bytes>. In short, they aim to replace a constant reference with a view object, just like std::string_view replaces const std::string&. For example, a View<Address> can be cheaply created from both Address and evmc::address types.
// BAD: if called with evmc::address, a conversion will be required (i.e. bytes copying)
void foo(const Address& addr);

// GOOD: no conversion required if called with Address, evmc::address, or pretty much any type that can construct a View<Address>
void bar(View<Address> addr);
  • SafeHash and the new SafeCompare now allow "transparent search". That means calls to .find() in map objects with different types than Key are allowed as long as they are equally comparable with the key type and the hash function accepts them. This is especially useful for the ContractHost needs, where we have maps whose key type is Address, but often searches use evmc::address objects. In this case, we would need to convert (i.e. copy the bytes) from one type to another, but with transparent search a call to find() with a evmc::address argument is perfectly valid.

  • Introduced bytes::random() and bytes::random(size_t) functions. They initialize byte containers with random data. The bytes::random() matches the container size, while the bytes::random(size_t) can be used where a sized initializer is required.

Address addr = bytes::random(); // exactly 20 random bytes generated
Hash hash = bytes::random();    // exactly 32 random bytes generated
Bytes bytes = Utils::makeBytes(bytes::random(666)); // 666 random bytes generated
  • Introduced bytes::hex() for initializing a container with a hexadecimal string representation. Ex: Address addr = bytes::hex("0xfb6916095ca1df60bb79ce92ce3ea74c37c5d359");

  • Introduced bytes::cast() function for general-purpose bytes range conversion. For example:

Hash hash; // some hash object
evmc::bytes32 asBytes32 = bytes::cast<evmc::bytes32>(hash); // instead of hash.toEvmcBytes()
  • Hash and View<Hash> can now be converted to uint256_t by using static_cast. Example:
Hash hash; // some hash object
uint256_t value = static_cast<uint256_t>(hash);
  • bytes::View deprecated and replaced by View<Bytes>.

  • strings.h header broke into multiple header files: fixedbytes.h, signature.h, address.h, and hash.h.

@Pedrozo Pedrozo self-assigned this Nov 7, 2024
@Pedrozo Pedrozo added the enhancement New feature or request label Nov 7, 2024
Copy link
Collaborator

@Jean-Lessa Jean-Lessa left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All good to me. This is probably gonna conflict real hard with my optimize branch (I changed a lot of things there, significant breaking changes), but I think it's better to merge this first so we don't have problems with the bigger ContractHost refactoring. I'll handle those conflicts on my end eventually so I can merge my part later on without prejudicing yours.

using Byte = uint8_t;

using Bytes = std::vector<Byte>;

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Friendly suggestion:

Suggested change
template <std::size_t N> using BytesArr = std::array<Byte, N>; ///< Typedef for BytesArr.

This is gonna help me a bit on my optimize branch, been duplicating those lines everywhere

@Pedrozo Pedrozo requested a review from fcecin December 20, 2024 18:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants