Class: Bitcoin::Protocol::PartialMerkleTree

Inherits:
Object
  • Object
show all
Defined in:
lib/bitcoin/protocol/partial_merkle_tree.rb

Overview

Defined Under Namespace

Classes: Node

Constant Summary collapse

BIT_MASK =
[0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80].freeze

Instance Method Summary collapse

Constructor Details

#initialize(total_txs, hashes, flags) ⇒ PartialMerkleTree

Returns a new instance of PartialMerkleTree.



9
10
11
12
13
14
# File 'lib/bitcoin/protocol/partial_merkle_tree.rb', line 9

def initialize(total_txs, hashes, flags)
  @total_txs = total_txs
  @flags = flags
  @hashes = hashes.map(&:reverse_hth)
  @visit_idx = 0
end

Instance Method Details

#assign_value(node = root) ⇒ Object



44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/bitcoin/protocol/partial_merkle_tree.rb', line 44

def assign_value(node = root)
  if current_flag || (node.left.nil? && node.right.nil?)
    node.value = @hashes.shift
    return
  end

  if node.left
    @visit_idx += 1
    assign_value(node.left)
  end
  if node.right
    @visit_idx += 1
    assign_value(node.right)
  end

  right = node.right || node.left
  node.value = Bitcoin.bitcoin_mrkl(node.left.value, right.value)

  nil
end

#build_treeObject



20
21
22
23
24
25
26
27
28
# File 'lib/bitcoin/protocol/partial_merkle_tree.rb', line 20

def build_tree
  lay = @leaves = Array.new(@total_txs) { Node.new(nil, nil, nil) }
  while lay.size > 1
    lay = lay.each_slice(2).map do |left, right|
      Node.new(nil, left, right)
    end
  end
  lay[0]
end

#current_flagObject



30
31
32
# File 'lib/bitcoin/protocol/partial_merkle_tree.rb', line 30

def current_flag
  (@flags[@visit_idx / 8].ord & BIT_MASK[@visit_idx % 8]).zero?
end

#rootObject



34
35
36
# File 'lib/bitcoin/protocol/partial_merkle_tree.rb', line 34

def root
  @root ||= build_tree
end

#set_value(node = root) ⇒ Object

rubocop:disable Naming/AccessorMethodName



38
39
40
41
42
# File 'lib/bitcoin/protocol/partial_merkle_tree.rb', line 38

def set_value(node = root) # rubocop:disable Naming/AccessorMethodName
  warn '[DEPRECATION] `PartialMerkleTree.set_value` is deprecated. ' \
    'Use `assign_value` instead.'
  assign_value(node)
end

#tx_hashesObject



16
17
18
# File 'lib/bitcoin/protocol/partial_merkle_tree.rb', line 16

def tx_hashes
  @leaves.reject { |n| n.value.nil? }.map(&:value)
end

#valid_tree?(mrkl_root_hash) ⇒ Boolean

Returns:

  • (Boolean)


65
66
67
68
69
70
# File 'lib/bitcoin/protocol/partial_merkle_tree.rb', line 65

def valid_tree?(mrkl_root_hash)
  return false unless @hashes.empty?
  return false if ((@visit_idx + 1) / 8.0).ceil != @flags.length
  return false if mrkl_root_hash != root.value
  true
end