Class: Drand::Chain

Inherits:
Object
  • Object
show all
Defined in:
lib/drand/chain.rb

Constant Summary collapse

DEFAULT_BASE_URL =
"https://api.drand.sh"

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(chain_hash:, genesis_time:, period:, base_url: DEFAULT_BASE_URL, name: "custom") ⇒ Chain

Returns a new instance of Chain.

Raises:



16
17
18
19
20
21
22
23
24
25
26
27
# File 'lib/drand/chain.rb', line 16

def initialize(chain_hash:, genesis_time:, period:, base_url: DEFAULT_BASE_URL, name: "custom")
  raise ArgumentError, "chain_hash required" if chain_hash.nil? || chain_hash.empty?
  raise ArgumentError, "genesis_time must be an Integer" unless genesis_time.is_a?(Integer)
  raise ArgumentError, "period must be a positive Integer" unless period.is_a?(Integer) && period.positive?

  @chain_hash = chain_hash
  @genesis_unix = genesis_time
  @period = period
  @base_url = base_url
  @name = name
  @http = HttpClient.new(base_url: base_url, chain_hash: chain_hash)
end

Instance Attribute Details

#base_urlObject (readonly)

Returns the value of attribute base_url.



14
15
16
# File 'lib/drand/chain.rb', line 14

def base_url
  @base_url
end

#chain_hashObject (readonly)

Returns the value of attribute chain_hash.



14
15
16
# File 'lib/drand/chain.rb', line 14

def chain_hash
  @chain_hash
end

#nameObject (readonly)

Returns the value of attribute name.



14
15
16
# File 'lib/drand/chain.rb', line 14

def name
  @name
end

#periodObject (readonly)

Returns the value of attribute period.



14
15
16
# File 'lib/drand/chain.rb', line 14

def period
  @period
end

Instance Method Details

#current_roundObject



46
47
48
# File 'lib/drand/chain.rb', line 46

def current_round
  round_at(Time.now.utc)
end

#draw(range, round: current_round) ⇒ Object



58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/drand/chain.rb', line 58

def draw(range, round: current_round)
  lo, hi = normalize_range(range)
  data = self.round(round)
  {
    value: sample_in(data[:randomness], lo, hi),
    range: { min: lo, max: hi },
    round: data[:round],
    chain: @name,
    chain_hash: @chain_hash,
    randomness: data[:randomness],
    signature: data[:signature],
    verified: false
  }
end

#genesis_timeObject



29
30
31
# File 'lib/drand/chain.rb', line 29

def genesis_time
  Time.at(@genesis_unix).utc
end

#round(number) ⇒ Object

Raises:



50
51
52
53
54
55
56
# File 'lib/drand/chain.rb', line 50

def round(number)
  raise ArgumentError, "round must be an Integer" unless number.is_a?(Integer)
  raise RoundError, "round must be >= 1" if number < 1
  raise RoundError, "round #{number} is in the future" if number > current_round

  @http.fetch_round(number).merge(verified: false)
end

#round_at(time) ⇒ Object

Raises:



33
34
35
36
37
38
# File 'lib/drand/chain.rb', line 33

def round_at(time)
  t = to_utc(time)
  elapsed = t.to_r - @genesis_unix
  raise RoundError, "time is before chain genesis" if elapsed.negative?
  (elapsed / @period).floor + 1
end

#time_of(round) ⇒ Object

Raises:



40
41
42
43
44
# File 'lib/drand/chain.rb', line 40

def time_of(round)
  raise ArgumentError, "round must be an Integer" unless round.is_a?(Integer)
  raise RoundError, "round must be >= 1" if round < 1
  Time.at(@genesis_unix + (round - 1) * @period).utc
end