zold 0.26.15 → 0.26.16
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +1 -1
- data/lib/zold/commands/fetch.rb +1 -1
- data/lib/zold/commands/node.rb +21 -8
- data/lib/zold/commands/push.rb +3 -5
- data/lib/zold/commands/remote.rb +3 -3
- data/lib/zold/hungry_wallets.rb +5 -4
- data/lib/zold/log.rb +31 -0
- data/lib/zold/node/front.rb +58 -1
- data/lib/zold/node/journaled_entrance.rb +96 -0
- data/lib/zold/patch.rb +1 -1
- data/lib/zold/txn.rb +1 -1
- data/lib/zold/version.rb +1 -1
- data/test/commands/test_merge.rb +0 -21
- data/test/node/test_front.rb +31 -32
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7b0ae546cf6416b998bfd75490dae5b662d89c3e6e598958f1c73c86e51fda17
|
4
|
+
data.tar.gz: bcc69294f383f7832b3ac832742c89630eb7d8a880741aefd7c0397a88cb9042
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f746fba3dad2802bce2170facba75809d44fee26f29cf61a95c1c74245c61668f1fd75fed47722ab50bfc7676093b287b16e4e1683b280f99fd18715321e8574
|
7
|
+
data.tar.gz: fe15c859e3ff938901b7ef369e80346dc005be4451e4c2abd2cd45bd778b0b5b8939c3d0201ae78e4802c8d3aec6475779d94ab96a12857eec61e3e8d9476a7b
|
data/.rubocop.yml
CHANGED
data/lib/zold/commands/fetch.rb
CHANGED
@@ -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.
|
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
|
data/lib/zold/commands/node.rb
CHANGED
@@ -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 =
|
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
|
-
|
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 =
|
253
|
-
wts =
|
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
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
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
|
data/lib/zold/commands/push.rb
CHANGED
@@ -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
|
-
|
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.
|
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.
|
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
|
data/lib/zold/commands/remote.rb
CHANGED
@@ -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.
|
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
|
data/lib/zold/hungry_wallets.rb
CHANGED
@@ -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.
|
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
|
data/lib/zold/node/front.rb
CHANGED
@@ -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.
|
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>—<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
|
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
data/lib/zold/version.rb
CHANGED
data/test/commands/test_merge.rb
CHANGED
@@ -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
|
data/test/node/test_front.rb
CHANGED
@@ -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(
|
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(
|
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(
|
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(['--
|
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(
|
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(
|
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
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
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(
|
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(
|
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(
|
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(
|
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(
|
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(
|
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(
|
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(
|
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(
|
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(
|
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(
|
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(
|
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.
|
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-
|
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.
|
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
|