Class: Bitcoin::Store::SPVChain

Inherits:
Object
  • Object
show all
Defined in:
lib/bitcoin/store/spv_chain.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(db = Bitcoin::Store::DB::LevelDB.new) ⇒ SPVChain

Returns a new instance of SPVChain.



17
18
19
20
21
# File 'lib/bitcoin/store/spv_chain.rb', line 17

def initialize(db = Bitcoin::Store::DB::LevelDB.new)
  @db = db # TODO multiple db switch
  @logger = Bitcoin::Logger.create(:debug)
  initialize_block
end

Instance Attribute Details

#dbObject (readonly)

Returns the value of attribute db.



14
15
16
# File 'lib/bitcoin/store/spv_chain.rb', line 14

def db
  @db
end

#loggerObject (readonly)

Returns the value of attribute logger.



15
16
17
# File 'lib/bitcoin/store/spv_chain.rb', line 15

def logger
  @logger
end

Instance Method Details

#append_header(header) ⇒ Bitcoin::Store::ChainEntry

append block header to chain.

Parameters:

Returns:



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/bitcoin/store/spv_chain.rb', line 46

def append_header(header)
  logger.info("append header #{header.block_id}")
  raise "this header is invalid. #{header.block_hash}" unless header.valid?
  best_block = latest_block
  current_height = best_block.height
  if best_block.block_hash == header.prev_hash
    entry = Bitcoin::Store::ChainEntry.new(header, current_height + 1)
    db.save_entry(entry)
    entry
  else
    unless find_entry_by_hash(header.block_hash)
      # TODO implements recovery process
      raise "header's previous hash(#{header.prev_hash}) does not match current best block's(#{best_block.block_hash})."
    end
  end
end

#find_entry_by_hash(hash) ⇒ Object

find block entry with the specified hash



37
38
39
40
41
# File 'lib/bitcoin/store/spv_chain.rb', line 37

def find_entry_by_hash(hash)
  payload = db.get_entry_payload_from_hash(hash)
  return nil unless payload
  ChainEntry.parse_from_payload(payload)
end

#find_entry_by_height(height) ⇒ Object

find block entry with the specified height.



32
33
34
# File 'lib/bitcoin/store/spv_chain.rb', line 32

def find_entry_by_height(height)
  find_entry_by_hash(db.get_hash_from_height(height))
end

#latest_blockObject

get latest block in the store. @return



25
26
27
28
29
# File 'lib/bitcoin/store/spv_chain.rb', line 25

def latest_block
  hash = db.best_hash
  return nil unless hash
  find_entry_by_hash(hash)
end

#mtp(hash) ⇒ Integer

get median time past for specified block hash

Parameters:

  • hash (String)

    the block hash.

Returns:

  • (Integer)

    the median time past value.



73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/bitcoin/store/spv_chain.rb', line 73

def mtp(hash)
  time = []
  Bitcoin::MEDIAN_TIME_SPAN.times do
    entry = find_entry_by_hash(hash)
    break unless entry

    time << entry.header.time
    hash = entry.header.prev_hash
  end
  time.sort!
  time[time.size / 2]
end

#next_hash(hash) ⇒ String

get next block hash for specified hash

Parameters:

  • hash (String)

    the block hash(little endian)

Returns:

  • (String)

    the next block hash. If it does not exist yet, return nil.



66
67
68
# File 'lib/bitcoin/store/spv_chain.rb', line 66

def next_hash(hash)
  db.next_hash(hash)
end