zold 0.26.15 → 0.26.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5f13f402152afeb770656e632fff9b86f48f4bb99669da498b74f4d78e42dca9
4
- data.tar.gz: 26e4591a34a4b9b7405181b584df64e04290c62777620ccac4ebf5afa85d8270
3
+ metadata.gz: 7b0ae546cf6416b998bfd75490dae5b662d89c3e6e598958f1c73c86e51fda17
4
+ data.tar.gz: bcc69294f383f7832b3ac832742c89630eb7d8a880741aefd7c0397a88cb9042
5
5
  SHA512:
6
- metadata.gz: 3bb478289ca360a81006c2d7eeac834e87fe08805a7374086cd0996babb2099122ef769131ea98c8d59a6d2d2fa9ea9156db6a9457642a2b6dabd8efdbf56b8a
7
- data.tar.gz: 2b82edcc6fc0ebd2bbeea606ab24206dd6358bbf6472ddcb3ca7e5869f2b79df07253786e0f123abb56c2c3541999f465187e98eb4a1be6894245bd74b5af014
6
+ metadata.gz: f746fba3dad2802bce2170facba75809d44fee26f29cf61a95c1c74245c61668f1fd75fed47722ab50bfc7676093b287b16e4e1683b280f99fd18715321e8574
7
+ data.tar.gz: fe15c859e3ff938901b7ef369e80346dc005be4451e4c2abd2cd45bd778b0b5b8939c3d0201ae78e4802c8d3aec6475779d94ab96a12857eec61e3e8d9476a7b
data/.rubocop.yml CHANGED
@@ -20,7 +20,7 @@ Metrics/BlockNesting:
20
20
  Metrics/BlockLength:
21
21
  Max: 130
22
22
  Metrics/ClassLength:
23
- Max: 500
23
+ Max: 600
24
24
  Layout/EndOfLine:
25
25
  EnforcedStyle: lf
26
26
  Metrics/ParameterLists:
@@ -171,7 +171,7 @@ run 'zold remote update' or use --tolerate-quorum=1"
171
171
  raise "The balance of #{id} is #{wallet.balance} and it's not a root wallet"
172
172
  end
173
173
  copy = cps.add(IO.read(f), score.host, score.port, score.value, master: r.master?)
