Class: XRBP::SHAMap::NodeID

Inherits:
Object
  • Object
show all
Defined in:
lib/xrbp/nodestore/shamap/node_id.rb

Overview

Encapsulates node key to allow for tree traversal.

Provides branch extraction/generation logic. Since branch is between 0-15, only a nibble (4bits) are needed to store. Thus each char (8bits) can describe 2 tree branches

Constant Summary collapse

MASK_SIZE =
65

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(args = {}) ⇒ NodeID

Returns a new instance of NodeID.


12
13
14
15
# File 'lib/xrbp/nodestore/shamap/node_id.rb', line 12

def initialize(args={})
  @depth ||= args[:depth] || 0
  @key   ||= args[:key]   || NodeStore.uint256
end

Instance Attribute Details

#depthObject (readonly)

Returns the value of attribute depth.


10
11
12
# File 'lib/xrbp/nodestore/shamap/node_id.rb', line 10

def depth
  @depth
end

#keyObject (readonly)

Returns the value of attribute key.


10
11
12
# File 'lib/xrbp/nodestore/shamap/node_id.rb', line 10

def key
  @key
end

Class Method Details

.masksObject

Masks corresponding to each tree level. Used to calculate inner node hash for tree level:

inner node = lookup key & mask

23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/xrbp/nodestore/shamap/node_id.rb', line 23

def self.masks
  @masks ||= begin
    masks = Array.new(MASK_SIZE)

    i = 0
    selector = NodeStore.uint256
    while(i < MASK_SIZE-1)
      masks[i] = String.new(selector)
      selector[i / 2] = 0xF0.chr
      masks[i+1] = String.new(selector)
      selector[i / 2] = 0xFF.chr
      i += 2
    end
    masks[MASK_SIZE-1] = selector

    masks
  end
end

Instance Method Details

#child_node_id(branch) ⇒ Object

Return NodeID for specified branch under this one.


69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/xrbp/nodestore/shamap/node_id.rb', line 69

def child_node_id(branch)
  raise unless branch >= 0 && branch < 16
  raise unless depth < 64

  # Copy local key and assign branch number to
  # nibble in byte at local depth
  child = key.unpack("C*")
  child[depth/2] |= ((depth & 1) == 1) ? branch : (branch << 4)

  NodeID.new :depth => (depth + 1),
             :key   => child.pack("C*")
end

#maskObject

Return mask for current tree depth


43
44
45
# File 'lib/xrbp/nodestore/shamap/node_id.rb', line 43

def mask
  @mask ||= self.class.masks[depth]
end

#select_branch(hash) ⇒ Object

Return branch number of specified hash.


48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/xrbp/nodestore/shamap/node_id.rb', line 48

def select_branch(hash)
  #if RIPPLE_VERIFY_NODEOBJECT_KEYS
  raise if depth >= 64
  raise if (hash.to_bn & mask.to_bn) != key.to_bn
  #end

  # Extract hash byte at local node depth
  br = hash[depth / 2].ord

  # Reduce to relevant nibble
  if (depth & 1) == 1
    br &= 0xf
  else
    br >>= 4
  end

  raise unless (br >= 0) && (br < 16)
  br
end