zold 0.17.10 → 0.18.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 80212bbebddbc1807018d0ddaf9ce6af4e902b446840efa3976f2bf8aaf70e7f
4
- data.tar.gz: 962892885f128f4841e36f7c75146ab695832e4a499822acf46fc07e5799934d
3
+ metadata.gz: 0ad2aeab01e066ea22a6fb9e5cd02c2d13a88e36f19e8ffc228c5f72d5b5bf1e
4
+ data.tar.gz: f87c069877d7741c99a38ebfade27d41721f9347a996b6ef4640c899ebe558af
5
5
  SHA512:
6
- metadata.gz: bf58960e766640f2acf4e6d1665dcbb896ac8590994147e0e8a3819d753633d4d6fe8d126d11637a4c8e5ef702c061b0e21202c411fa5c4f7b2b59f26cfff38c
7
- data.tar.gz: 300f10b27f536f837526f9d8464990fad14757152eb925096d863fed6e7f50a8c9b7005b3dfd6cd40926116611869f0849bac78ef54361d292a8326e955f27d7
6
+ metadata.gz: b47678bd890369fe2a3d09268c1f3ab35bb5e1707ae052353865c899334276b840099465e5a1be46537021e60a01891dafca7071b95a85ff8fe9fb90c02fcf9c
7
+ data.tar.gz: 8769ceb3b043b1eb7fe0de15be8574ae1ff5f9191fadbe58daa6c1de25ca2768652faac9c636229d181ed0039352fffc75d5673b04de5c9f2ed953d009e2dd52
@@ -53,6 +53,10 @@ module Zold
53
53
  @wallets.all
54
54
  end
55
55
 
56
+ def count
57
+ @wallets.count
58
+ end
59
+
56
60
  def acq(id, exclusive: false)
57
61
  @wallets.acq(id, exclusive: exclusive) do |wallet|
58
62
  c = @zache.get(id.to_s, lifetime: 5 * 60) { wallet }
@@ -75,7 +75,7 @@ Available options:"
75
75
  end
76
76
  @wallets.acq(t.bnf, exclusive: true) do |target|
77
77
  unless target.exists?
78
- @log.debug("#{t.amount * -1} to #{t.bnf}: wallet is absent")
78
+ @log.debug("#{t.amount * -1} from #{id} to #{t.bnf}: wallet is absent")
79
79
  next
80
80
  end
81
81
  unless target.network == network
@@ -227,7 +227,7 @@ Available options:"
227
227
  if scores.empty?
228
228
  @log.info("No winners elected out of #{@remotes.all.count} remotes")
229
229
  else
230
- scores.each { |s| @log.info("Elected: #{s}") }
230
+ scores.each { |s| @log.info("Elected: #{s.reduced(4)}") }
231
231
  end
232
232
  scores
233
233
  end
@@ -295,7 +295,9 @@ it's recommended to reboot, but I don't do it because of --never-reboot")
295
295
  selected = @remotes.all.sort_by { |r| r[:score] }.reverse.first(opts['max-nodes'])
296
296
  (@remotes.all - selected).each do |r|
297
297
  @remotes.remove(r[:host], r[:port])
298
+ @log.info("Remote #{r[:host]}:#{r[:port]}/#{r[:score]} removed from the list, #{@remotes.all.count} left")
298
299
  end
300
+ @log.info("#{opts['max-nodes']} remote nodes left in the list")
299
301
  end
300
302
 
301
303
  def terminate
data/lib/zold/http.rb CHANGED
@@ -145,7 +145,7 @@ module Zold
145
145
  headers[Http::VERSION_HEADER] = Zold::VERSION
146
146
  headers[Http::PROTOCOL_HEADER] = Zold::PROTOCOL.to_s
147
147
  headers[Http::NETWORK_HEADER] = @network
148
- headers[Http::SCORE_HEADER] = @score.reduced(4).to_text if @score.valid? && !@score.expired? && @score.value > 3
148
+ headers[Http::SCORE_HEADER] = @score.reduced(4).to_s if @score.valid? && !@score.expired? && @score.value > 3
149
149
  headers