174
- @log.info("#{r} returned #{wallet.mnemo} #{Age.new(json['mtime'])}/#{json['copies']}c \
174
+ @log.debug("#{r} returned #{wallet.mnemo} #{Age.new(json['mtime'])}/#{json['copies']}c \
175
175
  as copy ##{copy}/#{cps.all.count} in #{Age.new(start, limit: 4)}: \
176
176
  #{Rainbow(score.value).green} (#{json['version']})")
177
177
  end
@@ -45,6 +45,7 @@ require_relative '../node/async_entrance'
45
45
  require_relative '../node/sync_entrance'
46
46
  require_relative '../node/nodup_entrance'
47
47
  require_relative '../node/nospam_entrance'
48
+ require_relative '../node/journaled_entrance'
48
49
  require_relative '../node/front'
49
50
  require_relative '../node/trace'
50
51
  require_relative '../node/farm'
@@ -235,10 +236,10 @@ the node won\'t connect to the network like that; try to do "zold remote reset"
235
236
  #{@remotes.all.map { |r| "#{r[:host]}:#{r[:port]}" }.join(', ')}")
236
237
  @log.info("Wallets at: #{@wallets.path}")
237
238
  if opts['standalone']
238
- @remotes = Zold::Remotes::Empty.new
239
+ @remotes = Remotes::Empty.new
239
240
  @log.info('Running in standalone mode! (will never talk to other remotes)')
240
241
  elsif @remotes.exists?(host, port)
241
- Zold::Remote.new(remotes: @remotes).run(['remote', 'remove', host, port.to_s])
242
+ Remote.new(remotes: @remotes).run(['remote', 'remove', host, port.to_s])
242
243
  @log.info("Removed current node (#{address}) from list of remotes")
243
244
  end
244
245
  if File.exist?(@copies)
@@ -249,8 +250,8 @@ the node won\'t connect to the network like that; try to do "zold remote reset"
249
250
  if opts['not-hungry']
250
251
  @log.info('Hungry pulling disabled because of --not-hungry')
251
252
  else
252
- hungry = Zold::ThreadPool.new('hungry', log: @log)
253
- wts = Zold::HungryWallets.new(@wallets, @remotes, @copies, hungry, log: @log, network: opts['network'])
253
+ hungry = ThreadPool.new('hungry', log: @log)
254
+ wts = HungryWallets.new(@wallets, @remotes, @copies, hungry, log: @log, network: opts['network'])
254
255
  end
255
256
  Front.set(:zache, Zache.new(dirty: true))
256
257
  Front.set(:wallets, wts)
@@ -266,17 +267,29 @@ the node won\'t connect to the network like that; try to do "zold remote reset"
266
267
  async_dir = File.join(home, '.zoldata/async-entrance')
267
268
  FileUtils.mkdir_p(async_dir)
268
269
  Front.set(:async_dir, async_dir)
270
+ journal_dir = File.join(home, '.zoldata/journal')
271
+ FileUtils.mkdir_p(journal_dir)
272
+ Front.set(:journal_dir, journal_dir)
269
273
  Front.set(:node_alias, node_alias(opts, address))
274
+ jlog = Logger.new(File.join(journal_dir, 'journal'))
275
+ jlog.level = Logger::DEBUG
276
+ jlog.formatter = Log::COMPACT
270
277
  entrance = SafeEntrance.new(
271
278
  NoSpamEntrance.new(
272
279
  NoDupEntrance.new(
273
280
  AsyncEntrance.new(
274
281
  SpreadEntrance.new(
275
282
  SyncEntrance.new(
276
- Entrance.new(
277
- wts, @remotes, @copies, address,
278
- ledger: ledger,
279
- log: @log, network: opts['network']
283
+ JournaledEntrance.new(
284
+ Entrance.new(
285
+ wts, @remotes, @copies, address,
286
+ ledger: ledger,
287
+ log: Log::Tee.new(@log, jlog), network: opts['network']
288
+ ),
289
+ wts,
290
+ journal_dir,
291
+ jlog,
292
+ 'journal'
280
293
  ),
281
294
  File.join(home, '.zoldata/sync-entrance'),
282
295
  log: @log
@@ -135,10 +135,8 @@ out of #{nodes.value} in #{Age.new(start)}, total score for #{id} is #{total.val
135
135
  r.assert_valid_score(score)
136
136
  r.assert_score_ownership(score)
137
137
  r.assert_score_strength(score) unless opts['ignore-score-weakness']
138
- if @log.info?
139
- @log.info("#{r} accepted #{@wallets.acq(id, &:mnemo)} in #{Age.new(start, limit: 4)}: \
138
+ @log.debug("#{r} accepted #{@wallets.acq(id, &:mnemo)} in #{Age.new(start, limit: 4)}: \
140
139
  #{Rainbow(score.value).green} (#{json['version']})")
141
- end
142
140
  score.value
143
141
  end
144
142
  end
@@ -153,7 +151,7 @@ out of #{nodes.value} in #{Age.new(start)}, total score for #{id} is #{total.val
153
151
  r.http(uri).put(f)
154
152
  end
155
153
  if response.status == 304
156
- @log.info("#{r}: same version of #{@wallets.acq(id, &:mnemo)} there, didn't push \
154
+ @log.debug("#{r}: same version of #{@wallets.acq(id, &:mnemo)} there, didn't push \
157
155
  in #{Age.new(start, limit: 0.5)}")
158
156
  return 0
159
157
  end
@@ -164,7 +162,7 @@ in #{Age.new(start, limit: 0.5)}")
164
162
  rescue JsonPage::CantParse, Score::CantParse, RemoteNode::CantAssert => e
165
163
  attempt += 1
166
164
  if attempt < opts['retry']
167
- @log.error("#{r} failed to push #{id}, trying again (attempt no.#{attempt}): #{e.message}")
165
+ @log.debug("#{r} failed to push #{id}, trying again (attempt no.#{attempt}): #{e.message}")
168
166
  retry
169
167
  end
170
168
  raise e
@@ -316,7 +316,7 @@ Available options:"
316
316
  rescue JsonPage::CantParse, Score::CantParse, RemoteNode::CantAssert => e
317
317
  attempt += 1
318
318
  if attempt < opts['retry']
319
- @log.error("#{r} failed to read, trying again (attempt no.#{attempt}): #{e.message}")
319
+ @log.debug("#{r} failed to read, trying again (attempt no.#{attempt}): #{e.message}")
320
320
  retry
321
321
  end
322
322
  raise e
@@ -354,7 +354,7 @@ it's recommended to reboot, but I don't do it because of --never-reboot")
354
354
  @remotes.remove(r[:host], r[:port])
355
355
  @log.debug("Remote #{r[:host]}:#{r[:port]}/#{r[:score]}/#{r[:errors]}e removed from the list")
356
356
  end
357
- @log.info("#{@remotes.all.count} remote nodes were selected to stay in the list")
357
+ @log.info("#{@remotes.all.count} best remote nodes were selected to stay in the list")
358
358
  end
359
359
 
360
360
  def terminate
@@ -368,7 +368,7 @@ it's recommended to reboot, but I don't do it because of --never-reboot")
368
368
  res = Http.new(uri: "http://#{host}:#{port}/version", network: opts['network']).get
369
369
  return true if res.status == 200
370
370
  raise "The node #{host}:#{port} is not responding, #{res.status}:#{res.status_line}" unless opts['ignore-ping']
371
- @log.error("The node #{host}:#{port} is not responding, #{res.status}:#{res.status_line}")
371
+ @log.error("The node #{host}:#{port} is not responding but we --ignore-ping, #{res.status}:#{res.status_line}")
372
372
  false
373
373
  end
374
374
  end
@@ -57,12 +57,13 @@ module Zold
57
57
  unless wallet.exists?
58
58
  if @queue.size > 256
59
59
  @log.error("Hungry queue is full with #{@queue.size} wallets, can't add #{id}")
60
- elsif @missed.exists?(id)
61
- @log.error("Hungry queue has seen #{id} just #{Age.new(@missed.mtime(id))} ago and it was not-found")
60
+ elsif @missed.exists?(id.to_s)
61
+ @log.debug("Hungry queue has seen #{id} just #{Age.new(@missed.mtime(id.to_s))} ago
62
+ (amoung #{@missed.size} others) and it was not found")
62
63
  else
63
64
  @mutex.synchronize do
64
65
  unless @queue.include?(id)
65
- @missed.put(id, lifetime: 5 * 60)
66
+ @missed.put(id.to_s, lifetime: 5 * 60)
66
67
  @queue << id
67
68
  @log.debug("Hungry queue got #{id}, at the pos no.#{@queue.size - 1}")
68
69
  end
@@ -85,7 +86,7 @@ module Zold
85
86
  Pull.new(wallets: @wallets, remotes: @remotes, copies: @copies, log: @log).run(
86
87
  ['pull', id.to_s, "--network=#{@network}", '--tolerate-edges', '--tolerate-quorum=1']
87
88
  )
88
- @missed.remove(id)
89
+ @missed.remove(id.to_s)
89
90
  rescue Fetch::Error => e
90
91
  @log.error("Can't hungry-pull #{id}: #{e.message}")
91
92
  end
data/lib/zold/log.rb CHANGED
@@ -104,5 +104,36 @@ module Zold
104
104
  ERRORS.level = Logger::ERROR
105
105
  ERRORS.formatter = COMPACT
106
106
  ERRORS.freeze
107
+
108
+ # Tee logger.
109
+ class Tee
110
+ def initialize(first, second)
111
+ @first = first
112
+ @second = second
113
+ end
114
+
115
+ def debug(msg)
116
+ @first.debug(msg)
117
+ @second.debug(msg)
118
+ end
119
+
120
+ def debug?
121
+ @first.debug? || @second.debug?
122
+ end
123
+
124
+ def info(msg)
125
+ @first.info(msg)
126
+ @second.info(msg)
127
+ end
128
+
129
+ def info?
130
+ @first.info? || @second.info?
131
+ end
132
+
133
+ def error(msg)
134
+ @first.error(msg)
135
+ @second.error(msg)
136
+ end
137
+ end
107
138
  end
108
139
  end
@@ -82,6 +82,7 @@ module Zold
82
82
  set :node_alias, nil # to be injected at node.rb
83
83
  set :zache, nil # to be injected at node.rb
84
84
  set :async_dir, nil # to be injected at node.rb
85
+ set :journal_dir, nil # to be injected at node.rb
85
86
  end
86
87
  use Rack::Deflater
87
88
 
@@ -136,7 +137,7 @@ while #{settings.address} is in '#{settings.opts['network']}'")
136
137
  headers['X-Zold-Thread'] = Thread.current.object_id.to_s
137
138
  unless @start.nil?
138
139
  if Time.now - @start > 1
139
- settings.log.info("Slow response to #{request.request_method} #{request.url} \
140
+ settings.log.debug("Slow response to #{request.request_method} #{request.url} \
140
141
  from #{request.ip} in #{Age.new(@start, limit: 1)}")
141
142
  end
142
143
  headers['X-Zold-Milliseconds'] = ((Time.now - @start) * 1000).round.to_s
@@ -317,6 +318,43 @@ this is not a normal behavior, you may want to report a bug to our GitHub reposi
317
318
  end
318
319
  end
319
320
 
321
+ get %r{/wallet/(?<id>[A-Fa-f0-9]{16})\.html} do
322
+ fetch do |wallet|
323
+ [
324
+ '<!DOCTYPE html><html><head>',
325
+ '<title>' + wallet.id.to_s + '</title>',
326
+ '<link href="https://cdn.jsdelivr.net/gh/yegor256/tacit@gh-pages/tacit-css-1.4.2.min.css" rel="stylesheet"/>',
327
+ '<style>table { width: 100%; } td, th { padding: 0.2em .4em }</style>',
328
+ '</head><body><section>',
329
+ "<p>#{wallet.network}<br/>",
330
+ "#{wallet.protocol}<br/>",
331
+ "#{wallet.id}<br/>",
332
+ "#{wallet.key.to_pub}</p>",
333
+ '<table><thead><tr><th>Id</th><th>Date</th><th>Amount</th><th>Wallet</th><th>Details</th></thead>',
334
+ '<tbody>',
335
+ wallet.txns.map do |t|
336
+ [
337
+ '<tr>',
338
+ '<td style="color:' + (t.amount.negative? ? 'red' : 'green') + "\">#{t.id}</td>",
339
+ "<td>#{t.date.utc.iso8601}</td>",
340
+ '<td style="text-align:right">' + t.amount.to_zld(4) + '</td>',
341
+ "<td><a href='/wallet/#{t.bnf}.html'>#{t.bnf}</td>",
342
+ "<td>#{t.details}</td>",
343
+ '</tr>'
344
+ ].join
345
+ end.join,
346
+ '<p>&mdash;<br/>',
347
+ "Balance: #{wallet.balance.to_zld(8)} ZLD (#{wallet.balance.to_i} zents)<br/>",
348
+ "Transactions: #{wallet.txns.count}<br/>",
349
+ "Taxes: #{Tax.new(wallet).paid} paid, the debt is #{Tax.new(wallet).debt}<br/>",
350
+ "File size: #{Size.new(wallet.size)}/#{wallet.size}, \
351
+ #{Copies.new(File.join(settings.copies, wallet.id)).all.count} copies<br/>",
352
+ "Modified: #{wallet.mtime.utc.iso8601} (#{Age.new(wallet.mtime.utc.iso8601)} ago)<br/>",
353
+ "Digest: #{wallet.digest}</p></section></body></html>"
354
+ ].join
355
+ end
356
+ end
357
+
320
358
  get %r{/wallet/(?<id>[A-Fa-f0-9]{16})\.bin} do
321
359
  fetch { |w| send_file(w.path) }
322
360
  end
@@ -442,6 +480,25 @@ this is not a normal behavior, you may want to report a bug to our GitHub reposi
442
480
  end.join("\n")
443
481
  end
444
482
 
483
+ get '/journal' do
484
+ content_type('text/html')
485
+ [
486
+ '<!DOCTYPE html><html><head>',
487
+ '<title>/journal</title>',
488
+ '<link href="https://cdn.jsdelivr.net/gh/yegor256/tacit@gh-pages/tacit-css-1.4.2.min.css" rel="stylesheet"/>',
489
+ '</head><body><section>',
490
+ DirItems.new(settings.journal_dir).fetch.sort.map do |f|
491
+ "<p><a href='/journal/item?id=#{f}'>#{f}</a></p>"
492
+ end.join,
493
+ '</section></body></html>'
494
+ ].join
495
+ end
496
+
497
+ get '/journal/item' do
498
+ content_type('text/plain')
499
+ IO.read(File.join(settings.journal_dir, params[:id]))
500
+ end
501
+
445
502
  not_found do
446
503
  status(404)
447
504
  content_type('text/plain')
@@ -0,0 +1,96 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright (c) 2018-2019 Zerocracy, Inc.
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the 'Software'), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in all
13
+ # copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ # SOFTWARE.
22
+
23
+ require 'tempfile'
24
+ require_relative '../log'
25
+ require_relative '../remotes'
26
+ require_relative '../copies'
27
+ require_relative '../tax'
28
+ require_relative '../age'
29
+ require_relative '../commands/clean'
30
+ require_relative '../commands/merge'
31
+ require_relative '../commands/fetch'
32
+ require_relative '../commands/push'
33
+
34
+ # The entrance with journals.
35
+ # Author:: Yegor Bugayenko (yegor256@gmail.com)
36
+ # Copyright:: Copyright (c) 2018 Yegor Bugayenko
37
+ # License:: MIT
38
+ module Zold
39
+ # The entrance that keeps a journal for each wallet
40
+ class JournaledEntrance
41
+ # Decorated wallets
42
+ class Wallets < SimpleDelegator
43
+ def initialize(wallets, log)
44
+ @wallets = wallets
45
+ @log = log
46
+ super(wallets)
47
+ end
48
+
49
+ def acq(id, exclusive: false)
50
+ @wallets.acq(id, exclusive: exclusive) do |wallet|
51
+ return yield wallet unless exclusive
52
+ before = wallet.exists? ? IO.read(wallet.path) : ''
53
+ res = yield wallet
54
+ after = wallet.exists? ? IO.read(wallet.path) : ''
55
+ unless before == after
56
+ diff = Diffy::Diff.new(before, after, context: 0).to_s
57
+ @log.info("The wallet #{id} was modified:\n #{diff.gsub("\n", "\n ")}")
58
+ end
59
+ res
60
+ end
61
+ end
62
+ end
63
+
64
+ def initialize(entrance, wallets, dir, log, journal)
65
+ @wallets = JournaledEntrance::Wallets.new(wallets, log)
66
+ @entrance = entrance
67
+ @dir = File.expand_path(dir)
68
+ @log = log
69
+ @journal = File.join(@dir, journal)
70
+ end
71
+
72
+ def start
73
+ raise 'Block must be given to start()' unless block_given?
74
+ FileUtils.mkdir_p(@dir)
75
+ yield(self)
76
+ end
77
+
78
+ def to_json
79
+ @entrance.to_json.merge(
80
+ 'dir': @dir
81
+ )
82
+ end
83
+
84
+ # Returns a list of modifed wallets (as Zold::Id)
85
+ def push(id, body)
86
+ DirItems.new(@dir).fetch.each do |f|
87
+ f = File.join(@dir, f)
88
+ File.delete(f) if File.mtime(f) < Time.now - 24 * 60 * 60
89
+ end
90
+ @log.info("push(#{id}, #{body.length} bytes)")
91
+ modified = @entrance.push(id, body)
92
+ IO.write(File.join(@dir, "#{Time.now.utc.iso8601.gsub(/[^0-9]/, '-')}-#{id}"), IO.read(@journal))
93
+ modified
94
+ end
95
+ end
96
+ end
data/lib/zold/patch.rb CHANGED
@@ -172,7 +172,7 @@ doesn't have this transaction: \"#{txn.to_text}\"")
172
172
  end
173
173
  temp.refurbish
174
174
  if temp.balance.negative? && !temp.id.root? && !allow_negative_balance
175
- @log.info("The balance is negative, won't merge: #{wallet.mnemo}")
175
+ @log.info("The balance is negative, won't merge #{temp.mnemo} on top of #{wallet.mnemo}")
176
176
  else
177
177
  FileUtils.mkdir_p(File.dirname(file))
178
178
  IO.write(file, IO.read(f.path))
data/lib/zold/txn.rb CHANGED
@@ -128,7 +128,7 @@ module Zold
128
128
  end
129
129
 
130
130
  def to_text
131
- start = @amount.negative? ? "##{@id}" : '-'
131
+ start = @amount.negative? ? "##{@id}" : "(#{@id})"
132
132
  "#{start} #{@date.utc.iso8601} #{@amount} #{@bnf} #{@details}"
133
133
  end
134
134
 
data/lib/zold/version.rb CHANGED
@@ -25,7 +25,7 @@
25
25
  # Copyright:: Copyright (c) 2018 Yegor Bugayenko
26
26
  # License:: MIT
27
27
  module Zold
28
- VERSION = '0.26.15'
28
+ VERSION = '0.26.16'
29
29
  PROTOCOL = 2
30
30
  REPO = 'zold-io/zold'
31
31
  end
@@ -63,27 +63,6 @@ class TestMerge < Zold::Test
63
63
  end
64
64
  end
65
65
 
66
- def test_merges_into_empty_wallet
67
- FakeHome.new(log: test_log).run do |home|
68
- wallet = home.create_wallet
69
- first = home.create_wallet
70
- IO.write(first.path, IO.read(wallet.path))
71
- second = home.create_wallet
72
- IO.write(second.path, IO.read(wallet.path))
73
- Zold::Pay.new(wallets: home.wallets, copies: home.dir, remotes: home.remotes, log: test_log).run(
74
- ['pay', wallet.id.to_s, "NOPREFIX@#{Zold::Id.new}", '14.95', '--force', '--private-key=fixtures/id_rsa']
75
- )
76
- copies = home.copies(wallet)
77
- copies.add(IO.read(first.path), 'host-1', 80, 5)
78
- copies.add(IO.read(second.path), 'host-2', 80, 5)
79
- modified = Zold::Merge.new(wallets: home.wallets, remotes: home.remotes, copies: copies.root, log: test_log).run(
80
- ['merge', wallet.id.to_s]
81
- )
82
- assert(1, modified.count)
83
- assert(wallet.id, modified[0])
84
- end
85
- end
86
-
87
66
  def test_merges_with_a_broken_copy
88
67
  FakeHome.new(log: test_log).run do |home|
89
68
  wallet = home.create_wallet
@@ -45,7 +45,7 @@ class FrontTest < Zold::Test
45
45
  def test_memory_leakage
46
46
  skip
47
47
  report = MemoryProfiler.report(top: 10) do
48
- FakeNode.new(log: test_log).run(['--no-metronome', '--network=foo', '--threads=0']) do |port|
48
+ FakeNode.new(log: test_log).run(opts('--network=foo')) do |port|
49
49
  100.times do
50
50
  Zold::Http.new(uri: "http://localhost:#{port}/", network: 'foo').get
51
51
  end
@@ -55,7 +55,7 @@ class FrontTest < Zold::Test
55
55
  end
56
56
 
57
57
  def test_renders_front_json
58
- FakeNode.new(log: test_log).run(['--no-metronome', '--network=foo', '--threads=0']) do |port|
58
+ FakeNode.new(log: test_log).run(opts('--network=foo')) do |port|
59
59
  res = Zold::Http.new(uri: "http://localhost:#{port}/", network: 'foo').get
60
60
  json = JSON.parse(res.body)
61
61
  assert_equal(Zold::VERSION, json['version'])
@@ -73,7 +73,7 @@ class FrontTest < Zold::Test
73
73
  end
74
74
 
75
75
  def test_renders_public_pages
76
- FakeNode.new(log: test_log).run(['--ignore-score-weakness', '--no-metronome', '--threads=0']) do |port|
76
+ FakeNode.new(log: test_log).run(opts) do |port|
77
77
  {
78
78
  200 => [
79
79
  '/robots.txt',
@@ -85,6 +85,7 @@ class FrontTest < Zold::Test
85
85
  '/ledger',
86
86
  '/ledger.json',
87
87
  '/metronome',
88
+ '/journal',
88
89
  '/score',
89
90
  '/queue',
90
91
  '/trace',
@@ -115,7 +116,7 @@ class FrontTest < Zold::Test
115
116
  end
116
117
 
117
118
  def test_updates_list_of_remotes
118
- FakeNode.new(log: test_log).run(['--ignore-score-weakness', '--no-metronome', '--no-cache']) do |port|
119
+ FakeNode.new(log: test_log).run(['--no-metronome', '--ignore-score-weakness', '--no-cache']) do |port|
119
120
  (Zold::Remotes::MAX_NODES + 5).times do |i|
120
121
  score = Zold::Score.new(
121
122
  host: 'localhost', port: i + 1, invoice: 'NOPREFIX@ffffffffffffffff', strength: 1
@@ -136,7 +137,7 @@ class FrontTest < Zold::Test
136
137
  end
137
138
 
138
139
  def test_increments_score
139
- FakeNode.new(log: test_log).run(['--threads=1', '--strength=1', '--no-metronome', '--no-cache']) do |port|
140
+ FakeNode.new(log: test_log).run(opts('--threads=1')) do |port|
140
141
  3.times do |i|
141
142
  assert_equal_wait(true) do
142
143
  response = Zold::Http.new(uri: "http://localhost:#{port}/").get
@@ -150,28 +151,20 @@ class FrontTest < Zold::Test
150
151
 
151
152
  def test_renders_wallet_pages
152
153
  FakeHome.new(log: test_log).run do |home|
153
- FakeNode.new(log: test_log).run(['--ignore-score-weakness', '--standalone']) do |port|
154
+ FakeNode.new(log: test_log).run(opts) do |port|
154
155
  wallet = home.create_wallet(txns: 2)
155
156
  base = "http://localhost:#{port}"
156
157
  response = Zold::Http.new(uri: "#{base}/wallet/#{wallet.id}").put(wallet.path)
157
158
  assert_equal(200, response.status, response.body)
158
159
  assert_equal_wait(200) { Zold::Http.new(uri: "#{base}/wallet/#{wallet.id}").get.status }
159
160
  [
160
- "/wallet/#{wallet.id}.txt",
161
- "/wallet/#{wallet.id}/balance",
162
- "/wallet/#{wallet.id}/key",
163
- "/wallet/#{wallet.id}/mtime",
164
- "/wallet/#{wallet.id}/digest",
165
- "/wallet/#{wallet.id}/size",
166
- "/wallet/#{wallet.id}/age",
167
- "/wallet/#{wallet.id}/mnemo",
168
- "/wallet/#{wallet.id}/debt",
169
- "/wallet/#{wallet.id}/txns",
170
- "/wallet/#{wallet.id}/txns.json",
171
- "/wallet/#{wallet.id}.bin",
172
- "/wallet/#{wallet.id}/copies"
161
+ '.txt', '.html',
162
+ '/balance', '/key', '/mtime',
163
+ '/digest', '/size',
164
+ '/age', '/mnemo', '/debt', '/txns',
165
+ '/txns.json', '.bin', '/copies'
173
166
  ].each do |u|
174
- assert_equal_wait(200) { Zold::Http.new(uri: "#{base}#{u}").get.status }
167
+ assert_equal_wait(200) { Zold::Http.new(uri: "#{base}/wallet/#{wallet.id}#{u}").get.status }
175
168
  end
176
169
  end
177
170
  end
@@ -179,7 +172,7 @@ class FrontTest < Zold::Test
179
172
 
180
173
  def test_renders_wallets_page
181
174
  FakeHome.new(log: test_log).run do |home|
182
- FakeNode.new(log: test_log).run(['--ignore-score-weakness', '--standalone']) do |port|
175
+ FakeNode.new(log: test_log).run(opts) do |port|
183
176
  wallet = home.create_wallet(txns: 2)
184
177
  base = "http://localhost:#{port}"
185
178
  response = Zold::Http.new(uri: "#{base}/wallet/#{wallet.id}").put(wallet.path)
@@ -193,7 +186,7 @@ class FrontTest < Zold::Test
193
186
  end
194
187
 
195
188
  def test_fetch_in_multiple_threads
196
- FakeNode.new(log: test_log).run(['--no-metronome', '--threads=0', '--standalone']) do |port|
189
+ FakeNode.new(log: test_log).run(opts) do |port|
197
190
  FakeHome.new(log: test_log).run do |home|
198
191
  wallet = home.create_wallet
199
192
  base = "http://localhost:#{port}"
@@ -214,7 +207,7 @@ class FrontTest < Zold::Test
214
207
  end
215
208
 
216
209
  def test_pushes_twice
217
- FakeNode.new(log: test_log).run(['--no-metronome', '--threads=0', '--standalone']) do |port|
210
+ FakeNode.new(log: test_log).run(opts) do |port|
218
211
  FakeHome.new(log: test_log).run do |home|
219
212
  wallet = home.create_wallet
220
213
  base = "http://localhost:#{port}"
@@ -232,7 +225,7 @@ class FrontTest < Zold::Test
232
225
  end
233
226
 
234
227
  def test_pushes_many_wallets
235
- FakeNode.new(log: test_log).run(['--no-metronome', '--threads=0', '--standalone']) do |port|
228
+ FakeNode.new(log: test_log).run(opts) do |port|
236
229
  base = "http://localhost:#{port}"
237
230
  FakeHome.new(log: test_log).run do |home|
238
231
  Threads.new(5).assert do
@@ -278,7 +271,7 @@ class FrontTest < Zold::Test
278
271
  end
279
272
 
280
273
  def test_gzip
281
- FakeNode.new(log: test_log).run(['--ignore-score-weakness']) do |port|
274
+ FakeNode.new(log: test_log).run(opts) do |port|
282
275
  response = Zold::Http.new(uri: URI("http://localhost:#{port}/version")).get
283
276
  assert_equal(200, response.status, response)
284
277
  assert_operator(300, :>, response.body.length.to_i, 'Expected the content to be small')
@@ -287,7 +280,7 @@ class FrontTest < Zold::Test
287
280
 
288
281
  def test_performance
289
282
  times = Queue.new
290
- FakeNode.new(log: test_log).run(['--threads=4', '--strength=6', '--no-metronome']) do |port|
283
+ FakeNode.new(log: test_log).run(opts('--threads=4', '--strength=6')) do |port|
291
284
  Threads.new(10).assert(100) do
292
285
  start = Time.now
293
286
  Zold::Http.new(uri: URI("http://localhost:#{port}/")).get
@@ -304,7 +297,7 @@ class FrontTest < Zold::Test
304
297
  # HTTP request. This value is enough to identify a valueable node, and filter
305
298
  # out those that are too weak.
306
299
  def test_score_is_reduced
307
- FakeNode.new(log: test_log).run(['--threads=1', '--strength=1', '--no-metronome', '--farmer=plain']) do |port|
300
+ FakeNode.new(log: test_log).run(opts('--threads=1', '--strength=1', '--farmer=plain')) do |port|
308
301
  scores = []
309
302
  50.times do
310
303
  res = Zold::Http.new(uri: URI("http://localhost:#{port}/")).get
@@ -316,7 +309,7 @@ class FrontTest < Zold::Test
316
309
  end
317
310
 
318
311
  def test_headers_are_being_set_correctly
319
- FakeNode.new(log: test_log).run(['--expose-version=9.9.9', '--no-metronome', '--threads=0']) do |port|
312
+ FakeNode.new(log: test_log).run(opts('--expose-version=9.9.9')) do |port|
320
313
  response = Zold::Http.new(uri: URI("http://localhost:#{port}/")).get
321
314
  assert_equal('no-cache', response.headers['Cache-Control'])
322
315
  assert_equal('close', response.headers['Connection'])
@@ -330,7 +323,7 @@ class FrontTest < Zold::Test
330
323
 
331
324
  def test_alias_parameter
332
325
  name = SecureRandom.hex(4)
333
- FakeNode.new(log: test_log).run(['--ignore-score-weakness', "--alias=#{name}"]) do |port|
326
+ FakeNode.new(log: test_log).run(opts("--alias=#{name}")) do |port|
334
327
  uri = URI("http://localhost:#{port}/")
335
328
  response = Zold::Http.new(uri: uri).get
336
329
  assert_match(
@@ -342,7 +335,7 @@ class FrontTest < Zold::Test
342
335
  end
343
336
 
344
337
  def test_default_alias_parameter
345
- FakeNode.new(log: test_log).run(['--ignore-score-weakness', '--no-metronome']) do |port|
338
+ FakeNode.new(log: test_log).run(opts) do |port|
346
339
  uri = URI("http://localhost:#{port}/")
347
340
  response = Zold::Http.new(uri: uri).get
348
341
  assert_match(
@@ -355,7 +348,7 @@ class FrontTest < Zold::Test
355
348
 
356
349
  def test_invalid_alias
357
350
  exception = assert_raises RuntimeError do
358
- FakeNode.new(log: test_log).run(['--ignore-score-weakness', '--alias=invalid-alias']) do |port|
351
+ FakeNode.new(log: test_log).run(opts('--alias=invalid-alias')) do |port|
359
352
  uri = URI("http://localhost:#{port}/")
360
353
  Zold::Http.new(uri: uri).get
361
354
  end
@@ -365,7 +358,7 @@ class FrontTest < Zold::Test
365
358
 
366
359
  def test_push_fetch_in_multiple_threads
367
360
  key = Zold::Key.new(text: IO.read('fixtures/id_rsa'))
368
- FakeNode.new(log: test_log).run(['--no-metronome', '--threads=0', '--standalone']) do |port|
361
+ FakeNode.new(log: test_log).run(opts) do |port|
369
362
  FakeHome.new(log: test_log).run do |home|
370
363
  wallet = home.create_wallet(Zold::Id::ROOT)
371
364
  base = "http://localhost:#{port}"
@@ -383,4 +376,10 @@ class FrontTest < Zold::Test
383
376
  end
384
377
  end
385
378
  end
379
+
380
+ private
381
+
382
+ def opts(*extra)
383
+ ['--no-metronome', '--ignore-score-weakness', '--standalone', '--threads=0', '--strength=1'] + extra
384
+ end
386
385
  end
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.26.15
4
+ version: 0.26.16
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yegor Bugayenko
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-03-12 00:00:00.000000000 Z
11
+ date: 2019-03-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: backtrace
@@ -671,6 +671,7 @@ files:
671
671
  - lib/zold/node/farm.rb
672
672
  - lib/zold/node/farmers.rb
673
673
  - lib/zold/node/front.rb
674
+ - lib/zold/node/journaled_entrance.rb
674
675
  - lib/zold/node/nodup_entrance.rb
675
676
  - lib/zold/node/nospam_entrance.rb
676
677
  - lib/zold/node/safe_entrance.rb
@@ -779,7 +780,7 @@ licenses:
779
780
  - MIT
780
781
  metadata: {}
781
782
  post_install_message: |-
782
- Thanks for installing Zold 0.26.15!
783
+ Thanks for installing Zold 0.26.16!
783
784
  Study our White Paper: https://papers.zold.io/wp.pdf
784
785
  Read our blog posts: https://blog.zold.io
785
786
  Try ZLD online wallet at: https://wts.zold.io