class Bitcoin::Store::SPVChain
Attributes
db[R]
logger[R]
Public Class Methods
new(db = Bitcoin::Store::DB::LevelDB.new)
click to toggle source
# 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
Public Instance Methods
append_header(header)
click to toggle source
append block header to chain. @param [Bitcoin::BlockHeader] header a block header. @return [Bitcoin::Store::ChainEntry] appended block header entry.
# 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)
click to toggle source
find block entry with the specified hash
# 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)
click to toggle source
find block entry with the specified height.
# 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_block()
click to toggle source
get latest block in the store. @return
# 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)
click to toggle source
get median time past for specified block hash
@param [String] hash the block hash. @return [Integer] the median time past value.
# 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)
click to toggle source
get next block hash for specified hash
@param [String] hash the block hash(little endian) @return [String] the next block hash. If it does not exist yet, return nil.
# File lib/bitcoin/store/spv_chain.rb, line 66 def next_hash(hash) db.next_hash(hash) end
Private Instance Methods
initialize_block()
click to toggle source
if database is empty, put genesis block.
# File lib/bitcoin/store/spv_chain.rb, line 89 def initialize_block unless latest_block block = Bitcoin.chain_params.genesis_block genesis = ChainEntry.new(block.header, 0) db.save_entry(genesis) end end