150
150
  end
151
151
  end
@@ -105,7 +105,7 @@ while #{settings.address} is in '#{settings.opts['network']}'")
105
105
  if settings.opts['standalone']
106
106
  settings.log.debug("#{request.url}: we are in standalone mode, won't update remotes")
107
107
  else
108
- s = Score.parse_text(header)
108
+ s = Score.parse(header)
109
109
  error(400, 'The score is invalid') unless s.valid?
110
110
  error(400, 'The score is weak') if s.strength < Score::STRENGTH && !settings.opts['ignore-score-weakness']
111
111
  return if s.value < Front::MIN_SCORE && !settings.opts['ignore-score-weakness']
@@ -136,7 +136,7 @@ while #{settings.address} is in '#{settings.opts['network']}'")
136
136
  headers['X-Zold-Thread'] = Thread.current.object_id.to_s
137
137
  unless @start.nil?
138
138
  if Time.now - @start > 1
139
- settings.log.info("Slow response to #{request.request_method} #{request.url}
139
+ settings.log.info("Slow response to #{request.request_method} #{request.url} \
140
140
  from #{request.ip} in #{Age.new(@start, limit: 1)}")
141
141
  end
142
142
  headers['X-Zold-Milliseconds'] = ((Time.now - @start) * 1000).round.to_s
@@ -428,7 +428,11 @@ from #{request.ip} in #{Age.new(@start, limit: 1)}")
428
428
  e = env['sinatra.error']
429
429
  content_type 'text/plain'
430
430
  headers['X-Zold-Error'] = e.message
431
- settings.log.error(Backtrace.new(e).to_s) unless e.is_a?(SoftError)
431
+ if e.is_a?(SoftError)
432
+ settings.log.info("#{request.ip}:#{request.request_method}:#{request.url}: #{e.message}")
433
+ else
434
+ settings.log.error(Backtrace.new(e).to_s)
435
+ end
432
436
  if e.is_a?(Errno::ENOMEM) && !settings.opts['skip-oom']
433
437
  settings.log.error("We are running out of memory (#{Size.new(GetProcessMem.new.bytes.to_i)}), \
434
438
  time to stop; use --skip-oom to never quit")
@@ -452,7 +456,7 @@ time to stop; use --skip-oom to never quit")
452
456
  def total_wallets
453
457
  return 256 if settings.opts['network'] == Wallet::MAINET
454
458
  settings.zache.get(:wallets, lifetime: settings.opts['no-cache'] ? 0 : 60) do
455
- settings.wallets.all.count
459
+ settings.wallets.count
456
460
  end
457
461
  end
458
462
 
data/lib/zold/remotes.rb CHANGED
@@ -189,7 +189,7 @@ module Zold
189
189
  return if list.empty?
190
190
  best = farm.best[0]
191
191
  score = best.nil? ? Score::ZERO : best
192
- idx = 0
192
+ idx = Concurrent::AtomicFixnum.new
193
193
  pool = Concurrent::FixedThreadPool.new([list.count, Concurrent.processor_count * 4].min, max_queue: 0)
194
194
  list.each do |r|
195
195
  pool.post do
@@ -201,7 +201,7 @@ module Zold
201
201
  host: r[:host],
202
202
  port: r[:port],
203
203
  score: score,
204
- idx: idx,
204
+ idx: idx.increment - 1,
205
205
  log: log,
206
206
  network: @network
207
207
  )
@@ -213,7 +213,6 @@ module Zold
213
213
  remove(r[:host], r[:port]) if errors > TOLERANCE
214
214
  end
215
215
  end
216
- idx += 1
217
216
  end
218
217
  pool.shutdown
219
218
  pool.kill unless pool.wait_for_termination(5 * 60)
@@ -231,6 +230,7 @@ module Zold
231
230
  raise 'Port can\'t be nil' if port.nil?
232
231
  raise 'Score can\'t be nil' if score.nil?
233
232
  raise 'Port has to be of type Integer' unless port.is_a?(Integer)
233
+ raise 'Score has to be of type Integer' unless score.is_a?(Integer)
234
234
  if_present(host, port) { |r| r[:score] = score }
235
235
  end
236
236
 
@@ -23,17 +23,19 @@
23
23
  require 'futex'
24
24
  require_relative 'log'
25
25
 
26
- # Sync collection of wallets.
26
+ # Synchronized collection of wallets.
27
+ #
28
+ # This is a decorator for the Wallets class.
29
+ #
27
30
  # Author:: Yegor Bugayenko (yegor256@gmail.com)
28
31
  # Copyright:: Copyright (c) 2018 Yegor Bugayenko
29
32
  # License:: MIT
30
33
  module Zold
31
34
  # Synchronized collection of wallets
32
35
  class SyncWallets
33
- def initialize(wallets, timeout: 30, log: Log::NULL, dir: wallets.path)
36
+ def initialize(wallets, log: Log::NULL, dir: wallets.path)
34
37
  @wallets = wallets
35
38
  @log = log
36
- @timeout = timeout
37
39
  @dir = dir
38
40
  end
39
41
 
@@ -49,6 +51,10 @@ module Zold
49
51
  @wallets.all
50
52
  end
51
53
 
54
+ def count
55
+ @wallets.count
56
+ end
57
+
52
58
  def acq(id, exclusive: false)
53
59
  @wallets.acq(id, exclusive: exclusive) do |wallet|
54
60
  Futex.new(wallet.path, log: @log, lock: File.join(@dir, "#{id}.lock")).open(exclusive) do
data/lib/zold/tax.rb CHANGED
@@ -57,6 +57,14 @@ module Zold
57
57
  PREFIX = 'TAXES'
58
58
  private_constant :PREFIX
59
59
 
60
+ # When score strengths were updated. The numbers here indicate the
61
+ # strengths we accepted before these dates.
62
+ MILESTONES = {
63
+ Time.parse('30-11-2018') => 6,
64
+ Time.parse('09-12-2018') => 7
65
+ }.freeze
66
+ private_constant :MILESTONES
67
+
60
68
  def initialize(wallet, ignore_score_weakness: false, strength: Score::STRENGTH)
61
69
  raise "The wallet must be of type Wallet: #{wallet.class.name}" unless wallet.is_a?(Wallet)
62
70
  @wallet = wallet
@@ -70,7 +78,7 @@ module Zold
70
78
  end
71
79
 
72
80
  def details(best)
73
- "#{PREFIX} #{best.reduced(EXACT_SCORE).to_text}"
81
+ "#{PREFIX} #{best.reduced(EXACT_SCORE)}"
74
82
  end
75
83
 
76
84
  def pay(pvt, best)
@@ -94,9 +102,11 @@ module Zold
94
102
  scored = txns.map do |t|
95
103
  pfx, body = t.details.split(' ', 2)
96
104
  next if pfx != PREFIX || body.nil?
97
- score = Score.parse_text(body)
105
+ score = Score.parse(body)
98
106
  next if !score.valid? || score.value != EXACT_SCORE
99
- next if score.strength < @strength && !@ignore_score_weakness
107
+ if score.strength < @strength && !@ignore_score_weakness
108
+ next unless MILESTONES.find { |d, s| t.date < d && score.strength >= s }
109
+ end
100
110
  next if t.amount > MAX_PAYMENT
101
111
  t
102
112
  end.compact.uniq(&:details)
@@ -65,5 +65,9 @@ module Zold
65
65
  File.join(path, (id.to_s.split('', 5).take(4) + [id.to_s]).join('/') + Wallet::EXT)
66
66
  )
67
67
  end
68
+
69
+ def count
70
+ `find . -name "*.z" | wc -l`.strip.to_i
71
+ end
68
72
  end
69
73
  end
data/lib/zold/txn.rb CHANGED
@@ -35,7 +35,7 @@ module Zold
35
35
  # A single transaction
36
36
  class Txn
37
37
  # Regular expression for details
38
- RE_DETAILS = '[a-zA-Z0-9 @\!\?\*_\-\.:,\']+'
38
+ RE_DETAILS = '[a-zA-Z0-9 @\!\?\*_\-\.:,\'/]+'
39
39
  private_constant :RE_DETAILS
40
40
 
41
41
  # Regular expression for prefix
data/lib/zold/version.rb CHANGED
@@ -25,6 +25,6 @@
25
25
  # Copyright:: Copyright (c) 2018 Yegor Bugayenko
26
26
  # License:: MIT
27
27
  module Zold
28
- VERSION = '0.17.10'
28
+ VERSION = '0.18.0'
29
29
  PROTOCOL = 2
30
30
  end
data/lib/zold/wallets.rb CHANGED
@@ -25,6 +25,9 @@ require_relative 'wallet'
25
25
  require_relative 'dir_items'
26
26
 
27
27
  # The local collection of wallets.
28
+ #
29
+ # This class is not thread-safe!
30
+ #
28
31
  # Author:: Yegor Bugayenko (yegor256@gmail.com)
29
32
  # Copyright:: Copyright (c) 2018 Yegor Bugayenko
30
33
  # License:: MIT
@@ -67,5 +70,9 @@ module Zold
67
70
  raise "Id must be of type Id, #{id.class.name} instead" unless id.is_a?(Id)
68
71
  yield Wallet.new(File.join(path, id.to_s + Wallet::EXT))
69
72
  end
73
+
74
+ def count
75
+ Zold::DirItems.new(@dir).fetch(recursive: false).count
76
+ end
70
77
  end
71
78
  end
@@ -177,32 +177,9 @@ class TestRemote < Zold::Test
177
177
  Dir.mktmpdir do |dir|
178
178
  remotes = Zold::Remotes.new(file: File.join(dir, 'remotes.txt'))
179
179
  cmd = Zold::Remote.new(remotes: remotes, log: test_log)
180
- suffixes = []
181
- (5000..5010).each do |port|
182
- score = Zold::Score.new(
183
- host: 'example.com',
184
- port: port,
185
- invoice: 'MYPREFIX@ffffffffffffffff',
186
- suffixes: suffixes << '13f7f01'
187
- )
188
- stub_request(:get, "http://#{score.host}:#{score.port}/remotes").to_return(
189
- status: 200,
190
- body: {
191
- version: Zold::VERSION,
192
- score: score.to_h,
193
- all: [
194
- { host: 'localhost', port: port }
195
- ]
196
- }.to_json
197
- )
198
- stub_request(:get, "http://localhost:#{port}/version").to_return(
199
- status: 200,
200
- body: {
201
- version: Zold::VERSION
202
- }.to_json
203
- )
204
- cmd.run(%W[remote add localhost #{port}])
205
- remotes.rescore('localhost', port, score)
180
+ (1..11).each do |i|
181
+ cmd.run(%W[remote add localhost #{i} --skip-ping])
182
+ remotes.rescore('localhost', i, i)
206
183
  end
207
184
  cmd.run(%w[remote select --max-nodes=5])
208
185
  assert_equal(5, remotes.all.count)
@@ -295,17 +295,15 @@ class FrontTest < Zold::Test
295
295
  end
296
296
 
297
297
  def test_headers_are_being_set_correctly
298
- Time.stub :now, Time.at(0) do
299
- FakeNode.new(log: test_log).run(['--expose-version=9.9.9', '--no-metronome', '--threads=0']) do |port|
300
- response = Zold::Http.new(uri: URI("http://localhost:#{port}/")).get
301
- assert_equal('no-cache', response.headers['Cache-Control'])
302
- assert_equal('close', response.headers['Connection'])
303
- assert_equal('9.9.9', response.headers['X-Zold-Version'])
304
- assert_equal(app.settings.protocol.to_s, response.headers[Zold::Http::PROTOCOL_HEADER])
305
- assert_equal('*', response.headers['Access-Control-Allow-Origin'])
306
- assert(response.headers['X-Zold-Milliseconds'])
307
- assert(!response.headers[Zold::Http::SCORE_HEADER].nil?)
308
- end
298
+ FakeNode.new(log: test_log).run(['--expose-version=9.9.9', '--no-metronome', '--threads=0']) do |port|
299
+ response = Zold::Http.new(uri: URI("http://localhost:#{port}/")).get
300
+ assert_equal('no-cache', response.headers['Cache-Control'])
301
+ assert_equal('close', response.headers['Connection'])
302
+ assert_equal('9.9.9', response.headers['X-Zold-Version'])
303
+ assert_equal(app.settings.protocol.to_s, response.headers[Zold::Http::PROTOCOL_HEADER])
304
+ assert_equal('*', response.headers['Access-Control-Allow-Origin'])
305
+ assert(response.headers['X-Zold-Milliseconds'])
306
+ assert(!response.headers[Zold::Http::SCORE_HEADER].nil?)
309
307
  end
310
308
  end
311
309
 
@@ -57,4 +57,17 @@ class TestTreeWallets < Zold::Test
57
57
  assert_equal(10, wallets.all.count)
58
58
  end
59
59
  end
60
+
61
+ def test_count_tree_wallets
62
+ Dir.mktmpdir do |dir|
63
+ Dir.chdir(dir) do
64
+ 5.times { |i| FileUtils.touch("wallet_#{i}.z") }
65
+ Dir.mktmpdir(nil, dir) do |subdir|
66
+ 5.times { |i| FileUtils.touch("#{subdir}/wallet_#{i}.z") }
67
+ wallets = Zold::TreeWallets.new(Dir.pwd)
68
+ assert_equal(10, wallets.count)
69
+ end
70
+ end
71
+ end
72
+ end
60
73
  end
data/test/test_wallets.rb CHANGED
@@ -67,4 +67,14 @@ class TestWallets < Zold::Test
67
67
  end
68
68
  end
69
69
  end
70
+
71
+ def test_count_wallets
72
+ Dir.mktmpdir do |dir|
73
+ Dir.chdir(dir) do
74
+ 5.times { |i| FileUtils.touch("wallet_#{i}") }
75
+ wallets = Zold::Wallets.new(Dir.pwd)
76
+ assert_equal(5, wallets.count)
77
+ end
78
+ end
79
+ end
70
80
  end
data/zold.gemspec CHANGED
@@ -85,7 +85,7 @@ and suggests a different architecture for digital wallet maintenance.'
85
85
  s.add_runtime_dependency 'usagewatch_ext', '0.2.1'
86
86
  s.add_runtime_dependency 'xcop', '0.6'
87
87
  s.add_runtime_dependency 'zache', '0.4.0'
88
- s.add_runtime_dependency 'zold-score', '0.3.4'
88
+ s.add_runtime_dependency 'zold-score', '0.4.2'
89
89
  s.add_development_dependency 'codecov', '0.1.13'
90
90
  s.add_development_dependency 'minitest', '5.11.3'
91
91
  s.add_development_dependency 'minitest-fail-fast', '0.1.0'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: zold
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.17.10
4
+ version: 0.18.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yegor Bugayenko
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-12-05 00:00:00.000000000 Z
11
+ date: 2018-12-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: backtrace
@@ -352,14 +352,14 @@ dependencies:
352
352
  requirements:
353
353
  - - '='
354
354
  - !ruby/object:Gem::Version
355
- version: 0.3.4
355
+ version: 0.4.2
356
356
  type: :runtime
357
357
  prerelease: false
358
358
  version_requirements: !ruby/object:Gem::Requirement
359
359
  requirements:
360
360
  - - '='
361
361
  - !ruby/object:Gem::Version
362
- version: 0.3.4
362
+ version: 0.4.2
363
363
  - !ruby/object:Gem::Dependency
364
364
  name: codecov
365
365
  requirement: !ruby/object:Gem::Requirement
@@ -700,7 +700,7 @@ licenses:
700
700
  - MIT
701
701
  metadata: {}
702
702
  post_install_message: |-
703
- Thanks for installing Zold 0.17.10!
703
+ Thanks for installing Zold 0.18.0!
704
704
  Study our White Paper: https://papers.zold.io/wp.pdf
705
705
  Read our blog posts: https://blog.zold.io
706
706
  Try online wallet at: https://wts.zold.io