class Tapyrus::Store::DB::LevelDB

Attributes

db[R]
logger[R]

Public Class Methods

new(path = " click to toggle source
# File lib/tapyrus/store/db/level_db.rb, line 10
def initialize(path = "#{Tapyrus.base_dir}/db/spv")
  # @logger = Tapyrus::Logger.create(:debug)
  FileUtils.mkdir_p(path)
  @db = ::LevelDBNative::DB.new(path)
  # logger.debug 'Opened LevelDB successfully.'
end

Public Instance Methods

add_agg_pubkey(activate_height, agg_pubkey) click to toggle source

Add aggregated public key. @param [Integer] activate_height @param [String] agg_pubkey aggregated public key with hex format.

# File lib/tapyrus/store/db/level_db.rb, line 75
def add_agg_pubkey(activate_height, agg_pubkey)
  payload = activate_height.to_even_length_hex + agg_pubkey
  index = latest_agg_pubkey_index
  next_index = (index.nil? ? 0 : index + 1).to_even_length_hex
  db.batch do
    db.put(KEY_PREFIX[:agg_pubkey] + next_index, payload)
    db.put(KEY_PREFIX[:latest_agg_pubkey], next_index)
  end
end
agg_pubkey(index) click to toggle source

Get aggregated public key by specifying index. @param [Integer] index @return [Array] tupple of activate height and aggregated public key.

# File lib/tapyrus/store/db/level_db.rb, line 88
def agg_pubkey(index)
  payload = db.get(KEY_PREFIX[:agg_pubkey] + index.to_even_length_hex)
  [payload[0...(payload.length - 66)].to_i(16), payload[(payload.length - 66)..-1]]
end
agg_pubkey_with_height(height) click to toggle source

Get aggregated public key by specifying block height. @param [Integer] height block height. @return [String] aggregated public key with hex format.

# File lib/tapyrus/store/db/level_db.rb, line 96
def agg_pubkey_with_height(height)
  index = latest_agg_pubkey_index
  index ||= 0
  (index + 1).times do |i|
    target = index - i
    active_height, pubkey = agg_pubkey(target)
    return pubkey unless active_height > height
  end
end
agg_pubkeys() click to toggle source

Get aggregated public key list. @return [Array] list of public key and index

# File lib/tapyrus/store/db/level_db.rb, line 114
def agg_pubkeys
  index = latest_agg_pubkey_index
  (index + 1).times.map { |i| agg_pubkey(i) }
end
best_hash() click to toggle source

get best block hash.

# File lib/tapyrus/store/db/level_db.rb, line 33
def best_hash
  db.get(KEY_PREFIX[:best])
end
close() click to toggle source
# File lib/tapyrus/store/db/level_db.rb, line 119
def close
  db.close
end
delete(key) click to toggle source

delete specified key data.

# File lib/tapyrus/store/db/level_db.rb, line 38
def delete(key)
  db.delete(key)
end
get(key) click to toggle source

get value from specified key. @param [Object] key a key. @return the stored value.

# File lib/tapyrus/store/db/level_db.rb, line 28
def get(key)
  db.get(key)
end
get_entry_payload_from_hash(hash) click to toggle source

get entry payload @param [String] hash the hash with hex format. @return [String] the ChainEntry payload.

# File lib/tapyrus/store/db/level_db.rb, line 55
def get_entry_payload_from_hash(hash)
  db.get(KEY_PREFIX[:entry] + hash)
end
get_hash_from_height(height) click to toggle source

get block hash specified height

# File lib/tapyrus/store/db/level_db.rb, line 43
def get_hash_from_height(height)
  db.get(height_key(height))
end
latest_agg_pubkey() click to toggle source

Get latest aggregated public key. @return [Array] aggregated public key with hex format.

# File lib/tapyrus/store/db/level_db.rb, line 108
def latest_agg_pubkey
  agg_pubkey(latest_agg_pubkey_index)[1]
end
next_hash(hash) click to toggle source

get next block hash specified hash

# File lib/tapyrus/store/db/level_db.rb, line 48
def next_hash(hash)
  db.get(KEY_PREFIX[:next] + hash)
end
put(key, value) click to toggle source

put data into LevelDB. @param [Object] key a key. @param [Object] value a value.

# File lib/tapyrus/store/db/level_db.rb, line 20
def put(key, value)
  # logger.debug "put #{key} data"
  db.put(key, value)
end
save_entry(entry) click to toggle source

Save entry. @param [Tapyrus::Store::ChainEntry]

# File lib/tapyrus/store/db/level_db.rb, line 61
def save_entry(entry)
  db.batch do
    db.put(entry.key, entry.to_payload)
    db.put(height_key(entry.height), entry.block_hash)
    if entry.header.upgrade_agg_pubkey?
      add_agg_pubkey(entry.height == 0 ? 0 : entry.height + 1, entry.header.x_field)
    end
    connect_entry(entry)
  end
end

Private Instance Methods

connect_entry(entry) click to toggle source
# File lib/tapyrus/store/db/level_db.rb, line 131
def connect_entry(entry)
  unless entry.genesis?
    tip_block = Tapyrus::Store::ChainEntry.parse_from_payload(get_entry_payload_from_hash(best_hash))
    unless tip_block.block_hash == entry.prev_hash
      raise "entry(#{entry.block_hash}) does not reference current best block hash(#{tip_block.block_hash})"
    end
    raise 'block height is small than current best block.' unless tip_block.height + 1 == entry.height
  end
  db.put(KEY_PREFIX[:best], entry.block_hash)
  db.put(KEY_PREFIX[:next] + entry.prev_hash, entry.block_hash)
end
height_key(height) click to toggle source

generate height key

# File lib/tapyrus/store/db/level_db.rb, line 126
def height_key(height)
  height = height.to_even_length_hex
  KEY_PREFIX[:height] + height.rhex
end
latest_agg_pubkey_index() click to toggle source

Get latest aggregated public key index. @return [Integer] key index

# File lib/tapyrus/store/db/level_db.rb, line 145
def latest_agg_pubkey_index
  index = db.get(KEY_PREFIX[:latest_agg_pubkey])
  index&.to_i(16)
end