Class: Zold::Score
- Inherits:
-
Object
- Object
- Zold::Score
- Defined in:
- lib/zold/score.rb
Overview
Score
Defined Under Namespace
Classes: CantParse
Constant Summary collapse
- STRENGTH =
Default strength for the entire system, in production mode. The larger the number, the more difficult it is to find the next score for a node. If the number if too small, the values of the score will be big and the amount of data to be transferred from node to node will increase. The number is set empirically.
8- BEST_BEFORE =
The maximum amount of hours a score can stay “fresh.” After that it will be considered expired.
24- ZERO =
The default no-value score.
Score.new( time: Time.now, host: 'localhost', invoice: 'NOPREFIX@ffffffffffffffff' )
Instance Attribute Summary collapse
-
#created ⇒ Object
readonly
Returns the value of attribute created.
-
#host ⇒ Object
readonly
Returns the value of attribute host.
-
#invoice ⇒ Object
readonly
Returns the value of attribute invoice.
-
#port ⇒ Object
readonly
Returns the value of attribute port.
-
#strength ⇒ Object
readonly
Returns the value of attribute strength.
-
#suffixes ⇒ Object
readonly
Returns the value of attribute suffixes.
-
#time ⇒ Object
readonly
Returns the value of attribute time.
Class Method Summary collapse
-
.parse(text) ⇒ Object
Parses it back from the text generated by
to_s. -
.parse_json(json) ⇒ Object
Parses it back from the JSON.
Instance Method Summary collapse
-
#<(other) ⇒ Object
Compare with another Score, by value.
-
#<=>(other) ⇒ Object
Compare with another Score, by value.
-
#==(other) ⇒ Object
Compare with another Score, by text.
-
#>(other) ⇒ Object
Compare with another Score, by value.
-
#age ⇒ Object
The age of the score in seconds.
-
#expired?(hours = BEST_BEFORE) ⇒ Boolean
Returns TRUE if the age of the score is over 24 hours.
-
#hash ⇒ Object
Returns its crypto hash.
-
#initialize(time: Time.now, host:, port: 4096, invoice:, suffixes: [], strength: Score::STRENGTH, created: Time.now) ⇒ Score
constructor
Makes a new object of the class.
-
#next ⇒ Object
Calculates and returns the next score after the current one.
-
#prefix ⇒ Object
The prefix for the hash calculating algorithm.
-
#reduced(max = 4) ⇒ Object
Returns a new score, which is a copy of the current one, but the amount of hash suffixes is reduced to the
maxprovided. -
#to_h ⇒ Object
Converts the score to a hash, which can be used for JSON presentation of the score.
-
#to_mnemo ⇒ Object
A simple mnemo of the score.
-
#to_s ⇒ Object
Converts it to a string.
-
#valid? ⇒ Boolean
Returns TRUE if the score is valid: all its suffixes correctly consistute the hash, according to the algorithm explained in the White Paper.
-
#value ⇒ Object
Returns the value of the score, from zero and up.
-
#zero? ⇒ Boolean
Returns TRUE if the value of the score is zero.
Constructor Details
#initialize(time: Time.now, host:, port: 4096, invoice:, suffixes: [], strength: Score::STRENGTH, created: Time.now) ⇒ Score
Makes a new object of the class.
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
# File 'lib/zold/score.rb', line 61 def initialize(time: Time.now, host:, port: 4096, invoice:, suffixes: [], strength: Score::STRENGTH, created: Time.now) raise 'Time can\'t be nil' if time.nil? unless time.is_a?(Time) raise "Time must be Time, while #{time.class.name} is provided" end @time = time raise 'Host can\'t be nil' if host.nil? unless /^[0-9a-z\.\-]+$/.match?(host) raise "Host \"#{host}\" is in a wrong format" end @host = host raise 'Port can\'t be nil' if port.nil? unless port.is_a?(Integer) raise "Port must be Integer, while #{port.class.name} is provided" end if port > 65_535 raise "Port must be less than 65535, while #{port} is provided" end unless port.positive? raise "Port must be positive integer, while #{port} is provided" end @port = port raise 'Invoice can\'t be nil' if invoice.nil? unless /^[a-zA-Z0-9]{8,32}@[a-f0-9]{16}$/.match?(invoice) raise "Invoice \"#{invoice}\" is wrong" end @invoice = invoice raise 'Suffixes can\'t be nil' if suffixes.nil? raise 'Suffixes are not an array' unless suffixes.is_a?(Array) @suffixes = suffixes raise 'Strength can\'t be nil' if strength.nil? unless strength.positive? raise "Strength must be positive integer, while #{strength} is provided" end @strength = strength raise 'Created can\'t be nil' if created.nil? unless created.is_a?(Time) raise "Created must be Time, while #{created.class.name} is provided" end @created = created end |
Instance Attribute Details
#created ⇒ Object (readonly)
Returns the value of attribute created.
58 59 60 |
# File 'lib/zold/score.rb', line 58 def created @created end |
#host ⇒ Object (readonly)
Returns the value of attribute host.
58 59 60 |
# File 'lib/zold/score.rb', line 58 def host @host end |
#invoice ⇒ Object (readonly)
Returns the value of attribute invoice.
58 59 60 |
# File 'lib/zold/score.rb', line 58 def invoice @invoice end |
#port ⇒ Object (readonly)
Returns the value of attribute port.
58 59 60 |
# File 'lib/zold/score.rb', line 58 def port @port end |
#strength ⇒ Object (readonly)
Returns the value of attribute strength.
58 59 60 |
# File 'lib/zold/score.rb', line 58 def strength @strength end |
#suffixes ⇒ Object (readonly)
Returns the value of attribute suffixes.
58 59 60 |
# File 'lib/zold/score.rb', line 58 def suffixes @suffixes end |
#time ⇒ Object (readonly)
Returns the value of attribute time.
58 59 60 |
# File 'lib/zold/score.rb', line 58 def time @time end |
Class Method Details
.parse(text) ⇒ Object
Parses it back from the text generated by to_s.
165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 |
# File 'lib/zold/score.rb', line 165 def self.parse(text) raise 'Can\'t parse nil' if text.nil? parts = text.split(' ', 7) raise 'Invalid score, not enough parts' if parts.length < 6 Score.new( time: Time.at(parts[1].hex), host: parts[2], port: parts[3].hex, invoice: "#{parts[4]}@#{parts[5]}", suffixes: parts[6] ? parts[6].split(' ') : [], strength: parts[0].to_i ) rescue StandardError => e raise CantParse, "#{e.} in \"#{text}\"" end |
.parse_json(json) ⇒ Object
Parses it back from the JSON.
111 112 113 114 115 116 117 118 119 120 121 122 123 |
# File 'lib/zold/score.rb', line 111 def self.parse_json(json) raise CantParse, 'JSON can\'t be nil' if json.nil? Score.new( time: Time.parse(json['time']), host: json['host'], port: json['port'], invoice: json['invoice'], suffixes: json['suffixes'], strength: json['strength'] ) rescue StandardError => e raise CantParse, "#{e.} in \"#{json}\"" end |
Instance Method Details
#<(other) ⇒ Object
Compare with another Score, by value.
132 133 134 135 |
# File 'lib/zold/score.rb', line 132 def <(other) raise 'Can\'t compare with nil' if other.nil? value < other.value end |
#<=>(other) ⇒ Object
Compare with another Score, by value.
144 145 146 147 |
# File 'lib/zold/score.rb', line 144 def <=>(other) raise 'Can\'t compare with nil' if other.nil? value <=> other.value end |
#==(other) ⇒ Object
Compare with another Score, by text.
126 127 128 129 |
# File 'lib/zold/score.rb', line 126 def ==(other) raise 'Can\'t compare with nil' if other.nil? to_s == other.to_s end |
#>(other) ⇒ Object
Compare with another Score, by value.
138 139 140 141 |
# File 'lib/zold/score.rb', line 138 def >(other) raise 'Can\'t compare with nil' if other.nil? value > other.value end |
#age ⇒ Object
The age of the score in seconds.
244 245 246 |
# File 'lib/zold/score.rb', line 244 def age Time.now - @time end |
#expired?(hours = BEST_BEFORE) ⇒ Boolean
Returns TRUE if the age of the score is over 24 hours.
249 250 251 252 |
# File 'lib/zold/score.rb', line 249 def expired?(hours = BEST_BEFORE) raise 'Hours can\'t be nil' if hours.nil? age > hours * 60 * 60 end |
#hash ⇒ Object
Returns its crypto hash. Read the White Paper for more information.
182 183 184 185 186 187 |
# File 'lib/zold/score.rb', line 182 def hash raise 'Score has zero value, there is no hash' if @suffixes.empty? @suffixes.reduce(prefix) do |pfx, suffix| OpenSSL::Digest::SHA256.new("#{pfx} #{suffix}").hexdigest end end |
#next ⇒ Object
Calculates and returns the next score after the current one. This operation may take some time, from a few milliseconds to hours, depending on the CPU power and the strength of the current score.
228 229 230 231 232 233 234 235 236 237 238 239 240 241 |
# File 'lib/zold/score.rb', line 228 def next raise 'This score is not valid' unless valid? if expired? return Score.new( time: Time.now, host: @host, port: @port, invoice: @invoice, suffixes: [], strength: @strength ) end suffix = ScoreSuffix.new(suffixes.empty? ? prefix : hash, @strength) Score.new( time: @time, host: @host, port: @port, invoice: @invoice, suffixes: @suffixes + [suffix.value], strength: @strength ) end |
#prefix ⇒ Object
The prefix for the hash calculating algorithm. See the White Paper for more details.
256 257 258 |
# File 'lib/zold/score.rb', line 256 def prefix "#{@time.utc.iso8601} #{@host} #{@port} #{@invoice}" end |
#reduced(max = 4) ⇒ Object
Returns a new score, which is a copy of the current one, but the amount of hash suffixes is reduced to the max provided.
215 216 217 218 219 220 221 222 223 |
# File 'lib/zold/score.rb', line 215 def reduced(max = 4) raise 'Max can\'t be nil' if max.nil? raise "Max can't be negative: #{max}" if max.negative? Score.new( time: @time, host: @host, port: @port, invoice: @invoice, suffixes: @suffixes[0..[max, suffixes.count].min - 1], strength: @strength ) end |
#to_h ⇒ Object
Converts the score to a hash, which can be used for JSON presentation of the score.
196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 |
# File 'lib/zold/score.rb', line 196 def to_h { value: value, host: @host, port: @port, invoice: @invoice, time: @time.utc.iso8601, suffixes: @suffixes, strength: @strength, hash: value.zero? ? nil : hash, expired: expired?, valid: valid?, age: (age / 60).round, created: @created.utc.iso8601 } end |
#to_mnemo ⇒ Object
A simple mnemo of the score.
190 191 192 |
# File 'lib/zold/score.rb', line 190 def to_mnemo "#{value}:#{@time.strftime('%H%M')}" end |
#to_s ⇒ Object
Converts it to a string. You can parse it back using parse().
151 152 153 154 155 156 157 158 159 160 161 162 |
# File 'lib/zold/score.rb', line 151 def to_s pfx, bnf = @invoice.split('@') [ @strength, @time.to_i.to_s(16), @host, @port.to_s(16), pfx, bnf, @suffixes.join(' ') ].join(' ') end |
#valid? ⇒ Boolean
Returns TRUE if the score is valid: all its suffixes correctly consistute the hash, according to the algorithm explained in the White Paper.
262 263 264 |
# File 'lib/zold/score.rb', line 262 def valid? (@suffixes.empty? || hash.end_with?('0' * @strength)) && @time < Time.now end |
#value ⇒ Object
Returns the value of the score, from zero and up. The value is basically the amount of hash suffixes inside the score.
268 269 270 |
# File 'lib/zold/score.rb', line 268 def value @suffixes.length end |
#zero? ⇒ Boolean
Returns TRUE if the value of the score is zero.
273 274 275 |
# File 'lib/zold/score.rb', line 273 def zero? @suffixes.empty? end |