Class: Bitcoin::PartialTree
- Inherits:
-
Object
- Object
- Bitcoin::PartialTree
- Defined in:
- lib/bitcoin/partial_tree.rb
Overview
A class for recovering partial from merkleblock message. For a complete Merkle tree implementation, migrate to the merkle gem.
Defined Under Namespace
Classes: Node
Constant Summary collapse
- MAX_TX_COUNT =
The maximum number of transactions a block can contain, so the maximum tx_count a valid merkleblock message can commit to.
MAX_BLOCK_WEIGHT / MIN_TRANSACTION_WEIGHT
Instance Attribute Summary collapse
-
#root ⇒ Object
Returns the value of attribute root.
Class Method Summary collapse
- .build(tx_count, hashes, flags) ⇒ Bitcoin::PartialTree
- .build_initial_tree(nodes) ⇒ Object
-
.validate!(tx_count, hashes, flags) ⇒ Object
Validate the parameters of a partial merkle tree.
Instance Method Summary collapse
- #find_node(value) ⇒ Object
-
#initialize(root = nil) ⇒ PartialTree
constructor
A new instance of PartialTree.
- #merkle_root ⇒ Object
Constructor Details
#initialize(root = nil) ⇒ PartialTree
Returns a new instance of PartialTree.
13 14 15 |
# File 'lib/bitcoin/partial_tree.rb', line 13 def initialize(root = nil) @root = root end |
Instance Attribute Details
#root ⇒ Object
Returns the value of attribute root.
11 12 13 |
# File 'lib/bitcoin/partial_tree.rb', line 11 def root @root end |
Class Method Details
.build(tx_count, hashes, flags) ⇒ Bitcoin::PartialTree
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
# File 'lib/bitcoin/partial_tree.rb', line 27 def self.build(tx_count, hashes, flags) validate!(tx_count, hashes, flags) flags = flags.each_char.map(&:to_i) root = build_initial_tree( Array.new(tx_count) { Node.new }) current_node = root hash_index = 0 flags.each do |f| current_node.flag = f if f.zero? || current_node.leaf? current_node.value = hashes[hash_index] hash_index += 1 end current_node = current_node.next_partial if hash_index == hashes.size if current_node&.leaf? current_node.value = hashes.last end break end end new(root) end |
.build_initial_tree(nodes) ⇒ Object
64 65 66 67 68 69 70 71 72 73 74 75 |
# File 'lib/bitcoin/partial_tree.rb', line 64 def self.build_initial_tree(nodes) raise ArgumentError, 'nodes must not be empty.' if nodes.empty? while nodes.size != 1 nodes = nodes.each_slice(2).map { |m| parent = Node.new parent.left = m[0] parent.right = m[1] ? m[1] : m[0].dup parent } end nodes.first end |
.validate!(tx_count, hashes, flags) ⇒ Object
Validate the parameters of a partial merkle tree. A merkleblock message is received from an untrusted peer, so these bounds are required to stop it from making #build allocate an unbounded number of nodes or loop forever. See Bitcoin Core's CPartialMerkleTree::ExtractMatches.
55 56 57 58 59 60 61 62 |
# File 'lib/bitcoin/partial_tree.rb', line 55 def self.validate!(tx_count, hashes, flags) raise ArgumentError, 'tx_count must be greater than 0.' unless tx_count.is_a?(Integer) && tx_count > 0 raise ArgumentError, "tx_count must be less than or equal to #{MAX_TX_COUNT}." if tx_count > MAX_TX_COUNT # There can never be more hashes provided than one for every txid. raise ArgumentError, 'hashes must not be greater than tx_count.' if hashes.size > tx_count # There must be at least one bit per node in the partial tree, and at least one node per hash. raise ArgumentError, 'flags must have at least one bit per hash.' if flags.size < hashes.size end |