class Ethereum::Trie::NibbleKey

Nibble is half-byte.

Constants

HEX_VALUES
NIBBLE_ODD_FLAG
NIBBLE_TERMINATOR
NIBBLE_TERM_FLAG

Public Class Methods

decode(bytes) click to toggle source

Decode bytes to {NibbleKey}, with flags processed.

@see `unpack_to_nibbles` in pyethereum

@param bytes [String] compact hex encoded string.

@return [NibbleKey] nibbles array, may have a terminator

# File lib/ethereum/trie/nibble_key.rb, line 57
def decode(bytes)
  o = from_string bytes
  flags = o[0]

  o.push NIBBLE_TERMINATOR if flags & NIBBLE_TERM_FLAG > 0
  fill = flags & NIBBLE_ODD_FLAG > 0 ? 1 : 2

  new o[fill..-1]
end
encode(nibbles) click to toggle source

Encode nibbles to string.

@see `pack_nibbles` in pyethereum

@param nibbles [Array] array of nibbles to encode

@return [String] encoded string

# File lib/ethereum/trie/nibble_key.rb, line 26
def encode(nibbles)
  flags = 0

  if nibbles.last == NIBBLE_TERMINATOR
    flags |= NIBBLE_TERM_FLAG
    nibbles = nibbles[0...-1]
  end

  odd = nibbles.size % 2
  flags |= odd
  if odd == 1
    nibbles = [flags] + nibbles
  else
    nibbles = [flags, 0b0000] + nibbles
  end

  (nibbles.size/2).times.reduce('') do |s, i|
    base = 2*i
    s += (16*nibbles[base] + nibbles[base+1]).chr
  end
end
from_string(s) click to toggle source

Convert arbitrary string to {NibbleKey}.

@see `bin_to_nibbles` in pyethereum

@example

from_string('') # => []
from_string('h') # => [6, 8]
from_string('he') # => [6, 8, 6, 5]
from_string('hello') # => [6, 8, 6, 5, 6, 12, 6, 12, 6, 15]

@param s [String] any string

@return [NibbleKey] array of nibbles presented as interger smaller

than 16, has no terminator because plain string has no flags
# File lib/ethereum/trie/nibble_key.rb, line 83
def from_string(s)
  nibbles = RLP::Utils.encode_hex(s).each_char.map {|nibble| HEX_VALUES[nibble] }
  new nibbles
end
new(*args) click to toggle source
Calls superclass method
# File lib/ethereum/trie/nibble_key.rb, line 112
def initialize(*args)
  super
end
terminator() click to toggle source
# File lib/ethereum/trie/nibble_key.rb, line 107
def terminator
  new([NIBBLE_TERMINATOR])
end
to_string(nibbles) click to toggle source

Convert array of nibbles to string.

@see `nibbles_to_bin` in pyethereum

@param nibbles [Array] array of nibbles

@return [String] string represented by nibbles

# File lib/ethereum/trie/nibble_key.rb, line 97
def to_string(nibbles)
  raise ArgumentError, "nibbles can only be in 0..15" if nibbles.any? {|x| x > 15 || x < 0 }
  raise ArgumentError, "nibbles must be of even numbers" if nibbles.size % 2 == 1

  (nibbles.size/2).times.map do |i|
    base = i*2
    (16*nibbles[base] + nibbles[base+1]).chr
  end.join
end

Public Instance Methods

+(array) click to toggle source
Calls superclass method
# File lib/ethereum/trie/nibble_key.rb, line 176
def +(array)
  self.class.new(super(array))
end
common_prefix(another_key) click to toggle source

Find common prefix to another key.

@param another_key [Array] another array of nibbles

@return [Array] common prefix of both nibbles array

# File lib/ethereum/trie/nibble_key.rb, line 157
def common_prefix(another_key)
  prefix = []

  [size, another_key.size].min.times do |i|
    break if self[i] != another_key[i]
    prefix.push self[i]
  end

  self.class.new prefix
end
encode() click to toggle source
# File lib/ethereum/trie/nibble_key.rb, line 168
def encode
  self.class.encode self
end
prefix?(another_key) click to toggle source

test whether this is prefix of another {NibbleKey}

@param another_key [NibbleKey] the full key to test

@return [Bool]

# File lib/ethereum/trie/nibble_key.rb, line 145
def prefix?(another_key)
  return false if another_key.size < size
  another_key.take(size) == self
end
terminate(flag) click to toggle source

Get with or without terminator copy of this {NibbleKey}.

@param flag [Bool] set true to get a copy with terminator, otherwise

set false

@return [NibbleKey] a copy with or without terminator at end

# File lib/ethereum/trie/nibble_key.rb, line 128
def terminate(flag)
  dup.tap do |copy|
    if flag
      copy.push NIBBLE_TERMINATOR unless copy.terminate?
    else
      copy.pop if copy.terminate?
    end
  end
end
terminate?() click to toggle source
# File lib/ethereum/trie/nibble_key.rb, line 116
def terminate?
  last == NIBBLE_TERMINATOR
end
to_string() click to toggle source
# File lib/ethereum/trie/nibble_key.rb, line 172
def to_string
  self.class.to_string self
end