diff --git a/src/common/address.cr b/src/common/address.cr index 677b27f..d477f91 100644 --- a/src/common/address.cr +++ b/src/common/address.cr @@ -24,6 +24,7 @@ # For more information, please refer to require "./types" +require "./string_helper" require "big" @@ -38,9 +39,9 @@ module Pampero # To obtain a workable object, `check_format` needs to be over- # loaded to check that the address' format is correct. abstract struct Address - getter :bytes - getter :to_i - getter :little + getter bytes + getter to_i + getter little @str : String = "" @@ -56,7 +57,7 @@ module Pampero # order def initialize(str : String, @little : Bool = false) # Remove the header, not supported by BigInt.new - str = str[2..] if str[0] == '0' && (str[1] == 'x' || str[1] == 'X') + str = StringHelper.hexstring str @to_i = BigInt.new(str, 16) @bytes = Array(UInt8).new(str.size.as(Int) >> 1, 0u8) @@ -80,13 +81,13 @@ module Pampero end def to_s - hex_str() + hex_str end def from_bytes(bytes : Array(UInt8)) @bytes = bytes - if check_format() + if check_format # Calculates the integral version @to_i = BigInt.new(0) (@little ? @bytes.reverse : @bytes).each do |b| diff --git a/src/common/string_helper.cr b/src/common/string_helper.cr new file mode 100644 index 0000000..6d0a152 --- /dev/null +++ b/src/common/string_helper.cr @@ -0,0 +1,16 @@ +class StringHelper + + # Returns if *s* starts with `0x` + def self.hex?(s : String) : Bool + s.size > 2 && s[0] == '0' && s[1].downcase == 'x' + end + + # Returns the string without the `0x` prefix, if it has it, or the string itself otherwise. + def self.hexstring(s : String) : String + if self.hex?(s) + s[2..] + else + s + end + end +end diff --git a/src/common/types.cr b/src/common/types.cr index f4bf578..d1457c7 100644 --- a/src/common/types.cr +++ b/src/common/types.cr @@ -1,5 +1,7 @@ require "big" +require "./string_helper" + module Pampero alias Address32 = StaticArray(UInt8, 32) # Integers are little endian @@ -14,12 +16,11 @@ module Pampero def initialize(str : String) @data = uninitialized StaticArray(UInt8, 20) - str = str[2..] if str[0] == '0' && (str[1] == 'x' || str[1] == 'X') - if str.size != 40 - raise "Invalid format" - end + str = StringHelper.hexstring str + raise "Invalid format: string has #{str.size} size, but must be 40" if str.size != 40 + 20.times do |i| - @data[i] = str[2*i..2*i+1].to_u8(16) + @data[i] = str[2*i..2*i + 1].to_u8(16) end end end @@ -47,19 +48,18 @@ module Pampero def initialize(str : String) @data = uninitialized StaticArray(UInt8, 32) - str = str[2..] if str[0] == '0' && (str[1] == 'x' || str[1] == 'X') - if str.size != 64 - raise "Invalid format" - end + str = StringHelper.hexstring str + raise "Invalid format: string has #{str.size} size, but must be 64" if str.size != 64 + 32.times do |i| - @data[i] = str[2*i..2*i+1].to_u8(16) + @data[i] = str[2*i..2*i + 1].to_u8(16) end end def to_uint256 : UInt256 result = BigInt.new 0 32.times do |i| - result = result * 256 + @data[31-i] + result = result * 256 + @data[31 - i] end result end @@ -75,19 +75,19 @@ module Pampero end def to_s : String - to_hex() + to_hex end def inspect : String - to_hex() + to_hex end def to_json(json : JSON::Builder) : Nil - json.string(to_hex()) + json.string(to_hex) end def to_json_object_key : String - to_hex() + to_hex end end diff --git a/src/core/verkle_state.cr b/src/core/verkle_state.cr index 2ec572e..cccb206 100644 --- a/src/core/verkle_state.cr +++ b/src/core/verkle_state.cr @@ -13,23 +13,15 @@ module Pampero state_diff.suffix_diffs.map do |suffix_diff| suffix = suffix_diff.suffix if suffix.is_a?(String) - is_hex = suffix[0] == '0' && (suffix[1] == 'x' || suffix[1] == 'X') - suffix = if is_hex - suffix[2..].to_i(16) - else - suffix.to_i - end + is_hex = suffix[0] == '0' && (suffix[1].downcase == 'x') + suffix = is_hex ? suffix[2..].to_i(16) : suffix.to_i end key = Bytes32.new sprintf("%s%02x", stem, suffix) - current_value = get_leaf_value(suffix_diff.current_value) - if current_value - @state[key] = current_value - else - @state.delete key - end + current_value = suffix_diff.current_value.try { |x| get_leaf_value x } + write_key key, current_value - new_value = get_leaf_value(suffix_diff.new_value) + new_value = suffix_diff.new_value.try { |x| get_leaf_value x } if new_value @pos_state[key] = new_value else @@ -39,17 +31,14 @@ module Pampero end end - def get_leaf_value(leaf : String | LeafValue?) : Bytes32? - result = nil - if leaf.is_a?(String) - result = Bytes32.new(leaf) - elsif leaf.is_a?(LeafValue) - value = leaf.value - if value - result = Bytes32.new(value) - end + def get_leaf_value(leaf : String) : Bytes32 + Bytes32.new leaf + end + + def get_leaf_value(leaf : LeafValue) : Bytes32? + if value = leaf.value + Bytes32.new(value) end - result end def read_key(key : Bytes32) : Bytes32? diff --git a/src/core/verkle_state_manager.cr b/src/core/verkle_state_manager.cr index 7a177c3..378217d 100644 --- a/src/core/verkle_state_manager.cr +++ b/src/core/verkle_state_manager.cr @@ -16,7 +16,7 @@ module Pampero VERKLE_NODE_WIDTH = BigInt.new(256) HEADER_STORAGE_OFFSET = BigInt.new(64) - MAIN_STORAGE_OFFSET = VERKLE_NODE_WIDTH^31 + MAIN_STORAGE_OFFSET = VERKLE_NODE_WIDTH ^ 31 CHUNK_LENGTH = BigInt.new(31) @@ -32,18 +32,14 @@ module Pampero def get_account(address : Address20) : Account? stem = get_stem(address, UInt256.new(0)) - result = read_account(stem) - - version = result[:version] - balance = result[:balance] - nonce = result[:nonce] - code_hash = result[:code_hash] - code_size = result[:code_size] + version = read_version(stem) + balance = read_balance(stem) + nonce = read_nonce(stem) + code_hash = read_code_hash(stem) + code_size = read_code_size(stem) # If at least one of the fields is not nil we assume the account exists - if version.nil? && balance.nil? && nonce.nil? && code_hash.nil? && code_size.nil? - return nil - end + return nil if version.nil? && balance.nil? && nonce.nil? && code_hash.nil? && code_size.nil? account = Account.new account.version = version @@ -131,16 +127,6 @@ module Pampero get_tree_key address32, index, 0_u8 end - def read_account(stem : Bytes32) - { - version: read_version(stem), - balance: read_balance(stem), - nonce: read_nonce(stem), - code_hash: read_code_hash(stem), - code_size: read_code_size(stem), - } - end - def get_tree_key(address : Address32, treeIndex : Bytes32, subIndex : UInt8) : Bytes32 data = Bytes64.new address, treeIndex.@data key = Pampero::Crypto.hash data @@ -150,10 +136,10 @@ module Pampero def get_tree_storage_key(address : Address20, storage_key : UInt256) : Bytes32 position = if storage_key < CODE_OFFSET - HEADER_STORAGE_OFFSET - HEADER_STORAGE_OFFSET + storage_key - else - MAIN_STORAGE_OFFSET + storage_key - end + HEADER_STORAGE_OFFSET + storage_key + else + MAIN_STORAGE_OFFSET + storage_key + end calc_tree_key(address, position) end