zold 0.17.10 → 0.18.0
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 +4 -4
- data/lib/zold/cached_wallets.rb +4 -0
- data/lib/zold/commands/propagate.rb +1 -1
- data/lib/zold/commands/remote.rb +3 -1
- data/lib/zold/http.rb +1 -1
- data/lib/zold/node/front.rb +8 -4
- data/lib/zold/remotes.rb +3 -3
- data/lib/zold/sync_wallets.rb +9 -3
- data/lib/zold/tax.rb +13 -3
- data/lib/zold/tree_wallets.rb +4 -0
- data/lib/zold/txn.rb +1 -1
- data/lib/zold/version.rb +1 -1
- data/lib/zold/wallets.rb +7 -0
- data/test/commands/test_remote.rb +3 -26
- data/test/node/test_front.rb +9 -11
- data/test/test_tree_wallets.rb +13 -0
- data/test/test_wallets.rb +10 -0
- data/zold.gemspec +1 -1
- metadata +5 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0ad2aeab01e066ea22a6fb9e5cd02c2d13a88e36f19e8ffc228c5f72d5b5bf1e
|
4
|
+
data.tar.gz: f87c069877d7741c99a38ebfade27d41721f9347a996b6ef4640c899ebe558af
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b47678bd890369fe2a3d09268c1f3ab35bb5e1707ae052353865c899334276b840099465e5a1be46537021e60a01891dafca7071b95a85ff8fe9fb90c02fcf9c
|
7
|
+
data.tar.gz: 8769ceb3b043b1eb7fe0de15be8574ae1ff5f9191fadbe58daa6c1de25ca2768652faac9c636229d181ed0039352fffc75d5673b04de5c9f2ed953d009e2dd52
|
data/lib/zold/cached_wallets.rb
CHANGED
@@ -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
|
data/lib/zold/commands/remote.rb
CHANGED
@@ -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).
|
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
|
data/lib/zold/node/front.rb
CHANGED
@@ -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.
|
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
|
-
|
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.
|
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 =
|
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
|
|
data/lib/zold/sync_wallets.rb
CHANGED
@@ -23,17 +23,19 @@
|
|
23
23
|
require 'futex'
|
24
24
|
require_relative 'log'
|
25
25
|
|
26
|
-
#
|
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,
|
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)
|
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.
|
105
|
+
score = Score.parse(body)
|
98
106
|
next if !score.valid? || score.value != EXACT_SCORE
|
99
|
-
|
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)
|
data/lib/zold/tree_wallets.rb
CHANGED
data/lib/zold/txn.rb
CHANGED
data/lib/zold/version.rb
CHANGED
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
|
-
|
181
|
-
|
182
|
-
|
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)
|
data/test/node/test_front.rb
CHANGED
@@ -295,17 +295,15 @@ class FrontTest < Zold::Test
|
|
295
295
|
end
|
296
296
|
|
297
297
|
def test_headers_are_being_set_correctly
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
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
|
|
data/test/test_tree_wallets.rb
CHANGED
@@ -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.
|
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.
|
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-
|
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.
|
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.
|
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.
|
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
|